Re: [PATCH] net: fix the per task frag allocator size

2018-11-22 Thread Yunsheng Lin
On 2018/11/23 10:03, Li RongQing wrote:
> when fill task frag, 32K pages, 128MB memory is asked, it
> hardly successes when system has memory stress
> 
> and commit '5640f7685831 ("net: use a per task frag allocator")'
> said it wants 32768 bytes, not 32768 pages:
> 
>"(up to 32768 bytes per frag, thats order-3 pages on x86)"
> 
> Fixes: 5640f7685831e ("net: use a per task frag allocator")
> Signed-off-by: Zhang Yu 
> Signed-off-by: Li RongQing 
> ---
>  net/core/sock.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 6d7e189e3cd9..e3cbefeedf5c 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -2186,8 +2186,8 @@ static void sk_leave_memory_pressure(struct sock *sk)
>   }
>  }
>  
> -/* On 32bit arches, an skb frag is limited to 2^15 */
> -#define SKB_FRAG_PAGE_ORDER  get_order(32768)
> +/* On 32bit arches, an skb frag is limited to 2^15 bytes*/
> +#define SKB_FRAG_PAGE_ORDER  get_order(8)

get_order(8) returns zero here if I understood it correctly.


>  
>  /**
>   * skb_page_frag_refill - check that a page_frag contains enough room
> 



Re: [Patch net-next] net: dump more useful information in netdev_rx_csum_fault()

2018-11-09 Thread Yunsheng Lin
On 2018/11/10 10:09, Cong Wang wrote:
> On Fri, Nov 9, 2018 at 6:02 PM Yunsheng Lin  wrote:
>>
>> On 2018/11/10 9:42, Cong Wang wrote:
>>> On Fri, Nov 9, 2018 at 5:39 PM Yunsheng Lin  wrote:
>>>>
>>>> On 2018/11/10 3:43, Cong Wang wrote:
>>>>> Currently netdev_rx_csum_fault() only shows a device name,
>>>>> we need more information about the skb for debugging.
>>>>>
>>>>> Sample output:
>>>>>
>>>>>  ens3: hw csum failure
>>>>>  dev features: 0x00014b89
>>>>>  skb len=84 data_len=0 gso_size=0 gso_type=0 ip_summed=0 csum=0, 
>>>>> csum_complete_sw=0, csum_valid=0
>>>>>
>>>>> Signed-off-by: Cong Wang 
>>>>> ---
>>>>>  include/linux/netdevice.h |  5 +++--
>>>>>  net/core/datagram.c   |  6 +++---
>>>>>  net/core/dev.c| 10 --
>>>>>  net/sunrpc/socklib.c  |  2 +-
>>>>>  4 files changed, 15 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>>>>> index 857f8abf7b91..fabcd9fa6cf7 100644
>>>>> --- a/include/linux/netdevice.h
>>>>> +++ b/include/linux/netdevice.h
>>>>> @@ -4332,9 +4332,10 @@ static inline bool 
>>>>> can_checksum_protocol(netdev_features_t features,
>>>>>  }
>>>>>
>>>>>  #ifdef CONFIG_BUG
>>>>> -void netdev_rx_csum_fault(struct net_device *dev);
>>>>> +void netdev_rx_csum_fault(struct net_device *dev, struct sk_buff *skb);
>>>>>  #else
>>>>> -static inline void netdev_rx_csum_fault(struct net_device *dev)
>>>>> +static inline void netdev_rx_csum_fault(struct net_device *dev,
>>>>> + struct sk_buff *skb)
>>>>>  {
>>>>>  }
>>>>>  #endif
>>>>> diff --git a/net/core/datagram.c b/net/core/datagram.c
>>>>> index 57f3a6fcfc1e..d8f4d55cd6c5 100644
>>>>> --- a/net/core/datagram.c
>>>>> +++ b/net/core/datagram.c
>>>>> @@ -736,7 +736,7 @@ __sum16 __skb_checksum_complete_head(struct sk_buff 
>>>>> *skb, int len)
>>>>>   if (likely(!sum)) {
>>>>>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>>>>>   !skb->csum_complete_sw)
>>>>> - netdev_rx_csum_fault(skb->dev);
>>>>> + netdev_rx_csum_fault(skb->dev, skb);
>>>>>   }
>>>>>   if (!skb_shared(skb))
>>>>>   skb->csum_valid = !sum;
>>>>> @@ -756,7 +756,7 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb)
>>>>>   if (likely(!sum)) {
>>>>>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>>>>>   !skb->csum_complete_sw)
>>>>> - netdev_rx_csum_fault(skb->dev);
>>>>> + netdev_rx_csum_fault(skb->dev, skb);
>>>>>   }
>>>>>
>>>>>   if (!skb_shared(skb)) {
>>>>> @@ -810,7 +810,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff 
>>>>> *skb,
>>>>>
>>>>>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>>>>>   !skb->csum_complete_sw)
>>>>> - netdev_rx_csum_fault(NULL);
>>>>> + netdev_rx_csum_fault(NULL, skb);
>>>>>   }
>>>>>   return 0;
>>>>>  fault:
>>>>> diff --git a/net/core/dev.c b/net/core/dev.c
>>>>> index 0ffcbdd55fa9..2b337df26117 100644
>>>>> --- a/net/core/dev.c
>>>>> +++ b/net/core/dev.c
>>>>> @@ -3091,10 +3091,16 @@ EXPORT_SYMBOL(__skb_gso_segment);
>>>>>
>>>>>  /* Take action when hardware reception checksum errors are detected. */
>>>>>  #ifdef CONFIG_BUG
>>>>> -void netdev_rx_csum_fault(struct net_device *dev)
>>>>> +void netdev_rx_csum_fault(struct net_device *dev, struct sk_buff *skb)
>>>>>  {
>>>>>   if (net_ratelimit()) {
>>>>>   pr_err("%s: hw csum failure\n", dev ? dev->name : 
>>>>> ""

Re: [Patch net-next] net: dump more useful information in netdev_rx_csum_fault()

2018-11-09 Thread Yunsheng Lin
On 2018/11/10 9:42, Cong Wang wrote:
> On Fri, Nov 9, 2018 at 5:39 PM Yunsheng Lin  wrote:
>>
>> On 2018/11/10 3:43, Cong Wang wrote:
>>> Currently netdev_rx_csum_fault() only shows a device name,
>>> we need more information about the skb for debugging.
>>>
>>> Sample output:
>>>
>>>  ens3: hw csum failure
>>>  dev features: 0x00014b89
>>>  skb len=84 data_len=0 gso_size=0 gso_type=0 ip_summed=0 csum=0, 
>>> csum_complete_sw=0, csum_valid=0
>>>
>>> Signed-off-by: Cong Wang 
>>> ---
>>>  include/linux/netdevice.h |  5 +++--
>>>  net/core/datagram.c   |  6 +++---
>>>  net/core/dev.c| 10 --
>>>  net/sunrpc/socklib.c  |  2 +-
>>>  4 files changed, 15 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>>> index 857f8abf7b91..fabcd9fa6cf7 100644
>>> --- a/include/linux/netdevice.h
>>> +++ b/include/linux/netdevice.h
>>> @@ -4332,9 +4332,10 @@ static inline bool 
>>> can_checksum_protocol(netdev_features_t features,
>>>  }
>>>
>>>  #ifdef CONFIG_BUG
>>> -void netdev_rx_csum_fault(struct net_device *dev);
>>> +void netdev_rx_csum_fault(struct net_device *dev, struct sk_buff *skb);
>>>  #else
>>> -static inline void netdev_rx_csum_fault(struct net_device *dev)
>>> +static inline void netdev_rx_csum_fault(struct net_device *dev,
>>> + struct sk_buff *skb)
>>>  {
>>>  }
>>>  #endif
>>> diff --git a/net/core/datagram.c b/net/core/datagram.c
>>> index 57f3a6fcfc1e..d8f4d55cd6c5 100644
>>> --- a/net/core/datagram.c
>>> +++ b/net/core/datagram.c
>>> @@ -736,7 +736,7 @@ __sum16 __skb_checksum_complete_head(struct sk_buff 
>>> *skb, int len)
>>>   if (likely(!sum)) {
>>>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>>>   !skb->csum_complete_sw)
>>> - netdev_rx_csum_fault(skb->dev);
>>> + netdev_rx_csum_fault(skb->dev, skb);
>>>   }
>>>   if (!skb_shared(skb))
>>>   skb->csum_valid = !sum;
>>> @@ -756,7 +756,7 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb)
>>>   if (likely(!sum)) {
>>>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>>>   !skb->csum_complete_sw)
>>> - netdev_rx_csum_fault(skb->dev);
>>> + netdev_rx_csum_fault(skb->dev, skb);
>>>   }
>>>
>>>   if (!skb_shared(skb)) {
>>> @@ -810,7 +810,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
>>>
>>>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>>>   !skb->csum_complete_sw)
>>> - netdev_rx_csum_fault(NULL);
>>> + netdev_rx_csum_fault(NULL, skb);
>>>   }
>>>   return 0;
>>>  fault:
>>> diff --git a/net/core/dev.c b/net/core/dev.c
>>> index 0ffcbdd55fa9..2b337df26117 100644
>>> --- a/net/core/dev.c
>>> +++ b/net/core/dev.c
>>> @@ -3091,10 +3091,16 @@ EXPORT_SYMBOL(__skb_gso_segment);
>>>
>>>  /* Take action when hardware reception checksum errors are detected. */
>>>  #ifdef CONFIG_BUG
>>> -void netdev_rx_csum_fault(struct net_device *dev)
>>> +void netdev_rx_csum_fault(struct net_device *dev, struct sk_buff *skb)
>>>  {
>>>   if (net_ratelimit()) {
>>>   pr_err("%s: hw csum failure\n", dev ? dev->name : 
>>> "");
>>> + if (dev)
>>> + pr_err("dev features: %pNF\n", >features);
>>> + pr_err("skb len=%d data_len=%d gso_size=%d gso_type=%d 
>>> ip_summed=%d csum=%x, csum_complete_sw=%d, csum_valid=%d\n",
>>> +skb->len, skb->data_len, skb_shinfo(skb)->gso_size,
>>> +skb_shinfo(skb)->gso_type, skb->ip_summed, skb->csum,
>>> +skb->csum_complete_sw, skb->csum_valid);
>>
>>
>> This function also have the netdev available, use netdev_err to log the 
>> error?
> 
> It is apparently not me who picked pr_err() from the beginning,
> I just follow that pr_err(). If you are not happy with it, please send
> a followup.

Yes, but perhaps it is something to improve.
When using the netdev, then maybe it does not have to check if dev is null, 
because
netdev_err has handled the netdev being NULL case.
Maybe I missed something that netdev can not be used here?
If not, maybe I can send a followup.

> 
> 
>>
>> Also, dev->features was dumped before this patch, why remove it?
> 
> Seriously? Where do I remove it? Please be specific. :)

Sorry, I missed that, I thought it was removed when adding the new log.

> 
> .
> 



Re: [Patch net-next] net: dump more useful information in netdev_rx_csum_fault()

2018-11-09 Thread Yunsheng Lin
On 2018/11/10 3:43, Cong Wang wrote:
> Currently netdev_rx_csum_fault() only shows a device name,
> we need more information about the skb for debugging.
> 
> Sample output:
> 
>  ens3: hw csum failure
>  dev features: 0x00014b89
>  skb len=84 data_len=0 gso_size=0 gso_type=0 ip_summed=0 csum=0, 
> csum_complete_sw=0, csum_valid=0
> 
> Signed-off-by: Cong Wang 
> ---
>  include/linux/netdevice.h |  5 +++--
>  net/core/datagram.c   |  6 +++---
>  net/core/dev.c| 10 --
>  net/sunrpc/socklib.c  |  2 +-
>  4 files changed, 15 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 857f8abf7b91..fabcd9fa6cf7 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -4332,9 +4332,10 @@ static inline bool 
> can_checksum_protocol(netdev_features_t features,
>  }
>  
>  #ifdef CONFIG_BUG
> -void netdev_rx_csum_fault(struct net_device *dev);
> +void netdev_rx_csum_fault(struct net_device *dev, struct sk_buff *skb);
>  #else
> -static inline void netdev_rx_csum_fault(struct net_device *dev)
> +static inline void netdev_rx_csum_fault(struct net_device *dev,
> + struct sk_buff *skb)
>  {
>  }
>  #endif
> diff --git a/net/core/datagram.c b/net/core/datagram.c
> index 57f3a6fcfc1e..d8f4d55cd6c5 100644
> --- a/net/core/datagram.c
> +++ b/net/core/datagram.c
> @@ -736,7 +736,7 @@ __sum16 __skb_checksum_complete_head(struct sk_buff *skb, 
> int len)
>   if (likely(!sum)) {
>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>   !skb->csum_complete_sw)
> - netdev_rx_csum_fault(skb->dev);
> + netdev_rx_csum_fault(skb->dev, skb);
>   }
>   if (!skb_shared(skb))
>   skb->csum_valid = !sum;
> @@ -756,7 +756,7 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb)
>   if (likely(!sum)) {
>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>   !skb->csum_complete_sw)
> - netdev_rx_csum_fault(skb->dev);
> + netdev_rx_csum_fault(skb->dev, skb);
>   }
>  
>   if (!skb_shared(skb)) {
> @@ -810,7 +810,7 @@ int skb_copy_and_csum_datagram_msg(struct sk_buff *skb,
>  
>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>   !skb->csum_complete_sw)
> - netdev_rx_csum_fault(NULL);
> + netdev_rx_csum_fault(NULL, skb);
>   }
>   return 0;
>  fault:
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 0ffcbdd55fa9..2b337df26117 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -3091,10 +3091,16 @@ EXPORT_SYMBOL(__skb_gso_segment);
>  
>  /* Take action when hardware reception checksum errors are detected. */
>  #ifdef CONFIG_BUG
> -void netdev_rx_csum_fault(struct net_device *dev)
> +void netdev_rx_csum_fault(struct net_device *dev, struct sk_buff *skb)
>  {
>   if (net_ratelimit()) {
>   pr_err("%s: hw csum failure\n", dev ? dev->name : "");
> + if (dev)
> + pr_err("dev features: %pNF\n", >features);
> + pr_err("skb len=%d data_len=%d gso_size=%d gso_type=%d 
> ip_summed=%d csum=%x, csum_complete_sw=%d, csum_valid=%d\n",
> +skb->len, skb->data_len, skb_shinfo(skb)->gso_size,
> +skb_shinfo(skb)->gso_type, skb->ip_summed, skb->csum,
> +skb->csum_complete_sw, skb->csum_valid);


This function also have the netdev available, use netdev_err to log the error?

Also, dev->features was dumped before this patch, why remove it?


>   dump_stack();
>   }
>  }
> @@ -5779,7 +5785,7 @@ __sum16 __skb_gro_checksum_complete(struct sk_buff *skb)
>   if (likely(!sum)) {
>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>   !skb->csum_complete_sw)
> - netdev_rx_csum_fault(skb->dev);
> + netdev_rx_csum_fault(skb->dev, skb);
>   }
>  
>   NAPI_GRO_CB(skb)->csum = wsum;
> diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
> index 9062967575c4..7e55cfc69697 100644
> --- a/net/sunrpc/socklib.c
> +++ b/net/sunrpc/socklib.c
> @@ -175,7 +175,7 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct 
> sk_buff *skb)
>   return -1;
>   if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE) &&
>   !skb->csum_complete_sw)
> - netdev_rx_csum_fault(skb->dev);
> + netdev_rx_csum_fault(skb->dev, skb);
>   return 0;
>  no_checksum:
>   if (xdr_partial_copy_from_skb(xdr, 0, , xdr_skb_read_bits) < 0)
> 



Re: [PATCH][v2] xfrm: replace NR_CPU with nr_cpu_ids

2018-06-19 Thread Yunsheng Lin



On 2018/6/19 15:11, Li RongQing wrote:
> The default NR_CPUS can be very large, but actual possible nr_cpu_ids
> usually is very small. For some x86 distribution, the NR_CPUS is 8192
> and nr_cpu_ids is 4, so replace NR_CPU to save some memory
> 
> Signed-off-by: Li RongQing 
> Signed-off-by: Wang Li 
> ---
>  net/xfrm/xfrm_policy.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index 40b54cc64243..f8188685c1e9 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -2989,11 +2989,11 @@ void __init xfrm_init(void)
>  {
>   int i;
>  
> - xfrm_pcpu_work = kmalloc_array(NR_CPUS, sizeof(*xfrm_pcpu_work),
> + xfrm_pcpu_work = kmalloc_array(nr_cpu_ids, sizeof(*xfrm_pcpu_work),
>  GFP_KERNEL);

It seems that xfrm_pcpu_work is not used anymore, maybe it can be deleted to
save more memory.


>   BUG_ON(!xfrm_pcpu_work);
>  
> - for (i = 0; i < NR_CPUS; i++)
> + for (i = 0; i < nr_cpu_ids; i++)
>   INIT_WORK(_pcpu_work[i], xfrm_pcpu_work_fn);
>  
>   register_pernet_subsys(_net_ops);
> 



Re: [PATCH net 1/3] qed: Fix possible memory leak in Rx error path handling.

2018-06-19 Thread Yunsheng Lin



On 2018/6/19 14:42, Kalluru, Sudarsana wrote:
> 
> 
> -Original Message-
> From: Yunsheng Lin [mailto:linyunsh...@huawei.com] 
> Sent: 19 June 2018 11:32
> To: Kalluru, Sudarsana ; da...@davemloft.net
> Cc: netdev@vger.kernel.org; Elior, Ariel ; Kalderon, 
> Michal 
> Subject: Re: [PATCH net 1/3] qed: Fix possible memory leak in Rx error path 
> handling.
> 
> External Email
> 
> On 2018/6/19 12:58, Sudarsana Reddy Kalluru wrote:
>> Memory for packet buffers need to be freed in the error paths as there 
>> is no consumer (e.g., upper layer) for such packets and that memory 
>> will never get freed.
>> The issue was uncovered when port was attacked with flood of isatap 
>> packets, these are multicast packets hence were directed at all the PFs.
>> For foce PF, this meant they were routed to the ll2 module which in 
>> turn drops such packets.
>>
>> Fixes: 0a7fb11c ("qed: Add Light L2 support")
>> Signed-off-by: Sudarsana Reddy Kalluru 
>> Signed-off-by: Ariel Elior 
>> Signed-off-by: Michal Kalderon 
>> ---
>>  drivers/net/ethernet/qlogic/qed/qed_ll2.c | 11 +--
>>  1 file changed, 9 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c 
>> b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
>> index c97ebd6..012973d 100644
>> --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
>> +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
>> @@ -201,8 +201,9 @@ void qed_ll2b_complete_rx_packet(void *cxt, struct 
>> qed_ll2_comp_rx_data *data)
>>
>>   skb = build_skb(buffer->data, 0);
>>   if (!skb) {
>> - rc = -ENOMEM;
>> - goto out_post;
>> + DP_INFO(cdev, "Failed to build SKB\n");
>> + kfree(buffer->data);
>> + goto out_post1;
>>   }
>>
>>   data->u.placement_offset += NET_SKB_PAD; @@ -224,8 +225,14 @@ 
>> void qed_ll2b_complete_rx_packet(void *cxt, struct qed_ll2_comp_rx_data 
>> *data)
>>   cdev->ll2->cbs->rx_cb(cdev->ll2->cb_cookie, skb,
>> data->opaque_data_0,
>> data->opaque_data_1);
>> + } else {
>> + DP_VERBOSE(p_hwfn, (NETIF_MSG_RX_STATUS | NETIF_MSG_PKTDATA |
>> + QED_MSG_LL2 | QED_MSG_STORAGE),
>> +"Dropping the packet\n");
>> + kfree(buffer->data);
> 
> What about the memory used by skb itself?
> Does skb need to be freed by kfree_skb or something like that?
> 
> [Sudarsana] Thanks for reviewing the changes. qed_ll2_alloc_buffer() 
> allocates this memory. The allocated buffer (i.e., buffer->data) holds 
> complete memory for 'skb + data' as required by build_skb() implementation. 
> Hence freeing of (buffer->data) would suffice here. 

As I read through the code, the skb itself is allocated by kmem_cache_alloc,
see below:

build_skb -> __build_skb -> kmem_cache_alloc

Hope I am not missing something here.

> 
>>   }
>>
>> +out_post1:
>>   /* Update Buffer information and update FW producer */
>>   buffer->data = new_data;
>>   buffer->phys_addr = new_phys_addr;
>>
> 



Re: [PATCH net 1/3] qed: Fix possible memory leak in Rx error path handling.

2018-06-19 Thread Yunsheng Lin



On 2018/6/19 12:58, Sudarsana Reddy Kalluru wrote:
> Memory for packet buffers need to be freed in the error paths as there is
> no consumer (e.g., upper layer) for such packets and that memory will never
> get freed.
> The issue was uncovered when port was attacked with flood of isatap
> packets, these are multicast packets hence were directed at all the PFs.
> For foce PF, this meant they were routed to the ll2 module which in turn
> drops such packets.
> 
> Fixes: 0a7fb11c ("qed: Add Light L2 support")
> Signed-off-by: Sudarsana Reddy Kalluru 
> Signed-off-by: Ariel Elior 
> Signed-off-by: Michal Kalderon 
> ---
>  drivers/net/ethernet/qlogic/qed/qed_ll2.c | 11 +--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c 
> b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
> index c97ebd6..012973d 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
> @@ -201,8 +201,9 @@ void qed_ll2b_complete_rx_packet(void *cxt, struct 
> qed_ll2_comp_rx_data *data)
>  
>   skb = build_skb(buffer->data, 0);
>   if (!skb) {
> - rc = -ENOMEM;
> - goto out_post;
> + DP_INFO(cdev, "Failed to build SKB\n");
> + kfree(buffer->data);
> + goto out_post1;
>   }
>  
>   data->u.placement_offset += NET_SKB_PAD;
> @@ -224,8 +225,14 @@ void qed_ll2b_complete_rx_packet(void *cxt, struct 
> qed_ll2_comp_rx_data *data)
>   cdev->ll2->cbs->rx_cb(cdev->ll2->cb_cookie, skb,
> data->opaque_data_0,
> data->opaque_data_1);
> + } else {
> + DP_VERBOSE(p_hwfn, (NETIF_MSG_RX_STATUS | NETIF_MSG_PKTDATA |
> + QED_MSG_LL2 | QED_MSG_STORAGE),
> +"Dropping the packet\n");
> + kfree(buffer->data);

What about the memory used by skb itself?
Does skb need to be freed by kfree_skb or something like that?

>   }
>  
> +out_post1:
>   /* Update Buffer information and update FW producer */
>   buffer->data = new_data;
>   buffer->phys_addr = new_phys_addr;
> 



Re: BUG_ON triggered in skb_segment

2018-03-13 Thread Yunsheng Lin
Hi, Song

On 2018/3/13 13:45, Yonghong Song wrote:
> Hi,
> 
> One of our in-house projects, bpf-based NAT, hits a kernel BUG_ON at
> net-next function skb_segment, line 3667.
> 
> 3472 struct sk_buff *skb_segment(struct sk_buff *head_skb,
> 3473 netdev_features_t features)
> 3474 {
> 3475 struct sk_buff *segs = NULL;
> 3476 struct sk_buff *tail = NULL;
> ...
> 3665 while (pos < offset + len) {
> 3666 if (i >= nfrags) {
> 3667 BUG_ON(skb_headlen(list_skb));
> 3668
> 3669 i = 0;
> 3670 nfrags = skb_shinfo(list_skb)->nr_frags;
> 3671 frag = skb_shinfo(list_skb)->frags;
> 3672 frag_skb = list_skb;
> ...
> 
> call stack:
> ...
> #0 [883ffef034f8] machine_kexec at 81044c41
>  #1 [883ffef03558] __crash_kexec at 8110c525
>  #2 [883ffef03620] crash_kexec at 8110d5cc
>  #3 [883ffef03640] oops_end at 8101d7e7
>  #4 [883ffef03668] die at 8101deb2
>  #5 [883ffef03698] do_trap at 8101a700
>  #6 [883ffef036e8] do_error_trap at 8101abfe
>  #7 [883ffef037a0] do_invalid_op at 8101acd0
>  #8 [883ffef037b0] invalid_op at 81a00bab
> [exception RIP: skb_segment+3044]
> RIP: 817e4dd4  RSP: 883ffef03860  RFLAGS: 00010216
> RAX: 2bf6  RBX: 883feb7aaa00  RCX: 0011
> RDX: 883fb87910c0  RSI: 0011  RDI: 883feb7ab500
> RBP: 883ffef03928   R8: 2ce2   R9: 27da
> R10: 01ea  R11: 2d82  R12: 883f90a1ee80
> R13: 883fb8791120  R14: 883feb7abc00  R15: 2ce2
> ORIG_RAX:   CS: 0010  SS: 0018
>  #9 [883ffef03930] tcp_gso_segment at 818713e7
> #10 [883ffef03990] tcp4_gso_segment at 818717d8
> #11 [883ffef039b0] inet_gso_segment at 81882c9b
> #12 [883ffef03a10] skb_mac_gso_segment at 817f39b8
> #13 [883ffef03a38] __skb_gso_segment at 817f3ac9
> #14 [883ffef03a68] validate_xmit_skb at 817f3eed
> #15 [883ffef03aa8] validate_xmit_skb_list at 817f40a2
> #16 [883ffef03ad8] sch_direct_xmit at 81824efb
> #17 [883ffef03b20] __qdisc_run at 818251aa
> #18 [883ffef03b90] __dev_queue_xmit at 817f45ed
> #19 [883ffef03c08] dev_queue_xmit at 817f4b90
> #20 [883ffef03c18] __bpf_redirect at 81812b66
> #21 [883ffef03c40] skb_do_redirect at 81813209
> #22 [883ffef03c60] __netif_receive_skb_core at 817f310d
> #23 [883ffef03cc8] __netif_receive_skb at 817f32e8
> #24 [883ffef03ce8] netif_receive_skb_internal at 817f5538
> #25 [883ffef03d10] napi_gro_complete at 817f56c0
> #26 [883ffef03d28] dev_gro_receive at 817f5ea6
> #27 [883ffef03d78] napi_gro_receive at 817f6168
> #28 [883ffef03da0] mlx5e_handle_rx_cqe_mpwrq at 817381c2
> #29 [883ffef03e30] mlx5e_poll_rx_cq at 817386c2
> #30 [883ffef03e80] mlx5e_napi_poll at 8173926e
> #31 [883ffef03ed0] net_rx_action at 817f5a6e
> #32 [883ffef03f48] __softirqentry_text_start at 81c000c3
> #33 [883ffef03fa8] irq_exit at 8108f515
> #34 [883ffef03fb8] do_IRQ at 81a01b11
> ---  ---
> bt: cannot transition from IRQ stack to current process stack:
> IRQ stack pointer: 883ffef034f8
> process stack pointer: 81a01ae9
>current stack base: c9000c5c4000
> ...
> Setup:
> =
> 
> The test will involve three machines:
>   M_ipv6 <-> M_nat <-> M_ipv4
> 
> The M_nat will do ipv4<->ipv6 address translation and then forward packet
> to proper destination. The control plane will configure M_nat properly
> will understand virtual ipv4 address for machine M_ipv6, and
> virtual ipv6 address for machine M_ipv4.
> 
> M_nat runs a bpf program, which is attached to clsact (ingress) qdisc.
> The program uses bpf_skb_change_proto to do protocol conversion.
> bpf_skb_change_proto will adjust skb header_len and len properly
> based on protocol change.
> After the conversion, the program will make proper change on
> ethhdr and ip4/6 header, recalculate checksum, and send the packet out
> through bpf_redirect.
> 
> Experiment:
> ===
> 
> MTU: 1500B for all three machines.
> 
> The tso/lro/gro are enabled on the M_nat box.
> 
> ping works on both ways of M_ipv6 <-> M_ipv4.
> It works for transfering a small file (4KB) between M_ipv6 and M_ipv4 (both 
> ways).
> Transfering a large file (e.g., 4MB) from M_ipv6 to M_ipv4, failed with the 
> above BUG_ON, really fast.
> Did not really test from M_ipv4 to M_ipv6 with large file.
> 
> The error path likely to be (also from the above call 

Re: [PATCH net] net: phy: Restore phy_resume() locking assumption

2018-02-25 Thread Yunsheng Lin
Hi, Andrew

On 2018/2/26 7:04, Lunn wrote:
> commit f5e64032a799 ("net: phy: fix resume handling") changes the
> locking semantics for phy_resume() such that the caller now needs to
> hold the phy mutex. Not all call sites were adopted to this new
> semantic, resulting in warnings from the added
> WARN_ON(!mutex_is_locked(>lock)).  Rather than change the
> semantics, add a __phy_resume() and restore the old behavior of
> phy_resume().
> 
> Reported-by: Heiner Kallweit 
> Fixes: f5e64032a799 ("net: phy: fix resume handling")
> Signed-off-by: Andrew Lunn 
> ---
>  drivers/net/phy/phy.c|  2 +-
>  drivers/net/phy/phy_device.c | 18 +-
>  include/linux/phy.h  |  1 +
>  3 files changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index e3e29c2b028b..a6f924fee584 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -819,7 +819,7 @@ void phy_start(struct phy_device *phydev)
>   break;
>   case PHY_HALTED:
>   /* if phy was suspended, bring the physical link up again */
> - phy_resume(phydev);
> + __phy_resume(phydev);
>  
>   /* make sure interrupts are re-enabled for the PHY */
>   if (phy_interrupt_is_valid(phydev)) {
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index d39ae77707ef..4cfb3851ed1f 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -135,9 +135,7 @@ static int mdio_bus_phy_resume(struct device *dev)
>   if (!mdio_bus_phy_may_suspend(phydev))
>   goto no_resume;
>  
> - mutex_lock(>lock);
>   ret = phy_resume(phydev);
> - mutex_unlock(>lock);
>   if (ret < 0)
>   return ret;
>  
> @@ -1041,9 +1039,7 @@ int phy_attach_direct(struct net_device *dev, struct 
> phy_device *phydev,
>   if (err)
>   goto error;
>  
> - mutex_lock(>lock);
>   phy_resume(phydev);
> - mutex_unlock(>lock);
>   phy_led_triggers_register(phydev);
>  
>   return err;
> @@ -1172,7 +1168,7 @@ int phy_suspend(struct phy_device *phydev)
>  }
>  EXPORT_SYMBOL(phy_suspend);
>  
> -int phy_resume(struct phy_device *phydev)
> +int __phy_resume(struct phy_device *phydev)
>  {
>   struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
>   int ret = 0;
> @@ -1189,6 +1185,18 @@ int phy_resume(struct phy_device *phydev)
>  
>   return ret;
>  }
> +EXPORT_SYMBOL(__phy_resume);
> +
> +int phy_resume(struct phy_device *phydev)
> +{
> + int ret;
> +
> + mutex_lock(>lock);
> + ret = phy_resume(phydev);

phy_resume -> __phy_resume?

> + mutex_unlock(>lock);
> +
> + return ret;
> +}
>  EXPORT_SYMBOL(phy_resume);
>  
>  int phy_loopback(struct phy_device *phydev, bool enable)
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index 5a0c3e53e7c2..d7069539f351 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -924,6 +924,7 @@ void phy_device_remove(struct phy_device *phydev);
>  int phy_init_hw(struct phy_device *phydev);
>  int phy_suspend(struct phy_device *phydev);
>  int phy_resume(struct phy_device *phydev);
> +int __phy_resume(struct phy_device *phydev);
>  int phy_loopback(struct phy_device *phydev, bool enable);
>  struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
> phy_interface_t interface);
> 



Potential display issue with 88997e4208ae "net/8021q: create device with all possible features in wanted_features"

2018-02-06 Thread Yunsheng Lin
Hi, all

During testing, below cmd is used to add a vlan dev.
vconfig add eth0 1000

Without the commit 88997e4208ae(I revert the patch in the
latest net-next)

ethtool -k eth0 | grep rx-checksumming
rx-checksumming: on

ethtool -k eth0.1000 | grep rx-checksumming
rx-checksumming: on [fixed]

ethtool -K eth0 rx off

ethtool -k eth0 | grep rx-checksumming
rx-checksumming: off

ethtool -k eth0.1000 | grep rx-checksumming
rx-checksumming: off [fixed]

-

With the commit 88997e4208ae

ethtool -k eth0 | grep rx-checksumming
rx-checksumming: on

ethtool -k eth0.1000 | grep rx-checksumming
rx-checksumming: off [fixed]

ethtool -K eth0 rx off

ethtool -k eth0 | grep rx-checksumming
rx-checksumming: off

ethtool -k eth0.1000 | grep rx-checksumming
rx-checksumming: off [fixed]


So the vlan dev' rx-csum feature is not changed automatically
according to the lower dev' rx-csum feature after commit 88997e4208ae.

Is this a display issue? And Do we need to fix this issue?

MBR,
Yunsheng Lin




Re: [QUESTION] Doubt about NAPI_GRO_CB(skb)->is_atomic in tcpv4 gro process

2017-12-25 Thread Yunsheng Lin
Hi, Alexander

On 2017/12/23 0:32, Alexander Duyck wrote:
> On Fri, Dec 22, 2017 at 12:49 AM, Yunsheng Lin <linyunsh...@huawei.com> wrote:
>> Hi, Alexander
>>
>> On 2017/12/22 0:29, Alexander Duyck wrote:
>>> On Thu, Dec 21, 2017 at 1:16 AM, Yunsheng Lin <linyunsh...@huawei.com> 
>>> wrote:
>>>> Hi, Alexander
>>>>
>>>> On 2017/12/21 0:24, Alexander Duyck wrote:
>>>>> On Wed, Dec 20, 2017 at 1:09 AM, Yunsheng Lin <linyunsh...@huawei.com> 
>>>>> wrote:
>>>>>> Hi, all
>>>>>> I have some doubt about NAPI_GRO_CB(skb)->is_atomic when
>>>>>> analyzing the tcpv4 gro process:
>>>>>>
>>>>>> Firstly we set NAPI_GRO_CB(skb)->is_atomic to 1 in dev_gro_receive:
>>>>>> https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/core/dev.c#L4838
>>>>>>
>>>>>> And then in inet_gro_receive, we check the NAPI_GRO_CB(skb)->is_atomic
>>>>>> before setting NAPI_GRO_CB(skb)->is_atomic according to IP_DF bit in the 
>>>>>> ip header:
>>>>>> https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/ipv4/af_inet.c#L1319
>>>>>>
>>>>>> struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff 
>>>>>> *skb)
>>>>>> {
>>>>>> .
>>>>>> for (p = *head; p; p = p->next) {
>>>>>> 
>>>>>>
>>>>>> /* If the previous IP ID value was based on an atomic
>>>>>>  * datagram we can overwrite the value and ignore it.
>>>>>>  */
>>>>>> if (NAPI_GRO_CB(skb)->is_atomic)  
>>>>>> //we check it here
>>>>>> NAPI_GRO_CB(p)->flush_id = flush_id;
>>>>>> else
>>>>>> NAPI_GRO_CB(p)->flush_id |= flush_id;
>>>>>> }
>>>>>>
>>>>>> NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF));  
>>>>>> //we set it here
>>>>>> NAPI_GRO_CB(skb)->flush |= flush;
>>>>>> skb_set_network_header(skb, off);
>>>>>> 
>>>>>> }
>>>>>>
>>>>>> My question is whether we should check the NAPI_GRO_CB(skb)->is_atomic 
>>>>>> or NAPI_GRO_CB(p)->is_atomic?
>>>>>> If we should check NAPI_GRO_CB(skb)->is_atomic, then maybe it is 
>>>>>> unnecessary because it is alway true.
>>>>>> If we should check NAPI_GRO_CB(p)->is_atomic, maybe there is a bug here.
>>>>>>
>>>>>> So what is the logic here? I am just start analyzing the gro, maybe I 
>>>>>> miss something obvious here.
>>>>>
>>>>> The logic there is to address the multiple IP header case where there
>>>>> are 2 or more IP headers due to things like VXLAN or GRE tunnels. So
>>>>> what will happen is that an outer IP header will end up being sent
>>>>> with DF not set and will clear the is_atomic value then we want to OR
>>>>> in the next header that is applied. It defaults to assignment on
>>>>> is_atomic because the first IP header will encounter flush_id with no
>>>>> previous configuration occupying it.
>>>>
>>>> I see your point now.
>>>>
>>>> But for the same flow of tunnels packet, the outer and inner ip header must
>>>> have the same fixed id or increment id?
>>>>
>>>> For example, if we have a flow of tunnels packet which has fixed id in 
>>>> outer
>>>> header and increment id in inner header(the inner header does have DF flag 
>>>> set):
>>
>> Sorry, a typo error here. I meant the inner header does *not* have DF flag 
>> set here.
>>
>>>>
>>>> 1. For the first packet, NAPI_GRO_CB(skb)->is_atomic will be set to zero 
>>>> when
>>>> inet_gro_receive is processing the inner ip header.
>>>>
>>>> 2. For the second packet, when inet_gro_receive is processing the outer ip 
>>>> header
>>>> which has a fixed id, NAPI_GRO_CB(p)->is_atomic is zero 

Re: [QUESTION] Doubt about NAPI_GRO_CB(skb)->is_atomic in tcpv4 gro process

2017-12-22 Thread Yunsheng Lin
Hi, Alexander

On 2017/12/22 0:29, Alexander Duyck wrote:
> On Thu, Dec 21, 2017 at 1:16 AM, Yunsheng Lin <linyunsh...@huawei.com> wrote:
>> Hi, Alexander
>>
>> On 2017/12/21 0:24, Alexander Duyck wrote:
>>> On Wed, Dec 20, 2017 at 1:09 AM, Yunsheng Lin <linyunsh...@huawei.com> 
>>> wrote:
>>>> Hi, all
>>>> I have some doubt about NAPI_GRO_CB(skb)->is_atomic when
>>>> analyzing the tcpv4 gro process:
>>>>
>>>> Firstly we set NAPI_GRO_CB(skb)->is_atomic to 1 in dev_gro_receive:
>>>> https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/core/dev.c#L4838
>>>>
>>>> And then in inet_gro_receive, we check the NAPI_GRO_CB(skb)->is_atomic
>>>> before setting NAPI_GRO_CB(skb)->is_atomic according to IP_DF bit in the 
>>>> ip header:
>>>> https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/ipv4/af_inet.c#L1319
>>>>
>>>> struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff 
>>>> *skb)
>>>> {
>>>> .
>>>> for (p = *head; p; p = p->next) {
>>>> 
>>>>
>>>> /* If the previous IP ID value was based on an atomic
>>>>  * datagram we can overwrite the value and ignore it.
>>>>  */
>>>> if (NAPI_GRO_CB(skb)->is_atomic)  //we 
>>>> check it here
>>>> NAPI_GRO_CB(p)->flush_id = flush_id;
>>>> else
>>>> NAPI_GRO_CB(p)->flush_id |= flush_id;
>>>> }
>>>>
>>>> NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF));  
>>>> //we set it here
>>>> NAPI_GRO_CB(skb)->flush |= flush;
>>>> skb_set_network_header(skb, off);
>>>> 
>>>> }
>>>>
>>>> My question is whether we should check the NAPI_GRO_CB(skb)->is_atomic or 
>>>> NAPI_GRO_CB(p)->is_atomic?
>>>> If we should check NAPI_GRO_CB(skb)->is_atomic, then maybe it is 
>>>> unnecessary because it is alway true.
>>>> If we should check NAPI_GRO_CB(p)->is_atomic, maybe there is a bug here.
>>>>
>>>> So what is the logic here? I am just start analyzing the gro, maybe I miss 
>>>> something obvious here.
>>>
>>> The logic there is to address the multiple IP header case where there
>>> are 2 or more IP headers due to things like VXLAN or GRE tunnels. So
>>> what will happen is that an outer IP header will end up being sent
>>> with DF not set and will clear the is_atomic value then we want to OR
>>> in the next header that is applied. It defaults to assignment on
>>> is_atomic because the first IP header will encounter flush_id with no
>>> previous configuration occupying it.
>>
>> I see your point now.
>>
>> But for the same flow of tunnels packet, the outer and inner ip header must
>> have the same fixed id or increment id?
>>
>> For example, if we have a flow of tunnels packet which has fixed id in outer
>> header and increment id in inner header(the inner header does have DF flag 
>> set):

Sorry, a typo error here. I meant the inner header does *not* have DF flag set 
here.

>>
>> 1. For the first packet, NAPI_GRO_CB(skb)->is_atomic will be set to zero when
>> inet_gro_receive is processing the inner ip header.
>>
>> 2. For the second packet, when inet_gro_receive is processing the outer ip 
>> header
>> which has a fixed id, NAPI_GRO_CB(p)->is_atomic is zero according to [1], so
>> NAPI_GRO_CB(p)->flush_id will be set to 0x, then the second packet will 
>> not
>> be merged to first packet in tcp_gro_receive.
> 
> I'm not sure how valid your case here is. The is_atomic is only really
> meant to apply to the inner-most header.

For the new skb, NAPI_GRO_CB(skb)->is_atomic is indeed applied to the
inner-most header.

What about the NAPI_GRO_CB(p)->is_atomic, p is the same skb flow already
merged by gro.

Let me try if I understand it correctly:
when there is only one skb merged in p, then NAPI_GRO_CB(p)->is_atomic
is set according to the first skb' inner-most ip DF flags.

When the second skb comes, and inet_gro_receive is processing the
outer-most ip, for the below code, NAPI_GRO_CB(p)->is_atomic
is for first skb's inner-most ip DF flags, an

Re: [QUESTION] Doubt about NAPI_GRO_CB(skb)->is_atomic in tcpv4 gro process

2017-12-21 Thread Yunsheng Lin
Hi, Alexander

On 2017/12/21 0:24, Alexander Duyck wrote:
> On Wed, Dec 20, 2017 at 1:09 AM, Yunsheng Lin <linyunsh...@huawei.com> wrote:
>> Hi, all
>> I have some doubt about NAPI_GRO_CB(skb)->is_atomic when
>> analyzing the tcpv4 gro process:
>>
>> Firstly we set NAPI_GRO_CB(skb)->is_atomic to 1 in dev_gro_receive:
>> https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/core/dev.c#L4838
>>
>> And then in inet_gro_receive, we check the NAPI_GRO_CB(skb)->is_atomic
>> before setting NAPI_GRO_CB(skb)->is_atomic according to IP_DF bit in the ip 
>> header:
>> https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/ipv4/af_inet.c#L1319
>>
>> struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb)
>> {
>> .
>> for (p = *head; p; p = p->next) {
>> 
>>
>> /* If the previous IP ID value was based on an atomic
>>  * datagram we can overwrite the value and ignore it.
>>  */
>> if (NAPI_GRO_CB(skb)->is_atomic)  //we 
>> check it here
>> NAPI_GRO_CB(p)->flush_id = flush_id;
>> else
>> NAPI_GRO_CB(p)->flush_id |= flush_id;
>> }
>>
>> NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF));  
>> //we set it here
>> NAPI_GRO_CB(skb)->flush |= flush;
>> skb_set_network_header(skb, off);
>> 
>> }
>>
>> My question is whether we should check the NAPI_GRO_CB(skb)->is_atomic or 
>> NAPI_GRO_CB(p)->is_atomic?
>> If we should check NAPI_GRO_CB(skb)->is_atomic, then maybe it is unnecessary 
>> because it is alway true.
>> If we should check NAPI_GRO_CB(p)->is_atomic, maybe there is a bug here.
>>
>> So what is the logic here? I am just start analyzing the gro, maybe I miss 
>> something obvious here.
> 
> The logic there is to address the multiple IP header case where there
> are 2 or more IP headers due to things like VXLAN or GRE tunnels. So
> what will happen is that an outer IP header will end up being sent
> with DF not set and will clear the is_atomic value then we want to OR
> in the next header that is applied. It defaults to assignment on
> is_atomic because the first IP header will encounter flush_id with no
> previous configuration occupying it.

I see your point now.

But for the same flow of tunnels packet, the outer and inner ip header must
have the same fixed id or increment id?

For example, if we have a flow of tunnels packet which has fixed id in outer
header and increment id in inner header(the inner header does have DF flag set):

1. For the first packet, NAPI_GRO_CB(skb)->is_atomic will be set to zero when
inet_gro_receive is processing the inner ip header.

2. For the second packet, when inet_gro_receive is processing the outer ip 
header
which has a fixed id, NAPI_GRO_CB(p)->is_atomic is zero according to [1], so
NAPI_GRO_CB(p)->flush_id will be set to 0x, then the second packet will not
be merged to first packet in tcp_gro_receive.


I thought outer ip header could have a fixed id while inner ip header could
have a increment id. Do I miss something here?


> 
> The part I am not sure about is if we should be using assignment for
> is_atomic or using an "&=" to clear the bit and leave it cleared.

I am not sure I understood you here. is_atomic is a bit field, why do you
want to use "&="?


Thank very much for your time reqlying.
Yunsheng Lin

 I
> don't know if there has been much testing of multiple levels of tunnel
> header.
>> Thanks.
> 
> - Alex
> 
> .
> 



[QUESTION] Doubt about NAPI_GRO_CB(skb)->is_atomic in tcpv4 gro process

2017-12-20 Thread Yunsheng Lin
Hi, all
I have some doubt about NAPI_GRO_CB(skb)->is_atomic when
analyzing the tcpv4 gro process:

Firstly we set NAPI_GRO_CB(skb)->is_atomic to 1 in dev_gro_receive:
https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/core/dev.c#L4838

And then in inet_gro_receive, we check the NAPI_GRO_CB(skb)->is_atomic
before setting NAPI_GRO_CB(skb)->is_atomic according to IP_DF bit in the ip 
header:
https://elixir.free-electrons.com/linux/v4.15-rc4/source/net/ipv4/af_inet.c#L1319

struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb)
{
.
for (p = *head; p; p = p->next) {


/* If the previous IP ID value was based on an atomic
 * datagram we can overwrite the value and ignore it.
 */
if (NAPI_GRO_CB(skb)->is_atomic)  //we 
check it here
NAPI_GRO_CB(p)->flush_id = flush_id;
else
NAPI_GRO_CB(p)->flush_id |= flush_id;
}

NAPI_GRO_CB(skb)->is_atomic = !!(iph->frag_off & htons(IP_DF));  //we 
set it here
NAPI_GRO_CB(skb)->flush |= flush;
skb_set_network_header(skb, off);

}

My question is whether we should check the NAPI_GRO_CB(skb)->is_atomic or 
NAPI_GRO_CB(p)->is_atomic?
If we should check NAPI_GRO_CB(skb)->is_atomic, then maybe it is unnecessary 
because it is alway true.
If we should check NAPI_GRO_CB(p)->is_atomic, maybe there is a bug here.

So what is the logic here? I am just start analyzing the gro, maybe I miss 
something obvious here.



Re: [PATCH net-next 3/9] net: hns3: Refactor the initialization of command queue

2017-11-01 Thread Yunsheng Lin
Hi, Lipeng

On 2017/11/1 22:47, Lipeng wrote:
> From: qumingguang 
> 
> There is no necessary to reallocate the descriptor and remap the descriptor
> memory in reset process, But there is still some other action exit in both

exit -> exist

> reset process and initialization process.
> 
> To reuse the common interface of reset process and initialization process,

of -> in

> This patch moved out the descriptor allocate and memory maping from

This -> this, moved -> moves

> interface cmdq_init.
> 
> Signed-off-by: qumingguang 
> Signed-off-by: Lipeng 
> ---
>  .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 39 
> +-
>  .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  1 +
>  .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  9 -
>  3 files changed, 33 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c 
> b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
> index 60960e5..ff13d18 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
> @@ -62,7 +62,7 @@ static void hclge_free_cmd_desc(struct hclge_cmq_ring *ring)
>   ring->desc = NULL;
>  }
>  
> -static int hclge_init_cmd_queue(struct hclge_dev *hdev, int ring_type)
> +static int hclge_alloc_cmd_queue(struct hclge_dev *hdev, int ring_type)
>  {
>   struct hclge_hw *hw = >hw;
>   struct hclge_cmq_ring *ring =
> @@ -79,9 +79,6 @@ static int hclge_init_cmd_queue(struct hclge_dev *hdev, int 
> ring_type)
>   return ret;
>   }
>  
> - ring->next_to_clean = 0;
> - ring->next_to_use = 0;
> -
>   return 0;
>  }
>  
> @@ -302,37 +299,52 @@ static enum hclge_cmd_status 
> hclge_cmd_query_firmware_version(
>   return ret;
>  }
>  
> -int hclge_cmd_init(struct hclge_dev *hdev)
> +int hclge_cmd_queue_init(struct hclge_dev *hdev)
>  {
> - u32 version;
>   int ret;
>  
>   /* Setup the queue entries for use cmd queue */
>   hdev->hw.cmq.csq.desc_num = HCLGE_NIC_CMQ_DESC_NUM;
>   hdev->hw.cmq.crq.desc_num = HCLGE_NIC_CMQ_DESC_NUM;
>  
> - /* Setup the lock for command queue */
> - spin_lock_init(>hw.cmq.csq.lock);
> - spin_lock_init(>hw.cmq.crq.lock);
> -
>   /* Setup Tx write back timeout */
>   hdev->hw.cmq.tx_timeout = HCLGE_CMDQ_TX_TIMEOUT;
>  
>   /* Setup queue rings */
> - ret = hclge_init_cmd_queue(hdev, HCLGE_TYPE_CSQ);
> + ret = hclge_alloc_cmd_queue(hdev, HCLGE_TYPE_CSQ);
>   if (ret) {
>   dev_err(>pdev->dev,
>   "CSQ ring setup error %d\n", ret);
>   return ret;
>   }
>  
> - ret = hclge_init_cmd_queue(hdev, HCLGE_TYPE_CRQ);
> + ret = hclge_alloc_cmd_queue(hdev, HCLGE_TYPE_CRQ);
>   if (ret) {
>   dev_err(>pdev->dev,
>   "CRQ ring setup error %d\n", ret);
>   goto err_csq;
>   }
>  
> + return 0;
> +err_csq:
> + hclge_free_cmd_desc(>hw.cmq.csq);
> + return ret;
> +}
> +
> +int hclge_cmd_init(struct hclge_dev *hdev)
> +{
> + u32 version;
> + int ret;
> +
> + hdev->hw.cmq.csq.next_to_clean = 0;
> + hdev->hw.cmq.csq.next_to_use = 0;
> + hdev->hw.cmq.crq.next_to_clean = 0;
> + hdev->hw.cmq.crq.next_to_use = 0;
> +
> + /* Setup the lock for command queue */
> + spin_lock_init(>hw.cmq.csq.lock);
> + spin_lock_init(>hw.cmq.crq.lock);
> +
>   hclge_cmd_init_regs(>hw);
>  
>   ret = hclge_cmd_query_firmware_version(>hw, );
> @@ -346,9 +358,6 @@ int hclge_cmd_init(struct hclge_dev *hdev)
>   dev_info(>pdev->dev, "The firmware version is %08x\n", version);
>  
>   return 0;
> -err_csq:
> - hclge_free_cmd_desc(>hw.cmq.csq);
> - return ret;
>  }
>  
>  static void hclge_destroy_queue(struct hclge_cmq_ring *ring)
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
> b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
> index b437334..6bdc216 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
> @@ -750,4 +750,5 @@ enum hclge_cmd_status hclge_cmd_mdio_read(struct hclge_hw 
> *hw,
> struct hclge_desc *desc);
>  
>  void hclge_destroy_cmd_queue(struct hclge_hw *hw);
> +int hclge_cmd_queue_init(struct hclge_dev *hdev);
>  #endif
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
> b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> index 4ef4592..a7686fe 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> @@ -4446,7 +4446,14 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev 
> *ae_dev)
>   goto err_pci_init;
>   }
>  
> - /* Command queue initialize */
> + /* Firmware command queue 

Re: [PATCH net-next] bnxt_en: Fix randconfig build errors.

2017-10-28 Thread Yunsheng Lin
Hi, Michael

On 2017/10/28 13:56, Michael Chan wrote:
> Fix undefined symbols when CONFIG_VLAN_8021Q or CONFIG_INET is not set.
> 
> Fixes: 8c95f773b4a3 ("bnxt_en: add support for Flower based vxlan encap/decap 
> offload")
> Reported-by: Jakub Kicinski <kubak...@wp.pl>
> Signed-off-by: Michael Chan <michael.c...@broadcom.com>
> ---
>  drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c 
> b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
> index 798d139..d5031f4 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
> @@ -904,6 +904,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
>  struct bnxt_tc_l2_key *l2_info,
>  struct net_device *real_dst_dev)
>  {
> +#ifdef CONFIG_INET

Can we use #if IS_ENABLED(CONFIG_INET) here too?

I am not familiar with IS_ENABLED, just thought it would be
good to be constistent because you are using IS_ENABLED below.

Best Regards
Yunsheng Lin

>   struct flowi4 flow = { {0} };
>   struct net_device *dst_dev;
>   struct neighbour *nbr;
> @@ -925,6 +926,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
>*/
>   dst_dev = rt->dst.dev;
>   if (is_vlan_dev(dst_dev)) {
> +#if IS_ENABLED(CONFIG_VLAN_8021Q)
>   struct vlan_dev_priv *vlan = vlan_dev_priv(dst_dev);
>  
>   if (vlan->real_dev != real_dst_dev) {
> @@ -938,6 +940,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
>   l2_info->inner_vlan_tci = htons(vlan->vlan_id);
>   l2_info->inner_vlan_tpid = vlan->vlan_proto;
>   l2_info->num_vlans = 1;
> +#endif
>   } else if (dst_dev != real_dst_dev) {
>   netdev_info(bp->dev,
>   "dst_dev(%s) for %pI4b is not PF-if(%s)",
> @@ -966,6 +969,9 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
>  put_rt:
>   ip_rt_put(rt);
>   return rc;
> +#else
> + return -EOPNOTSUPP;
> +#endif
>  }
>  
>  static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow 
> *flow,
> 



Re: [PATCH net-next] qed: Set error code for allocation failures

2017-10-27 Thread Yunsheng Lin
Hi, Dan

On 2017/10/27 19:52, Dan Carpenter wrote:
> On Fri, Oct 27, 2017 at 05:32:42PM +0800, Yunsheng Lin wrote:
>> Hi, Dan
>>
>> On 2017/10/27 14:40, Dan Carpenter wrote:
>>> There are several places where we accidentally return success when
>>> kcalloc() fails.
>>>
>>> Fixes: fcb39f6c10b2 ("qed: Add mpa buffer descriptors for storing and 
>>> processing mpa fpdus")
>>> Signed-off-by: Dan Carpenter <dan.carpen...@oracle.com>
>>>
>>> diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c 
>>> b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
>>> index 409041eab189..6366f2ef82b7 100644
>>> --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
>>> +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
>>> @@ -2585,7 +2585,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
>>> struct qed_ll2_cbs cbs;
>>> u32 mpa_buff_size;
>>> u16 n_ooo_bufs;
>>> -   int rc = 0;
>>> +   int rc;
>>> int i;
>>>  
>>> iwarp_info = _hwfn->p_rdma_info->iwarp;
>>> @@ -2696,6 +2696,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
>>> if (rc)
>>> goto err;
>>>  
>>> +   rc = -ENOMEM;
>>> iwarp_info->partial_fpdus = kcalloc((u16)p_hwfn->p_rdma_info->num_qps,
>>> sizeof(*iwarp_info->partial_fpdus),
>>> GFP_KERNEL);
>>
>> Does the memory allocated here need to be freed when error happens below?
>>
> 
> Hm...  I think you're right that it leaks.  Also I'm confused by the
> qed_iwarp_ll2_alloc_buffers() allocation.  The comment in there says
> that /* buffers will be deallocated by qed_ll2 */ but qed_ll2 is not
> a function name or something which is useful to grep.

Yes, I am confused by it too.

Even in qed_iwarp_ll2_alloc_buffers, if kzcalloc failed, it do not clean
up the memory allocated by pre kzcalloc.

> 
> regards,
> dan carpenter
> 
> 
> .
> 



Re: [PATCH net-next] qed: Set error code for allocation failures

2017-10-27 Thread Yunsheng Lin
Hi, Dan

On 2017/10/27 14:40, Dan Carpenter wrote:
> There are several places where we accidentally return success when
> kcalloc() fails.
> 
> Fixes: fcb39f6c10b2 ("qed: Add mpa buffer descriptors for storing and 
> processing mpa fpdus")
> Signed-off-by: Dan Carpenter 
> 
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c 
> b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
> index 409041eab189..6366f2ef82b7 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c
> @@ -2585,7 +2585,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
>   struct qed_ll2_cbs cbs;
>   u32 mpa_buff_size;
>   u16 n_ooo_bufs;
> - int rc = 0;
> + int rc;
>   int i;
>  
>   iwarp_info = _hwfn->p_rdma_info->iwarp;
> @@ -2696,6 +2696,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
>   if (rc)
>   goto err;
>  
> + rc = -ENOMEM;
>   iwarp_info->partial_fpdus = kcalloc((u16)p_hwfn->p_rdma_info->num_qps,
>   sizeof(*iwarp_info->partial_fpdus),
>   GFP_KERNEL);

Does the memory allocated here need to be freed when error happens below?


> @@ -2724,7 +2725,7 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn,
>   for (i = 0; i < data.input.rx_num_desc; i++)
>   list_add_tail(_info->mpa_bufs[i].list_entry,
> _info->mpa_buf_list);
> - return rc;
> + return 0;
>  err:
>   qed_iwarp_ll2_stop(p_hwfn, p_ptt);
>  
> 
> .
> 



[PATCH net-next 0/2] Add mac loopback selftest support in hns3 driver

2017-10-19 Thread Yunsheng Lin
This patchset refactors the skb receiving and transmitting function
before adding mac loopback selftest support in hns3 driver.

Yunsheng Lin (2):
  net: hns3: Refactor the skb receiving and transmitting function
  net: hns3: Add mac loopback selftest support in hns3 driver

 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  54 
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c |  17 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   4 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c  | 273 +
 4 files changed, 343 insertions(+), 5 deletions(-)

-- 
1.9.1



[PATCH net-next 1/2] net: hns3: Refactor the skb receiving and transmitting function

2017-10-19 Thread Yunsheng Lin
This patch refactors the skb receiving and transmitting functions
and export them in order to support the ethtool's mac loopback
selftest.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 17 -
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |  4 
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 8fa4e65..8383d67 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -900,8 +900,7 @@ static void hns_nic_dma_unmap(struct hns3_enet_ring *ring, 
int next_to_use_orig)
}
 }
 
-static netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb,
-struct net_device *netdev)
+netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hns3_nic_ring_data *ring_data =
@@ -1943,6 +1942,11 @@ static void hns3_rx_checksum(struct hns3_enet_ring 
*ring, struct sk_buff *skb,
}
 }
 
+static void hns3_rx_skb(struct hns3_enet_ring *ring, struct sk_buff *skb)
+{
+   napi_gro_receive(>tqp_vector->napi, skb);
+}
+
 static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
 struct sk_buff **out_skb, int *out_bnum)
 {
@@ -2077,7 +2081,9 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
return 0;
 }
 
-static int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget)
+int hns3_clean_rx_ring(
+   struct hns3_enet_ring *ring, int budget,
+   void (*rx_fn)(struct hns3_enet_ring *, struct sk_buff *))
 {
 #define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
struct net_device *netdev = ring->tqp->handle->kinfo.netdev;
@@ -2115,7 +2121,7 @@ static int hns3_clean_rx_ring(struct hns3_enet_ring 
*ring, int budget)
 
/* Do update ip stack process */
skb->protocol = eth_type_trans(skb, netdev);
-   (void)napi_gro_receive(>tqp_vector->napi, skb);
+   rx_fn(ring, skb);
 
recv_pkts++;
}
@@ -2258,7 +2264,8 @@ static int hns3_nic_common_poll(struct napi_struct *napi, 
int budget)
rx_budget = max(budget / tqp_vector->num_tqps, 1);
 
hns3_for_each_ring(ring, tqp_vector->rx_group) {
-   int rx_cleaned = hns3_clean_rx_ring(ring, rx_budget);
+   int rx_cleaned = hns3_clean_rx_ring(ring, rx_budget,
+   hns3_rx_skb);
 
if (rx_cleaned >= rx_budget)
clean_complete = false;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h
index 6659989..6228b26 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h
@@ -597,6 +597,10 @@ static inline void hns3_write_reg(void __iomem *base, u32 
reg, u32 value)
 int hns3_clean_tx_ring(struct hns3_enet_ring *ring, int budget);
 int hns3_init_all_ring(struct hns3_nic_priv *priv);
 int hns3_uninit_all_ring(struct hns3_nic_priv *priv);
+netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
+int hns3_clean_rx_ring(
+   struct hns3_enet_ring *ring, int budget,
+   void (*rx_fn)(struct hns3_enet_ring *, struct sk_buff *));
 
 #ifdef CONFIG_HNS3_DCB
 void hns3_dcbnl_setup(struct hnae3_handle *handle);
-- 
1.9.1



[PATCH net-next 2/2] net: hns3: Add mac loopback selftest support in hns3 driver

2017-10-19 Thread Yunsheng Lin
This patch adds mac loopback selftest support for ethtool cmd
by checking if a transmitted packet can be received correctly
when mac loopback is enabled.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  54 
 .../ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c  | 273 +
 2 files changed, 327 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index c322b45..e5454e0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3149,6 +3149,59 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, 
bool enable)
"mac enable fail, ret =%d.\n", ret);
 }
 
+static int hclge_set_loopback(struct hnae3_handle *handle,
+ enum hnae3_loop loop_mode, bool en)
+{
+   struct hclge_vport *vport = hclge_get_vport(handle);
+   struct hclge_config_mac_mode_cmd *req;
+   struct hclge_dev *hdev = vport->back;
+   struct hclge_desc desc;
+   u32 loop_en;
+   int ret;
+
+   switch (loop_mode) {
+   case HNAE3_MAC_INTER_LOOP_MAC:
+   req = (struct hclge_config_mac_mode_cmd *)[0];
+   /* 1 Read out the MAC mode config at first */
+   hclge_cmd_setup_basic_desc(,
+  HCLGE_OPC_CONFIG_MAC_MODE,
+  true);
+   ret = hclge_cmd_send(>hw, , 1);
+   if (ret) {
+   dev_err(>pdev->dev,
+   "mac loopback get fail, ret =%d.\n",
+   ret);
+   return ret;
+   }
+
+   /* 2 Then setup the loopback flag */
+   loop_en = le32_to_cpu(req->txrx_pad_fcs_loop_en);
+   if (en)
+   hnae_set_bit(loop_en, HCLGE_MAC_APP_LP_B, 1);
+   else
+   hnae_set_bit(loop_en, HCLGE_MAC_APP_LP_B, 0);
+
+   req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en);
+
+   /* 3 Config mac work mode with loopback flag
+* and its original configure parameters
+*/
+   hclge_cmd_reuse_desc(, false);
+   ret = hclge_cmd_send(>hw, , 1);
+   if (ret)
+   dev_err(>pdev->dev,
+   "mac loopback set fail, ret =%d.\n", ret);
+   break;
+   default:
+   ret = -ENOTSUPP;
+   dev_err(>pdev->dev,
+   "loop_mode %d is not supported\n", loop_mode);
+   break;
+   }
+
+   return ret;
+}
+
 static int hclge_tqp_enable(struct hclge_dev *hdev, int tqp_id,
int stream_id, bool enable)
 {
@@ -4486,6 +4539,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev 
*ae_dev)
.unmap_ring_from_vector = hclge_unmap_ring_from_vector,
.get_vector = hclge_get_vector,
.set_promisc_mode = hclge_set_promisc_mode,
+   .set_loopback = hclge_set_loopback,
.start = hclge_ae_start,
.stop = hclge_ae_stop,
.get_status = hclge_get_status,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c
index ddbd7f3..6c469e4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c
@@ -59,6 +59,16 @@ struct hns3_stats {
 
 #define HNS3_TQP_STATS_COUNT (HNS3_TXQ_STATS_COUNT + HNS3_RXQ_STATS_COUNT)
 
+#define HNS3_SELF_TEST_TPYE_NUM1
+#define HNS3_NIC_LB_TEST_PKT_NUM   1
+#define HNS3_NIC_LB_TEST_RING_ID   0
+#define HNS3_NIC_LB_TEST_PACKET_SIZE   128
+
+/* Nic loopback test err  */
+#define HNS3_NIC_LB_TEST_NO_MEM_ERR1
+#define HNS3_NIC_LB_TEST_TX_CNT_ERR2
+#define HNS3_NIC_LB_TEST_RX_CNT_ERR3
+
 struct hns3_link_mode_mapping {
u32 hns3_link_mode;
u32 ethtool_link_mode;
@@ -77,6 +87,268 @@ struct hns3_link_mode_mapping {
{HNS3_LM_1000BASET_FULL_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT},
 };
 
+static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop)
+{
+   struct hnae3_handle *h = hns3_get_handle(ndev);
+   int ret;
+
+   if (!h->ae_algo->ops->set_loopback ||
+   !h->ae_algo->ops->set_promisc_mode)
+   return -EOPNOTSUPP;
+
+   switch (loop) {
+   case HNAE3_MAC_INTER_LOOP_MAC:
+   ret = h->ae_algo->ops->set_loopback(h, loop, true);
+   break;
+   case HNAE3_MAC_LOOP_NONE:
+   ret = h->ae_algo->ops->set_loopback(h,
+   HNAE3_MAC_INT

Re: [net-next 4/9] i40e: Enable 'channel' mode in mqprio for TC configs

2017-10-17 Thread Yunsheng Lin
Hi, Nambiar

On 2017/10/17 0:03, Nambiar, Amritha wrote:
> On 10/16/2017 1:53 AM, Yunsheng Lin wrote:
>> Hi, Jeff
>>
>> On 2017/10/14 5:52, Jeff Kirsher wrote:
>>> From: Amritha Nambiar <amritha.namb...@intel.com>
>>>
>>> The i40e driver is modified to enable the new mqprio hardware
>>> offload mode and factor the TCs and queue configuration by
>>> creating channel VSIs. In this mode, the priority to traffic
>>> class mapping and the user specified queue ranges are used
>>> to configure the traffic classes by setting the mode option to
>>> 'channel'.
>>>
>>> Example:
>>>   map 0 0 0 0 1 2 2 3 queues 2@0 2@2 1@4 1@5\
>>>   hw 1 mode channel
>>>
>>> qdisc mqprio 8038: root  tc 4 map 0 0 0 0 1 2 2 3 0 0 0 0 0 0 0 0
>>>  queues:(0:1) (2:3) (4:4) (5:5)
>>>  mode:channel
>>>  shaper:dcb
>>>
>>> The HW channels created are removed and all the queue configuration
>>> is set to default when the qdisc is detached from the root of the
>>> device.
>>>
>>> This patch also disables setting up channels via ethtool (ethtool -L)
>>> when the TCs are configured using mqprio scheduler.
>>>
>>> The patch also limits setting ethtool Rx flow hash indirection
>>> (ethtool -X eth0 equal N) to max queues configured via mqprio.
>>> The Rx flow hash indirection input through ethtool should be
>>> validated so that it is within in the queue range configured via
>>> tc/mqprio. The bound checking is achieved by reporting the current
>>> rss size to the kernel when queues are configured via mqprio.
>>>
>>> Example:
>>>   map 0 0 0 1 0 2 3 0 queues 2@0 4@2 8@6 11@14\
>>>   hw 1 mode channel
>>>
>>> Cannot set RX flow hash configuration: Invalid argument
>>>
>>> Signed-off-by: Amritha Nambiar <amritha.namb...@intel.com>
>>> Tested-by: Andrew Bowers <andrewx.bow...@intel.com>
>>> Signed-off-by: Jeff Kirsher <jeffrey.t.kirs...@intel.com>
>>> ---
>>>  drivers/net/ethernet/intel/i40e/i40e.h |   3 +
>>>  drivers/net/ethernet/intel/i40e/i40e_ethtool.c |   8 +-
>>>  drivers/net/ethernet/intel/i40e/i40e_main.c| 457 
>>> +++--
>>>  3 files changed, 362 insertions(+), 106 deletions(-)
>>>
>>> diff --git a/drivers/net/ethernet/intel/i40e/i40e.h 
>>> b/drivers/net/ethernet/intel/i40e/i40e.h
>>> index bde982541772..024c88474951 100644
>>> --- a/drivers/net/ethernet/intel/i40e/i40e.h
>>> +++ b/drivers/net/ethernet/intel/i40e/i40e.h
>>> @@ -54,6 +54,7 @@
>>>  #include 
>>>  #include 
>>>  #include 
>>> +#include 
>>>  #include "i40e_type.h"
>>>  #include "i40e_prototype.h"
>>>  #include "i40e_client.h"
>>> @@ -700,6 +701,7 @@ struct i40e_vsi {
>>> enum i40e_vsi_type type;  /* VSI type, e.g., LAN, FCoE, etc */
>>> s16 vf_id;  /* Virtual function ID for SRIOV VSIs */
>>>  
>>> +   struct tc_mqprio_qopt_offload mqprio_qopt; /* queue parameters */
>>> struct i40e_tc_configuration tc_config;
>>> struct i40e_aqc_vsi_properties_data info;
>>>  
>>> @@ -725,6 +727,7 @@ struct i40e_vsi {
>>> u16 cnt_q_avail;/* num of queues available for channel usage */
>>> u16 orig_rss_size;
>>> u16 current_rss_size;
>>> +   bool reconfig_rss;
>>>  
>>> u16 next_base_queue;/* next queue to be used for channel setup */
>>>  
>>> diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c 
>>> b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
>>> index afd3ca8d9851..72d5f2cdf419 100644
>>> --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
>>> +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
>>> @@ -2652,7 +2652,7 @@ static int i40e_get_rxnfc(struct net_device *netdev, 
>>> struct ethtool_rxnfc *cmd,
>>>  
>>> switch (cmd->cmd) {
>>> case ETHTOOL_GRXRINGS:
>>> -   cmd->data = vsi->num_queue_pairs;
>>> +   cmd->data = vsi->rss_size;
>>> ret = 0;
>>> break;
>>> case ETHTOOL_GRXFH:
>>> @@ -3897,6 +3897,12 @@ static int i40e_set_channels(struct net_device *dev,
>>> if (vsi->type != I40E_VSI_MAIN)
>>> return -EINVAL;
>>>  
>>> +   /* We do n

[PATCH v2 net-next] net: hns3: Add mqprio hardware offload support in hns3 driver

2017-10-17 Thread Yunsheng Lin
When using tc qdisc, dcb_ops->setup_tc is used to tell hclge_dcb
module to do the tm related setup. Only TC_MQPRIO_MODE_CHANNEL
offload mode is supported.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
V2:
1. Add HCLGE_FLAG_MQPRIO_ENABLE to indicate offlaoding the
mqprio.
2. Change to support TC_MQPRIO_MODE_CHANNEL mode.
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 47 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 56 +++---
 4 files changed, 86 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 575f50d..3acd8db 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -381,6 +381,7 @@ struct hnae3_dcb_ops {
u8   (*setdcbx)(struct hnae3_handle *, u8);
 
int (*map_update)(struct hnae3_handle *);
+   int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
 };
 
 struct hnae3_ae_algo {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index 1b30a6f..5018d66 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -178,7 +178,8 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct 
ieee_ets *ets)
u8 num_tc = 0;
int ret;
 
-   if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
+   if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
+   hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
return -EINVAL;
 
ret = hclge_ets_validate(hdev, ets, _tc, _changed);
@@ -228,7 +229,8 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct 
ieee_pfc *pfc)
struct hclge_dev *hdev = vport->back;
u8 i, j, pfc_map, *prio_tc;
 
-   if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
+   if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
+   hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
return -EINVAL;
 
prio_tc = hdev->tm_info.prio_tc;
@@ -257,6 +259,9 @@ static u8 hclge_getdcbx(struct hnae3_handle *h)
struct hclge_vport *vport = hclge_get_vport(h);
struct hclge_dev *hdev = vport->back;
 
+   if (hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
+   return 0;
+
return hdev->dcbx_cap;
 }
 
@@ -276,6 +281,43 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
return 0;
 }
 
+/* Set up TC for hardware offloaded mqprio in channel mode */
+static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
+{
+   struct hclge_vport *vport = hclge_get_vport(h);
+   struct hclge_dev *hdev = vport->back;
+   int ret;
+
+   if (hdev->flag & HCLGE_FLAG_DCB_ENABLE)
+   return -EINVAL;
+
+   if (tc > hdev->tc_max) {
+   dev_err(>pdev->dev,
+   "setup tc failed, tc(%u) > tc_max(%u)\n",
+   tc, hdev->tc_max);
+   return -EINVAL;
+   }
+
+   hclge_tm_schd_info_update(hdev, tc);
+
+   ret = hclge_tm_prio_tc_info_update(hdev, prio_tc);
+   if (ret)
+   return ret;
+
+   ret = hclge_tm_init_hw(hdev);
+   if (ret)
+   return ret;
+
+   hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
+
+   if (tc > 1)
+   hdev->flag |= HCLGE_FLAG_MQPRIO_ENABLE;
+   else
+   hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE;
+
+   return 0;
+}
+
 static const struct hnae3_dcb_ops hns3_dcb_ops = {
.ieee_getets= hclge_ieee_getets,
.ieee_setets= hclge_ieee_setets,
@@ -284,6 +326,7 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
.getdcbx= hclge_getdcbx,
.setdcbx= hclge_setdcbx,
.map_update = hclge_map_update,
+   .setup_tc   = hclge_setup_tc,
 };
 
 void hclge_dcb_ops_set(struct hclge_dev *hdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index a7c018c..bca4430 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -470,6 +470,7 @@ struct hclge_dev {
 #define HCLGE_FLAG_MAIN0x0004
 #define HCLGE_FLAG_DCB_CAPABLE 0x0008
 #define HCLGE_FLAG_DCB_ENABLE  0x0010
+#define HCLGE_FLAG_MQPRIO_ENABLE   0x0020
u32 flag;
 
u32 pkt_buf_size; /* Total pf buf size for tx/rx */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index ba550c1..8fa4e65 100644
--- a/drivers/net/eth

Re: [net-next 4/9] i40e: Enable 'channel' mode in mqprio for TC configs

2017-10-16 Thread Yunsheng Lin
* @vsi: vsi structure
> + * @seed: RSS hash seed
> + **/

[...]

> + * i40e_vsi_set_default_tc_config - set default values for tc configuration
> + * @vsi: the VSI being configured
> + **/
> +static void i40e_vsi_set_default_tc_config(struct i40e_vsi *vsi)
> +{
> + u16 qcount;
> + int i;
> +
> + /* Only TC0 is enabled */
> + vsi->tc_config.numtc = 1;
> + vsi->tc_config.enabled_tc = 1;
> + qcount = min_t(int, vsi->alloc_queue_pairs,
> +i40e_pf_get_max_q_per_tc(vsi->back));
> + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
> + /* For the TC that is not enabled set the offset to to default
> +  * queue and allocate one queue for the given TC.
> +  */
> + vsi->tc_config.tc_info[i].qoffset = 0;
> + if (i == 0)
> + vsi->tc_config.tc_info[i].qcount = qcount;
> + else
> + vsi->tc_config.tc_info[i].qcount = 1;
> + vsi->tc_config.tc_info[i].netdev_tc = 0;
> + }
> +}
> +
>  /**
>   * i40e_setup_tc - configure multiple traffic classes
>   * @netdev: net device to configure
> - * @tc: number of traffic classes to enable
> + * @type_data: tc offload data
>   **/
> -static int i40e_setup_tc(struct net_device *netdev, u8 tc)
> +static int i40e_setup_tc(struct net_device *netdev, void *type_data)
>  {
> + struct tc_mqprio_qopt_offload *mqprio_qopt = type_data;
>   struct i40e_netdev_priv *np = netdev_priv(netdev);
>   struct i40e_vsi *vsi = np->vsi;
>   struct i40e_pf *pf = vsi->back;
> - u8 enabled_tc = 0;
> + u8 enabled_tc = 0, num_tc, hw;
> + bool need_reset = false;
>   int ret = -EINVAL;
> + u16 mode;
>   int i;
>  
> - /* Check if DCB enabled to continue */
> - if (!(pf->flags & I40E_FLAG_DCB_ENABLED)) {
> - netdev_info(netdev, "DCB is not enabled for adapter\n");
> - goto exit;
> + num_tc = mqprio_qopt->qopt.num_tc;
> + hw = mqprio_qopt->qopt.hw;
> + mode = mqprio_qopt->mode;
> + if (!hw) {

When stack call the ndo_setup_tc, then qopt.hw is always non-zero, Can you
tell me why you need to check for this?

Thanks,
Yunsheng Lin

> + pf->flags &= ~I40E_FLAG_TC_MQPRIO;
> + memcpy(>mqprio_qopt, mqprio_qopt, sizeof(*mqprio_qopt));
> + goto config_tc;
>   }
>  
>   /* Check if MFP enabled */
>   if (pf->flags & I40E_FLAG_MFP_ENABLED) {
> - netdev_info(netdev, "Configuring TC not supported in MFP 
> mode\n");
> - goto exit;
> + netdev_info(netdev,
> + "Configuring TC not supported in MFP mode\n");
> + return ret;
>   }
> + switch (mode) {
> + case TC_MQPRIO_MODE_DCB:
> + pf->flags &= ~I40E_FLAG_TC_MQPRIO;
>  
> - /* Check whether tc count is within enabled limit */
> - if (tc > i40e_pf_get_num_tc(pf)) {
> - netdev_info(netdev, "TC count greater than enabled on link for 
> adapter\n");
> - goto exit;
> + /* Check if DCB enabled to continue */
> + if (!(pf->flags & I40E_FLAG_DCB_ENABLED)) {
> + netdev_info(netdev,
> + "DCB is not enabled for adapter\n");
> + return ret;
> + }
> +
> + /* Check whether tc count is within enabled limit */
> + if (num_tc > i40e_pf_get_num_tc(pf)) {
> + netdev_info(netdev,
> + "TC count greater than enabled on link for 
> adapter\n");
> + return ret;
> + }
> + break;
> + case TC_MQPRIO_MODE_CHANNEL:
> + if (pf->flags & I40E_FLAG_DCB_ENABLED) {
> + netdev_info(netdev,
> + "Full offload of TC Mqprio options is not 
> supported when DCB is enabled\n");
> + return ret;
> + }
> + if (!(pf->flags & I40E_FLAG_MSIX_ENABLED))
> + return ret;
> + ret = i40e_validate_mqprio_qopt(vsi, mqprio_qopt);
> + if (ret)
> + return ret;
> + memcpy(>mqprio_qopt, mqprio_qopt,
> +sizeof(*mqprio_qopt));
> + pf->flags |= I40E_FLAG_TC_MQPRIO;
> + pf->flags &= ~I40E_FLAG_DCB_ENABLED;
> + break;
> + default:
> +   

Re: [PATCH net-next 0/2] Add mqprio hardware offload support in hns3 driver

2017-10-16 Thread Yunsheng Lin
qdisc);
if (old)
qdisc_destroy(old);

--Only call qdisc_hash_add when  ntx < 
dev->real_num_tx_queues---

        if (ntx < dev->real_num_tx_queues)
qdisc_hash_add(qdisc, false);
}
kfree(priv->qdiscs);
priv->qdiscs = NULL;
}


> 
>>
>>>
>>>>
>>>> Maybe we can add a callback to notify mqprio the configuration has
>> changed.
>>>>
>>>
>>> Which would do what?
>>> You already have the notifications available for monitoring using dcbnl 
>>> logic
>> if the
>>> configuration change [for user]; So user can re-configure whatever it
>> wants.
>>
>> Yes, if user is only using dcb tool.
>>
>>> But other than dropping all the qdisc configurations and going back to the
>> default
>>> qdiscs, what default action would mqprio be able to do when configuration
>> changes
>>> that actually makes sense?
>>
>> As explained above, after dcb changing the configuration, some queue may
>> have no qdisc
>> attached, so I was thinking maybe we can add pfifo to it if there is no qdsic
>> attached
>> to it.
>>
>> Thanks,
>> Yunsheng Lin
>>
>>>
>>>> Thanks
>>>> Yunsheng Lin
>>>>
>>>>>
>>>>> Cheers,
>>>>> Yuval
>>>>>
>>>>>>
>>>>>> Yunsheng Lin (2):
>>>>>>   mqprio: Add a new hardware offload type in mqprio
>>>>>>   net: hns3: Add mqprio hardware offload support in hns3 driver
>>>>>>
>>>>>>  drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
>>>>>>  .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 23
>> +++
>>>>>>  .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 46
>>>> ++-
>>>>>> ---
>>>>>>  include/uapi/linux/pkt_sched.h |  1 +
>>>>>>  4 files changed, 55 insertions(+), 16 deletions(-)
>>>>>>
>>>>>> --
>>>>>> 1.9.1
>>>>>
>>>>>
>>>>>
>>>
> 



Re: [PATCH net-next 0/2] Add mqprio hardware offload support in hns3 driver

2017-10-15 Thread Yunsheng Lin
Hi, Yuval

On 2017/10/15 16:51, Yuval Mintz wrote:
>>>>> This patchset adds a new hardware offload type in mqprio before
>> adding
>>>>> mqprio hardware offload support in hns3 driver.
> 
> Apparently Dave has already accepted  Amirtha's changes to mqprio:
> https://marc.info/?l=linux-netdev=150803219824053=2 
> so I guess you need to revise your patchs to align to the new conventions.

Ok.

"If offloads are supported by setting the 'hw' option to 1, the default
offload mode is 'dcb' where only the TC values are offloaded to the
device. "

According to the description of the above patchset, the default mode is already
dcb, so i will drop the dcb mode patch.

I think the scenario you mentioned still existed, and I am willing to implement
it if we come to a solution that will suit most in the community.

Thanks,
Yunsheng Lin

> 
>>>>
>>>> I think one of the biggest issues in tying this to DCB configuration is the
>>>> non-immediate [and possibly non persistent] configuration.
>>>>
>>>> Scenario #1:
>>>> User is configuring mqprio offloaded with 3 TCs while device is in willing
>>> mode.
>>>> Would you expect the driver to immediately respond with a success or
>>> instead
>>>> delay the return until the DCBx negotiation is complete and the
>> operational
>>>> num of TCs is actually 3?
>>>
>>> Well, when user requsts the mqprio offloaded by a hardware shared by
>> DCB,
>>> I expect
>>> the user is not using the dcb tool.
>>> If user is still using dcb tool, then result is undefined.
>>>
>>> The scenario you mention maybe can be enforced by setting willing to zero
>>> when user
>>> is requesting the mqprio offload, and restore the willing bit when unloaded
>>> the mqprio
>>> offload.
>>
>> Sounds a bit harsh but would probably work.
>>
>>> But I think the real issue is that dcb and mqprio shares the tc system in 
>>> the
>>> stack,
>>> the problem may be better to be fixed in the stack rather than in the
>> driver,
>>> as you
>>> suggested in the DCB patchset. What do you think?
>>
>> What did you have in mind?
>>
>>>
>>>>
>>>> Scenario #2:
>>>> Assume user explicitly offloaded mqprio with 3 TCs, but now DCB
>>> configuration
>>>> has changed on the peer side and 4 TCs is the new negotiated operational
>>> value.
>>>> Your current driver logic would change the number of TCs underneath
>> the
>>> user
>>>> configuration [and it would actually probably work due to mqprio being a
>>> crappy
>>>> qdisc]. But was that the user actual intention?
>>>> [I think the likely answer in this scenario is 'yes' since the alternative 
>>>> is no
>>> better.
>>>> But I still thought it was worth mentioning]
>>>
>>> You are right, the problem also have something to do with mqprio and dcb
>>> sharing
>>> the tc in the stack.
>>>
>>> Druing testing, when user explicitly offloaded mqprio with 3 TCs, all
>>> queue has a default pfifo mqprio attached, after DCB changes the tc num
>> to
>>> 4,
>>> using tc qdisc shows some queue does not have a default pfifo mqprio
>>> attached.
>>
>> Really? Then what did it show?
>> [I assume it has some pfifo attached, and it's an mqprio dump kind of an
>> issue]
>>
>>>
>>> Maybe we can add a callback to notify mqprio the configuration has
>> changed.
>>>
>>
>> Which would do what?
>> You already have the notifications available for monitoring using dcbnl 
>> logic if
>> the
>> configuration change [for user]; So user can re-configure whatever it wants.
>> But other than dropping all the qdisc configurations and going back to the
>> default
>> qdiscs, what default action would mqprio be able to do when configuration
>> changes
>> that actually makes sense?
>>
>>> Thanks
>>> Yunsheng Lin
>>>
>>>>
>>>> Cheers,
>>>> Yuval
>>>>
>>>>>
>>>>> Yunsheng Lin (2):
>>>>>   mqprio: Add a new hardware offload type in mqprio
>>>>>   net: hns3: Add mqprio hardware offload support in hns3 driver
>>>>>
>>>>>  drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
>>>>>  .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 23 +++
>>>>>  .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 46
>>> ++-
>>>>> ---
>>>>>  include/uapi/linux/pkt_sched.h |  1 +
>>>>>  4 files changed, 55 insertions(+), 16 deletions(-)
>>>>>
>>>>> --
>>>>> 1.9.1
>>>>
>>>>
>>>>
> 



Re: [PATCH net-next 0/2] Add mqprio hardware offload support in hns3 driver

2017-10-15 Thread Yunsheng Lin
Hi, Yuval

On 2017/10/15 13:14, Yuval Mintz wrote:
>> Hi, Yuval
>>
>> On 2017/10/13 4:21, Yuval Mintz wrote:
>>>> This patchset adds a new hardware offload type in mqprio before adding
>>>> mqprio hardware offload support in hns3 driver.
>>>
>>> I think one of the biggest issues in tying this to DCB configuration is the
>>> non-immediate [and possibly non persistent] configuration.
>>>
>>> Scenario #1:
>>> User is configuring mqprio offloaded with 3 TCs while device is in willing
>> mode.
>>> Would you expect the driver to immediately respond with a success or
>> instead
>>> delay the return until the DCBx negotiation is complete and the operational
>>> num of TCs is actually 3?
>>
>> Well, when user requsts the mqprio offloaded by a hardware shared by DCB,
>> I expect
>> the user is not using the dcb tool.
>> If user is still using dcb tool, then result is undefined.
>>
>> The scenario you mention maybe can be enforced by setting willing to zero
>> when user
>> is requesting the mqprio offload, and restore the willing bit when unloaded
>> the mqprio
>> offload.
> 
> Sounds a bit harsh but would probably work.
> 
>> But I think the real issue is that dcb and mqprio shares the tc system in the
>> stack,
>> the problem may be better to be fixed in the stack rather than in the driver,
>> as you
>> suggested in the DCB patchset. What do you think?
> 
> What did you have in mind?

I was thinking maybe the tc system can provide a notification to mqprio and dcb.
mqprio and dcb register a callback to the tc system, when there is some change 
of
tc configuration, the tc system call the callback from mqprio and dcb.

> 
>>
>>>
>>> Scenario #2:
>>> Assume user explicitly offloaded mqprio with 3 TCs, but now DCB
>> configuration
>>> has changed on the peer side and 4 TCs is the new negotiated operational
>> value.
>>> Your current driver logic would change the number of TCs underneath the
>> user
>>> configuration [and it would actually probably work due to mqprio being a
>> crappy
>>> qdisc]. But was that the user actual intention?
>>> [I think the likely answer in this scenario is 'yes' since the alternative 
>>> is no
>> better.
>>> But I still thought it was worth mentioning]
>>
>> You are right, the problem also have something to do with mqprio and dcb
>> sharing
>> the tc in the stack.
>>
>> Druing testing, when user explicitly offloaded mqprio with 3 TCs, all
>> queue has a default pfifo mqprio attached, after DCB changes the tc num to
>> 4,
>> using tc qdisc shows some queue does not have a default pfifo mqprio
>> attached.
> 
> Really? Then what did it show? 
> [I assume it has some pfifo attached, and it's an mqprio dump kind of an 
> issue]

When queue size of the ndev is 16 and tc num is 3, we set the real queue size to
15 ( 5 * 3 = 15), mqprio only attach pfifo to the first 15 queue, when tc num 
change
to 4 by DCB, we set the real queue size to 16 (4 * 4 = 16).
So tc qdisc shows the last queue has no qdisc attached.

> 
>>
>> Maybe we can add a callback to notify mqprio the configuration has changed.
>>
> 
> Which would do what?
> You already have the notifications available for monitoring using dcbnl logic 
> if the
> configuration change [for user]; So user can re-configure whatever it wants.

Yes, if user is only using dcb tool.

> But other than dropping all the qdisc configurations and going back to the 
> default
> qdiscs, what default action would mqprio be able to do when configuration 
> changes
> that actually makes sense?

As explained above, after dcb changing the configuration, some queue may have 
no qdisc
attached, so I was thinking maybe we can add pfifo to it if there is no qdsic 
attached
to it.

Thanks,
Yunsheng Lin

> 
>> Thanks
>> Yunsheng Lin
>>
>>>
>>> Cheers,
>>> Yuval
>>>
>>>>
>>>> Yunsheng Lin (2):
>>>>   mqprio: Add a new hardware offload type in mqprio
>>>>   net: hns3: Add mqprio hardware offload support in hns3 driver
>>>>
>>>>  drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
>>>>  .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 23 +++
>>>>  .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 46
>> ++-
>>>> ---
>>>>  include/uapi/linux/pkt_sched.h |  1 +
>>>>  4 files changed, 55 insertions(+), 16 deletions(-)
>>>>
>>>> --
>>>> 1.9.1
>>>
>>>
>>>
> 



Re: [PATCH net-next 1/2] mqprio: Add a new hardware offload type in mqprio

2017-10-12 Thread Yunsheng Lin
Hi, Yuval

On 2017/10/13 4:10, Yuval Mintz wrote:
>> When a driver supports both dcb and hardware offloaded mqprio, and
>> user is running mqprio and dcb tool concurrently, the configuration
>> set by each tool may be conflicted with each other because the dcb
> (for second 'each') s/each/the
> 

Will do, Thanks

>> and mqprio may be using the same hardwere offload component and share
> s/hardwere/hardware

Will do, Thanks

> 
>> the tc system in the network stack.
>>
>> This patch adds a new offload type to indicate that the underlying
>> driver offload prio mapping as part of DCB. If the driver would be
> 'should' offload

Will do, Thanks

> 
>> incapable of that it would refuse the offload. User would then have
>> to explicitly request that qdisc offload.
> 
> 
> 



Re: [PATCH net-next 0/2] Add mqprio hardware offload support in hns3 driver

2017-10-12 Thread Yunsheng Lin
Hi, Yuval

On 2017/10/13 4:21, Yuval Mintz wrote:
>> This patchset adds a new hardware offload type in mqprio before adding
>> mqprio hardware offload support in hns3 driver.
> 
> I think one of the biggest issues in tying this to DCB configuration is the
> non-immediate [and possibly non persistent] configuration.
> 
> Scenario #1:
> User is configuring mqprio offloaded with 3 TCs while device is in willing 
> mode.
> Would you expect the driver to immediately respond with a success or instead
> delay the return until the DCBx negotiation is complete and the operational
> num of TCs is actually 3?

Well, when user requsts the mqprio offloaded by a hardware shared by DCB, I 
expect
the user is not using the dcb tool.
If user is still using dcb tool, then result is undefined.

The scenario you mention maybe can be enforced by setting willing to zero when 
user
is requesting the mqprio offload, and restore the willing bit when unloaded the 
mqprio
offload.
But I think the real issue is that dcb and mqprio shares the tc system in the 
stack,
the problem may be better to be fixed in the stack rather than in the driver, 
as you
suggested in the DCB patchset. What do you think?

> 
> Scenario #2:
> Assume user explicitly offloaded mqprio with 3 TCs, but now DCB configuration
> has changed on the peer side and 4 TCs is the new negotiated operational 
> value.
> Your current driver logic would change the number of TCs underneath the user
> configuration [and it would actually probably work due to mqprio being a 
> crappy
> qdisc]. But was that the user actual intention?
> [I think the likely answer in this scenario is 'yes' since the alternative is 
> no better.
> But I still thought it was worth mentioning]

You are right, the problem also have something to do with mqprio and dcb sharing
the tc in the stack.

Druing testing, when user explicitly offloaded mqprio with 3 TCs, all
queue has a default pfifo mqprio attached, after DCB changes the tc num to 4,
using tc qdisc shows some queue does not have a default pfifo mqprio attached.

Maybe we can add a callback to notify mqprio the configuration has changed.

Thanks
Yunsheng Lin

> 
> Cheers,
> Yuval
> 
>>
>> Yunsheng Lin (2):
>>   mqprio: Add a new hardware offload type in mqprio
>>   net: hns3: Add mqprio hardware offload support in hns3 driver
>>
>>  drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
>>  .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 23 +++
>>  .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 46 ++-
>> ---
>>  include/uapi/linux/pkt_sched.h |  1 +
>>  4 files changed, 55 insertions(+), 16 deletions(-)
>>
>> --
>> 1.9.1
> 
> 
> 



[PATCH net-next 0/2] Add mqprio hardware offload support in hns3 driver

2017-10-11 Thread Yunsheng Lin
This patchset adds a new hardware offload type in mqprio before adding
mqprio hardware offload support in hns3 driver.

Yunsheng Lin (2):
  mqprio: Add a new hardware offload type in mqprio
  net: hns3: Add mqprio hardware offload support in hns3 driver

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 23 +++
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 46 ++
 include/uapi/linux/pkt_sched.h |  1 +
 4 files changed, 55 insertions(+), 16 deletions(-)

-- 
1.9.1



[PATCH net-next 1/2] mqprio: Add a new hardware offload type in mqprio

2017-10-11 Thread Yunsheng Lin
When a driver supports both dcb and hardware offloaded mqprio, and
user is running mqprio and dcb tool concurrently, the configuration
set by each tool may be conflicted with each other because the dcb
and mqprio may be using the same hardwere offload component and share
the tc system in the network stack.

This patch adds a new offload type to indicate that the underlying
driver offload prio mapping as part of DCB. If the driver would be
incapable of that it would refuse the offload. User would then have
to explicitly request that qdisc offload.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
Suggested-by: Yuval Mintz <yuv...@mellanox.com>
---
 include/uapi/linux/pkt_sched.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h
index 099bf55..8016027 100644
--- a/include/uapi/linux/pkt_sched.h
+++ b/include/uapi/linux/pkt_sched.h
@@ -620,6 +620,7 @@ struct tc_drr_stats {
 enum {
TC_MQPRIO_HW_OFFLOAD_NONE,  /* no offload requested */
TC_MQPRIO_HW_OFFLOAD_TCS,   /* offload TCs, no queue counts */
+   TC_MQPRIO_HW_OFFLOAD_DCB,   /* offload shared by DCB */
__TC_MQPRIO_HW_OFFLOAD_MAX
 };
 
-- 
1.9.1



[PATCH net-next 2/2] net: hns3: Add mqprio hardware offload support in hns3 driver

2017-10-11 Thread Yunsheng Lin
When using tc qdisc, dcb_ops->setup_tc is used to tell hclge_dcb
module to do the tm related setup. Only TC_MQPRIO_HW_OFFLOAD_DCB
offload type is supported.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 23 +++
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 46 ++
 3 files changed, 54 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 575f50d..3acd8db 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -381,6 +381,7 @@ struct hnae3_dcb_ops {
u8   (*setdcbx)(struct hnae3_handle *, u8);
 
int (*map_update)(struct hnae3_handle *);
+   int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
 };
 
 struct hnae3_ae_algo {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
index 1b30a6f..7ec9484 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -276,6 +276,28 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
return 0;
 }
 
+static int hclge_setup_tc(struct hnae3_handle *h, u8 tc, u8 *prio_tc)
+{
+   struct hclge_vport *vport = hclge_get_vport(h);
+   struct hclge_dev *hdev = vport->back;
+   int ret;
+
+   if (tc > hdev->tc_max) {
+   dev_err(>pdev->dev,
+   "setup tc failed, tc(%u) > tc_max(%u)\n",
+   tc, hdev->tc_max);
+   return -EINVAL;
+   }
+
+   hclge_tm_schd_info_update(hdev, tc);
+
+   ret = hclge_tm_prio_tc_info_update(hdev, prio_tc);
+   if (ret)
+   return ret;
+
+   return hclge_tm_init_hw(hdev);
+}
+
 static const struct hnae3_dcb_ops hns3_dcb_ops = {
.ieee_getets= hclge_ieee_getets,
.ieee_setets= hclge_ieee_setets,
@@ -284,6 +306,7 @@ static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
.getdcbx= hclge_getdcbx,
.setdcbx= hclge_setdcbx,
.map_update = hclge_map_update,
+   .setup_tc   = hclge_setup_tc,
 };
 
 void hclge_dcb_ops_set(struct hclge_dev *hdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index ba550c1..79d8d6b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -1186,42 +1186,56 @@ static void hns3_nic_udp_tunnel_del(struct net_device 
*netdev,
}
 }
 
-static int hns3_setup_tc(struct net_device *netdev, u8 tc)
+static int hns3_setup_tc(struct net_device *netdev, u8 tc, u8 *prio_tc)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_knic_private_info *kinfo = >kinfo;
+   bool if_running;
unsigned int i;
int ret;
 
if (tc > HNAE3_MAX_TC)
return -EINVAL;
 
-   if (kinfo->num_tc == tc)
-   return 0;
-
if (!netdev)
return -EINVAL;
 
-   if (!tc) {
-   netdev_reset_tc(netdev);
-   return 0;
+   if_running = netif_running(netdev);
+   if (if_running) {
+   hns3_nic_net_stop(netdev);
+   msleep(100);
}
 
-   /* Set num_tc for netdev */
-   ret = netdev_set_num_tc(netdev, tc);
+   ret = (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
+   kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP;
if (ret)
-   return ret;
+   goto out;
+
+   if (tc <= 1) {
+   netdev_reset_tc(netdev);
+   } else {
+   ret = netdev_set_num_tc(netdev, tc);
+   if (ret)
+   goto out;
+
+   for (i = 0; i < HNAE3_MAX_TC; i++) {
+   if (!kinfo->tc_info[i].enable)
+   continue;
 
-   /* Set per TC queues for the VSI */
-   for (i = 0; i < HNAE3_MAX_TC; i++) {
-   if (kinfo->tc_info[i].enable)
netdev_set_tc_queue(netdev,
kinfo->tc_info[i].tc,
kinfo->tc_info[i].tqp_count,
kinfo->tc_info[i].tqp_offset);
+   }
}
 
-   return 0;
+   ret = hns3_nic_set_real_num_queue(netdev);
+
+out:
+   if (if_running)
+   hns3_nic_net_open(netdev);
+
+   return ret;
 }
 
 static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
@@ -1229,10 +1243,10 @@ static int hns3_nic_setup_tc(struct net_device *dev, 
e

[PATCH net-next 1/7] net: hns3: Cleanup for shifting true in hns3 driver

2017-10-09 Thread Yunsheng Lin
This patch fixes a shifting true in hclge_main module.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 1a13614..5c1bf12 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1687,7 +1687,7 @@ static int hclge_rx_priv_buf_alloc(struct hclge_dev *hdev,
req->buf_num[i] =
cpu_to_le16(priv->buf_size >> HCLGE_BUF_UNIT_S);
req->buf_num[i] |=
-   cpu_to_le16(true << HCLGE_TC0_PRI_BUF_EN_B);
+   cpu_to_le16(1 << HCLGE_TC0_PRI_BUF_EN_B);
}
 
req->shared_buf =
-- 
1.9.1



[PATCH net-next 0/7] A few cleanup for hns3 ethernet driver

2017-10-09 Thread Yunsheng Lin
This patchset contains a few cleanup for hns3 ethernet driver.
No functional change intended.

Yunsheng Lin (7):
  net: hns3: Cleanup for shifting true in hns3 driver
  net: hns3: Add hns3_get_handle macro in hns3 driver
  net: hns3: Cleanup indentation for Kconfig in the the hisilicon folder
  net: hns3: Consistently using GENMASK in hns3 driver
  net: hns3: Cleanup for struct that used to send cmd to firmware
  net: hns3: Cleanup for endian issue in hns3 driver
  net: hns3: Cleanup for non-static function in hns3 driver

 drivers/net/ethernet/hisilicon/Kconfig |   6 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |  16 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 130 +++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 385 +++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   4 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  26 +-
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c|  18 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c |  61 +---
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   3 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c  |  42 +--
 10 files changed, 344 insertions(+), 347 deletions(-)

-- 
1.9.1



[PATCH net-next 2/7] net: hns3: Add hns3_get_handle macro in hns3 driver

2017-10-09 Thread Yunsheng Lin
There are many places that will need to get the handle
of netdev, so add a macro to get the handle of netdev.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c| 18 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 39 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |  3 ++
 .../ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c  | 38 -
 4 files changed, 35 insertions(+), 63 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
index 9832172..925619a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
@@ -13,8 +13,7 @@
 static
 int hns3_dcbnl_ieee_getets(struct net_device *ndev, struct ieee_ets *ets)
 {
-   struct hns3_nic_priv *priv = netdev_priv(ndev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(ndev);
 
if (h->kinfo.dcb_ops->ieee_getets)
return h->kinfo.dcb_ops->ieee_getets(h, ets);
@@ -25,8 +24,7 @@ int hns3_dcbnl_ieee_getets(struct net_device *ndev, struct 
ieee_ets *ets)
 static
 int hns3_dcbnl_ieee_setets(struct net_device *ndev, struct ieee_ets *ets)
 {
-   struct hns3_nic_priv *priv = netdev_priv(ndev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(ndev);
 
if (h->kinfo.dcb_ops->ieee_setets)
return h->kinfo.dcb_ops->ieee_setets(h, ets);
@@ -37,8 +35,7 @@ int hns3_dcbnl_ieee_setets(struct net_device *ndev, struct 
ieee_ets *ets)
 static
 int hns3_dcbnl_ieee_getpfc(struct net_device *ndev, struct ieee_pfc *pfc)
 {
-   struct hns3_nic_priv *priv = netdev_priv(ndev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(ndev);
 
if (h->kinfo.dcb_ops->ieee_getpfc)
return h->kinfo.dcb_ops->ieee_getpfc(h, pfc);
@@ -49,8 +46,7 @@ int hns3_dcbnl_ieee_getpfc(struct net_device *ndev, struct 
ieee_pfc *pfc)
 static
 int hns3_dcbnl_ieee_setpfc(struct net_device *ndev, struct ieee_pfc *pfc)
 {
-   struct hns3_nic_priv *priv = netdev_priv(ndev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(ndev);
 
if (h->kinfo.dcb_ops->ieee_setpfc)
return h->kinfo.dcb_ops->ieee_setpfc(h, pfc);
@@ -61,8 +57,7 @@ int hns3_dcbnl_ieee_setpfc(struct net_device *ndev, struct 
ieee_pfc *pfc)
 /* DCBX configuration */
 static u8 hns3_dcbnl_getdcbx(struct net_device *ndev)
 {
-   struct hns3_nic_priv *priv = netdev_priv(ndev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(ndev);
 
if (h->kinfo.dcb_ops->getdcbx)
return h->kinfo.dcb_ops->getdcbx(h);
@@ -73,8 +68,7 @@ static u8 hns3_dcbnl_getdcbx(struct net_device *ndev)
 /* return 0 if successful, otherwise fail */
 static u8 hns3_dcbnl_setdcbx(struct net_device *ndev, u8 mode)
 {
-   struct hns3_nic_priv *priv = netdev_priv(ndev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(ndev);
 
if (h->kinfo.dcb_ops->setdcbx)
return h->kinfo.dcb_ops->setdcbx(h, mode);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index c315065..c2a0537 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -198,8 +198,7 @@ static void hns3_vector_gl_rl_init(struct 
hns3_enet_tqp_vector *tqp_vector)
 
 static int hns3_nic_set_real_num_queue(struct net_device *netdev)
 {
-   struct hns3_nic_priv *priv = netdev_priv(netdev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(netdev);
struct hnae3_knic_private_info *kinfo = >kinfo;
unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
int ret;
@@ -307,8 +306,7 @@ static int hns3_nic_net_stop(struct net_device *netdev)
 
 void hns3_set_multicast_list(struct net_device *netdev)
 {
-   struct hns3_nic_priv *priv = netdev_priv(netdev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_get_handle(netdev);
struct netdev_hw_addr *ha = NULL;
 
if (h->ae_algo->ops->set_mc_addr) {
@@ -321,8 +319,7 @@ void hns3_set_multicast_list(struct net_device *netdev)
 static int hns3_nic_uc_sync(struct net_device *netdev,
const unsigned char *addr)
 {
-   struct hns3_nic_priv *priv = netdev_priv(netdev);
-   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_handle *h = hns3_

[PATCH net-next 7/7] net: hns3: Cleanup for non-static function in hns3 driver

2017-10-09 Thread Yunsheng Lin
This patch fixes the following warning from sparse:
warning: symbol 'hns3_set_multicast_list' was not declared.
Should it be static.

hns3_set_multicast_list turns out to be not used, so delete it.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c   |  4 ++--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c  | 14 +++---
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c   | 20 
 .../ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c|  4 ++--
 4 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 05985d8..8ecd807 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -276,8 +276,8 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc 
*desc, int num)
return retval;
 }
 
-enum hclge_cmd_status hclge_cmd_query_firmware_version(struct hclge_hw *hw,
-  u32 *version)
+static enum hclge_cmd_status hclge_cmd_query_firmware_version(
+   struct hclge_hw *hw, u32 *version)
 {
struct hclge_query_version_cmd *resp;
struct hclge_desc desc;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 6115c2f..c91c779 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1550,8 +1550,8 @@ static int hclge_tx_buffer_calc(struct hclge_dev *hdev,
  * @buf_alloc: pointer to buffer calculation data
  * @return: 0: calculate sucessful, negative: fail
  */
-int hclge_rx_buffer_calc(struct hclge_dev *hdev,
-struct hclge_pkt_buf_alloc *buf_alloc)
+static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
+   struct hclge_pkt_buf_alloc *buf_alloc)
 {
u32 rx_all = hdev->pkt_buf_size;
int no_pfc_priv_num, pfc_priv_num;
@@ -2828,9 +2828,9 @@ int hclge_map_vport_ring_to_vector(struct hclge_vport 
*vport, int vector_id,
return 0;
 }
 
-int hclge_map_handle_ring_to_vector(struct hnae3_handle *handle,
-   int vector,
-   struct hnae3_ring_chain_node *ring_chain)
+static int hclge_map_handle_ring_to_vector(
+   struct hnae3_handle *handle, int vector,
+   struct hnae3_ring_chain_node *ring_chain)
 {
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
@@ -3206,8 +3206,8 @@ static void hclge_prepare_mac_addr(struct 
hclge_mac_vlan_tbl_entry_cmd *new_req,
new_req->mac_addr_lo16 = cpu_to_le16(low_val & 0x);
 }
 
-u16 hclge_get_mac_addr_to_mta_index(struct hclge_vport *vport,
-   const u8 *addr)
+static u16 hclge_get_mac_addr_to_mta_index(struct hclge_vport *vport,
+  const u8 *addr)
 {
u16 high_val = addr[1] | (addr[0] << 8);
struct hclge_dev *hdev = vport->back;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index aa73855..26bbc91 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -24,7 +24,7 @@
 #include "hnae3.h"
 #include "hns3_enet.h"
 
-const char hns3_driver_name[] = "hns3";
+static const char hns3_driver_name[] = "hns3";
 const char hns3_driver_version[] = VERMAGIC_STRING;
 static const char hns3_driver_string[] =
"Hisilicon Ethernet Network Driver for Hip08 Family";
@@ -304,18 +304,6 @@ static int hns3_nic_net_stop(struct net_device *netdev)
return 0;
 }
 
-void hns3_set_multicast_list(struct net_device *netdev)
-{
-   struct hnae3_handle *h = hns3_get_handle(netdev);
-   struct netdev_hw_addr *ha = NULL;
-
-   if (h->ae_algo->ops->set_mc_addr) {
-   netdev_for_each_mc_addr(ha, netdev)
-   if (h->ae_algo->ops->set_mc_addr(h, ha->addr))
-   netdev_err(netdev, "set multicast fail\n");
-   }
-}
-
 static int hns3_nic_uc_sync(struct net_device *netdev,
const unsigned char *addr)
 {
@@ -360,7 +348,7 @@ static int hns3_nic_mc_unsync(struct net_device *netdev,
return 0;
 }
 
-void hns3_nic_set_rx_mode(struct net_device *netdev)
+static void hns3_nic_set_rx_mode(struct net_device *netdev)
 {
struct hnae3_handle *h = hns3_get_handle(netdev);
 
@@ -2596,7 +2584,7 @@ static void hns3_fini_ring(struct hns3_enet_ring *ring)
ring->next_to_use = 0;
 }
 
-int hns3_buf_size2t

[PATCH net-next 3/7] net: hns3: Cleanup indentation for Kconfig in the the hisilicon folder

2017-10-09 Thread Yunsheng Lin
This patch fixes a few indentation for Kconfig file in the
hisilicon folder.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/Kconfig | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 9d7cb03..3b6 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -78,7 +78,7 @@ config HNS_ENET
 
 config HNS3
tristate "Hisilicon Network Subsystem Support HNS3 (Framework)"
-depends on PCI
+   depends on PCI
---help---
  This selects the framework support for Hisilicon Network Subsystem 3.
  This layer facilitates clients like ENET, RoCE and user-space ethernet
@@ -87,7 +87,7 @@ config HNS3
 
 config HNS3_HCLGE
tristate "Hisilicon HNS3 HCLGE Acceleration Engine & Compatibility 
Layer Support"
-depends on PCI_MSI
+   depends on PCI_MSI
depends on HNS3
---help---
  This selects the HNS3_HCLGE network acceleration engine & its hardware
@@ -96,7 +96,7 @@ config HNS3_HCLGE
 
 config HNS3_ENET
tristate "Hisilicon HNS3 Ethernet Device Support"
-depends on 64BIT && PCI
+   depends on 64BIT && PCI
depends on HNS3 && HNS3_HCLGE
---help---
  This selects the Ethernet Driver for Hisilicon Network Subsystem 3 
for hip08
-- 
1.9.1



[PATCH net-next 6/7] net: hns3: Cleanup for endian issue in hns3 driver

2017-10-09 Thread Yunsheng Lin
This patch fixes a lot of endian issues detected by sparse.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |   8 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  10 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 206 -
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  26 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c |   4 +-
 5 files changed, 145 insertions(+), 109 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 648b64b..05985d8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -208,7 +208,7 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc 
*desc, int num)
 * which will be use for hardware to write back
 */
ntc = hw->cmq.csq.next_to_use;
-   opcode = desc[0].opcode;
+   opcode = le16_to_cpu(desc[0].opcode);
while (handle < num) {
desc_to_use = >cmq.csq.desc[hw->cmq.csq.next_to_use];
*desc_to_use = desc[handle];
@@ -225,7 +225,7 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc 
*desc, int num)
 * If the command is sync, wait for the firmware to write back,
 * if multi descriptors to be sent, use the first one to check
 */
-   if (HCLGE_SEND_SYNC(desc->flag)) {
+   if (HCLGE_SEND_SYNC(le16_to_cpu(desc->flag))) {
do {
if (hclge_cmd_csq_done(hw))
break;
@@ -244,9 +244,9 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc 
*desc, int num)
pr_debug("Get cmd desc:\n");
 
if (likely(!hclge_is_special_opcode(opcode)))
-   desc_ret = desc[handle].retval;
+   desc_ret = le16_to_cpu(desc[handle].retval);
else
-   desc_ret = desc[0].retval;
+   desc_ret = le16_to_cpu(desc[0].retval);
 
if ((enum hclge_cmd_return_status)desc_ret ==
HCLGE_CMD_EXEC_SUCCESS)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index d2ff0e3..8f3ba02a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -434,8 +434,8 @@ struct hclge_rss_input_tuple_cmd {
 #define HCLGE_RSS_CFG_TBL_SIZE 16
 
 struct hclge_rss_indirection_table_cmd {
-   u16 start_table_index;
-   u16 rss_set_bitmap;
+   __le16 start_table_index;
+   __le16 rss_set_bitmap;
u8 rsv[4];
u8 rss_result[HCLGE_RSS_CFG_TBL_SIZE];
 };
@@ -446,7 +446,7 @@ struct hclge_rss_indirection_table_cmd {
 #define HCLGE_RSS_TC_SIZE_MGENMASK(14, 12)
 #define HCLGE_RSS_TC_VALID_B   15
 struct hclge_rss_tc_mode_cmd {
-   u16 rss_tc_mode[HCLGE_MAX_TC_NUM];
+   __le16 rss_tc_mode[HCLGE_MAX_TC_NUM];
u8 rsv[8];
 };
 
@@ -601,7 +601,7 @@ struct hclge_cfg_func_mta_filter_cmd {
 #define HCLGE_CFG_MTA_ITEM_IDX_S   0x0
 #define HCLGE_CFG_MTA_ITEM_IDX_M   GENMASK(11, 0)
 struct hclge_cfg_func_mta_item_cmd {
-   u16 item_idx; /* Only used lowest 12 bit */
+   __le16  item_idx; /* Only used lowest 12 bit */
u8  accept;   /* Only used lowest 1 bit */
u8  rsv[21];
 };
@@ -645,7 +645,7 @@ struct hclge_vlan_filter_pf_cfg_cmd {
 };
 
 struct hclge_vlan_filter_vf_cfg_cmd {
-   u16 vlan_id;
+   __le16 vlan_id;
u8  resp_code;
u8  rsv;
u8  vlan_cfg;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 5103f23..6115c2f 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -362,7 +362,7 @@ static int hclge_64_bit_update_stats(struct hclge_dev *hdev)
 #define HCLGE_64_BIT_RTN_DATANUM 4
u64 *data = (u64 *)(>hw_stats.all_64_bit_stats);
struct hclge_desc desc[HCLGE_64_BIT_CMD_NUM];
-   u64 *desc_data;
+   __le64 *desc_data;
int i, k, n;
int ret;
 
@@ -376,14 +376,14 @@ static int hclge_64_bit_update_stats(struct hclge_dev 
*hdev)
 
for (i = 0; i < HCLGE_64_BIT_CMD_NUM; i++) {
if (unlikely(i == 0)) {
-   desc_data = (u64 *)([i].data[0]);
+   desc_data = (__le64 *)([i].data[0]);
n = HCLGE_64_BIT_RTN_DATANUM - 1;
} else {
-   desc_data = (u64 *)([i]);
+   desc_data = (__le64 *)([i]);

[PATCH net-next 5/7] net: hns3: Cleanup for struct that used to send cmd to firmware

2017-10-09 Thread Yunsheng Lin
The hclge_tm module has already added _cmd to the end of struct
that used to send cmd to firmware. This will help us finding the
endian issues.
This patch adds the _cmd to the end of struct that used to send
cmd to firmware in hclge_main module.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c |   4 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  72 -
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 163 +++--
 3 files changed, 120 insertions(+), 119 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 8b511e6..648b64b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -279,12 +279,12 @@ int hclge_cmd_send(struct hclge_hw *hw, struct hclge_desc 
*desc, int num)
 enum hclge_cmd_status hclge_cmd_query_firmware_version(struct hclge_hw *hw,
   u32 *version)
 {
-   struct hclge_query_version *resp;
+   struct hclge_query_version_cmd *resp;
struct hclge_desc desc;
int ret;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_QUERY_FW_VER, 1);
-   resp = (struct hclge_query_version *)desc.data;
+   resp = (struct hclge_query_version_cmd *)desc.data;
 
ret = hclge_cmd_send(hw, , 1);
if (!ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 9cff7db..d2ff0e3 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -221,12 +221,12 @@ enum hclge_opcode_type {
 #define HCLGE_RCB_INIT_QUERY_TIMEOUT   10
 #define HCLGE_RCB_INIT_FLAG_EN_B   0
 #define HCLGE_RCB_INIT_FLAG_FINI_B 8
-struct hclge_config_rcb_init {
+struct hclge_config_rcb_init_cmd {
__le16 rcb_init_flag;
u8 rsv[22];
 };
 
-struct hclge_tqp_map {
+struct hclge_tqp_map_cmd {
__le16 tqp_id;  /* Absolute tqp id for in this pf */
u8 tqp_vf;  /* VF id */
 #define HCLGE_TQP_MAP_TYPE_PF  0
@@ -246,7 +246,7 @@ enum hclge_int_type {
HCLGE_INT_EVENT,
 };
 
-struct hclge_ctrl_vector_chain {
+struct hclge_ctrl_vector_chain_cmd {
u8 int_vector_id;
u8 int_cause_num;
 #define HCLGE_INT_TYPE_S   0
@@ -263,18 +263,18 @@ struct hclge_ctrl_vector_chain {
 #define HCLGE_TC_NUM   8
 #define HCLGE_TC0_PRI_BUF_EN_B 15 /* Bit 15 indicate enable or not */
 #define HCLGE_BUF_UNIT_S   7  /* Buf size is united by 128 bytes */
-struct hclge_tx_buff_alloc {
+struct hclge_tx_buff_alloc_cmd {
__le16 tx_pkt_buff[HCLGE_TC_NUM];
u8 tx_buff_rsv[8];
 };
 
-struct hclge_rx_priv_buff {
+struct hclge_rx_priv_buff_cmd {
__le16 buf_num[HCLGE_TC_NUM];
__le16 shared_buf;
u8 rsv[6];
 };
 
-struct hclge_query_version {
+struct hclge_query_version_cmd {
__le32 firmware;
__le32 firmware_rsv[5];
 };
@@ -328,14 +328,14 @@ struct hclge_pkt_buf_alloc {
 };
 
 #define HCLGE_RX_COM_WL_EN_B   15
-struct hclge_rx_com_wl_buf {
+struct hclge_rx_com_wl_buf_cmd {
__le16 high_wl;
__le16 low_wl;
u8 rsv[20];
 };
 
 #define HCLGE_RX_PKT_EN_B  15
-struct hclge_rx_pkt_buf {
+struct hclge_rx_pkt_buf_cmd {
__le16 high_pkt;
__le16 low_pkt;
u8 rsv[20];
@@ -348,7 +348,7 @@ struct hclge_rx_pkt_buf {
 #define HCLGE_PF_MAC_NUM_MASK  0x3
 #define HCLGE_PF_STATE_MAINBIT(HCLGE_PF_STATE_MAIN_B)
 #define HCLGE_PF_STATE_DONEBIT(HCLGE_PF_STATE_DONE_B)
-struct hclge_func_status {
+struct hclge_func_status_cmd {
__le32  vf_rst_state[4];
u8 pf_state;
u8 mac_id;
@@ -359,7 +359,7 @@ struct hclge_func_status {
u8 rsv[2];
 };
 
-struct hclge_pf_res {
+struct hclge_pf_res_cmd {
__le16 tqp_num;
__le16 buf_size;
__le16 msixcap_localid_ba_nic;
@@ -395,7 +395,7 @@ struct hclge_pf_res {
 #define HCLGE_CFG_DEFAULT_SPEED_S  16
 #define HCLGE_CFG_DEFAULT_SPEED_M  GENMASK(23, 16)
 
-struct hclge_cfg_param {
+struct hclge_cfg_param_cmd {
__le32 offset;
__le32 rsv;
__le32 param[4];
@@ -405,7 +405,7 @@ struct hclge_cfg_param {
 #define HCLGE_DESC_NUM 0x40
 
 #define HCLGE_ALLOC_VALID_B0
-struct hclge_vf_num {
+struct hclge_vf_num_cmd {
u8 alloc_valid;
u8 rsv[23];
 };
@@ -413,13 +413,13 @@ struct hclge_vf_num {
 #define HCLGE_RSS_DEFAULT_OUTPORT_B4
 #define HCLGE_RSS_HASH_KEY_OFFSET_B4
 #define HCLGE_RSS_HASH_KEY_NUM 16
-struct hclge_rss_config {
+struct hclge_rss_config_cmd {
u8 hash_config;
u8 rsv[7];
u8 hash_key[HCLGE_RSS_HASH_KEY_NUM];
 };
 
-struct hclge_rss_input_tuple {
+struct hclge_rss_input_tuple_cmd {
u8 ipv4_tcp_en;
u8 ipv4_udp_en;
u8 ipv4_s

[PATCH net-next 4/7] net: hns3: Consistently using GENMASK in hns3 driver

2017-10-09 Thread Yunsheng Lin
This patch uses GENMASK to generate bit mask whenever
possible in hns3 driver.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 48 +++---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  4 +-
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 6b6d28e..9cff7db 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -250,11 +250,11 @@ struct hclge_ctrl_vector_chain {
u8 int_vector_id;
u8 int_cause_num;
 #define HCLGE_INT_TYPE_S   0
-#define HCLGE_INT_TYPE_M   0x3
+#define HCLGE_INT_TYPE_M   GENMASK(1, 0)
 #define HCLGE_TQP_ID_S 2
-#define HCLGE_TQP_ID_M (0x7ff << HCLGE_TQP_ID_S)
+#define HCLGE_TQP_ID_M GENMASK(12, 2)
 #define HCLGE_INT_GL_IDX_S 13
-#define HCLGE_INT_GL_IDX_M (0x3 << HCLGE_INT_GL_IDX_S)
+#define HCLGE_INT_GL_IDX_M GENMASK(14, 13)
__le16 tqp_type_and_id[HCLGE_VECTOR_ELEMENTS_PER_CMD];
u8 vfid;
u8 rsv;
@@ -372,28 +372,28 @@ struct hclge_pf_res {
 };
 
 #define HCLGE_CFG_OFFSET_S 0
-#define HCLGE_CFG_OFFSET_M 0xf /* Byte (8-10.3) */
+#define HCLGE_CFG_OFFSET_M GENMASK(19, 0)
 #define HCLGE_CFG_RD_LEN_S 24
-#define HCLGE_CFG_RD_LEN_M (0xf << HCLGE_CFG_RD_LEN_S)
+#define HCLGE_CFG_RD_LEN_M GENMASK(27, 24)
 #define HCLGE_CFG_RD_LEN_BYTES 16
 #define HCLGE_CFG_RD_LEN_UNIT  4
 
 #define HCLGE_CFG_VMDQ_S   0
-#define HCLGE_CFG_VMDQ_M   (0xff << HCLGE_CFG_VMDQ_S)
+#define HCLGE_CFG_VMDQ_M   GENMASK(7, 0)
 #define HCLGE_CFG_TC_NUM_S 8
-#define HCLGE_CFG_TC_NUM_M (0xff << HCLGE_CFG_TC_NUM_S)
+#define HCLGE_CFG_TC_NUM_M GENMASK(15, 8)
 #define HCLGE_CFG_TQP_DESC_N_S 16
-#define HCLGE_CFG_TQP_DESC_N_M (0x << HCLGE_CFG_TQP_DESC_N_S)
+#define HCLGE_CFG_TQP_DESC_N_M GENMASK(31, 16)
 #define HCLGE_CFG_PHY_ADDR_S   0
-#define HCLGE_CFG_PHY_ADDR_M   (0x1f << HCLGE_CFG_PHY_ADDR_S)
+#define HCLGE_CFG_PHY_ADDR_M   GENMASK(4, 0)
 #define HCLGE_CFG_MEDIA_TP_S   8
-#define HCLGE_CFG_MEDIA_TP_M   (0xff << HCLGE_CFG_MEDIA_TP_S)
+#define HCLGE_CFG_MEDIA_TP_M   GENMASK(15, 8)
 #define HCLGE_CFG_RX_BUF_LEN_S 16
-#define HCLGE_CFG_RX_BUF_LEN_M (0x << HCLGE_CFG_RX_BUF_LEN_S)
+#define HCLGE_CFG_RX_BUF_LEN_M GENMASK(31, 16)
 #define HCLGE_CFG_MAC_ADDR_H_S 0
-#define HCLGE_CFG_MAC_ADDR_H_M (0x << HCLGE_CFG_MAC_ADDR_H_S)
+#define HCLGE_CFG_MAC_ADDR_H_M GENMASK(15, 0)
 #define HCLGE_CFG_DEFAULT_SPEED_S  16
-#define HCLGE_CFG_DEFAULT_SPEED_M  (0xff << HCLGE_CFG_DEFAULT_SPEED_S)
+#define HCLGE_CFG_DEFAULT_SPEED_M  GENMASK(23, 16)
 
 struct hclge_cfg_param {
__le32 offset;
@@ -441,9 +441,9 @@ struct hclge_rss_indirection_table {
 };
 
 #define HCLGE_RSS_TC_OFFSET_S  0
-#define HCLGE_RSS_TC_OFFSET_M  (0x3ff << HCLGE_RSS_TC_OFFSET_S)
+#define HCLGE_RSS_TC_OFFSET_M  GENMASK(9, 0)
 #define HCLGE_RSS_TC_SIZE_S12
-#define HCLGE_RSS_TC_SIZE_M(0x7 << HCLGE_RSS_TC_SIZE_S)
+#define HCLGE_RSS_TC_SIZE_MGENMASK(14, 12)
 #define HCLGE_RSS_TC_VALID_B   15
 struct hclge_rss_tc_mode {
u16 rss_tc_mode[HCLGE_MAX_TC_NUM];
@@ -501,7 +501,7 @@ struct hclge_config_mac_mode {
 };
 
 #define HCLGE_CFG_SPEED_S  0
-#define HCLGE_CFG_SPEED_M  (0x3f << HCLGE_CFG_SPEED_S)
+#define HCLGE_CFG_SPEED_M  GENMASK(5, 0)
 
 #define HCLGE_CFG_DUPLEX_B 7
 #define HCLGE_CFG_DUPLEX_M BIT(HCLGE_CFG_DUPLEX_B)
@@ -518,7 +518,7 @@ struct hclge_config_mac_speed_dup {
 #define HCLGE_QUERY_AN_B   0
 #define HCLGE_QUERY_DUPLEX_B   2
 
-#define HCLGE_QUERY_SPEED_M(0x1f << HCLGE_QUERY_SPEED_S)
+#define HCLGE_QUERY_SPEED_MGENMASK(4, 0)
 #define HCLGE_QUERY_AN_M   BIT(HCLGE_QUERY_AN_B)
 #define HCLGE_QUERY_DUPLEX_M   BIT(HCLGE_QUERY_DUPLEX_B)
 
@@ -528,7 +528,7 @@ struct hclge_query_an_speed_dup {
u8 rsv[23];
 };
 
-#define HCLGE_RING_ID_MASK 0x3ff
+#define HCLGE_RING_ID_MASK GENMASK(9, 0)
 #define HCLGE_TQP_ENABLE_B 0
 
 #define HCLGE_MAC_CFG_AN_EN_B  0
@@ -565,9 +565,9 @@ enum hclge_mac_vlan_tbl_opcode {
 #define HCLGE_MAC_EPORT_SW_EN_B0xc
 #define HCLGE_MAC_EPORT_TYPE_B 0xb
 #define HCLGE_MAC_EPORT_VFID_S 0x3
-#define HCLGE_MAC_EPORT_VFID_M (0xff << HCLGE_MAC_EPORT_VFID_S)
+#define HCLGE_MAC_EPORT_VFID_M GENMASK(10, 3)
 #define HCLGE_MAC_EPORT_PFID_S 0x0
-#define HCLGE_MAC_EPORT_PFID_M (0x7 << HCLGE_MAC_EPORT_PFID_S)
+#define HCLGE_MAC_EPORT_PFID_M GENMASK(2, 0)
 struct hclge_mac_vlan_tbl_e

Re: [PATCH] net: hns3: Fix an error handling path in 'hclge_rss_init_hw()'

2017-09-30 Thread Yunsheng Lin
Hi, Christophe

On 2017/9/30 13:34, Christophe JAILLET wrote:
> If this sanity check fails, we must free 'rss_indir'. Otherwise there is a
> memory leak.
> 'goto err' as done in the other error handling paths to fix it.

Thanks for fixing.

> 
> Fixes: 46a3df9f9718 ("net: hns3: Fix for setting rss_size incorrectly")
> Signed-off-by: Christophe JAILLET 
> ---
>  drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
> b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> index e0685e630afe..c1cdbfd83bdb 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
> @@ -2652,7 +2652,8 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
>   dev_err(>pdev->dev,
>   "Configure rss tc size failed, invalid TC_SIZE = %d\n",
>   rss_size);
> - return -EINVAL;
> + ret = -EINVAL;
> + goto err;
>   }
>  
>   roundup_size = roundup_pow_of_two(rss_size);
> 



Re: [PATCH] net: hns3: fix null pointer dereference before null check

2017-09-29 Thread Yunsheng Lin
Hi, Colin

On 2017/9/30 3:51, Colin King wrote:
> From: Colin Ian King 
> 
> pointer ndev is being dereferenced with the call to netif_running
> before it is being null checked.  Re-order the code to only dereference
> ndev after it has been null checked.

Thanks for fixing it.

> 
> Detected by CoverityScan, CID#1457206 ("Dereference before null check")
> 
> Fixes: 9df8f79a4d29 ("net: hns3: Add DCB support when interacting with 
> network stack")
> Signed-off-by: Colin Ian King 
> ---
>  drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
> b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
> index 4a0890f98b70..c31506514e5d 100644
> --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
> +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
> @@ -2865,7 +2865,7 @@ static int hns3_client_setup_tc(struct hnae3_handle 
> *handle, u8 tc)
>  {
>   struct hnae3_knic_private_info *kinfo = >kinfo;
>   struct net_device *ndev = kinfo->netdev;
> - bool if_running = netif_running(ndev);
> + bool if_running;
>   int ret;
>   u8 i;
>  
> @@ -2875,6 +2875,8 @@ static int hns3_client_setup_tc(struct hnae3_handle 
> *handle, u8 tc)
>   if (!ndev)
>   return -ENODEV;
>  
> + if_running = netif_running(ndev);
> +
>   ret = netdev_set_num_tc(ndev, tc);
>   if (ret)
>   return ret;
> 



[PATCH v3 net-next 00/10] Add support for DCB feature in hns3 driver

2017-09-26 Thread Yunsheng Lin
The patchset contains some enhancement related to DCB before
adding support for DCB feature.

This patchset depends on the following patchset:
https://patchwork.ozlabs.org/cover/815646/
https://patchwork.ozlabs.org/cover/816145/

High Level Architecture:

   [ lldpad ]
   |
   |
   |
 [ hns3_dcbnl ]
   |
   |
   |
 [ hclge_dcb ]
   /  \
/\
 /  \
 [ hclge_main ][ hclge_tm ]

Current patch-set support following functionality:
   Use of lldptool to configure the tc schedule mode, tc
   bandwidth(if schedule mode is ETS), prio_tc_map and
   PFC parameter.

---
V3: Drop mqprio support

V2: Fix for not defining variables in local loop.

V1: Initial Submit.

Yunsheng Lin (10):
  net: hns3: Support for dynamically assigning tx buffer to TC
  net: hns3: Add support for dynamically buffer reallocation
  net: hns3: Add support for PFC setting in TM module
  net: hns3: Add support for port shaper setting in TM module
  net: hns3: Add tc-based TM support for sriov enabled port
  net: hns3: Add some interface for the support of DCB feature
  net: hns3: Add hclge_dcb module for the support of DCB feature
  net: hns3: Add dcb netlink interface for the support of DCB feature
  net: hns3: Setting for fc_mode and dcb enable flag in TM module
  net: hns3: Add DCB support when interacting with network stack

 drivers/net/ethernet/hisilicon/Kconfig |   9 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  17 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   4 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   6 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 304 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h |  21 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 214 ++-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   8 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 231 ++--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  15 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c| 106 +++
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 104 ++-
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   7 +
 13 files changed, 927 insertions(+), 119 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c

-- 
1.9.1



[PATCH v3 net-next 01/10] net: hns3: Support for dynamically assigning tx buffer to TC

2017-09-26 Thread Yunsheng Lin
This patch add support of dynamically assigning tx buffer to
TC when the TC is enabled.
It will save buffer for rx direction to avoid packet loss.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
V2:
Fix for not defining variables in local loop.

V1:
Initial submit.
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  1 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 64 ++
 2 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 758cf39..a81c6cb 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -311,6 +311,7 @@ struct hclge_tc_thrd {
 struct hclge_priv_buf {
struct hclge_waterline wl;  /* Waterline for low and high*/
u32 buf_size;   /* TC private buffer size */
+   u32 tx_buf_size;
u32 enable; /* Enable TC private buffer or not */
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index d27618b..02da3d5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1324,7 +1324,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
return 0;
 }
 
-static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev, u16 buf_size)
+static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
 {
 /* TX buffer size is unit by 128 byte */
 #define HCLGE_BUF_SIZE_UNIT_SHIFT  7
@@ -1337,10 +1337,13 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev, u16 buf_size)
req = (struct hclge_tx_buff_alloc *)desc.data;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TX_BUFF_ALLOC, 0);
-   for (i = 0; i < HCLGE_TC_NUM; i++)
+   for (i = 0; i < HCLGE_TC_NUM; i++) {
+   u32 buf_size = hdev->priv_buf[i].tx_buf_size;
+
req->tx_pkt_buff[i] =
cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |
 HCLGE_BUF_SIZE_UPDATE_EN_MSK);
+   }
 
ret = hclge_cmd_send(>hw, , 1);
if (ret) {
@@ -1352,9 +1355,9 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev, u16 buf_size)
return 0;
 }
 
-static int hclge_tx_buffer_alloc(struct hclge_dev *hdev, u32 buf_size)
+static int hclge_tx_buffer_alloc(struct hclge_dev *hdev)
 {
-   int ret = hclge_cmd_alloc_tx_buff(hdev, buf_size);
+   int ret = hclge_cmd_alloc_tx_buff(hdev);
 
if (ret) {
dev_err(>pdev->dev,
@@ -1433,6 +1436,16 @@ static u32 hclge_get_rx_priv_buff_alloced(struct 
hclge_dev *hdev)
return rx_priv;
 }
 
+static u32 hclge_get_tx_buff_alloced(struct hclge_dev *hdev)
+{
+   u32 i, total_tx_size = 0;
+
+   for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
+   total_tx_size += hdev->priv_buf[i].tx_buf_size;
+
+   return total_tx_size;
+}
+
 static bool  hclge_is_rx_buf_ok(struct hclge_dev *hdev, u32 rx_all)
 {
u32 shared_buf_min, shared_buf_tc, shared_std;
@@ -1477,18 +1490,43 @@ static bool  hclge_is_rx_buf_ok(struct hclge_dev *hdev, 
u32 rx_all)
return true;
 }
 
+static int hclge_tx_buffer_calc(struct hclge_dev *hdev)
+{
+   u32 i, total_size;
+
+   total_size = hdev->pkt_buf_size;
+
+   /* alloc tx buffer for all enabled tc */
+   for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+   struct hclge_priv_buf *priv = >priv_buf[i];
+
+   if (total_size < HCLGE_DEFAULT_TX_BUF)
+   return -ENOMEM;
+
+   if (hdev->hw_tc_map & BIT(i))
+   priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
+   else
+   priv->tx_buf_size = 0;
+
+   total_size -= priv->tx_buf_size;
+   }
+
+   return 0;
+}
+
 /* hclge_rx_buffer_calc: calculate the rx private buffer size for all TCs
  * @hdev: pointer to struct hclge_dev
- * @tx_size: the allocated tx buffer for all TCs
  * @return: 0: calculate sucessful, negative: fail
  */
-int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 tx_size)
+int hclge_rx_buffer_calc(struct hclge_dev *hdev)
 {
-   u32 rx_all = hdev->pkt_buf_size - tx_size;
+   u32 rx_all = hdev->pkt_buf_size;
int no_pfc_priv_num, pfc_priv_num;
struct hclge_priv_buf *priv;
int i;
 
+   rx_all -= hclge_get_tx_buff_alloced(hdev);
+
/* When DCB is not supported, rx private
 * buffer is not allocated.
 */
@@ -1771,7 +1809,6 @@ static int hclge_common_wl_config(struct hclge_dev *hdev)
 
 int hclge_buffer_alloc(struct hclge_dev *hdev)
 {
-   u32 tx_buf_size = HCLGE_DEFAULT_TX_BUF;
int ret;
 
hdev->priv_buf = devm_kmalloc_array(>pdev->dev, HCLGE

[PATCH v3 net-next 10/10] net: hns3: Add DCB support when interacting with network stack

2017-09-26 Thread Yunsheng Lin
When using lldptool to configure DCB parameter, hclge_dcb module
call the client_ops->setup_tc to tell network stack which queue
and priority is using for specific tc.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
V2:
Drop mqprio support.

V1:
Initial submit.
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 102 ++---
 1 file changed, 87 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 11dab26..4a0890f9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -196,6 +196,32 @@ static void hns3_vector_gl_rl_init(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->tx_group.flow_level = HNS3_FLOW_LOW;
 }
 
+static int hns3_nic_set_real_num_queue(struct net_device *netdev)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_knic_private_info *kinfo = >kinfo;
+   unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
+   int ret;
+
+   ret = netif_set_real_num_tx_queues(netdev, queue_size);
+   if (ret) {
+   netdev_err(netdev,
+  "netif_set_real_num_tx_queues fail, ret=%d!\n",
+  ret);
+   return ret;
+   }
+
+   ret = netif_set_real_num_rx_queues(netdev, queue_size);
+   if (ret) {
+   netdev_err(netdev,
+  "netif_set_real_num_rx_queues fail, ret=%d!\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 static int hns3_nic_net_up(struct net_device *netdev)
 {
struct hns3_nic_priv *priv = netdev_priv(netdev);
@@ -232,26 +258,13 @@ static int hns3_nic_net_up(struct net_device *netdev)
 
 static int hns3_nic_net_open(struct net_device *netdev)
 {
-   struct hns3_nic_priv *priv = netdev_priv(netdev);
-   struct hnae3_handle *h = priv->ae_handle;
int ret;
 
netif_carrier_off(netdev);
 
-   ret = netif_set_real_num_tx_queues(netdev, h->kinfo.num_tqps);
-   if (ret) {
-   netdev_err(netdev,
-  "netif_set_real_num_tx_queues fail, ret=%d!\n",
-  ret);
-   return ret;
-   }
-
-   ret = netif_set_real_num_rx_queues(netdev, h->kinfo.num_tqps);
-   if (ret) {
-   netdev_err(netdev,
-  "netif_set_real_num_rx_queues fail, ret=%d!\n", ret);
+   ret = hns3_nic_set_real_num_queue(netdev);
+   if (ret)
return ret;
-   }
 
ret = hns3_nic_net_up(netdev);
if (ret) {
@@ -2848,10 +2861,69 @@ static void hns3_link_status_change(struct hnae3_handle 
*handle, bool linkup)
}
 }
 
+static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
+{
+   struct hnae3_knic_private_info *kinfo = >kinfo;
+   struct net_device *ndev = kinfo->netdev;
+   bool if_running = netif_running(ndev);
+   int ret;
+   u8 i;
+
+   if (tc > HNAE3_MAX_TC)
+   return -EINVAL;
+
+   if (!ndev)
+   return -ENODEV;
+
+   ret = netdev_set_num_tc(ndev, tc);
+   if (ret)
+   return ret;
+
+   if (if_running) {
+   (void)hns3_nic_net_stop(ndev);
+   msleep(100);
+   }
+
+   ret = (kinfo->dcb_ops && kinfo->dcb_ops->map_update) ?
+   kinfo->dcb_ops->map_update(handle) : -EOPNOTSUPP;
+   if (ret)
+   goto err_out;
+
+   if (tc <= 1) {
+   netdev_reset_tc(ndev);
+   goto out;
+   }
+
+   for (i = 0; i < HNAE3_MAX_TC; i++) {
+   struct hnae3_tc_info *tc_info = >tc_info[i];
+
+   if (tc_info->enable)
+   netdev_set_tc_queue(ndev,
+   tc_info->tc,
+   tc_info->tqp_count,
+   tc_info->tqp_offset);
+   }
+
+   for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
+   netdev_set_prio_tc_map(ndev, i,
+  kinfo->prio_tc[i]);
+   }
+
+out:
+   ret = hns3_nic_set_real_num_queue(ndev);
+
+err_out:
+   if (if_running)
+   (void)hns3_nic_net_open(ndev);
+
+   return ret;
+}
+
 const struct hnae3_client_ops client_ops = {
.init_instance = hns3_client_init,
.uninit_instance = hns3_client_uninit,
.link_status_change = hns3_link_status_change,
+   .setup_tc = hns3_client_setup_tc,
 };
 
 /* hns3_init_module - Driver registration routine
-- 
1.9.1



[PATCH v3 net-next 03/10] net: hns3: Add support for PFC setting in TM module

2017-09-26 Thread Yunsheng Lin
This patch add a pfc_pause_en cmd, and use it to configure
PFC option according to fc_mode in hdev->tm_info.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 68 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  5 ++
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 73a75d7..0b4b5d9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -124,6 +124,20 @@ static int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, 
bool tx, bool rx)
return hclge_cmd_send(>hw, , 1);
 }
 
+static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
+ u8 pfc_bitmap)
+{
+   struct hclge_desc desc;
+   struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)
+
+   hclge_cmd_setup_basic_desc(, HCLGE_OPC_CFG_PFC_PAUSE_EN, false);
+
+   pfc->tx_rx_en_bitmap = tx_rx_bitmap;
+   pfc->pri_en_bitmap = pfc_bitmap;
+
+   return hclge_cmd_send(>hw, , 1);
+}
+
 static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
 {
u8 tc;
@@ -969,20 +983,64 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
return hclge_tm_schd_mode_hw(hdev);
 }
 
+static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
+{
+   u8 enable_bitmap = 0;
+
+   if (hdev->tm_info.fc_mode == HCLGE_FC_PFC)
+   enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK |
+   HCLGE_RX_MAC_PAUSE_EN_MSK;
+
+   return hclge_pfc_pause_en_cfg(hdev, enable_bitmap,
+ hdev->tm_info.hw_pfc_map);
+}
+
+static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
+{
+   bool tx_en, rx_en;
+
+   switch (hdev->tm_info.fc_mode) {
+   case HCLGE_FC_NONE:
+   tx_en = false;
+   rx_en = false;
+   break;
+   case HCLGE_FC_RX_PAUSE:
+   tx_en = false;
+   rx_en = true;
+   break;
+   case HCLGE_FC_TX_PAUSE:
+   tx_en = true;
+   rx_en = false;
+   break;
+   case HCLGE_FC_FULL:
+   tx_en = true;
+   rx_en = true;
+   break;
+   default:
+   tx_en = true;
+   rx_en = true;
+   }
+
+   return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en);
+}
+
 int hclge_pause_setup_hw(struct hclge_dev *hdev)
 {
-   bool en = hdev->tm_info.fc_mode != HCLGE_FC_PFC;
int ret;
u8 i;
 
-   ret = hclge_mac_pause_en_cfg(hdev, en, en);
-   if (ret)
-   return ret;
+   if (hdev->tm_info.fc_mode != HCLGE_FC_PFC)
+   return hclge_mac_pause_setup_hw(hdev);
 
-   /* Only DCB-supported dev supports qset back pressure setting */
+   /* Only DCB-supported dev supports qset back pressure and pfc cmd */
if (!hnae3_dev_dcb_supported(hdev))
return 0;
 
+   /* When MAC is GE Mode, hdev does not support pfc setting */
+   ret = hclge_pfc_setup_hw(hdev);
+   if (ret)
+   dev_warn(>pdev->dev, "set pfc pause failed:%d\n", ret);
+
for (i = 0; i < hdev->tm_info.num_tc; i++) {
ret = hclge_tm_qs_bp_cfg(hdev, i);
if (ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 85158b0..8ecd83c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -94,6 +94,11 @@ struct hclge_bp_to_qs_map_cmd {
u32 rsvd1;
 };
 
+struct hclge_pfc_en_cmd {
+   u8 tx_rx_en_bitmap;
+   u8 pri_en_bitmap;
+};
+
 #define hclge_tm_set_field(dest, string, val) \
hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH), val)
-- 
1.9.1



[PATCH v3 net-next 06/10] net: hns3: Add some interface for the support of DCB feature

2017-09-26 Thread Yunsheng Lin
This patch add some interface and export some interface from
hclge_tm and hclgc_main to support the upcoming DCB feature.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  3 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  3 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 48 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  6 +++
 4 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index b345070..ca7e3bc 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -30,7 +30,6 @@
 #define HCLGE_64BIT_STATS_FIELD_OFF(f) (offsetof(struct hclge_64_bit_stats, f))
 #define HCLGE_32BIT_STATS_FIELD_OFF(f) (offsetof(struct hclge_32_bit_stats, f))
 
-static int hclge_rss_init_hw(struct hclge_dev *hdev);
 static int hclge_set_mta_filter_mode(struct hclge_dev *hdev,
 enum hclge_mta_dmac_sel_type mta_mac_sel,
 bool enable);
@@ -2655,7 +2654,7 @@ static int hclge_get_tc_size(struct hnae3_handle *handle)
return hdev->rss_size_max;
 }
 
-static int hclge_rss_init_hw(struct hclge_dev *hdev)
+int hclge_rss_init_hw(struct hclge_dev *hdev)
 {
const  u8 hfunc = HCLGE_RSS_HASH_ALGO_TOEPLITZ;
struct hclge_vport *vport = hdev->vport;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 4fc36f0..394b587 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -515,4 +515,7 @@ static inline int hclge_get_queue_id(struct hnae3_queue 
*queue)
 int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex);
 int hclge_set_vf_vlan_common(struct hclge_dev *vport, int vfid,
 bool is_kill, u16 vlan, u8 qos, __be16 proto);
+
+int hclge_buffer_alloc(struct hclge_dev *hdev);
+int hclge_rss_init_hw(struct hclge_dev *hdev);
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index ea94d23..8295684 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -883,10 +883,14 @@ static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev)
return 0;
 }
 
-static int hclge_tm_map_cfg(struct hclge_dev *hdev)
+int hclge_tm_map_cfg(struct hclge_dev *hdev)
 {
int ret;
 
+   ret = hclge_up_to_tc_map(hdev);
+   if (ret)
+   return ret;
+
ret = hclge_tm_pg_to_pri_map(hdev);
if (ret)
return ret;
@@ -994,7 +998,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
return 0;
 }
 
-static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
+int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
 {
int ret;
 
@@ -1092,7 +1096,45 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev)
return ret;
}
 
-   return hclge_up_to_tc_map(hdev);
+   return 0;
+}
+
+int hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc)
+{
+   struct hclge_vport *vport = hdev->vport;
+   struct hnae3_knic_private_info *kinfo;
+   u32 i, k;
+
+   for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
+   if (prio_tc[i] >= hdev->tm_info.num_tc)
+   return -EINVAL;
+   hdev->tm_info.prio_tc[i] = prio_tc[i];
+
+   for (k = 0;  k < hdev->num_alloc_vport; k++) {
+   kinfo = [k].nic.kinfo;
+   kinfo->prio_tc[i] = prio_tc[i];
+   }
+   }
+   return 0;
+}
+
+void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc)
+{
+   u8 i, bit_map = 0;
+
+   hdev->tm_info.num_tc = num_tc;
+
+   for (i = 0; i < hdev->tm_info.num_tc; i++)
+   bit_map |= BIT(i);
+
+   if (!bit_map) {
+   bit_map = 1;
+   hdev->tm_info.num_tc = 1;
+   }
+
+   hdev->hw_tc_map = bit_map;
+
+   hclge_tm_schd_info_init(hdev);
 }
 
 int hclge_tm_init_hw(struct hclge_dev *hdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 19a01e4..bf59961 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -112,4 +112,10 @@ struct hclge_port_shapping_cmd {
 
 int hclge_tm_schd_init(struct hclge_dev *hdev);
 int hclge_pause_setup_hw(struct hclge_dev *hdev);
+int hclge_tm_schd_mode_hw(struct hclge_dev *hdev);
+int hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc

[PATCH v3 net-next 08/10] net: hns3: Add dcb netlink interface for the support of DCB feature

2017-09-26 Thread Yunsheng Lin
This patch add dcb netlink interface by calling the interface from
hclge_dcb module.

This patch also update Makefile in order to build hns3_dcbnl module.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   2 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c| 106 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c |   2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   7 ++
 4 files changed, 117 insertions(+)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
index 7023dc87..d2b20d0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
@@ -11,3 +11,5 @@ hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o
 
 obj-$(CONFIG_HNS3_ENET) += hns3.o
 hns3-objs = hns3_enet.o hns3_ethtool.o
+
+hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
new file mode 100644
index 000..9832172
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "hnae3.h"
+#include "hns3_enet.h"
+
+static
+int hns3_dcbnl_ieee_getets(struct net_device *ndev, struct ieee_ets *ets)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_getets)
+   return h->kinfo.dcb_ops->ieee_getets(h, ets);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_setets(struct net_device *ndev, struct ieee_ets *ets)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_setets)
+   return h->kinfo.dcb_ops->ieee_setets(h, ets);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_getpfc(struct net_device *ndev, struct ieee_pfc *pfc)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_getpfc)
+   return h->kinfo.dcb_ops->ieee_getpfc(h, pfc);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_setpfc(struct net_device *ndev, struct ieee_pfc *pfc)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_setpfc)
+   return h->kinfo.dcb_ops->ieee_setpfc(h, pfc);
+
+   return -EOPNOTSUPP;
+}
+
+/* DCBX configuration */
+static u8 hns3_dcbnl_getdcbx(struct net_device *ndev)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->getdcbx)
+   return h->kinfo.dcb_ops->getdcbx(h);
+
+   return 0;
+}
+
+/* return 0 if successful, otherwise fail */
+static u8 hns3_dcbnl_setdcbx(struct net_device *ndev, u8 mode)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->setdcbx)
+   return h->kinfo.dcb_ops->setdcbx(h, mode);
+
+   return 1;
+}
+
+static const struct dcbnl_rtnl_ops hns3_dcbnl_ops = {
+   .ieee_getets= hns3_dcbnl_ieee_getets,
+   .ieee_setets= hns3_dcbnl_ieee_setets,
+   .ieee_getpfc= hns3_dcbnl_ieee_getpfc,
+   .ieee_setpfc= hns3_dcbnl_ieee_setpfc,
+   .getdcbx= hns3_dcbnl_getdcbx,
+   .setdcbx= hns3_dcbnl_setdcbx,
+};
+
+/* hclge_dcbnl_setup - DCBNL setup
+ * @handle: the corresponding vport handle
+ * Set up DCBNL
+ */
+void hns3_dcbnl_setup(struct hnae3_handle *handle)
+{
+   struct net_device *dev = handle->kinfo.netdev;
+
+   if (!handle->kinfo.dcb_ops)
+   return;
+
+   dev->dcbnl_ops = _dcbnl_ops;
+}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 35369e1..11dab26 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -2790,6 +2790,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_reg_netdev_fail;
}
 
+   hns3_dcbnl_setup(handle);
+
/* MTU range: (ETH_MIN_MTU(kernel default) - 9706) */
netdev->max_mtu = HNS3_MAX_

[PATCH v3 net-next 09/10] net: hns3: Setting for fc_mode and dcb enable flag in TM module

2017-09-26 Thread Yunsheng Lin
After the DCB feature is supported, fc_mode and dcb enable flag
must be set according to the DCB parameter.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 34 +++---
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 8295684..359ee67 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -486,7 +486,11 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
hdev->tm_info.prio_tc[i] =
(i >= hdev->tm_info.num_tc) ? 0 : i;
 
-   hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
+   /* DCB is enabled if we have more than 1 TC */
+   if (hdev->tm_info.num_tc > 1)
+   hdev->flag |= HCLGE_FLAG_DCB_ENABLE;
+   else
+   hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
 }
 
 static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
@@ -512,6 +516,24 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
}
 }
 
+static void hclge_pfc_info_init(struct hclge_dev *hdev)
+{
+   if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) {
+   if (hdev->fc_mode_last_time == HCLGE_FC_PFC)
+   dev_warn(>pdev->dev,
+"DCB is disable, but last mode is FC_PFC\n");
+
+   hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
+   } else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
+   /* fc_mode_last_time record the last fc_mode when
+* DCB is enabled, so that fc_mode can be set to
+* the correct value when DCB is disabled.
+*/
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hdev->tm_info.fc_mode = HCLGE_FC_PFC;
+   }
+}
+
 static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
 {
if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
@@ -524,8 +546,7 @@ static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
 
hclge_tm_vport_info_update(hdev);
 
-   hdev->tm_info.fc_mode = HCLGE_FC_NONE;
-   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hclge_pfc_info_init(hdev);
 
return 0;
 }
@@ -1158,8 +1179,13 @@ int hclge_tm_init_hw(struct hclge_dev *hdev)
 
 int hclge_tm_schd_init(struct hclge_dev *hdev)
 {
-   int ret = hclge_tm_schd_info_init(hdev);
+   int ret;
+
+   /* fc_mode is HCLGE_FC_FULL on reset */
+   hdev->tm_info.fc_mode = HCLGE_FC_FULL;
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
 
+   ret = hclge_tm_schd_info_init(hdev);
if (ret)
return ret;
 
-- 
1.9.1



[PATCH v3 net-next 07/10] net: hns3: Add hclge_dcb module for the support of DCB feature

2017-09-26 Thread Yunsheng Lin
The hclge_dcb module calls the interface from hclge_main/tm
and provide interface for the dcb netlink interface.

This patch also update Makefiles required to build the DCB
supported code in HNS3 Ethernet driver and update the existing
Kconfig file in the hisilicon folder.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/Kconfig |   9 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  17 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 304 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h |  21 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  25 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   3 +
 7 files changed, 375 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 91c7bdb..9d7cb03 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -103,4 +103,13 @@ config HNS3_ENET
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
  devices and their associated operations.
 
+config HNS3_DCB
+   bool "Hisilicon HNS3 Data Center Bridge Support"
+   default n
+   depends on HNS3 && HNS3_HCLGE && DCB
+   ---help---
+ Say Y here if you want to use Data Center Bridging (DCB) in the HNS3 
driver.
+
+ If unsure, say N.
+
 endif # NET_VENDOR_HISILICON
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 1a01cad..c677530 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -28,6 +28,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -131,6 +132,7 @@ struct hnae3_client_ops {
int (*init_instance)(struct hnae3_handle *handle);
void (*uninit_instance)(struct hnae3_handle *handle, bool reset);
void (*link_status_change)(struct hnae3_handle *handle, bool state);
+   int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
 };
 
 #define HNAE3_CLIENT_NAME_LENGTH 16
@@ -363,6 +365,20 @@ struct hnae3_ae_ops {
  u16 vlan, u8 qos, __be16 proto);
 };
 
+struct hnae3_dcb_ops {
+   /* IEEE 802.1Qaz std */
+   int (*ieee_getets)(struct hnae3_handle *, struct ieee_ets *);
+   int (*ieee_setets)(struct hnae3_handle *, struct ieee_ets *);
+   int (*ieee_getpfc)(struct hnae3_handle *, struct ieee_pfc *);
+   int (*ieee_setpfc)(struct hnae3_handle *, struct ieee_pfc *);
+
+   /* DCBX configuration */
+   u8   (*getdcbx)(struct hnae3_handle *);
+   u8   (*setdcbx)(struct hnae3_handle *, u8);
+
+   int (*map_update)(struct hnae3_handle *);
+};
+
 struct hnae3_ae_algo {
const struct hnae3_ae_ops *ops;
struct list_head node;
@@ -394,6 +410,7 @@ struct hnae3_knic_private_info {
 
u16 num_tqps; /* total number of TQPs in this handle */
struct hnae3_queue **tqp;  /* array base of all TQPs in this instance */
+   const struct hnae3_dcb_ops *dcb_ops;
 };
 
 struct hnae3_roce_private_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
index 162e8a42..7023dc87 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
@@ -7,5 +7,7 @@ ccflags-y := -Idrivers/net/ethernet/hisilicon/hns3
 obj-$(CONFIG_HNS3_HCLGE) += hclge.o
 hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o
 
+hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o
+
 obj-$(CONFIG_HNS3_ENET) += hns3.o
 hns3-objs = hns3_enet.o hns3_ethtool.o
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
new file mode 100644
index 000..1b30a6f
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "hclge_main.h"
+#include "hclge_tm.h"
+#include "hnae3.h"
+
+#define BW_PERCENT 100
+
+static int hclge_ieee_ets_to_tm_info(struct hclge_dev *hdev,
+struct ieee_ets *ets)
+{
+   u8 i;
+
+   for (i = 0; i < HNAE3_MAX_TC; i++) {
+   switch (ets->tc_tsa[i]) {
+   case IEEE_8021QAZ_TSA_

[PATCH v3 net-next 02/10] net: hns3: Add support for dynamically buffer reallocation

2017-09-26 Thread Yunsheng Lin
Current buffer allocation can only happen at init, when
doing buffer reallocation after init, care must be taken
care of memory which priv_buf points to.
This patch fixes it by using a dynamic allocated temporary
memory. Because we only do buffer reallocation at init or
when setting up the DCB parameter, and priv_buf is only
used at buffer allocation process, so it is ok to use a
dynamic allocated temporary memory.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   5 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 150 +++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   2 -
 3 files changed, 87 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index a81c6cb..6b6d28e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -322,6 +322,11 @@ struct hclge_shared_buf {
u32 buf_size;
 };
 
+struct hclge_pkt_buf_alloc {
+   struct hclge_priv_buf priv_buf[HCLGE_MAX_TC_NUM];
+   struct hclge_shared_buf s_buf;
+};
+
 #define HCLGE_RX_COM_WL_EN_B   15
 struct hclge_rx_com_wl_buf {
__le16 high_wl;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 02da3d5..b345070 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1324,7 +1324,8 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
return 0;
 }
 
-static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
+static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev,
+   struct hclge_pkt_buf_alloc *buf_alloc)
 {
 /* TX buffer size is unit by 128 byte */
 #define HCLGE_BUF_SIZE_UNIT_SHIFT  7
@@ -1338,7 +1339,7 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev)
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TX_BUFF_ALLOC, 0);
for (i = 0; i < HCLGE_TC_NUM; i++) {
-   u32 buf_size = hdev->priv_buf[i].tx_buf_size;
+   u32 buf_size = buf_alloc->priv_buf[i].tx_buf_size;
 
req->tx_pkt_buff[i] =
cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |
@@ -1355,9 +1356,10 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev)
return 0;
 }
 
-static int hclge_tx_buffer_alloc(struct hclge_dev *hdev)
+static int hclge_tx_buffer_alloc(struct hclge_dev *hdev,
+struct hclge_pkt_buf_alloc *buf_alloc)
 {
-   int ret = hclge_cmd_alloc_tx_buff(hdev);
+   int ret = hclge_cmd_alloc_tx_buff(hdev, buf_alloc);
 
if (ret) {
dev_err(>pdev->dev,
@@ -1390,13 +1392,14 @@ static int hclge_get_pfc_enalbe_num(struct hclge_dev 
*hdev)
 }
 
 /* Get the number of pfc enabled TCs, which have private buffer */
-static int hclge_get_pfc_priv_num(struct hclge_dev *hdev)
+static int hclge_get_pfc_priv_num(struct hclge_dev *hdev,
+ struct hclge_pkt_buf_alloc *buf_alloc)
 {
struct hclge_priv_buf *priv;
int i, cnt = 0;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if ((hdev->tm_info.hw_pfc_map & BIT(i)) &&
priv->enable)
cnt++;
@@ -1406,13 +1409,14 @@ static int hclge_get_pfc_priv_num(struct hclge_dev 
*hdev)
 }
 
 /* Get the number of pfc disabled TCs, which have private buffer */
-static int hclge_get_no_pfc_priv_num(struct hclge_dev *hdev)
+static int hclge_get_no_pfc_priv_num(struct hclge_dev *hdev,
+struct hclge_pkt_buf_alloc *buf_alloc)
 {
struct hclge_priv_buf *priv;
int i, cnt = 0;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if (hdev->hw_tc_map & BIT(i) &&
!(hdev->tm_info.hw_pfc_map & BIT(i)) &&
priv->enable)
@@ -1422,31 +1426,33 @@ static int hclge_get_no_pfc_priv_num(struct hclge_dev 
*hdev)
return cnt;
 }
 
-static u32 hclge_get_rx_priv_buff_alloced(struct hclge_dev *hdev)
+static u32 hclge_get_rx_priv_buff_alloced(struct hclge_pkt_buf_alloc 
*buf_alloc)
 {
struct hclge_priv_buf *priv;
u32 rx_priv = 0;
int i;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if (priv->enable)
rx_priv += priv->buf_size;
}
return rx_priv;
 }
 
-static u32 hclge_get_tx_buff_alloced(str

[PATCH v3 net-next 05/10] net: hns3: Add tc-based TM support for sriov enabled port

2017-09-26 Thread Yunsheng Lin
When sriov is enabled and TM is in tc-based mode, vf's TM
parameters is not set in TM initialization process.
This patch add the tc_based TM support for sriov enabled
using the information in vport struct.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 49 ++
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index f79cebd..ea94d23 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -388,13 +388,13 @@ static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev 
*hdev, u8 pri_id)
return hclge_cmd_send(>hw, , 1);
 }
 
-static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id)
+static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 
mode)
 {
struct hclge_desc desc;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false);
 
-   if (hdev->tm_info.tc_info[qs_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR)
+   if (mode == HCLGE_SCH_MODE_DWRR)
desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
else
desc.data[1] = 0;
@@ -638,17 +638,18 @@ static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev)
 {
struct hclge_vport *vport = hdev->vport;
int ret;
-   u32 i;
+   u32 i, k;
 
if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
/* Cfg qs -> pri mapping, one by one mapping */
-   for (i = 0; i < hdev->tm_info.num_tc; i++) {
-   ret = hclge_tm_qs_to_pri_map_cfg(hdev, i, i);
-   if (ret)
-   return ret;
-   }
+   for (k = 0; k < hdev->num_alloc_vport; k++)
+   for (i = 0; i < hdev->tm_info.num_tc; i++) {
+   ret = hclge_tm_qs_to_pri_map_cfg(
+   hdev, vport[k].qs_offset + i, i);
+   if (ret)
+   return ret;
+   }
} else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) {
-   int k;
/* Cfg qs -> pri mapping,  qs = tc, pri = vf, 8 qs -> 1 pri */
for (k = 0; k < hdev->num_alloc_vport; k++)
for (i = 0; i < HNAE3_MAX_TC; i++) {
@@ -797,10 +798,11 @@ static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev)
 
 static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
 {
+   struct hclge_vport *vport = hdev->vport;
struct hclge_pg_info *pg_info;
u8 dwrr;
int ret;
-   u32 i;
+   u32 i, k;
 
for (i = 0; i < hdev->tm_info.num_tc; i++) {
pg_info =
@@ -811,9 +813,13 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev 
*hdev)
if (ret)
return ret;
 
-   ret = hclge_tm_qs_weight_cfg(hdev, i, dwrr);
-   if (ret)
-   return ret;
+   for (k = 0; k < hdev->num_alloc_vport; k++) {
+   ret = hclge_tm_qs_weight_cfg(
+   hdev, vport[k].qs_offset + i,
+   vport[k].dwrr);
+   if (ret)
+   return ret;
+   }
}
 
return 0;
@@ -944,7 +950,10 @@ static int hclge_tm_schd_mode_vnet_base_cfg(struct 
hclge_vport *vport)
return ret;
 
for (i = 0; i < kinfo->num_tc; i++) {
-   ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i);
+   u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode;
+
+   ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i,
+   sch_mode);
if (ret)
return ret;
}
@@ -956,7 +965,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
 {
struct hclge_vport *vport = hdev->vport;
int ret;
-   u8 i;
+   u8 i, k;
 
if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
for (i = 0; i < hdev->tm_info.num_tc; i++) {
@@ -964,9 +973,13 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
if (ret)
return ret;
 
-   ret = hclge_tm_qs_schd_mode_cfg(hdev, i);
-   if (ret)
-   return ret;
+   for (k = 0; k < hdev->num_alloc_vport; k++) {
+   ret = hclge_tm_qs_schd_mode_cfg(
+   hdev, vport[k].qs_offset +

[PATCH v3 net-next 04/10] net: hns3: Add support for port shaper setting in TM module

2017-09-26 Thread Yunsheng Lin
This patch add a tm_port_shaper cmd and set port shaper
to HCLGE_ETHER_MAX_RATE on TM initialization process.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 32 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  4 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 0b4b5d9..f79cebd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -301,6 +301,34 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
return hclge_cmd_send(>hw, , 1);
 }
 
+static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev)
+{
+   struct hclge_port_shapping_cmd *shap_cfg_cmd;
+   struct hclge_desc desc;
+   u32 shapping_para = 0;
+   u8 ir_u, ir_b, ir_s;
+   int ret;
+
+   ret = hclge_shaper_para_calc(HCLGE_ETHER_MAX_RATE,
+HCLGE_SHAPER_LVL_PORT,
+_b, _u, _s);
+   if (ret)
+   return ret;
+
+   hclge_cmd_setup_basic_desc(, HCLGE_OPC_TM_PORT_SHAPPING, false);
+   shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
+
+   hclge_tm_set_field(shapping_para, IR_B, ir_b);
+   hclge_tm_set_field(shapping_para, IR_U, ir_u);
+   hclge_tm_set_field(shapping_para, IR_S, ir_s);
+   hclge_tm_set_field(shapping_para, BS_B, HCLGE_SHAPER_BS_U_DEF);
+   hclge_tm_set_field(shapping_para, BS_S, HCLGE_SHAPER_BS_S_DEF);
+
+   shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para);
+
+   return hclge_cmd_send(>hw, , 1);
+}
+
 static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev,
 enum hclge_shap_bucket bucket, u8 pri_id,
 u8 ir_b, u8 ir_u, u8 ir_s,
@@ -864,6 +892,10 @@ static int hclge_tm_shaper_cfg(struct hclge_dev *hdev)
 {
int ret;
 
+   ret = hclge_tm_port_shaper_cfg(hdev);
+   if (ret)
+   return ret;
+
ret = hclge_tm_pg_shaper_cfg(hdev);
if (ret)
return ret;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 8ecd83c..19a01e4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -99,6 +99,10 @@ struct hclge_pfc_en_cmd {
u8 pri_en_bitmap;
 };
 
+struct hclge_port_shapping_cmd {
+   __le32 port_shapping_para;
+};
+
 #define hclge_tm_set_field(dest, string, val) \
hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH), val)
-- 
1.9.1



Re: [PATCH v2 net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-26 Thread Yunsheng Lin
Hi, Yuval

On 2017/9/26 20:29, Yuval Mintz wrote:
>> Hi, Yuval
>>
>> On 2017/9/26 14:43, Yuval Mintz wrote:
 When using tc qdisc to configure DCB parameter, dcb_ops->setup_tc
 is used to tell hclge_dcb module to do the setup.
>>>
>>> While this might be a step in the right direction, this causes an 
>>> inconsistency
>>> in user experience - Some [well, most] vendors didn't allow the mqprio
>>> priority mapping to affect DCB, instead relying on the dcbnl functionality
>>> to control that configuration.
>>>
>>> A couple of options to consider:
>>>   - Perhaps said logic shouldn't be contained inside the driver but rather
>>>  in mqprio logic itself. I.e., rely on DCBNL functionality [if 
>>> available] from
>>>  within mqprio and try changing the configuration.
>>
>> In net/dcb/dcbnl.c
>> dcbnl_ieee_set already call dcbnl_ieee_notify to notify the user space
>> configuration has changed, does this dcbnl_ieee_notify function do the
>> job for us? I am not sure if lldpad has registered for this notifition.
> 
> Not that familiar with the dcbnl calls; Shouldn't dcbnl_setall be called to
> make the configuration apply [or is that only for ieee]?

dcbnl_setall is for cee to make the configuration apply.
ieee does not have the apply operation.

> Regardless, don't know if it makes sense to assume user-application would
> fix the qdisc configuration by notification while dcbnl logic in kernel could 
> have
> done that instead.
> 
>> As you suggested below, can we add a new TC_MQPRIO_HW_OFFLOAD_
>> value to
>> reflect that the configuration is needed to be changed by dcbnl_ieee_set
>> (perhaps some other function) in dcbnl?
>> Do you think it is feasible?
> 
> Either I'm miseading your answer or we think of it from 2 opposite end.
> I was thinking that the new offloaded flag would indicate to the underlying
> driver that it's expected to offload the prio mapping [as part of DCB].
> If the driver would be incapable of that it would refuse the offload.
> User would then have to explicitly request that the qdisc offload.


Adding a new offloaded flag to indicate that mqpri is using a hardware offload
shared by dcbnl seems a good idea.
As I do not know how the idea go with other, I will drop the mqprio support in
this patch, and try to add the mqprio support as you suggested in the next
patchset.

Thanks again for the lengthly reply.

> 
>>
>>
>>>   - Add a new TC_MQPRIO_HW_OFFLOAD_ value to explicitly reflect user
>>>  request to allow this configuration to affect DCB.
>>>
 When using lldptool to configure DCB parameter, hclge_dcb module
 call the client_ops->setup_tc to tell network stack which queue
 and priority is using for specific tc.
>>>
>>> You're basically bypassing the mqprio logic.
>>> Since you're configuring the prio->queue mapping from DCB flow,
>>> you'll get an mqprio-like behavior [meaning a transmitted packet
>>> would reach a transmission queue associated with its priority] even
>>> if device wasn't grated with an mqprio qdisc.
>>> Why should your user even use mqprio? What benefit does he get from it?
>>>
>>> ...
>>>
 +static int hns3_nic_set_real_num_queue(struct net_device *netdev)
 +{
 +  struct hns3_nic_priv *priv = netdev_priv(netdev);
 +  struct hnae3_handle *h = priv->ae_handle;
 +  struct hnae3_knic_private_info *kinfo = >kinfo;
 +  unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
 +  int ret;
 +
 +  ret = netif_set_real_num_tx_queues(netdev, queue_size);
 +  if (ret) {
 +  netdev_err(netdev,
 + "netif_set_real_num_tx_queues fail, ret=%d!\n",
 + ret);
 +  return ret;
 +  }
 +
 +  ret = netif_set_real_num_rx_queues(netdev, queue_size);
>>>
>>> I don't think you're changing the driver behavior, but why are you setting
>>> the real number of rx queues based on the number of TCs?
>>> Do you actually open (TC x RSS) Rx queues?
>>>
>>> .
>>>
> 



Re: [PATCH v2 net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-26 Thread Yunsheng Lin
Hi, Yuval

On 2017/9/26 14:43, Yuval Mintz wrote:
>> When using tc qdisc to configure DCB parameter, dcb_ops->setup_tc
>> is used to tell hclge_dcb module to do the setup.
> 
> While this might be a step in the right direction, this causes an 
> inconsistency
> in user experience - Some [well, most] vendors didn't allow the mqprio
> priority mapping to affect DCB, instead relying on the dcbnl functionality
> to control that configuration.
> 
> A couple of options to consider:
>   - Perhaps said logic shouldn't be contained inside the driver but rather
>  in mqprio logic itself. I.e., rely on DCBNL functionality [if available] 
> from
>  within mqprio and try changing the configuration. 

In net/dcb/dcbnl.c
dcbnl_ieee_set already call dcbnl_ieee_notify to notify the user space
configuration has changed, does this dcbnl_ieee_notify function do the
job for us? I am not sure if lldpad has registered for this notifition.

As you suggested below, can we add a new TC_MQPRIO_HW_OFFLOAD_ value to
reflect that the configuration is needed to be changed by dcbnl_ieee_set
(perhaps some other function) in dcbnl?
Do you think it is feasible?


>   - Add a new TC_MQPRIO_HW_OFFLOAD_ value to explicitly reflect user
>  request to allow this configuration to affect DCB.
> 
>> When using lldptool to configure DCB parameter, hclge_dcb module
>> call the client_ops->setup_tc to tell network stack which queue
>> and priority is using for specific tc.
> 
> You're basically bypassing the mqprio logic.
> Since you're configuring the prio->queue mapping from DCB flow,
> you'll get an mqprio-like behavior [meaning a transmitted packet
> would reach a transmission queue associated with its priority] even
> if device wasn't grated with an mqprio qdisc.
> Why should your user even use mqprio? What benefit does he get from it?
> 
> ...
> 
>> +static int hns3_nic_set_real_num_queue(struct net_device *netdev)
>> +{
>> +struct hns3_nic_priv *priv = netdev_priv(netdev);
>> +struct hnae3_handle *h = priv->ae_handle;
>> +struct hnae3_knic_private_info *kinfo = >kinfo;
>> +unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
>> +int ret;
>> +
>> +ret = netif_set_real_num_tx_queues(netdev, queue_size);
>> +if (ret) {
>> +netdev_err(netdev,
>> +   "netif_set_real_num_tx_queues fail, ret=%d!\n",
>> +   ret);
>> +return ret;
>> +}
>> +
>> +ret = netif_set_real_num_rx_queues(netdev, queue_size);
> 
> I don't think you're changing the driver behavior, but why are you setting
> the real number of rx queues based on the number of TCs?
> Do you actually open (TC x RSS) Rx queues?
> 
> .
> 



Re: [PATCH v2 net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-26 Thread Yunsheng Lin
Hi, Yuval

On 2017/9/26 14:43, Yuval Mintz wrote:
>> When using tc qdisc to configure DCB parameter, dcb_ops->setup_tc
>> is used to tell hclge_dcb module to do the setup.
> 
> While this might be a step in the right direction, this causes an 
> inconsistency
> in user experience - Some [well, most] vendors didn't allow the mqprio
> priority mapping to affect DCB, instead relying on the dcbnl functionality
> to control that configuration.
> 
> A couple of options to consider:
>   - Perhaps said logic shouldn't be contained inside the driver but rather
>  in mqprio logic itself. I.e., rely on DCBNL functionality [if available] 
> from
>  within mqprio and try changing the configuration. 
>   - Add a new TC_MQPRIO_HW_OFFLOAD_ value to explicitly reflect user
>  request to allow this configuration to affect DCB.
> 
>> When using lldptool to configure DCB parameter, hclge_dcb module
>> call the client_ops->setup_tc to tell network stack which queue
>> and priority is using for specific tc.
> 
> You're basically bypassing the mqprio logic.
> Since you're configuring the prio->queue mapping from DCB flow,
> you'll get an mqprio-like behavior [meaning a transmitted packet
> would reach a transmission queue associated with its priority] even
> if device wasn't grated with an mqprio qdisc.
> Why should your user even use mqprio? What benefit does he get from it?
> 
> ...
> 
>> +static int hns3_nic_set_real_num_queue(struct net_device *netdev)
>> +{
>> +struct hns3_nic_priv *priv = netdev_priv(netdev);
>> +struct hnae3_handle *h = priv->ae_handle;
>> +struct hnae3_knic_private_info *kinfo = >kinfo;
>> +unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
>> +int ret;
>> +
>> +ret = netif_set_real_num_tx_queues(netdev, queue_size);
>> +if (ret) {
>> +netdev_err(netdev,
>> +   "netif_set_real_num_tx_queues fail, ret=%d!\n",
>> +   ret);
>> +return ret;
>> +}
>> +
>> +ret = netif_set_real_num_rx_queues(netdev, queue_size);
> 
> I don't think you're changing the driver behavior, but why are you setting
> the real number of rx queues based on the number of TCs?
> Do you actually open (TC x RSS) Rx queues?

Yes, our hardware can do the rss based on TC.

Sorry for almost forget to answer this question.
Thanks for your time reviewing again.

> 
> .
> 



Re: [PATCH v2 net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-26 Thread Yunsheng Lin
Hi, Yuval

On 2017/9/26 14:43, Yuval Mintz wrote:
>> When using tc qdisc to configure DCB parameter, dcb_ops->setup_tc
>> is used to tell hclge_dcb module to do the setup.
> 
> While this might be a step in the right direction, this causes an 
> inconsistency
> in user experience - Some [well, most] vendors didn't allow the mqprio
> priority mapping to affect DCB, instead relying on the dcbnl functionality
> to control that configuration.
> 
> A couple of options to consider:
>   - Perhaps said logic shouldn't be contained inside the driver but rather
>  in mqprio logic itself. I.e., rely on DCBNL functionality [if available] 
> from
>  within mqprio and try changing the configuration. 
>   - Add a new TC_MQPRIO_HW_OFFLOAD_ value to explicitly reflect user
>  request to allow this configuration to affect DCB.
> 
>> When using lldptool to configure DCB parameter, hclge_dcb module
>> call the client_ops->setup_tc to tell network stack which queue
>> and priority is using for specific tc.
> 
> You're basically bypassing the mqprio logic.
> Since you're configuring the prio->queue mapping from DCB flow,
> you'll get an mqprio-like behavior [meaning a transmitted packet
> would reach a transmission queue associated with its priority] even
> if device wasn't grated with an mqprio qdisc.
> Why should your user even use mqprio? What benefit does he get from it?


When adding mqprio and lldptool support, I was thinking user can use
tc qdisc or lldptool to do the configuration, giving user two option to
setup the DCB.

If user is only tc qdisc or lldptool, I think there is no problem here.

when user is using tc qdisc and lldptool, As you explained above, When
tc qdisc changes the configuration, there should be a way to notify dcbnl,
so that the dcbnl can response correctly(like tell the peer it's configuration
has changed).

I will try to find if there is a way to do notify the dcbnl when using tc qdisc
to setup the configuration.
If there is not a way to do it now, then I will drop the mqprio in this patch, 
and
will address this problem if there is need for the tc qdisc.

Please let me know if I was misunderstood.
And thanks for your time reviewing.

> 
> ...
> 
>> +static int hns3_nic_set_real_num_queue(struct net_device *netdev)
>> +{
>> +struct hns3_nic_priv *priv = netdev_priv(netdev);
>> +struct hnae3_handle *h = priv->ae_handle;
>> +struct hnae3_knic_private_info *kinfo = >kinfo;
>> +unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
>> +int ret;
>> +
>> +ret = netif_set_real_num_tx_queues(netdev, queue_size);
>> +if (ret) {
>> +netdev_err(netdev,
>> +   "netif_set_real_num_tx_queues fail, ret=%d!\n",
>> +   ret);
>> +return ret;
>> +}
>> +
>> +ret = netif_set_real_num_rx_queues(netdev, queue_size);
> 
> I don't think you're changing the driver behavior, but why are you setting
> the real number of rx queues based on the number of TCs?
> Do you actually open (TC x RSS) Rx queues?
> 
> .
> 



[PATCH v2 net-next 00/10] Add support for DCB feature in hns3 driver

2017-09-25 Thread Yunsheng Lin
The patchset contains some enhancement related to DCB before
adding support for DCB feature.

This patchset depends on the following patchset:
https://patchwork.ozlabs.org/cover/815646/
https://patchwork.ozlabs.org/cover/816145/

High Level Architecture:

   [ tc qdisc ][ lldpad ]
 | |
 | |
 | |
   [ hns3_enet ][ hns3_dcbnl ]
 \/
\  /
   \/
 [ hclge_dcb ]
   /  \
/\
 /  \
 [ hclge_main ][ hclge_tm ]

Current patch-set support following functionality:
1. Use of tc qdisc to configure the tc num and prio_tc_map.
2. Use of lldptool to configure the tc schedule mode, tc
   bandwidth(if schedule mode is ETS), prio_tc_map and
   PFC parameter.

---
V2: Fix for not defining variables in local loop.

V1: Initial Submit.

Yunsheng Lin (10):
  net: hns3: Support for dynamically assigning tx buffer to TC
  net: hns3: Add support for dynamically buffer reallocation
  net: hns3: Add support for PFC setting in TM module
  net: hns3: Add support for port shaper setting in TM module
  net: hns3: Add tc-based TM support for sriov enabled port
  net: hns3: Add some interface for the support of DCB feature
  net: hns3: Add hclge_dcb module for the support of DCB feature
  net: hns3: Add dcb netlink interface for the support of DCB feature
  net: hns3: Setting for fc_mode and dcb enable flag in TM module
  net: hns3: Add mqprio support when interacting with network stack

 drivers/net/ethernet/hisilicon/Kconfig |   9 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  20 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   4 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   6 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 327 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h |  21 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 214 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   8 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 231 +--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  15 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c| 106 +++
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 137 +++--
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   7 +
 13 files changed, 977 insertions(+), 128 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c

-- 
1.9.1



[PATCH v2 net-next 03/10] net: hns3: Add support for PFC setting in TM module

2017-09-25 Thread Yunsheng Lin
This patch add a pfc_pause_en cmd, and use it to configure
PFC option according to fc_mode in hdev->tm_info.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 68 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  5 ++
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 73a75d7..0b4b5d9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -124,6 +124,20 @@ static int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, 
bool tx, bool rx)
return hclge_cmd_send(>hw, , 1);
 }
 
+static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
+ u8 pfc_bitmap)
+{
+   struct hclge_desc desc;
+   struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)
+
+   hclge_cmd_setup_basic_desc(, HCLGE_OPC_CFG_PFC_PAUSE_EN, false);
+
+   pfc->tx_rx_en_bitmap = tx_rx_bitmap;
+   pfc->pri_en_bitmap = pfc_bitmap;
+
+   return hclge_cmd_send(>hw, , 1);
+}
+
 static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
 {
u8 tc;
@@ -969,20 +983,64 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
return hclge_tm_schd_mode_hw(hdev);
 }
 
+static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
+{
+   u8 enable_bitmap = 0;
+
+   if (hdev->tm_info.fc_mode == HCLGE_FC_PFC)
+   enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK |
+   HCLGE_RX_MAC_PAUSE_EN_MSK;
+
+   return hclge_pfc_pause_en_cfg(hdev, enable_bitmap,
+ hdev->tm_info.hw_pfc_map);
+}
+
+static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
+{
+   bool tx_en, rx_en;
+
+   switch (hdev->tm_info.fc_mode) {
+   case HCLGE_FC_NONE:
+   tx_en = false;
+   rx_en = false;
+   break;
+   case HCLGE_FC_RX_PAUSE:
+   tx_en = false;
+   rx_en = true;
+   break;
+   case HCLGE_FC_TX_PAUSE:
+   tx_en = true;
+   rx_en = false;
+   break;
+   case HCLGE_FC_FULL:
+   tx_en = true;
+   rx_en = true;
+   break;
+   default:
+   tx_en = true;
+   rx_en = true;
+   }
+
+   return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en);
+}
+
 int hclge_pause_setup_hw(struct hclge_dev *hdev)
 {
-   bool en = hdev->tm_info.fc_mode != HCLGE_FC_PFC;
int ret;
u8 i;
 
-   ret = hclge_mac_pause_en_cfg(hdev, en, en);
-   if (ret)
-   return ret;
+   if (hdev->tm_info.fc_mode != HCLGE_FC_PFC)
+   return hclge_mac_pause_setup_hw(hdev);
 
-   /* Only DCB-supported dev supports qset back pressure setting */
+   /* Only DCB-supported dev supports qset back pressure and pfc cmd */
if (!hnae3_dev_dcb_supported(hdev))
return 0;
 
+   /* When MAC is GE Mode, hdev does not support pfc setting */
+   ret = hclge_pfc_setup_hw(hdev);
+   if (ret)
+   dev_warn(>pdev->dev, "set pfc pause failed:%d\n", ret);
+
for (i = 0; i < hdev->tm_info.num_tc; i++) {
ret = hclge_tm_qs_bp_cfg(hdev, i);
if (ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 85158b0..8ecd83c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -94,6 +94,11 @@ struct hclge_bp_to_qs_map_cmd {
u32 rsvd1;
 };
 
+struct hclge_pfc_en_cmd {
+   u8 tx_rx_en_bitmap;
+   u8 pri_en_bitmap;
+};
+
 #define hclge_tm_set_field(dest, string, val) \
hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH), val)
-- 
1.9.1



[PATCH v2 net-next 06/10] net: hns3: Add some interface for the support of DCB feature

2017-09-25 Thread Yunsheng Lin
This patch add some interface and export some interface from
hclge_tm and hclgc_main to support the upcoming DCB feature.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  3 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  3 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 48 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  6 +++
 4 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index b345070..ca7e3bc 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -30,7 +30,6 @@
 #define HCLGE_64BIT_STATS_FIELD_OFF(f) (offsetof(struct hclge_64_bit_stats, f))
 #define HCLGE_32BIT_STATS_FIELD_OFF(f) (offsetof(struct hclge_32_bit_stats, f))
 
-static int hclge_rss_init_hw(struct hclge_dev *hdev);
 static int hclge_set_mta_filter_mode(struct hclge_dev *hdev,
 enum hclge_mta_dmac_sel_type mta_mac_sel,
 bool enable);
@@ -2655,7 +2654,7 @@ static int hclge_get_tc_size(struct hnae3_handle *handle)
return hdev->rss_size_max;
 }
 
-static int hclge_rss_init_hw(struct hclge_dev *hdev)
+int hclge_rss_init_hw(struct hclge_dev *hdev)
 {
const  u8 hfunc = HCLGE_RSS_HASH_ALGO_TOEPLITZ;
struct hclge_vport *vport = hdev->vport;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 4fc36f0..394b587 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -515,4 +515,7 @@ static inline int hclge_get_queue_id(struct hnae3_queue 
*queue)
 int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex);
 int hclge_set_vf_vlan_common(struct hclge_dev *vport, int vfid,
 bool is_kill, u16 vlan, u8 qos, __be16 proto);
+
+int hclge_buffer_alloc(struct hclge_dev *hdev);
+int hclge_rss_init_hw(struct hclge_dev *hdev);
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index ea94d23..8295684 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -883,10 +883,14 @@ static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev)
return 0;
 }
 
-static int hclge_tm_map_cfg(struct hclge_dev *hdev)
+int hclge_tm_map_cfg(struct hclge_dev *hdev)
 {
int ret;
 
+   ret = hclge_up_to_tc_map(hdev);
+   if (ret)
+   return ret;
+
ret = hclge_tm_pg_to_pri_map(hdev);
if (ret)
return ret;
@@ -994,7 +998,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
return 0;
 }
 
-static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
+int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
 {
int ret;
 
@@ -1092,7 +1096,45 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev)
return ret;
}
 
-   return hclge_up_to_tc_map(hdev);
+   return 0;
+}
+
+int hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc)
+{
+   struct hclge_vport *vport = hdev->vport;
+   struct hnae3_knic_private_info *kinfo;
+   u32 i, k;
+
+   for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
+   if (prio_tc[i] >= hdev->tm_info.num_tc)
+   return -EINVAL;
+   hdev->tm_info.prio_tc[i] = prio_tc[i];
+
+   for (k = 0;  k < hdev->num_alloc_vport; k++) {
+   kinfo = [k].nic.kinfo;
+   kinfo->prio_tc[i] = prio_tc[i];
+   }
+   }
+   return 0;
+}
+
+void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc)
+{
+   u8 i, bit_map = 0;
+
+   hdev->tm_info.num_tc = num_tc;
+
+   for (i = 0; i < hdev->tm_info.num_tc; i++)
+   bit_map |= BIT(i);
+
+   if (!bit_map) {
+   bit_map = 1;
+   hdev->tm_info.num_tc = 1;
+   }
+
+   hdev->hw_tc_map = bit_map;
+
+   hclge_tm_schd_info_init(hdev);
 }
 
 int hclge_tm_init_hw(struct hclge_dev *hdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 19a01e4..bf59961 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -112,4 +112,10 @@ struct hclge_port_shapping_cmd {
 
 int hclge_tm_schd_init(struct hclge_dev *hdev);
 int hclge_pause_setup_hw(struct hclge_dev *hdev);
+int hclge_tm_schd_mode_hw(struct hclge_dev *hdev);
+int hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc

[PATCH v2 net-next 04/10] net: hns3: Add support for port shaper setting in TM module

2017-09-25 Thread Yunsheng Lin
This patch add a tm_port_shaper cmd and set port shaper
to HCLGE_ETHER_MAX_RATE on TM initialization process.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 32 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  4 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 0b4b5d9..f79cebd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -301,6 +301,34 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
return hclge_cmd_send(>hw, , 1);
 }
 
+static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev)
+{
+   struct hclge_port_shapping_cmd *shap_cfg_cmd;
+   struct hclge_desc desc;
+   u32 shapping_para = 0;
+   u8 ir_u, ir_b, ir_s;
+   int ret;
+
+   ret = hclge_shaper_para_calc(HCLGE_ETHER_MAX_RATE,
+HCLGE_SHAPER_LVL_PORT,
+_b, _u, _s);
+   if (ret)
+   return ret;
+
+   hclge_cmd_setup_basic_desc(, HCLGE_OPC_TM_PORT_SHAPPING, false);
+   shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
+
+   hclge_tm_set_field(shapping_para, IR_B, ir_b);
+   hclge_tm_set_field(shapping_para, IR_U, ir_u);
+   hclge_tm_set_field(shapping_para, IR_S, ir_s);
+   hclge_tm_set_field(shapping_para, BS_B, HCLGE_SHAPER_BS_U_DEF);
+   hclge_tm_set_field(shapping_para, BS_S, HCLGE_SHAPER_BS_S_DEF);
+
+   shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para);
+
+   return hclge_cmd_send(>hw, , 1);
+}
+
 static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev,
 enum hclge_shap_bucket bucket, u8 pri_id,
 u8 ir_b, u8 ir_u, u8 ir_s,
@@ -864,6 +892,10 @@ static int hclge_tm_shaper_cfg(struct hclge_dev *hdev)
 {
int ret;
 
+   ret = hclge_tm_port_shaper_cfg(hdev);
+   if (ret)
+   return ret;
+
ret = hclge_tm_pg_shaper_cfg(hdev);
if (ret)
return ret;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 8ecd83c..19a01e4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -99,6 +99,10 @@ struct hclge_pfc_en_cmd {
u8 pri_en_bitmap;
 };
 
+struct hclge_port_shapping_cmd {
+   __le32 port_shapping_para;
+};
+
 #define hclge_tm_set_field(dest, string, val) \
hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH), val)
-- 
1.9.1



[PATCH v2 net-next 05/10] net: hns3: Add tc-based TM support for sriov enabled port

2017-09-25 Thread Yunsheng Lin
When sriov is enabled and TM is in tc-based mode, vf's TM
parameters is not set in TM initialization process.
This patch add the tc_based TM support for sriov enabled
using the information in vport struct.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 49 ++
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index f79cebd..ea94d23 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -388,13 +388,13 @@ static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev 
*hdev, u8 pri_id)
return hclge_cmd_send(>hw, , 1);
 }
 
-static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id)
+static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 
mode)
 {
struct hclge_desc desc;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false);
 
-   if (hdev->tm_info.tc_info[qs_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR)
+   if (mode == HCLGE_SCH_MODE_DWRR)
desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
else
desc.data[1] = 0;
@@ -638,17 +638,18 @@ static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev)
 {
struct hclge_vport *vport = hdev->vport;
int ret;
-   u32 i;
+   u32 i, k;
 
if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
/* Cfg qs -> pri mapping, one by one mapping */
-   for (i = 0; i < hdev->tm_info.num_tc; i++) {
-   ret = hclge_tm_qs_to_pri_map_cfg(hdev, i, i);
-   if (ret)
-   return ret;
-   }
+   for (k = 0; k < hdev->num_alloc_vport; k++)
+   for (i = 0; i < hdev->tm_info.num_tc; i++) {
+   ret = hclge_tm_qs_to_pri_map_cfg(
+   hdev, vport[k].qs_offset + i, i);
+   if (ret)
+   return ret;
+   }
} else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) {
-   int k;
/* Cfg qs -> pri mapping,  qs = tc, pri = vf, 8 qs -> 1 pri */
for (k = 0; k < hdev->num_alloc_vport; k++)
for (i = 0; i < HNAE3_MAX_TC; i++) {
@@ -797,10 +798,11 @@ static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev)
 
 static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
 {
+   struct hclge_vport *vport = hdev->vport;
struct hclge_pg_info *pg_info;
u8 dwrr;
int ret;
-   u32 i;
+   u32 i, k;
 
for (i = 0; i < hdev->tm_info.num_tc; i++) {
pg_info =
@@ -811,9 +813,13 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev 
*hdev)
if (ret)
return ret;
 
-   ret = hclge_tm_qs_weight_cfg(hdev, i, dwrr);
-   if (ret)
-   return ret;
+   for (k = 0; k < hdev->num_alloc_vport; k++) {
+   ret = hclge_tm_qs_weight_cfg(
+   hdev, vport[k].qs_offset + i,
+   vport[k].dwrr);
+   if (ret)
+   return ret;
+   }
}
 
return 0;
@@ -944,7 +950,10 @@ static int hclge_tm_schd_mode_vnet_base_cfg(struct 
hclge_vport *vport)
return ret;
 
for (i = 0; i < kinfo->num_tc; i++) {
-   ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i);
+   u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode;
+
+   ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i,
+   sch_mode);
if (ret)
return ret;
}
@@ -956,7 +965,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
 {
struct hclge_vport *vport = hdev->vport;
int ret;
-   u8 i;
+   u8 i, k;
 
if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
for (i = 0; i < hdev->tm_info.num_tc; i++) {
@@ -964,9 +973,13 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
if (ret)
return ret;
 
-   ret = hclge_tm_qs_schd_mode_cfg(hdev, i);
-   if (ret)
-   return ret;
+   for (k = 0; k < hdev->num_alloc_vport; k++) {
+   ret = hclge_tm_qs_schd_mode_cfg(
+   hdev, vport[k].qs_offset +

[PATCH v2 net-next 02/10] net: hns3: Add support for dynamically buffer reallocation

2017-09-25 Thread Yunsheng Lin
Current buffer allocation can only happen at init, when
doing buffer reallocation after init, care must be taken
care of memory which priv_buf points to.
This patch fixes it by using a dynamic allocated temporary
memory. Because we only do buffer reallocation at init or
when setting up the DCB parameter, and priv_buf is only
used at buffer allocation process, so it is ok to use a
dynamic allocated temporary memory.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   5 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 150 +++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   2 -
 3 files changed, 87 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index a81c6cb..6b6d28e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -322,6 +322,11 @@ struct hclge_shared_buf {
u32 buf_size;
 };
 
+struct hclge_pkt_buf_alloc {
+   struct hclge_priv_buf priv_buf[HCLGE_MAX_TC_NUM];
+   struct hclge_shared_buf s_buf;
+};
+
 #define HCLGE_RX_COM_WL_EN_B   15
 struct hclge_rx_com_wl_buf {
__le16 high_wl;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 02da3d5..b345070 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1324,7 +1324,8 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
return 0;
 }
 
-static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
+static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev,
+   struct hclge_pkt_buf_alloc *buf_alloc)
 {
 /* TX buffer size is unit by 128 byte */
 #define HCLGE_BUF_SIZE_UNIT_SHIFT  7
@@ -1338,7 +1339,7 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev)
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TX_BUFF_ALLOC, 0);
for (i = 0; i < HCLGE_TC_NUM; i++) {
-   u32 buf_size = hdev->priv_buf[i].tx_buf_size;
+   u32 buf_size = buf_alloc->priv_buf[i].tx_buf_size;
 
req->tx_pkt_buff[i] =
cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |
@@ -1355,9 +1356,10 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev)
return 0;
 }
 
-static int hclge_tx_buffer_alloc(struct hclge_dev *hdev)
+static int hclge_tx_buffer_alloc(struct hclge_dev *hdev,
+struct hclge_pkt_buf_alloc *buf_alloc)
 {
-   int ret = hclge_cmd_alloc_tx_buff(hdev);
+   int ret = hclge_cmd_alloc_tx_buff(hdev, buf_alloc);
 
if (ret) {
dev_err(>pdev->dev,
@@ -1390,13 +1392,14 @@ static int hclge_get_pfc_enalbe_num(struct hclge_dev 
*hdev)
 }
 
 /* Get the number of pfc enabled TCs, which have private buffer */
-static int hclge_get_pfc_priv_num(struct hclge_dev *hdev)
+static int hclge_get_pfc_priv_num(struct hclge_dev *hdev,
+ struct hclge_pkt_buf_alloc *buf_alloc)
 {
struct hclge_priv_buf *priv;
int i, cnt = 0;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if ((hdev->tm_info.hw_pfc_map & BIT(i)) &&
priv->enable)
cnt++;
@@ -1406,13 +1409,14 @@ static int hclge_get_pfc_priv_num(struct hclge_dev 
*hdev)
 }
 
 /* Get the number of pfc disabled TCs, which have private buffer */
-static int hclge_get_no_pfc_priv_num(struct hclge_dev *hdev)
+static int hclge_get_no_pfc_priv_num(struct hclge_dev *hdev,
+struct hclge_pkt_buf_alloc *buf_alloc)
 {
struct hclge_priv_buf *priv;
int i, cnt = 0;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if (hdev->hw_tc_map & BIT(i) &&
!(hdev->tm_info.hw_pfc_map & BIT(i)) &&
priv->enable)
@@ -1422,31 +1426,33 @@ static int hclge_get_no_pfc_priv_num(struct hclge_dev 
*hdev)
return cnt;
 }
 
-static u32 hclge_get_rx_priv_buff_alloced(struct hclge_dev *hdev)
+static u32 hclge_get_rx_priv_buff_alloced(struct hclge_pkt_buf_alloc 
*buf_alloc)
 {
struct hclge_priv_buf *priv;
u32 rx_priv = 0;
int i;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if (priv->enable)
rx_priv += priv->buf_size;
}
return rx_priv;
 }
 
-static u32 hclge_get_tx_buff_alloced(str

[PATCH v2 net-next 01/10] net: hns3: Support for dynamically assigning tx buffer to TC

2017-09-25 Thread Yunsheng Lin
This patch add support of dynamically assigning tx buffer to
TC when the TC is enabled.
It will save buffer for rx direction to avoid packet loss.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
V2:
Fix for not defining variables in local loop.

V1:
Initial submit.
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  1 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 64 ++
 2 files changed, 55 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 758cf39..a81c6cb 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -311,6 +311,7 @@ struct hclge_tc_thrd {
 struct hclge_priv_buf {
struct hclge_waterline wl;  /* Waterline for low and high*/
u32 buf_size;   /* TC private buffer size */
+   u32 tx_buf_size;
u32 enable; /* Enable TC private buffer or not */
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index d27618b..02da3d5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1324,7 +1324,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
return 0;
 }
 
-static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev, u16 buf_size)
+static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
 {
 /* TX buffer size is unit by 128 byte */
 #define HCLGE_BUF_SIZE_UNIT_SHIFT  7
@@ -1337,10 +1337,13 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev, u16 buf_size)
req = (struct hclge_tx_buff_alloc *)desc.data;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TX_BUFF_ALLOC, 0);
-   for (i = 0; i < HCLGE_TC_NUM; i++)
+   for (i = 0; i < HCLGE_TC_NUM; i++) {
+   u32 buf_size = hdev->priv_buf[i].tx_buf_size;
+
req->tx_pkt_buff[i] =
cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |
 HCLGE_BUF_SIZE_UPDATE_EN_MSK);
+   }
 
ret = hclge_cmd_send(>hw, , 1);
if (ret) {
@@ -1352,9 +1355,9 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev, u16 buf_size)
return 0;
 }
 
-static int hclge_tx_buffer_alloc(struct hclge_dev *hdev, u32 buf_size)
+static int hclge_tx_buffer_alloc(struct hclge_dev *hdev)
 {
-   int ret = hclge_cmd_alloc_tx_buff(hdev, buf_size);
+   int ret = hclge_cmd_alloc_tx_buff(hdev);
 
if (ret) {
dev_err(>pdev->dev,
@@ -1433,6 +1436,16 @@ static u32 hclge_get_rx_priv_buff_alloced(struct 
hclge_dev *hdev)
return rx_priv;
 }
 
+static u32 hclge_get_tx_buff_alloced(struct hclge_dev *hdev)
+{
+   u32 i, total_tx_size = 0;
+
+   for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
+   total_tx_size += hdev->priv_buf[i].tx_buf_size;
+
+   return total_tx_size;
+}
+
 static bool  hclge_is_rx_buf_ok(struct hclge_dev *hdev, u32 rx_all)
 {
u32 shared_buf_min, shared_buf_tc, shared_std;
@@ -1477,18 +1490,43 @@ static bool  hclge_is_rx_buf_ok(struct hclge_dev *hdev, 
u32 rx_all)
return true;
 }
 
+static int hclge_tx_buffer_calc(struct hclge_dev *hdev)
+{
+   u32 i, total_size;
+
+   total_size = hdev->pkt_buf_size;
+
+   /* alloc tx buffer for all enabled tc */
+   for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+   struct hclge_priv_buf *priv = >priv_buf[i];
+
+   if (total_size < HCLGE_DEFAULT_TX_BUF)
+   return -ENOMEM;
+
+   if (hdev->hw_tc_map & BIT(i))
+   priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
+   else
+   priv->tx_buf_size = 0;
+
+   total_size -= priv->tx_buf_size;
+   }
+
+   return 0;
+}
+
 /* hclge_rx_buffer_calc: calculate the rx private buffer size for all TCs
  * @hdev: pointer to struct hclge_dev
- * @tx_size: the allocated tx buffer for all TCs
  * @return: 0: calculate sucessful, negative: fail
  */
-int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 tx_size)
+int hclge_rx_buffer_calc(struct hclge_dev *hdev)
 {
-   u32 rx_all = hdev->pkt_buf_size - tx_size;
+   u32 rx_all = hdev->pkt_buf_size;
int no_pfc_priv_num, pfc_priv_num;
struct hclge_priv_buf *priv;
int i;
 
+   rx_all -= hclge_get_tx_buff_alloced(hdev);
+
/* When DCB is not supported, rx private
 * buffer is not allocated.
 */
@@ -1771,7 +1809,6 @@ static int hclge_common_wl_config(struct hclge_dev *hdev)
 
 int hclge_buffer_alloc(struct hclge_dev *hdev)
 {
-   u32 tx_buf_size = HCLGE_DEFAULT_TX_BUF;
int ret;
 
hdev->priv_buf = devm_kmalloc_array(>pdev->dev, HCLGE

[PATCH v2 net-next 07/10] net: hns3: Add hclge_dcb module for the support of DCB feature

2017-09-25 Thread Yunsheng Lin
The hclge_dcb module calls the interface from hclge_main/tm
and provide interface for the dcb netlink interface.

This patch also update Makefiles required to build the DCB
supported code in HNS3 Ethernet driver and update the existing
Kconfig file in the hisilicon folder.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/Kconfig |   9 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  20 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 327 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h |  21 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  25 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   3 +
 7 files changed, 401 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 91c7bdb..9d7cb03 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -103,4 +103,13 @@ config HNS3_ENET
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
  devices and their associated operations.
 
+config HNS3_DCB
+   bool "Hisilicon HNS3 Data Center Bridge Support"
+   default n
+   depends on HNS3 && HNS3_HCLGE && DCB
+   ---help---
+ Say Y here if you want to use Data Center Bridging (DCB) in the HNS3 
driver.
+
+ If unsure, say N.
+
 endif # NET_VENDOR_HISILICON
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 1a01cad..5a6fa53 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -28,6 +28,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -131,6 +132,7 @@ struct hnae3_client_ops {
int (*init_instance)(struct hnae3_handle *handle);
void (*uninit_instance)(struct hnae3_handle *handle, bool reset);
void (*link_status_change)(struct hnae3_handle *handle, bool state);
+   int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
 };
 
 #define HNAE3_CLIENT_NAME_LENGTH 16
@@ -363,6 +365,23 @@ struct hnae3_ae_ops {
  u16 vlan, u8 qos, __be16 proto);
 };
 
+struct hnae3_dcb_ops {
+   /* IEEE 802.1Qaz std */
+   int (*ieee_getets)(struct hnae3_handle *, struct ieee_ets *);
+   int (*ieee_setets)(struct hnae3_handle *, struct ieee_ets *);
+   int (*ieee_getpfc)(struct hnae3_handle *, struct ieee_pfc *);
+   int (*ieee_setpfc)(struct hnae3_handle *, struct ieee_pfc *);
+
+   /* DCBX configuration */
+   u8   (*getdcbx)(struct hnae3_handle *);
+   u8   (*setdcbx)(struct hnae3_handle *, u8);
+
+   /* TC setup */
+   int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
+
+   int (*map_update)(struct hnae3_handle *);
+};
+
 struct hnae3_ae_algo {
const struct hnae3_ae_ops *ops;
struct list_head node;
@@ -394,6 +413,7 @@ struct hnae3_knic_private_info {
 
u16 num_tqps; /* total number of TQPs in this handle */
struct hnae3_queue **tqp;  /* array base of all TQPs in this instance */
+   const struct hnae3_dcb_ops *dcb_ops;
 };
 
 struct hnae3_roce_private_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
index 162e8a42..7023dc87 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
@@ -7,5 +7,7 @@ ccflags-y := -Idrivers/net/ethernet/hisilicon/hns3
 obj-$(CONFIG_HNS3_HCLGE) += hclge.o
 hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o
 
+hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o
+
 obj-$(CONFIG_HNS3_ENET) += hns3.o
 hns3-objs = hns3_enet.o hns3_ethtool.o
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
new file mode 100644
index 000..178333b
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "hclge_main.h"
+#include "hclge_tm.h"
+#include "hnae3.h"
+
+#define BW_PERCENT 100
+
+static int hclge_ieee_ets_to_tm_info(struct hclge_dev *hdev,
+struct ieee_ets *ets)
+{
+   u8 i;
+
+   for (i = 0; i < HNAE3_MAX_TC; i++) {
+   switc

[PATCH v2 net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-25 Thread Yunsheng Lin
When using tc qdisc to configure DCB parameter, dcb_ops->setup_tc
is used to tell hclge_dcb module to do the setup.
When using lldptool to configure DCB parameter, hclge_dcb module
call the client_ops->setup_tc to tell network stack which queue
and priority is using for specific tc.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 135 +
 1 file changed, 111 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 11dab26..31fcda4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -196,6 +196,32 @@ static void hns3_vector_gl_rl_init(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->tx_group.flow_level = HNS3_FLOW_LOW;
 }
 
+static int hns3_nic_set_real_num_queue(struct net_device *netdev)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_knic_private_info *kinfo = >kinfo;
+   unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
+   int ret;
+
+   ret = netif_set_real_num_tx_queues(netdev, queue_size);
+   if (ret) {
+   netdev_err(netdev,
+  "netif_set_real_num_tx_queues fail, ret=%d!\n",
+  ret);
+   return ret;
+   }
+
+   ret = netif_set_real_num_rx_queues(netdev, queue_size);
+   if (ret) {
+   netdev_err(netdev,
+  "netif_set_real_num_rx_queues fail, ret=%d!\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 static int hns3_nic_net_up(struct net_device *netdev)
 {
struct hns3_nic_priv *priv = netdev_priv(netdev);
@@ -232,26 +258,13 @@ static int hns3_nic_net_up(struct net_device *netdev)
 
 static int hns3_nic_net_open(struct net_device *netdev)
 {
-   struct hns3_nic_priv *priv = netdev_priv(netdev);
-   struct hnae3_handle *h = priv->ae_handle;
int ret;
 
netif_carrier_off(netdev);
 
-   ret = netif_set_real_num_tx_queues(netdev, h->kinfo.num_tqps);
-   if (ret) {
-   netdev_err(netdev,
-  "netif_set_real_num_tx_queues fail, ret=%d!\n",
-  ret);
-   return ret;
-   }
-
-   ret = netif_set_real_num_rx_queues(netdev, h->kinfo.num_tqps);
-   if (ret) {
-   netdev_err(netdev,
-  "netif_set_real_num_rx_queues fail, ret=%d!\n", ret);
+   ret = hns3_nic_set_real_num_queue(netdev);
+   if (ret)
return ret;
-   }
 
ret = hns3_nic_net_up(netdev);
if (ret) {
@@ -1193,32 +1206,40 @@ static void hns3_nic_udp_tunnel_del(struct net_device 
*netdev,
}
 }
 
-static int hns3_setup_tc(struct net_device *netdev, u8 tc)
+static int hns3_setup_tc(struct net_device *netdev, u8 tc, u8 *prio_tc)
 {
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
struct hnae3_knic_private_info *kinfo = >kinfo;
+   bool if_running = netif_running(netdev);
unsigned int i;
int ret;
 
if (tc > HNAE3_MAX_TC)
return -EINVAL;
 
-   if (kinfo->num_tc == tc)
-   return 0;
-
if (!netdev)
return -EINVAL;
 
-   if (!tc) {
+   if (if_running) {
+   (void)hns3_nic_net_stop(netdev);
+   msleep(100);
+   }
+
+   ret = (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
+   kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP;
+   if (ret)
+   goto err_out;
+
+   if (tc <= 1) {
netdev_reset_tc(netdev);
-   return 0;
+   goto out;
}
 
/* Set num_tc for netdev */
ret = netdev_set_num_tc(netdev, tc);
if (ret)
-   return ret;
+   goto err_out;
 
/* Set per TC queues for the VSI */
for (i = 0; i < HNAE3_MAX_TC; i++) {
@@ -1229,7 +1250,14 @@ static int hns3_setup_tc(struct net_device *netdev, u8 
tc)
kinfo->tc_info[i].tqp_offset);
}
 
-   return 0;
+out:
+   ret = hns3_nic_set_real_num_queue(netdev);
+
+err_out:
+   if (if_running)
+   (void)hns3_nic_net_open(netdev);
+
+   return ret;
 }
 
 static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
@@ -1240,7 +1268,7 @@ static int hns3_nic_setup_tc(struct net_device *dev, enum 
tc_setup_type type,
if (type != TC_SETUP_MQPRIO)
return -EOPNOTSUPP;
 
-   return hns3_setup_tc(dev, mqprio->num_tc);
+   retu

[PATCH v2 net-next 09/10] net: hns3: Setting for fc_mode and dcb enable flag in TM module

2017-09-25 Thread Yunsheng Lin
After the DCB feature is supported, fc_mode and dcb enable flag
must be set according to the DCB parameter.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 34 +++---
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 8295684..359ee67 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -486,7 +486,11 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
hdev->tm_info.prio_tc[i] =
(i >= hdev->tm_info.num_tc) ? 0 : i;
 
-   hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
+   /* DCB is enabled if we have more than 1 TC */
+   if (hdev->tm_info.num_tc > 1)
+   hdev->flag |= HCLGE_FLAG_DCB_ENABLE;
+   else
+   hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
 }
 
 static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
@@ -512,6 +516,24 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
}
 }
 
+static void hclge_pfc_info_init(struct hclge_dev *hdev)
+{
+   if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) {
+   if (hdev->fc_mode_last_time == HCLGE_FC_PFC)
+   dev_warn(>pdev->dev,
+"DCB is disable, but last mode is FC_PFC\n");
+
+   hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
+   } else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
+   /* fc_mode_last_time record the last fc_mode when
+* DCB is enabled, so that fc_mode can be set to
+* the correct value when DCB is disabled.
+*/
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hdev->tm_info.fc_mode = HCLGE_FC_PFC;
+   }
+}
+
 static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
 {
if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
@@ -524,8 +546,7 @@ static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
 
hclge_tm_vport_info_update(hdev);
 
-   hdev->tm_info.fc_mode = HCLGE_FC_NONE;
-   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hclge_pfc_info_init(hdev);
 
return 0;
 }
@@ -1158,8 +1179,13 @@ int hclge_tm_init_hw(struct hclge_dev *hdev)
 
 int hclge_tm_schd_init(struct hclge_dev *hdev)
 {
-   int ret = hclge_tm_schd_info_init(hdev);
+   int ret;
+
+   /* fc_mode is HCLGE_FC_FULL on reset */
+   hdev->tm_info.fc_mode = HCLGE_FC_FULL;
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
 
+   ret = hclge_tm_schd_info_init(hdev);
if (ret)
return ret;
 
-- 
1.9.1



[PATCH v2 net-next 08/10] net: hns3: Add dcb netlink interface for the support of DCB feature

2017-09-25 Thread Yunsheng Lin
This patch add dcb netlink interface by calling the interface from
hclge_dcb module.

This patch also update Makefile in order to build hns3_dcbnl module.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   2 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c| 106 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c |   2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   7 ++
 4 files changed, 117 insertions(+)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
index 7023dc87..d2b20d0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
@@ -11,3 +11,5 @@ hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o
 
 obj-$(CONFIG_HNS3_ENET) += hns3.o
 hns3-objs = hns3_enet.o hns3_ethtool.o
+
+hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
new file mode 100644
index 000..9832172
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "hnae3.h"
+#include "hns3_enet.h"
+
+static
+int hns3_dcbnl_ieee_getets(struct net_device *ndev, struct ieee_ets *ets)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_getets)
+   return h->kinfo.dcb_ops->ieee_getets(h, ets);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_setets(struct net_device *ndev, struct ieee_ets *ets)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_setets)
+   return h->kinfo.dcb_ops->ieee_setets(h, ets);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_getpfc(struct net_device *ndev, struct ieee_pfc *pfc)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_getpfc)
+   return h->kinfo.dcb_ops->ieee_getpfc(h, pfc);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_setpfc(struct net_device *ndev, struct ieee_pfc *pfc)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_setpfc)
+   return h->kinfo.dcb_ops->ieee_setpfc(h, pfc);
+
+   return -EOPNOTSUPP;
+}
+
+/* DCBX configuration */
+static u8 hns3_dcbnl_getdcbx(struct net_device *ndev)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->getdcbx)
+   return h->kinfo.dcb_ops->getdcbx(h);
+
+   return 0;
+}
+
+/* return 0 if successful, otherwise fail */
+static u8 hns3_dcbnl_setdcbx(struct net_device *ndev, u8 mode)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->setdcbx)
+   return h->kinfo.dcb_ops->setdcbx(h, mode);
+
+   return 1;
+}
+
+static const struct dcbnl_rtnl_ops hns3_dcbnl_ops = {
+   .ieee_getets= hns3_dcbnl_ieee_getets,
+   .ieee_setets= hns3_dcbnl_ieee_setets,
+   .ieee_getpfc= hns3_dcbnl_ieee_getpfc,
+   .ieee_setpfc= hns3_dcbnl_ieee_setpfc,
+   .getdcbx= hns3_dcbnl_getdcbx,
+   .setdcbx= hns3_dcbnl_setdcbx,
+};
+
+/* hclge_dcbnl_setup - DCBNL setup
+ * @handle: the corresponding vport handle
+ * Set up DCBNL
+ */
+void hns3_dcbnl_setup(struct hnae3_handle *handle)
+{
+   struct net_device *dev = handle->kinfo.netdev;
+
+   if (!handle->kinfo.dcb_ops)
+   return;
+
+   dev->dcbnl_ops = _dcbnl_ops;
+}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 35369e1..11dab26 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -2790,6 +2790,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_reg_netdev_fail;
}
 
+   hns3_dcbnl_setup(handle);
+
/* MTU range: (ETH_MIN_MTU(kernel default) - 9706) */
netdev->max_mtu = HNS3_MAX_

Re: [PATCH net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-25 Thread Yunsheng Lin
Hi, Jiri

On 2017/9/25 14:57, Jiri Pirko wrote:
> Mon, Sep 25, 2017 at 02:45:08AM CEST, linyunsh...@huawei.com wrote:
>> Hi, Jiri
>>
>> On 2017/9/24 19:37, Jiri Pirko wrote:
>>> Sat, Sep 23, 2017 at 02:47:20AM CEST, linyunsh...@huawei.com wrote:
 Hi, Jiri

 On 2017/9/23 0:03, Jiri Pirko wrote:
> Fri, Sep 22, 2017 at 04:11:51PM CEST, linyunsh...@huawei.com wrote:
>> Hi, Jiri
>>
 - if (!tc) {
 + if (if_running) {
 + (void)hns3_nic_net_stop(netdev);
 + msleep(100);
 + }
 +
 + ret = (kinfo->dcb_ops && kinfo->dcb_ops->>setup_tc) ?
 + kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : ->EOPNOTSUPP;
>>
>>> This is most odd. Why do you call dcb_ops from >ndo_setup_tc callback?
>>> Why are you mixing this together? prio->tc mapping >can be done
>>> directly in dcbnl
>>
>> Here is what we do in dcb_ops->setup_tc:
>> Firstly, if current tc num is different from the tc num
>> that user provide, then we setup the queues for each
>> tc.
>>
>> Secondly, we tell hardware the pri to tc mapping that
>> the stack is using. In rx direction, our hardware need
>> that mapping to put different packet into different tc'
>> queues according to the priority of the packet, then
>> rss decides which specific queue in the tc should the
>> packet goto.
>>
>> By mixing, I suppose you meant why we need the
>> pri to tc infomation?
>
> by mixing, I mean what I wrote. You are calling dcb_ops callback from
> ndo_setup_tc callback. So you are mixing DCBNL subsystem and TC
> subsystem. Why? Why do you need sch_mqprio? Why DCBNL is not enough for
> all?

 When using lldptool, dcbnl is involved.

 But when using tc qdisc, dcbbl is not involved, below is the a few key
 call graph in the kernel when tc qdisc cmd is executed.

 cmd:
 tc qdisc add dev eth0 root handle 1:0 mqprio num_tc 4 map 1 2 3 3 1 3 1 1 
 hw 1

 call graph:
 rtnetlink_rcv_msg -> tc_modify_qdisc -> qdisc_create -> mqprio_init ->
 hns3_nic_setup_tc

 When hns3_nic_setup_tc is called, we need to know how many tc num and
 prio_tc mapping from the tc_mqprio_qopt which is provided in the paramter
 in the ndo_setup_tc function, and dcb_ops is the our hardware specific
 method to setup the tc related parameter to the hardware, so this is why
 we call dcb_ops callback in ndo_setup_tc callback.

 I hope this will answer your question, thanks for your time.
>>>
>>> Okay. I understand that you have a usecase for mqprio mapping offload
>>> without lldptool being involved. Ok. I believe it is wrong to call dcb_ops
>>> from tc callback. You should have a generic layer inside the driver and
>>> call it from both dcb_ops and tc callbacks.
>>
>> Actually, dcb_ops is our generic layer inside the driver.
>> Below is high level architecture:
>>
>>   [ tc qdisc ]  [ lldpad ]
>> | |
>> | |
>> | |
>>   [ hns3_enet ][ hns3_dcbnl ]
>> \/
>>\  /
>>   \/
>> [ hclge_dcb ]
>>   /  \
>>/\
>> /  \
>> [ hclgc_main ][ hclge_tm ]
>>
>> hns3_enet.c implements the ndo_setup_tc callback.
>> hns3_dcbnl.c implements the dcbnl_rtnl_ops for stack's DCBNL system.
>> hclge_dcb implements the dcb_ops.
>> So we already have a generic layer that tc and dcbnl all call from.
>>
>>>
>>> Also, what happens If I run lldptool concurrently with mqprio? Who wins
>>> and is going to configure the mapping?
>>
>> Both lldptool and tc qdisc cmd use rtnl interface provided by stack, so
>> they are both protected by rtnl_lock, so we do not have to do the locking
>> in the driver.
> 
> I was not asking about locking, which is obvious, I was asking about the
> behaviour. Like for example:
> If I use tc to configure some mapping, later on I run lldptool and change
> the mapping. Does the tc dump show the updated values or the original
> ones?

If it is that case, tc dump show the updated values.
Normally, we use tc qdisc to configure the netdev to use mqprio, and
then use the lldptool the tc_prio mapping, tc schedule mode, tc bandwidth
and pfc option.

if lldptool change the tc num and tc_prio mapping, it will tell the tc
system by the following function which is called in client_ops->setup_tc:
netdev_set_tc_queue
netdev_set_prio_tc_map

So lldptool and tc qdisc can work together.



> 
>>
>> The locking is in rtnetlink_rcv_msg:
>>
>>  rtnl_lock();
>>  handlers = rtnl_dereference(rtnl_msg_handlers[family]);
>>  if (handlers) {
>>  doit = READ_ONCE(handlers[type].doit);
>>  if (doit)
>>  err = doit(skb, nlh, extack);
>>  }

Re: [patch net-next v2 03/12] ipmr: Add FIB notification access functions

2017-09-25 Thread Yunsheng Lin
Hi, Yotam

On 2017/9/25 13:38, Yotam Gigi wrote:
> On 09/25/2017 04:19 AM, Yunsheng Lin wrote:
>> Hi, Jiri
>>
>> On 2017/9/25 1:22, Jiri Pirko wrote:
>>> From: Yotam Gigi <yot...@mellanox.com>
>>>
>>> Make the ipmr module register as a FIB notifier. To do that, implement both
>>> the ipmr_seq_read and ipmr_dump ops.
>>>
>>> The ipmr_seq_read op returns a sequence counter that is incremented on
>>> every notification related operation done by the ipmr. To implement that,
>>> add a sequence counter in the netns_ipv4 struct and increment it whenever a
>>> new MFC route or VIF are added or deleted. The sequence operations are
>>> protected by the RTNL lock.
>>>
>>> The ipmr_dump iterates the list of MFC routes and the list of VIF entries
>>> and sends notifications about them. The entries dump is done under RCU
>>> where the VIF dump uses the mrt_lock too, as the vif->dev field can change
>>> under RCU.
>>>
>>> Signed-off-by: Yotam Gigi <yot...@mellanox.com>
>>> Reviewed-by: Ido Schimmel <ido...@mellanox.com>
>>> Signed-off-by: Jiri Pirko <j...@mellanox.com>
>>> ---
>>> v1->v2:
>>>  - Take the mrt_lock when dumping VIF entries.
>>> ---
>>>  include/linux/mroute.h   |  15 ++
>>>  include/net/netns/ipv4.h |   3 ++
>>>  net/ipv4/ipmr.c  | 137 
>>> ++-
>>>  3 files changed, 153 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/include/linux/mroute.h b/include/linux/mroute.h
>>> index 10028f2..54c5cb8 100644
>>> --- a/include/linux/mroute.h
>>> +++ b/include/linux/mroute.h
>>> @@ -5,6 +5,7 @@
>>>  #include 
>>>  #include 
>>>  #include 
>>> +#include 
>>>  #include 
>>>  
>>>  #ifdef CONFIG_IP_MROUTE
>>> @@ -58,6 +59,14 @@ struct vif_device {
>>> int link;   /* Physical interface index 
>>> */
>>>  };
>>>  
>>> +struct vif_entry_notifier_info {
>>> +   struct fib_notifier_info info;
>>> +   struct net_device *dev;
>>> +   vifi_t vif_index;
>>> +   unsigned short vif_flags;
>>> +   u32 tb_id;
>>> +};
>>> +
>>>  #define VIFF_STATIC 0x8000
>>>  
>>>  #define VIF_EXISTS(_mrt, _idx) ((_mrt)->vif_table[_idx].dev != NULL)
>>> @@ -146,6 +155,12 @@ struct mfc_cache {
>>> struct rcu_head rcu;
>>>  };
>>>  
>>> +struct mfc_entry_notifier_info {
>>> +   struct fib_notifier_info info;
>>> +   struct mfc_cache *mfc;
>>> +   u32 tb_id;
>>> +};
>>> +
>>>  struct rtmsg;
>>>  int ipmr_get_route(struct net *net, struct sk_buff *skb,
>>>__be32 saddr, __be32 daddr,
>>> diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
>>> index 8387f09..abc84d9 100644
>>> --- a/include/net/netns/ipv4.h
>>> +++ b/include/net/netns/ipv4.h
>>> @@ -163,6 +163,9 @@ struct netns_ipv4 {
>>> struct fib_notifier_ops *notifier_ops;
>>> unsigned intfib_seq;/* protected by rtnl_mutex */
>>>  
>>> +   struct fib_notifier_ops *ipmr_notifier_ops;
>> Can we add a const here?
> 
> It cannot be const as it get initialized it in ipmr_notifier_init.
> 
>>
>>> +   unsigned intipmr_seq;   /* protected by rtnl_mutex */
>>> +
>>> atomic_trt_genid;
>>>  };
>>>  #endif
>>> diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
>>> index 86dc5f9..49879c3 100644
>>> --- a/net/ipv4/ipmr.c
>>> +++ b/net/ipv4/ipmr.c
>>> @@ -264,6 +264,16 @@ static void __net_exit ipmr_rules_exit(struct net *net)
>>> fib_rules_unregister(net->ipv4.mr_rules_ops);
>>> rtnl_unlock();
>>>  }
>>> +
>>> +static int ipmr_rules_dump(struct net *net, struct notifier_block *nb)
>>> +{
>>> +   return fib_rules_dump(net, nb, RTNL_FAMILY_IPMR);
>>> +}
>>> +
>>> +static unsigned int ipmr_rules_seq_read(struct net *net)
>>> +{
>>> +   return fib_rules_seq_read(net, RTNL_FAMILY_IPMR);
>>> +}
>>>  #else
>>>  #define ipmr_for_each_table(mrt, net) \
>>> for (mrt = net->ipv4.mrt; mrt; mrt = NULL)
>>> @@ -298,6 +308,16 @@ static void __net_exit ipmr_rules_exit(struct net *net)
>>> net->ipv4.mrt = NULL;
>>>  

Re: [patch net-next v2 07/12] mlxsw: spectrum: Add the multicast routing offloading logic

2017-09-24 Thread Yunsheng Lin
Hi, Jiri

On 2017/9/25 1:22, Jiri Pirko wrote:
> From: Yotam Gigi 
> 
> Add the multicast router offloading logic, which is in charge of handling
> the VIF and MFC notifications and translating it to the hardware logic API.
> 
> The offloading logic has to overcome several obstacles in order to safely
> comply with the kernel multicast router user API:
>  - It must keep track of the mapping between VIFs to netdevices. The user
>can add an MFC cache entry pointing to a VIF, delete the VIF and add
>re-add it with a different netdevice. The offloading logic has to handle
>this in order to be compatible with the kernel logic.
>  - It must keep track of the mapping between netdevices to spectrum RIFs,
>as the current hardware implementation assume having a RIF for every
>port in a multicast router.
>  - It must handle routes pointing to pimreg device to be trapped to the
>kernel, as the packet should be delivered to userspace.
>  - It must handle routes pointing tunnel VIFs. The current implementation
>does not support multicast forwarding to tunnels, thus routes that point
>to a tunnel should be trapped to the kernel.
>  - It must be aware of proxy multicast routes, which include both (*,*)
>routes and duplicate routes. Currently proxy routes are not offloaded
>and trigger the abort mechanism: removal of all routes from hardware and
>triggering the traffic to go through the kernel.
> 
> The multicast routing offloading logic also updates the counters of the
> offloaded MFC routes in a periodic work.
> 
> Signed-off-by: Yotam Gigi 
> Reviewed-by: Ido Schimmel 
> Signed-off-by: Jiri Pirko 
> ---
> v1->v2:
>  - Update the lastuse MFC entry field too, in addition to packets an bytes.
> ---
>  drivers/net/ethernet/mellanox/mlxsw/Makefile  |3 +-
>  drivers/net/ethernet/mellanox/mlxsw/spectrum.h|1 +
>  drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c | 1014 
> +
>  drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.h |  133 +++
>  4 files changed, 1150 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
>  create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.h
> 
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/Makefile 
> b/drivers/net/ethernet/mellanox/mlxsw/Makefile
> index 4b88158..9b29764 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/Makefile
> +++ b/drivers/net/ethernet/mellanox/mlxsw/Makefile
> @@ -17,7 +17,8 @@ mlxsw_spectrum-objs := spectrum.o 
> spectrum_buffers.o \
>  spectrum_kvdl.o spectrum_acl_tcam.o \
>  spectrum_acl.o spectrum_flower.o \
>  spectrum_cnt.o spectrum_fid.o \
> -spectrum_ipip.o spectrum_acl_flex_actions.o
> +spectrum_ipip.o spectrum_acl_flex_actions.o \
> +spectrum_mr.o
>  mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB)  += spectrum_dcb.o
>  mlxsw_spectrum-$(CONFIG_NET_DEVLINK) += spectrum_dpipe.o
>  obj-$(CONFIG_MLXSW_MINIMAL)  += mlxsw_minimal.o
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h 
> b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
> index e907ec4..51d8b9f 100644
> --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
> @@ -153,6 +153,7 @@ struct mlxsw_sp {
>   struct mlxsw_sp_sb *sb;
>   struct mlxsw_sp_bridge *bridge;
>   struct mlxsw_sp_router *router;
> + struct mlxsw_sp_mr *mr;
>   struct mlxsw_afa *afa;
>   struct mlxsw_sp_acl *acl;
>   struct mlxsw_sp_fid_core *fid_core;
> diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c 
> b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
> new file mode 100644
> index 000..89b2e60
> --- /dev/null
> +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
> @@ -0,0 +1,1014 @@
> +/*
> + * drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
> + * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
> + * Copyright (c) 2017 Yotam Gigi 
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are 
> met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *notice, this list of conditions and the following disclaimer in the
> + *documentation and/or other materials provided with the distribution.
> + * 3. Neither the names of the copyright holders nor the names of its
> + *contributors may be used to endorse or promote products derived from
> + *this software without specific prior written 

Re: [patch net-next v2 06/12] net: mroute: Check if rule is a default rule

2017-09-24 Thread Yunsheng Lin
Hi, Jiri

On 2017/9/25 1:22, Jiri Pirko wrote:
> From: Yotam Gigi 
> 
> When the ipmr starts, it adds one default FIB rule that matches all packets
> and sends them to the DEFAULT (multicast) FIB table. A more complex rule
> can be added by user to specify that for a specific interface, a packet
> should be look up at either an arbitrary table or according to the l3mdev
> of the interface.
> 
> For drivers willing to offload the ipmr logic into a hardware but don't
> want to offload all the FIB rules functionality, provide a function that
> can indicate whether the FIB rule is the default multicast rule, thus only
> one routing table is needed.
> 
> This way, a driver can register to the FIB notification chain, get
> notifications about FIB rules added and trigger some kind of an internal
> abort mechanism when a non default rule is added by the user.
> 
> Signed-off-by: Yotam Gigi 
> Reviewed-by: Ido Schimmel 
> Signed-off-by: Jiri Pirko 
> ---
>  include/linux/mroute.h |  7 +++
>  net/ipv4/ipmr.c| 10 ++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/include/linux/mroute.h b/include/linux/mroute.h
> index 5566580..b072a84 100644
> --- a/include/linux/mroute.h
> +++ b/include/linux/mroute.h
> @@ -5,6 +5,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  
> @@ -19,6 +20,7 @@ int ip_mroute_getsockopt(struct sock *, int, char __user *, 
> int __user *);
>  int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
>  int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
>  int ip_mr_init(void);
> +bool ipmr_rule_default(const struct fib_rule *rule);
>  #else
>  static inline int ip_mroute_setsockopt(struct sock *sock, int optname,
>  char __user *optval, unsigned int optlen)
> @@ -46,6 +48,11 @@ static inline int ip_mroute_opt(int opt)
>  {
>   return 0;
>  }
> +
> +static inline bool ipmr_rule_default(const struct fib_rule *rule)
> +{
> + return true;
> +}
>  #endif
>  
>  struct vif_device {
> diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
> index 2a795d2..a714f55 100644
> --- a/net/ipv4/ipmr.c
> +++ b/net/ipv4/ipmr.c
> @@ -320,6 +320,16 @@ static unsigned int ipmr_rules_seq_read(struct net *net)
>  }
>  #endif
>  
> +bool ipmr_rule_default(const struct fib_rule *rule)
> +{
> +#if IS_ENABLED(CONFIG_FIB_RULES)
> + return fib_rule_matchall(rule) && rule->table == RT_TABLE_DEFAULT;
> +#else
> + return true;
> +#endif

In patch 02, You have the following, can you do the same for the above?
+#ifdef CONFIG_IP_MROUTE
+void ipmr_cache_free(struct mfc_cache *mfc_cache);
+#else
+static inline void ipmr_cache_free(struct mfc_cache *mfc_cache)
+{
+}
+#endif

> +}
> +EXPORT_SYMBOL(ipmr_rule_default);
> +
>  static inline int ipmr_hash_cmp(struct rhashtable_compare_arg *arg,
>   const void *ptr)
>  {
> 



Re: [patch net-next v2 03/12] ipmr: Add FIB notification access functions

2017-09-24 Thread Yunsheng Lin
Hi, Jiri

On 2017/9/25 1:22, Jiri Pirko wrote:
> From: Yotam Gigi 
> 
> Make the ipmr module register as a FIB notifier. To do that, implement both
> the ipmr_seq_read and ipmr_dump ops.
> 
> The ipmr_seq_read op returns a sequence counter that is incremented on
> every notification related operation done by the ipmr. To implement that,
> add a sequence counter in the netns_ipv4 struct and increment it whenever a
> new MFC route or VIF are added or deleted. The sequence operations are
> protected by the RTNL lock.
> 
> The ipmr_dump iterates the list of MFC routes and the list of VIF entries
> and sends notifications about them. The entries dump is done under RCU
> where the VIF dump uses the mrt_lock too, as the vif->dev field can change
> under RCU.
> 
> Signed-off-by: Yotam Gigi 
> Reviewed-by: Ido Schimmel 
> Signed-off-by: Jiri Pirko 
> ---
> v1->v2:
>  - Take the mrt_lock when dumping VIF entries.
> ---
>  include/linux/mroute.h   |  15 ++
>  include/net/netns/ipv4.h |   3 ++
>  net/ipv4/ipmr.c  | 137 
> ++-
>  3 files changed, 153 insertions(+), 2 deletions(-)
> 
> diff --git a/include/linux/mroute.h b/include/linux/mroute.h
> index 10028f2..54c5cb8 100644
> --- a/include/linux/mroute.h
> +++ b/include/linux/mroute.h
> @@ -5,6 +5,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #ifdef CONFIG_IP_MROUTE
> @@ -58,6 +59,14 @@ struct vif_device {
>   int link;   /* Physical interface index 
> */
>  };
>  
> +struct vif_entry_notifier_info {
> + struct fib_notifier_info info;
> + struct net_device *dev;
> + vifi_t vif_index;
> + unsigned short vif_flags;
> + u32 tb_id;
> +};
> +
>  #define VIFF_STATIC 0x8000
>  
>  #define VIF_EXISTS(_mrt, _idx) ((_mrt)->vif_table[_idx].dev != NULL)
> @@ -146,6 +155,12 @@ struct mfc_cache {
>   struct rcu_head rcu;
>  };
>  
> +struct mfc_entry_notifier_info {
> + struct fib_notifier_info info;
> + struct mfc_cache *mfc;
> + u32 tb_id;
> +};
> +
>  struct rtmsg;
>  int ipmr_get_route(struct net *net, struct sk_buff *skb,
>  __be32 saddr, __be32 daddr,
> diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
> index 8387f09..abc84d9 100644
> --- a/include/net/netns/ipv4.h
> +++ b/include/net/netns/ipv4.h
> @@ -163,6 +163,9 @@ struct netns_ipv4 {
>   struct fib_notifier_ops *notifier_ops;
>   unsigned intfib_seq;/* protected by rtnl_mutex */
>  
> + struct fib_notifier_ops *ipmr_notifier_ops;

Can we add a const here?

> + unsigned intipmr_seq;   /* protected by rtnl_mutex */
> +
>   atomic_trt_genid;
>  };
>  #endif
> diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
> index 86dc5f9..49879c3 100644
> --- a/net/ipv4/ipmr.c
> +++ b/net/ipv4/ipmr.c
> @@ -264,6 +264,16 @@ static void __net_exit ipmr_rules_exit(struct net *net)
>   fib_rules_unregister(net->ipv4.mr_rules_ops);
>   rtnl_unlock();
>  }
> +
> +static int ipmr_rules_dump(struct net *net, struct notifier_block *nb)
> +{
> + return fib_rules_dump(net, nb, RTNL_FAMILY_IPMR);
> +}
> +
> +static unsigned int ipmr_rules_seq_read(struct net *net)
> +{
> + return fib_rules_seq_read(net, RTNL_FAMILY_IPMR);
> +}
>  #else
>  #define ipmr_for_each_table(mrt, net) \
>   for (mrt = net->ipv4.mrt; mrt; mrt = NULL)
> @@ -298,6 +308,16 @@ static void __net_exit ipmr_rules_exit(struct net *net)
>   net->ipv4.mrt = NULL;
>   rtnl_unlock();
>  }
> +
> +static int ipmr_rules_dump(struct net *net, struct notifier_block *nb)
> +{
> + return 0;
> +}
> +
> +static unsigned int ipmr_rules_seq_read(struct net *net)
> +{
> + return 0;
> +}
>  #endif
>  
>  static inline int ipmr_hash_cmp(struct rhashtable_compare_arg *arg,
> @@ -587,6 +607,43 @@ static struct net_device *ipmr_reg_vif(struct net *net, 
> struct mr_table *mrt)
>  }
>  #endif
>  
> +static int call_ipmr_vif_entry_notifier(struct notifier_block *nb,
> + struct net *net,
> + enum fib_event_type event_type,
> + struct vif_device *vif,
> + vifi_t vif_index, u32 tb_id)
> +{
> + struct vif_entry_notifier_info info = {
> + .info = {
> + .family = RTNL_FAMILY_IPMR,
> + .net = net,
> + },
> + .dev = vif->dev,
> + .vif_index = vif_index,
> + .vif_flags = vif->flags,
> + .tb_id = tb_id,
> + };

We only use info.info which is fib_notifier_info, the
vif_entry_notifier_info seems to be not needed, why not just
use fib_notifier_info?

> +
> + return call_fib_notifier(nb, net, event_type, );
> +}
> +
> +static int call_ipmr_mfc_entry_notifier(struct notifier_block *nb,
> + 

Re: [PATCH net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-24 Thread Yunsheng Lin
Hi, Jiri

On 2017/9/24 19:37, Jiri Pirko wrote:
> Sat, Sep 23, 2017 at 02:47:20AM CEST, linyunsh...@huawei.com wrote:
>> Hi, Jiri
>>
>> On 2017/9/23 0:03, Jiri Pirko wrote:
>>> Fri, Sep 22, 2017 at 04:11:51PM CEST, linyunsh...@huawei.com wrote:
 Hi, Jiri

>> - if (!tc) {
>> + if (if_running) {
>> + (void)hns3_nic_net_stop(netdev);
>> + msleep(100);
>> + }
>> +
>> + ret = (kinfo->dcb_ops && kinfo->dcb_ops->>setup_tc) ?
>> + kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : ->EOPNOTSUPP;

> This is most odd. Why do you call dcb_ops from >ndo_setup_tc callback?
> Why are you mixing this together? prio->tc mapping >can be done
> directly in dcbnl

 Here is what we do in dcb_ops->setup_tc:
 Firstly, if current tc num is different from the tc num
 that user provide, then we setup the queues for each
 tc.

 Secondly, we tell hardware the pri to tc mapping that
 the stack is using. In rx direction, our hardware need
 that mapping to put different packet into different tc'
 queues according to the priority of the packet, then
 rss decides which specific queue in the tc should the
 packet goto.

 By mixing, I suppose you meant why we need the
 pri to tc infomation?
>>>
>>> by mixing, I mean what I wrote. You are calling dcb_ops callback from
>>> ndo_setup_tc callback. So you are mixing DCBNL subsystem and TC
>>> subsystem. Why? Why do you need sch_mqprio? Why DCBNL is not enough for
>>> all?
>>
>> When using lldptool, dcbnl is involved.
>>
>> But when using tc qdisc, dcbbl is not involved, below is the a few key
>> call graph in the kernel when tc qdisc cmd is executed.
>>
>> cmd:
>> tc qdisc add dev eth0 root handle 1:0 mqprio num_tc 4 map 1 2 3 3 1 3 1 1 hw 
>> 1
>>
>> call graph:
>> rtnetlink_rcv_msg -> tc_modify_qdisc -> qdisc_create -> mqprio_init ->
>> hns3_nic_setup_tc
>>
>> When hns3_nic_setup_tc is called, we need to know how many tc num and
>> prio_tc mapping from the tc_mqprio_qopt which is provided in the paramter
>> in the ndo_setup_tc function, and dcb_ops is the our hardware specific
>> method to setup the tc related parameter to the hardware, so this is why
>> we call dcb_ops callback in ndo_setup_tc callback.
>>
>> I hope this will answer your question, thanks for your time.
> 
> Okay. I understand that you have a usecase for mqprio mapping offload
> without lldptool being involved. Ok. I believe it is wrong to call dcb_ops
> from tc callback. You should have a generic layer inside the driver and
> call it from both dcb_ops and tc callbacks.

Actually, dcb_ops is our generic layer inside the driver.
Below is high level architecture:

   [ tc qdisc ][ lldpad ]
 | |
 | |
 | |
   [ hns3_enet ][ hns3_dcbnl ]
 \/
\  /
   \/
 [ hclge_dcb ]
   /  \
/\
 /  \
 [ hclgc_main ][ hclge_tm ]

hns3_enet.c implements the ndo_setup_tc callback.
hns3_dcbnl.c implements the dcbnl_rtnl_ops for stack's DCBNL system.
hclge_dcb implements the dcb_ops.
So we already have a generic layer that tc and dcbnl all call from.

> 
> Also, what happens If I run lldptool concurrently with mqprio? Who wins
> and is going to configure the mapping?

Both lldptool and tc qdisc cmd use rtnl interface provided by stack, so
they are both protected by rtnl_lock, so we do not have to do the locking
in the driver.

The locking is in rtnetlink_rcv_msg:

rtnl_lock();
handlers = rtnl_dereference(rtnl_msg_handlers[family]);
if (handlers) {
doit = READ_ONCE(handlers[type].doit);
if (doit)
err = doit(skb, nlh, extack);
}
rtnl_unlock();

Thanks.

> 
> 
>>
>>>
>>>
>>>
 I hope I did not misunderstand your question, thanks
 for your time reviewing.
>>>
>>> .
>>>
>>
> 
> .
> 



Re: [PATCH net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-22 Thread Yunsheng Lin
Hi, Jiri

On 2017/9/23 0:03, Jiri Pirko wrote:
> Fri, Sep 22, 2017 at 04:11:51PM CEST, linyunsh...@huawei.com wrote:
>> Hi, Jiri
>>
 - if (!tc) {
 + if (if_running) {
 + (void)hns3_nic_net_stop(netdev);
 + msleep(100);
 + }
 +
 + ret = (kinfo->dcb_ops && kinfo->dcb_ops->>setup_tc) ?
 + kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : ->EOPNOTSUPP;
>>
>>> This is most odd. Why do you call dcb_ops from >ndo_setup_tc callback?
>>> Why are you mixing this together? prio->tc mapping >can be done
>>> directly in dcbnl
>>
>> Here is what we do in dcb_ops->setup_tc:
>> Firstly, if current tc num is different from the tc num
>> that user provide, then we setup the queues for each
>> tc.
>>
>> Secondly, we tell hardware the pri to tc mapping that
>> the stack is using. In rx direction, our hardware need
>> that mapping to put different packet into different tc'
>> queues according to the priority of the packet, then
>> rss decides which specific queue in the tc should the
>> packet goto.
>>
>> By mixing, I suppose you meant why we need the
>> pri to tc infomation?
> 
> by mixing, I mean what I wrote. You are calling dcb_ops callback from
> ndo_setup_tc callback. So you are mixing DCBNL subsystem and TC
> subsystem. Why? Why do you need sch_mqprio? Why DCBNL is not enough for
> all?

When using lldptool, dcbnl is involved.

But when using tc qdisc, dcbbl is not involved, below is the a few key
call graph in the kernel when tc qdisc cmd is executed.

cmd:
tc qdisc add dev eth0 root handle 1:0 mqprio num_tc 4 map 1 2 3 3 1 3 1 1 hw 1

call graph:
rtnetlink_rcv_msg -> tc_modify_qdisc -> qdisc_create -> mqprio_init ->
hns3_nic_setup_tc

When hns3_nic_setup_tc is called, we need to know how many tc num and
prio_tc mapping from the tc_mqprio_qopt which is provided in the paramter
in the ndo_setup_tc function, and dcb_ops is the our hardware specific
method to setup the tc related parameter to the hardware, so this is why
we call dcb_ops callback in ndo_setup_tc callback.

I hope this will answer your question, thanks for your time.

> 
> 
> 
>> I hope I did not misunderstand your question, thanks
>> for your time reviewing.
> 
> .
> 



Re: [PATCH net-next 01/10] net: hns3: Support for dynamically assigning tx buffer to TC

2017-09-21 Thread Yunsheng Lin
Hi, David

On 2017/9/22 9:41, David Miller wrote:
> From: Yunsheng Lin <linyunsh...@huawei.com>
> Date: Thu, 21 Sep 2017 19:21:44 +0800
> 
>> @@ -1324,23 +1324,28 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
>>  return 0;
>>  }
>>  
>> -static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev, u16 buf_size)
>> +static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
>>  {
>>  /* TX buffer size is unit by 128 byte */
>>  #define HCLGE_BUF_SIZE_UNIT_SHIFT   7
>>  #define HCLGE_BUF_SIZE_UPDATE_EN_MSKBIT(15)
>>  struct hclge_tx_buff_alloc *req;
>> +struct hclge_priv_buf *priv;
>>  struct hclge_desc desc;
>> +u32 buf_size;
>>  int ret;
>>  u8 i;
>>  
>>  req = (struct hclge_tx_buff_alloc *)desc.data;
>>  
>>  hclge_cmd_setup_basic_desc(, HCLGE_OPC_TX_BUFF_ALLOC, 0);
>> -for (i = 0; i < HCLGE_TC_NUM; i++)
>> +for (i = 0; i < HCLGE_TC_NUM; i++) {
>> +priv = >priv_buf[i];
>> +buf_size = priv->tx_buf_size;
>>  req->tx_pkt_buff[i] =
>>  cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |

buf_size is used here

>>   HCLGE_BUF_SIZE_UPDATE_EN_MSK);
>> +}
>>  
>>  ret = hclge_cmd_send(>hw, , 1);
>>  if (ret) {
> 
> Local variable 'buf_size' is assigned but never used in this function.
> And with 'buf_size' removed, 'priv' also becomes unused.

> 
> If it gets used in a later patch, add it in that later patch.
> 
> You can also declare the variables locally in the basic block of
> the for() loop.

You are right. Will do it if there is more comment coming, thanks for
reviewing .

> 
> .
> 



[PATCH net-next 00/10] Add support for DCB feature in hns3 driver

2017-09-21 Thread Yunsheng Lin
The patchset contains some enhancement related to DCB before
adding support for DCB feature.

This patchset depends on the following patchset:
https://patchwork.ozlabs.org/cover/815646/
https://patchwork.ozlabs.org/cover/816145/

High Level Architecture:

   [ tc qdisc ][ lldpad ]
 | |
 | |
 | |
   [ hns3_enet ][ hns3_dcbnl ]
 \/
\  /
   \/
 [ hclge_dcb ]
   /  \
/\
 /  \
 [ hclgc_main ][ hclge_tm ]

Current patch-set support following functionality:
1. Use of tc qdisc to configure the tc num and prio_tc_map.
2. Use of lldptool to configure the tc schedule mode, tc
   bandwidth(if schedule mode is ETS), prio_tc_map and
   PFC parameter.

Yunsheng Lin (10):
  net: hns3: Support for dynamically assigning tx buffer to TC
  net: hns3: Add support for dynamically buffer reallocation
  net: hns3: Add support for PFC setting in TM module
  net: hns3: Add support for port shaper setting in TM module
  net: hns3: Add tc-based TM support for sriov enabled port
  net: hns3: Add some interface for the support of DCB feature
  net: hns3: Add hclge_dcb module for the support of DCB feature
  net: hns3: Add dcb netlink interface for the support of DCB feature
  net: hns3: Setting for fc_mode and dcb enable flag in TM module
  net: hns3: Add mqprio support when interacting with network stack

 drivers/net/ethernet/hisilicon/Kconfig |   9 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  20 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   4 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   6 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 327 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h |  21 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 219 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   8 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 232 +--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  15 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c| 106 +++
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 137 +++--
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   7 +
 13 files changed, 983 insertions(+), 128 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c

-- 
1.9.1



[PATCH net-next 03/10] net: hns3: Add support for PFC setting in TM module

2017-09-21 Thread Yunsheng Lin
This patch add a pfc_pause_en cmd, and use it to configure
PFC option according to fc_mode in hdev->tm_info.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 68 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  5 ++
 2 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 73a75d7..0b4b5d9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -124,6 +124,20 @@ static int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, 
bool tx, bool rx)
return hclge_cmd_send(>hw, , 1);
 }
 
+static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
+ u8 pfc_bitmap)
+{
+   struct hclge_desc desc;
+   struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)
+
+   hclge_cmd_setup_basic_desc(, HCLGE_OPC_CFG_PFC_PAUSE_EN, false);
+
+   pfc->tx_rx_en_bitmap = tx_rx_bitmap;
+   pfc->pri_en_bitmap = pfc_bitmap;
+
+   return hclge_cmd_send(>hw, , 1);
+}
+
 static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
 {
u8 tc;
@@ -969,20 +983,64 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
return hclge_tm_schd_mode_hw(hdev);
 }
 
+static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
+{
+   u8 enable_bitmap = 0;
+
+   if (hdev->tm_info.fc_mode == HCLGE_FC_PFC)
+   enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK |
+   HCLGE_RX_MAC_PAUSE_EN_MSK;
+
+   return hclge_pfc_pause_en_cfg(hdev, enable_bitmap,
+ hdev->tm_info.hw_pfc_map);
+}
+
+static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
+{
+   bool tx_en, rx_en;
+
+   switch (hdev->tm_info.fc_mode) {
+   case HCLGE_FC_NONE:
+   tx_en = false;
+   rx_en = false;
+   break;
+   case HCLGE_FC_RX_PAUSE:
+   tx_en = false;
+   rx_en = true;
+   break;
+   case HCLGE_FC_TX_PAUSE:
+   tx_en = true;
+   rx_en = false;
+   break;
+   case HCLGE_FC_FULL:
+   tx_en = true;
+   rx_en = true;
+   break;
+   default:
+   tx_en = true;
+   rx_en = true;
+   }
+
+   return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en);
+}
+
 int hclge_pause_setup_hw(struct hclge_dev *hdev)
 {
-   bool en = hdev->tm_info.fc_mode != HCLGE_FC_PFC;
int ret;
u8 i;
 
-   ret = hclge_mac_pause_en_cfg(hdev, en, en);
-   if (ret)
-   return ret;
+   if (hdev->tm_info.fc_mode != HCLGE_FC_PFC)
+   return hclge_mac_pause_setup_hw(hdev);
 
-   /* Only DCB-supported dev supports qset back pressure setting */
+   /* Only DCB-supported dev supports qset back pressure and pfc cmd */
if (!hnae3_dev_dcb_supported(hdev))
return 0;
 
+   /* When MAC is GE Mode, hdev does not support pfc setting */
+   ret = hclge_pfc_setup_hw(hdev);
+   if (ret)
+   dev_warn(>pdev->dev, "set pfc pause failed:%d\n", ret);
+
for (i = 0; i < hdev->tm_info.num_tc; i++) {
ret = hclge_tm_qs_bp_cfg(hdev, i);
if (ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 85158b0..8ecd83c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -94,6 +94,11 @@ struct hclge_bp_to_qs_map_cmd {
u32 rsvd1;
 };
 
+struct hclge_pfc_en_cmd {
+   u8 tx_rx_en_bitmap;
+   u8 pri_en_bitmap;
+};
+
 #define hclge_tm_set_field(dest, string, val) \
hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH), val)
-- 
1.9.1



[PATCH net-next 02/10] net: hns3: Add support for dynamically buffer reallocation

2017-09-21 Thread Yunsheng Lin
Current buffer allocation can only happen at init, when
doing buffer reallocation after init, care must be taken
care of memory which priv_buf points to.
This patch fixes it by using a dynamic allocated temporary
memory. Because we only do buffer reallocation at init or
when setting up the DCB parameter, and priv_buf is only
used at buffer allocation process, so it is ok to use a
dynamic allocated temporary memory.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   5 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 150 +++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   2 -
 3 files changed, 87 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index a81c6cb..6b6d28e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -322,6 +322,11 @@ struct hclge_shared_buf {
u32 buf_size;
 };
 
+struct hclge_pkt_buf_alloc {
+   struct hclge_priv_buf priv_buf[HCLGE_MAX_TC_NUM];
+   struct hclge_shared_buf s_buf;
+};
+
 #define HCLGE_RX_COM_WL_EN_B   15
 struct hclge_rx_com_wl_buf {
__le16 high_wl;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index dfe0fd2..c27b460 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1324,7 +1324,8 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
return 0;
 }
 
-static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
+static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev,
+   struct hclge_pkt_buf_alloc *buf_alloc)
 {
 /* TX buffer size is unit by 128 byte */
 #define HCLGE_BUF_SIZE_UNIT_SHIFT  7
@@ -1340,7 +1341,7 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev)
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TX_BUFF_ALLOC, 0);
for (i = 0; i < HCLGE_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
buf_size = priv->tx_buf_size;
req->tx_pkt_buff[i] =
cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |
@@ -1357,9 +1358,10 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev)
return 0;
 }
 
-static int hclge_tx_buffer_alloc(struct hclge_dev *hdev)
+static int hclge_tx_buffer_alloc(struct hclge_dev *hdev,
+struct hclge_pkt_buf_alloc *buf_alloc)
 {
-   int ret = hclge_cmd_alloc_tx_buff(hdev);
+   int ret = hclge_cmd_alloc_tx_buff(hdev, buf_alloc);
 
if (ret) {
dev_err(>pdev->dev,
@@ -1392,13 +1394,14 @@ static int hclge_get_pfc_enalbe_num(struct hclge_dev 
*hdev)
 }
 
 /* Get the number of pfc enabled TCs, which have private buffer */
-static int hclge_get_pfc_priv_num(struct hclge_dev *hdev)
+static int hclge_get_pfc_priv_num(struct hclge_dev *hdev,
+ struct hclge_pkt_buf_alloc *buf_alloc)
 {
struct hclge_priv_buf *priv;
int i, cnt = 0;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if ((hdev->tm_info.hw_pfc_map & BIT(i)) &&
priv->enable)
cnt++;
@@ -1408,13 +1411,14 @@ static int hclge_get_pfc_priv_num(struct hclge_dev 
*hdev)
 }
 
 /* Get the number of pfc disabled TCs, which have private buffer */
-static int hclge_get_no_pfc_priv_num(struct hclge_dev *hdev)
+static int hclge_get_no_pfc_priv_num(struct hclge_dev *hdev,
+struct hclge_pkt_buf_alloc *buf_alloc)
 {
struct hclge_priv_buf *priv;
int i, cnt = 0;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if (hdev->hw_tc_map & BIT(i) &&
!(hdev->tm_info.hw_pfc_map & BIT(i)) &&
priv->enable)
@@ -1424,33 +1428,35 @@ static int hclge_get_no_pfc_priv_num(struct hclge_dev 
*hdev)
return cnt;
 }
 
-static u32 hclge_get_rx_priv_buff_alloced(struct hclge_dev *hdev)
+static u32 hclge_get_rx_priv_buff_alloced(struct hclge_pkt_buf_alloc 
*buf_alloc)
 {
struct hclge_priv_buf *priv;
u32 rx_priv = 0;
int i;
 
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   priv = >priv_buf[i];
+   priv = _alloc->priv_buf[i];
if (priv->enable)
rx_priv += priv->buf_size;
}
return rx_priv;
 }
 
-static u32 hclge_get_tx_buff_alloced(s

[PATCH net-next 01/10] net: hns3: Support for dynamically assigning tx buffer to TC

2017-09-21 Thread Yunsheng Lin
This patch add support of dynamically assigning tx buffer to
TC when the TC is enabled.
It will save buffer for rx direction to avoid packet loss.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |  1 +
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 69 ++
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 758cf39..a81c6cb 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -311,6 +311,7 @@ struct hclge_tc_thrd {
 struct hclge_priv_buf {
struct hclge_waterline wl;  /* Waterline for low and high*/
u32 buf_size;   /* TC private buffer size */
+   u32 tx_buf_size;
u32 enable; /* Enable TC private buffer or not */
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index d27618b..dfe0fd2 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1324,23 +1324,28 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
return 0;
 }
 
-static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev, u16 buf_size)
+static int  hclge_cmd_alloc_tx_buff(struct hclge_dev *hdev)
 {
 /* TX buffer size is unit by 128 byte */
 #define HCLGE_BUF_SIZE_UNIT_SHIFT  7
 #define HCLGE_BUF_SIZE_UPDATE_EN_MSK   BIT(15)
struct hclge_tx_buff_alloc *req;
+   struct hclge_priv_buf *priv;
struct hclge_desc desc;
+   u32 buf_size;
int ret;
u8 i;
 
req = (struct hclge_tx_buff_alloc *)desc.data;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TX_BUFF_ALLOC, 0);
-   for (i = 0; i < HCLGE_TC_NUM; i++)
+   for (i = 0; i < HCLGE_TC_NUM; i++) {
+   priv = >priv_buf[i];
+   buf_size = priv->tx_buf_size;
req->tx_pkt_buff[i] =
cpu_to_le16((buf_size >> HCLGE_BUF_SIZE_UNIT_SHIFT) |
 HCLGE_BUF_SIZE_UPDATE_EN_MSK);
+   }
 
ret = hclge_cmd_send(>hw, , 1);
if (ret) {
@@ -1352,9 +1357,9 @@ static int  hclge_cmd_alloc_tx_buff(struct hclge_dev 
*hdev, u16 buf_size)
return 0;
 }
 
-static int hclge_tx_buffer_alloc(struct hclge_dev *hdev, u32 buf_size)
+static int hclge_tx_buffer_alloc(struct hclge_dev *hdev)
 {
-   int ret = hclge_cmd_alloc_tx_buff(hdev, buf_size);
+   int ret = hclge_cmd_alloc_tx_buff(hdev);
 
if (ret) {
dev_err(>pdev->dev,
@@ -1433,6 +1438,18 @@ static u32 hclge_get_rx_priv_buff_alloced(struct 
hclge_dev *hdev)
return rx_priv;
 }
 
+static u32 hclge_get_tx_buff_alloced(struct hclge_dev *hdev)
+{
+   struct hclge_priv_buf *priv;
+   u32 tx_buf = 0, i;
+
+   for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+   priv = >priv_buf[i];
+   tx_buf += priv->tx_buf_size;
+   }
+   return tx_buf;
+}
+
 static bool  hclge_is_rx_buf_ok(struct hclge_dev *hdev, u32 rx_all)
 {
u32 shared_buf_min, shared_buf_tc, shared_std;
@@ -1477,18 +1494,44 @@ static bool  hclge_is_rx_buf_ok(struct hclge_dev *hdev, 
u32 rx_all)
return true;
 }
 
+static int hclge_tx_buffer_calc(struct hclge_dev *hdev)
+{
+   struct hclge_priv_buf *priv;
+   u32 i, total_size;
+
+   total_size = hdev->pkt_buf_size;
+
+   /* alloc tx buffer for all enabled tc */
+   for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+   priv = >priv_buf[i];
+
+   if (total_size < HCLGE_DEFAULT_TX_BUF)
+   return -ENOMEM;
+
+   if (hdev->hw_tc_map & BIT(i))
+   priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
+   else
+   priv->tx_buf_size = 0;
+
+   total_size -= priv->tx_buf_size;
+   }
+
+   return 0;
+}
+
 /* hclge_rx_buffer_calc: calculate the rx private buffer size for all TCs
  * @hdev: pointer to struct hclge_dev
- * @tx_size: the allocated tx buffer for all TCs
  * @return: 0: calculate sucessful, negative: fail
  */
-int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 tx_size)
+int hclge_rx_buffer_calc(struct hclge_dev *hdev)
 {
-   u32 rx_all = hdev->pkt_buf_size - tx_size;
+   u32 rx_all = hdev->pkt_buf_size;
int no_pfc_priv_num, pfc_priv_num;
struct hclge_priv_buf *priv;
int i;
 
+   rx_all -= hclge_get_tx_buff_alloced(hdev);
+
/* When DCB is not supported, rx private
 * buffer is not allocated.
 */
@@ -1771,7 +1814,6 @@ static int hclge_common_wl_config(struct hclge_dev *hdev)
 
 int hclge_buffer_alloc(struct hclge_dev *hdev)
 {
-   u3

[PATCH net-next 06/10] net: hns3: Add some interface for the support of DCB feature

2017-09-21 Thread Yunsheng Lin
This patch add some interface and export some interface from
hclge_tm and hclgc_main to support the upcoming DCB feature.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  3 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  3 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 48 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  6 +++
 4 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index c27b460..49a11d5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -30,7 +30,6 @@
 #define HCLGE_64BIT_STATS_FIELD_OFF(f) (offsetof(struct hclge_64_bit_stats, f))
 #define HCLGE_32BIT_STATS_FIELD_OFF(f) (offsetof(struct hclge_32_bit_stats, f))
 
-static int hclge_rss_init_hw(struct hclge_dev *hdev);
 static int hclge_set_mta_filter_mode(struct hclge_dev *hdev,
 enum hclge_mta_dmac_sel_type mta_mac_sel,
 bool enable);
@@ -2660,7 +2659,7 @@ static int hclge_get_tc_size(struct hnae3_handle *handle)
return hdev->rss_size_max;
 }
 
-static int hclge_rss_init_hw(struct hclge_dev *hdev)
+int hclge_rss_init_hw(struct hclge_dev *hdev)
 {
const  u8 hfunc = HCLGE_RSS_HASH_ALGO_TOEPLITZ;
struct hclge_vport *vport = hdev->vport;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 4fc36f0..394b587 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -515,4 +515,7 @@ static inline int hclge_get_queue_id(struct hnae3_queue 
*queue)
 int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex);
 int hclge_set_vf_vlan_common(struct hclge_dev *vport, int vfid,
 bool is_kill, u16 vlan, u8 qos, __be16 proto);
+
+int hclge_buffer_alloc(struct hclge_dev *hdev);
+int hclge_rss_init_hw(struct hclge_dev *hdev);
 #endif
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 2bc7d63c..e158e66 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -884,10 +884,14 @@ static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev)
return 0;
 }
 
-static int hclge_tm_map_cfg(struct hclge_dev *hdev)
+int hclge_tm_map_cfg(struct hclge_dev *hdev)
 {
int ret;
 
+   ret = hclge_up_to_tc_map(hdev);
+   if (ret)
+   return ret;
+
ret = hclge_tm_pg_to_pri_map(hdev);
if (ret)
return ret;
@@ -995,7 +999,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
return 0;
 }
 
-static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
+int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
 {
int ret;
 
@@ -1093,7 +1097,45 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev)
return ret;
}
 
-   return hclge_up_to_tc_map(hdev);
+   return 0;
+}
+
+int hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc)
+{
+   struct hclge_vport *vport = hdev->vport;
+   struct hnae3_knic_private_info *kinfo;
+   u32 i, k;
+
+   for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
+   if (prio_tc[i] >= hdev->tm_info.num_tc)
+   return -EINVAL;
+   hdev->tm_info.prio_tc[i] = prio_tc[i];
+
+   for (k = 0;  k < hdev->num_alloc_vport; k++) {
+   kinfo = [k].nic.kinfo;
+   kinfo->prio_tc[i] = prio_tc[i];
+   }
+   }
+   return 0;
+}
+
+void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc)
+{
+   u8 i, bit_map = 0;
+
+   hdev->tm_info.num_tc = num_tc;
+
+   for (i = 0; i < hdev->tm_info.num_tc; i++)
+   bit_map |= BIT(i);
+
+   if (!bit_map) {
+   bit_map = 1;
+   hdev->tm_info.num_tc = 1;
+   }
+
+   hdev->hw_tc_map = bit_map;
+
+   hclge_tm_schd_info_init(hdev);
 }
 
 int hclge_tm_init_hw(struct hclge_dev *hdev)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 19a01e4..bf59961 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -112,4 +112,10 @@ struct hclge_port_shapping_cmd {
 
 int hclge_tm_schd_init(struct hclge_dev *hdev);
 int hclge_pause_setup_hw(struct hclge_dev *hdev);
+int hclge_tm_schd_mode_hw(struct hclge_dev *hdev);
+int hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc

[PATCH net-next 07/10] net: hns3: Add hclge_dcb module for the support of DCB feature

2017-09-21 Thread Yunsheng Lin
The hclge_dcb module calls the interface from hclge_main/tm
and provide interface for the dcb netlink interface.

This patch also update Makefiles required to build the DCB
supported code in HNS3 Ethernet driver and update the existing
Kconfig file in the hisilicon folder.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/Kconfig |   9 +
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  20 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 327 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h |  21 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c|  25 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   3 +
 7 files changed, 401 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.h

diff --git a/drivers/net/ethernet/hisilicon/Kconfig 
b/drivers/net/ethernet/hisilicon/Kconfig
index 91c7bdb..9d7cb03 100644
--- a/drivers/net/ethernet/hisilicon/Kconfig
+++ b/drivers/net/ethernet/hisilicon/Kconfig
@@ -103,4 +103,13 @@ config HNS3_ENET
  family of SoCs. This module depends upon HNAE3 driver to access the 
HNAE3
  devices and their associated operations.
 
+config HNS3_DCB
+   bool "Hisilicon HNS3 Data Center Bridge Support"
+   default n
+   depends on HNS3 && HNS3_HCLGE && DCB
+   ---help---
+ Say Y here if you want to use Data Center Bridging (DCB) in the HNS3 
driver.
+
+ If unsure, say N.
+
 endif # NET_VENDOR_HISILICON
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 1a01cad..5a6fa53 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -28,6 +28,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -131,6 +132,7 @@ struct hnae3_client_ops {
int (*init_instance)(struct hnae3_handle *handle);
void (*uninit_instance)(struct hnae3_handle *handle, bool reset);
void (*link_status_change)(struct hnae3_handle *handle, bool state);
+   int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
 };
 
 #define HNAE3_CLIENT_NAME_LENGTH 16
@@ -363,6 +365,23 @@ struct hnae3_ae_ops {
  u16 vlan, u8 qos, __be16 proto);
 };
 
+struct hnae3_dcb_ops {
+   /* IEEE 802.1Qaz std */
+   int (*ieee_getets)(struct hnae3_handle *, struct ieee_ets *);
+   int (*ieee_setets)(struct hnae3_handle *, struct ieee_ets *);
+   int (*ieee_getpfc)(struct hnae3_handle *, struct ieee_pfc *);
+   int (*ieee_setpfc)(struct hnae3_handle *, struct ieee_pfc *);
+
+   /* DCBX configuration */
+   u8   (*getdcbx)(struct hnae3_handle *);
+   u8   (*setdcbx)(struct hnae3_handle *, u8);
+
+   /* TC setup */
+   int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
+
+   int (*map_update)(struct hnae3_handle *);
+};
+
 struct hnae3_ae_algo {
const struct hnae3_ae_ops *ops;
struct list_head node;
@@ -394,6 +413,7 @@ struct hnae3_knic_private_info {
 
u16 num_tqps; /* total number of TQPs in this handle */
struct hnae3_queue **tqp;  /* array base of all TQPs in this instance */
+   const struct hnae3_dcb_ops *dcb_ops;
 };
 
 struct hnae3_roce_private_info {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
index 162e8a42..7023dc87 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
@@ -7,5 +7,7 @@ ccflags-y := -Idrivers/net/ethernet/hisilicon/hns3
 obj-$(CONFIG_HNS3_HCLGE) += hclge.o
 hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o
 
+hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o
+
 obj-$(CONFIG_HNS3_ENET) += hns3.o
 hns3-objs = hns3_enet.o hns3_ethtool.o
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
new file mode 100644
index 000..178333b
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "hclge_main.h"
+#include "hclge_tm.h"
+#include "hnae3.h"
+
+#define BW_PERCENT 100
+
+static int hclge_ieee_ets_to_tm_info(struct hclge_dev *hdev,
+struct ieee_ets *ets)
+{
+   u8 i;
+
+   for (i = 0; i < HNAE3_MAX_TC; i++) {
+   switc

[PATCH net-next 04/10] net: hns3: Add support for port shaper setting in TM module

2017-09-21 Thread Yunsheng Lin
This patch add a tm_port_shaper cmd and set port shaper
to HCLGE_ETHER_MAX_RATE on TM initialization process.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 33 ++
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |  4 +++
 2 files changed, 37 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 0b4b5d9..33090d0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -301,6 +301,35 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
return hclge_cmd_send(>hw, , 1);
 }
 
+static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev)
+{
+   struct hclge_port_shapping_cmd *shap_cfg_cmd;
+   struct hclge_desc desc;
+   u8 ir_u, ir_b, ir_s;
+   int ret;
+
+   ret = hclge_shaper_para_calc(HCLGE_ETHER_MAX_RATE,
+HCLGE_SHAPER_LVL_PORT,
+_b, _u, _s);
+   if (ret)
+   return ret;
+
+   hclge_cmd_setup_basic_desc(, HCLGE_OPC_TM_PORT_SHAPPING, false);
+   shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
+
+   hclge_tm_set_field(shap_cfg_cmd->port_shapping_para, IR_B, ir_b);
+   hclge_tm_set_field(shap_cfg_cmd->port_shapping_para, IR_U, ir_u);
+   hclge_tm_set_field(shap_cfg_cmd->port_shapping_para, IR_S, ir_s);
+   hclge_tm_set_field(shap_cfg_cmd->port_shapping_para,
+  BS_B, HCLGE_SHAPER_BS_U_DEF);
+   hclge_tm_set_field(shap_cfg_cmd->port_shapping_para,
+  BS_S, HCLGE_SHAPER_BS_S_DEF);
+   shap_cfg_cmd->port_shapping_para =
+   cpu_to_le32(shap_cfg_cmd->port_shapping_para);
+
+   return hclge_cmd_send(>hw, , 1);
+}
+
 static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev,
 enum hclge_shap_bucket bucket, u8 pri_id,
 u8 ir_b, u8 ir_u, u8 ir_s,
@@ -864,6 +893,10 @@ static int hclge_tm_shaper_cfg(struct hclge_dev *hdev)
 {
int ret;
 
+   ret = hclge_tm_port_shaper_cfg(hdev);
+   if (ret)
+   return ret;
+
ret = hclge_tm_pg_shaper_cfg(hdev);
if (ret)
return ret;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 8ecd83c..19a01e4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -99,6 +99,10 @@ struct hclge_pfc_en_cmd {
u8 pri_en_bitmap;
 };
 
+struct hclge_port_shapping_cmd {
+   __le32 port_shapping_para;
+};
+
 #define hclge_tm_set_field(dest, string, val) \
hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH), val)
-- 
1.9.1



[PATCH net-next 05/10] net: hns3: Add tc-based TM support for sriov enabled port

2017-09-21 Thread Yunsheng Lin
When sriov is enabled and TM is in tc-based mode, vf's TM
parameters is not set in TM initialization process.
This patch add the tc_based TM support for sriov enabled
using the information in vport struct.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 49 ++
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 33090d0..2bc7d63c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -389,13 +389,13 @@ static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev 
*hdev, u8 pri_id)
return hclge_cmd_send(>hw, , 1);
 }
 
-static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id)
+static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 
mode)
 {
struct hclge_desc desc;
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false);
 
-   if (hdev->tm_info.tc_info[qs_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR)
+   if (mode == HCLGE_SCH_MODE_DWRR)
desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
else
desc.data[1] = 0;
@@ -639,17 +639,18 @@ static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev)
 {
struct hclge_vport *vport = hdev->vport;
int ret;
-   u32 i;
+   u32 i, k;
 
if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
/* Cfg qs -> pri mapping, one by one mapping */
-   for (i = 0; i < hdev->tm_info.num_tc; i++) {
-   ret = hclge_tm_qs_to_pri_map_cfg(hdev, i, i);
-   if (ret)
-   return ret;
-   }
+   for (k = 0; k < hdev->num_alloc_vport; k++)
+   for (i = 0; i < hdev->tm_info.num_tc; i++) {
+   ret = hclge_tm_qs_to_pri_map_cfg(
+   hdev, vport[k].qs_offset + i, i);
+   if (ret)
+   return ret;
+   }
} else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) {
-   int k;
/* Cfg qs -> pri mapping,  qs = tc, pri = vf, 8 qs -> 1 pri */
for (k = 0; k < hdev->num_alloc_vport; k++)
for (i = 0; i < HNAE3_MAX_TC; i++) {
@@ -798,10 +799,11 @@ static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev)
 
 static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
 {
+   struct hclge_vport *vport = hdev->vport;
struct hclge_pg_info *pg_info;
u8 dwrr;
int ret;
-   u32 i;
+   u32 i, k;
 
for (i = 0; i < hdev->tm_info.num_tc; i++) {
pg_info =
@@ -812,9 +814,13 @@ static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev 
*hdev)
if (ret)
return ret;
 
-   ret = hclge_tm_qs_weight_cfg(hdev, i, dwrr);
-   if (ret)
-   return ret;
+   for (k = 0; k < hdev->num_alloc_vport; k++) {
+   ret = hclge_tm_qs_weight_cfg(
+   hdev, vport[k].qs_offset + i,
+   vport[k].dwrr);
+   if (ret)
+   return ret;
+   }
}
 
return 0;
@@ -945,7 +951,10 @@ static int hclge_tm_schd_mode_vnet_base_cfg(struct 
hclge_vport *vport)
return ret;
 
for (i = 0; i < kinfo->num_tc; i++) {
-   ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i);
+   u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode;
+
+   ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i,
+   sch_mode);
if (ret)
return ret;
}
@@ -957,7 +966,7 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
 {
struct hclge_vport *vport = hdev->vport;
int ret;
-   u8 i;
+   u8 i, k;
 
if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
for (i = 0; i < hdev->tm_info.num_tc; i++) {
@@ -965,9 +974,13 @@ static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev 
*hdev)
if (ret)
return ret;
 
-   ret = hclge_tm_qs_schd_mode_cfg(hdev, i);
-   if (ret)
-   return ret;
+   for (k = 0; k < hdev->num_alloc_vport; k++) {
+   ret = hclge_tm_qs_schd_mode_cfg(
+   

[PATCH net-next 09/10] net: hns3: Setting for fc_mode and dcb enable flag in TM module

2017-09-21 Thread Yunsheng Lin
After the DCB feature is supported, fc_mode and dcb enable flag
must be set according to the DCB parameter.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  | 34 +++---
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index e158e66..cc5efda 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -487,7 +487,11 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
hdev->tm_info.prio_tc[i] =
(i >= hdev->tm_info.num_tc) ? 0 : i;
 
-   hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
+   /* DCB is enabled if we have more than 1 TC */
+   if (hdev->tm_info.num_tc > 1)
+   hdev->flag |= HCLGE_FLAG_DCB_ENABLE;
+   else
+   hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
 }
 
 static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
@@ -513,6 +517,24 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
}
 }
 
+static void hclge_pfc_info_init(struct hclge_dev *hdev)
+{
+   if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) {
+   if (hdev->fc_mode_last_time == HCLGE_FC_PFC)
+   dev_warn(>pdev->dev,
+"DCB is disable, but last mode is FC_PFC\n");
+
+   hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
+   } else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
+   /* fc_mode_last_time record the last fc_mode when
+* DCB is enabled, so that fc_mode can be set to
+* the correct value when DCB is disabled.
+*/
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hdev->tm_info.fc_mode = HCLGE_FC_PFC;
+   }
+}
+
 static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
 {
if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
@@ -525,8 +547,7 @@ static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
 
hclge_tm_vport_info_update(hdev);
 
-   hdev->tm_info.fc_mode = HCLGE_FC_NONE;
-   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
+   hclge_pfc_info_init(hdev);
 
return 0;
 }
@@ -1159,8 +1180,13 @@ int hclge_tm_init_hw(struct hclge_dev *hdev)
 
 int hclge_tm_schd_init(struct hclge_dev *hdev)
 {
-   int ret = hclge_tm_schd_info_init(hdev);
+   int ret;
+
+   /* fc_mode is HCLGE_FC_FULL on reset */
+   hdev->tm_info.fc_mode = HCLGE_FC_FULL;
+   hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
 
+   ret = hclge_tm_schd_info_init(hdev);
if (ret)
return ret;
 
-- 
1.9.1



[PATCH net-next 10/10] net: hns3: Add mqprio support when interacting with network stack

2017-09-21 Thread Yunsheng Lin
When using tc qdisc to configure DCB parameter, dcb_ops->setup_tc
is used to tell hclge_dcb module to do the setup.
When using lldptool to configure DCB parameter, hclge_dcb module
call the client_ops->setup_tc to tell network stack which queue
and priority is using for specific tc.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 135 +
 1 file changed, 111 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 11dab26..31fcda4 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -196,6 +196,32 @@ static void hns3_vector_gl_rl_init(struct 
hns3_enet_tqp_vector *tqp_vector)
tqp_vector->tx_group.flow_level = HNS3_FLOW_LOW;
 }
 
+static int hns3_nic_set_real_num_queue(struct net_device *netdev)
+{
+   struct hns3_nic_priv *priv = netdev_priv(netdev);
+   struct hnae3_handle *h = priv->ae_handle;
+   struct hnae3_knic_private_info *kinfo = >kinfo;
+   unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
+   int ret;
+
+   ret = netif_set_real_num_tx_queues(netdev, queue_size);
+   if (ret) {
+   netdev_err(netdev,
+  "netif_set_real_num_tx_queues fail, ret=%d!\n",
+  ret);
+   return ret;
+   }
+
+   ret = netif_set_real_num_rx_queues(netdev, queue_size);
+   if (ret) {
+   netdev_err(netdev,
+  "netif_set_real_num_rx_queues fail, ret=%d!\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+
 static int hns3_nic_net_up(struct net_device *netdev)
 {
struct hns3_nic_priv *priv = netdev_priv(netdev);
@@ -232,26 +258,13 @@ static int hns3_nic_net_up(struct net_device *netdev)
 
 static int hns3_nic_net_open(struct net_device *netdev)
 {
-   struct hns3_nic_priv *priv = netdev_priv(netdev);
-   struct hnae3_handle *h = priv->ae_handle;
int ret;
 
netif_carrier_off(netdev);
 
-   ret = netif_set_real_num_tx_queues(netdev, h->kinfo.num_tqps);
-   if (ret) {
-   netdev_err(netdev,
-  "netif_set_real_num_tx_queues fail, ret=%d!\n",
-  ret);
-   return ret;
-   }
-
-   ret = netif_set_real_num_rx_queues(netdev, h->kinfo.num_tqps);
-   if (ret) {
-   netdev_err(netdev,
-  "netif_set_real_num_rx_queues fail, ret=%d!\n", ret);
+   ret = hns3_nic_set_real_num_queue(netdev);
+   if (ret)
return ret;
-   }
 
ret = hns3_nic_net_up(netdev);
if (ret) {
@@ -1193,32 +1206,40 @@ static void hns3_nic_udp_tunnel_del(struct net_device 
*netdev,
}
 }
 
-static int hns3_setup_tc(struct net_device *netdev, u8 tc)
+static int hns3_setup_tc(struct net_device *netdev, u8 tc, u8 *prio_tc)
 {
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
struct hnae3_knic_private_info *kinfo = >kinfo;
+   bool if_running = netif_running(netdev);
unsigned int i;
int ret;
 
if (tc > HNAE3_MAX_TC)
return -EINVAL;
 
-   if (kinfo->num_tc == tc)
-   return 0;
-
if (!netdev)
return -EINVAL;
 
-   if (!tc) {
+   if (if_running) {
+   (void)hns3_nic_net_stop(netdev);
+   msleep(100);
+   }
+
+   ret = (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
+   kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP;
+   if (ret)
+   goto err_out;
+
+   if (tc <= 1) {
netdev_reset_tc(netdev);
-   return 0;
+   goto out;
}
 
/* Set num_tc for netdev */
ret = netdev_set_num_tc(netdev, tc);
if (ret)
-   return ret;
+   goto err_out;
 
/* Set per TC queues for the VSI */
for (i = 0; i < HNAE3_MAX_TC; i++) {
@@ -1229,7 +1250,14 @@ static int hns3_setup_tc(struct net_device *netdev, u8 
tc)
kinfo->tc_info[i].tqp_offset);
}
 
-   return 0;
+out:
+   ret = hns3_nic_set_real_num_queue(netdev);
+
+err_out:
+   if (if_running)
+   (void)hns3_nic_net_open(netdev);
+
+   return ret;
 }
 
 static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
@@ -1240,7 +1268,7 @@ static int hns3_nic_setup_tc(struct net_device *dev, enum 
tc_setup_type type,
if (type != TC_SETUP_MQPRIO)
return -EOPNOTSUPP;
 
-   return hns3_setup_tc(dev, mqprio->num_tc);
+   retu

[PATCH net-next 08/10] net: hns3: Add dcb netlink interface for the support of DCB feature

2017-09-21 Thread Yunsheng Lin
This patch add dcb netlink interface by calling the interface from
hclge_dcb module.

This patch also update Makefile in order to build hns3_dcbnl module.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/Makefile|   2 +
 .../ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c| 106 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c |   2 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h |   7 ++
 4 files changed, 117 insertions(+)
 create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
index 7023dc87..d2b20d0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile
@@ -11,3 +11,5 @@ hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o
 
 obj-$(CONFIG_HNS3_ENET) += hns3.o
 hns3-objs = hns3_enet.o hns3_ethtool.o
+
+hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
new file mode 100644
index 000..9832172
--- /dev/null
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include "hnae3.h"
+#include "hns3_enet.h"
+
+static
+int hns3_dcbnl_ieee_getets(struct net_device *ndev, struct ieee_ets *ets)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_getets)
+   return h->kinfo.dcb_ops->ieee_getets(h, ets);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_setets(struct net_device *ndev, struct ieee_ets *ets)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_setets)
+   return h->kinfo.dcb_ops->ieee_setets(h, ets);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_getpfc(struct net_device *ndev, struct ieee_pfc *pfc)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_getpfc)
+   return h->kinfo.dcb_ops->ieee_getpfc(h, pfc);
+
+   return -EOPNOTSUPP;
+}
+
+static
+int hns3_dcbnl_ieee_setpfc(struct net_device *ndev, struct ieee_pfc *pfc)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->ieee_setpfc)
+   return h->kinfo.dcb_ops->ieee_setpfc(h, pfc);
+
+   return -EOPNOTSUPP;
+}
+
+/* DCBX configuration */
+static u8 hns3_dcbnl_getdcbx(struct net_device *ndev)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->getdcbx)
+   return h->kinfo.dcb_ops->getdcbx(h);
+
+   return 0;
+}
+
+/* return 0 if successful, otherwise fail */
+static u8 hns3_dcbnl_setdcbx(struct net_device *ndev, u8 mode)
+{
+   struct hns3_nic_priv *priv = netdev_priv(ndev);
+   struct hnae3_handle *h = priv->ae_handle;
+
+   if (h->kinfo.dcb_ops->setdcbx)
+   return h->kinfo.dcb_ops->setdcbx(h, mode);
+
+   return 1;
+}
+
+static const struct dcbnl_rtnl_ops hns3_dcbnl_ops = {
+   .ieee_getets= hns3_dcbnl_ieee_getets,
+   .ieee_setets= hns3_dcbnl_ieee_setets,
+   .ieee_getpfc= hns3_dcbnl_ieee_getpfc,
+   .ieee_setpfc= hns3_dcbnl_ieee_setpfc,
+   .getdcbx= hns3_dcbnl_getdcbx,
+   .setdcbx= hns3_dcbnl_setdcbx,
+};
+
+/* hclge_dcbnl_setup - DCBNL setup
+ * @handle: the corresponding vport handle
+ * Set up DCBNL
+ */
+void hns3_dcbnl_setup(struct hnae3_handle *handle)
+{
+   struct net_device *dev = handle->kinfo.netdev;
+
+   if (!handle->kinfo.dcb_ops)
+   return;
+
+   dev->dcbnl_ops = _dcbnl_ops;
+}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 35369e1..11dab26 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -2790,6 +2790,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_reg_netdev_fail;
}
 
+   hns3_dcbnl_setup(handle);
+
/* MTU range: (ETH_MIN_MTU(kernel default) - 9706) */
netdev->max_mtu = HNS3_MAX_

Re: [PATCH net 2/4] net:ethernet:aquantia: Fix Tx queue hangups

2017-09-21 Thread Yunsheng Lin
Hi, Igor

On 2017/9/21 18:53, Igor Russkikh wrote:
> Driver did a poor job in managing its Tx queues: Sometimes it could stop
> tx queues due to link down condition in aq_nic_xmit - but never waked up
> them. That led to Tx path total suspend.
> This patch fixes this and improves generic queue management:
> - introduces queue restart counter
> - uses generic netif_ interface to disable and enable tx path
> - refactors link up/down condition and introduces dmesg log event when
>   link changes.
> - introduces new constant for minimum descriptors count required for queue
>   wakeup
> 
> Signed-off-by: Pavel Belous 
> Signed-off-by: Igor Russkikh 
> ---
>  drivers/net/ethernet/aquantia/atlantic/aq_cfg.h  |  4 ++
>  drivers/net/ethernet/aquantia/atlantic/aq_nic.c  | 91 
> +++-
>  drivers/net/ethernet/aquantia/atlantic/aq_nic.h  |  2 -
>  drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 26 +++
>  drivers/net/ethernet/aquantia/atlantic/aq_ring.h |  4 ++
>  drivers/net/ethernet/aquantia/atlantic/aq_vec.c  |  8 +--
>  6 files changed, 76 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h 
> b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
> index 2149864..0fdaaa6 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
> @@ -51,6 +51,10 @@
>  
>  #define AQ_CFG_SKB_FRAGS_MAX   32U
>  
> +/* Number of descriptors available in one ring to resume this ring queue
> + */
> +#define AQ_CFG_RESTART_DESC_THRES   (AQ_CFG_SKB_FRAGS_MAX * 2)
> +
>  #define AQ_CFG_NAPI_WEIGHT 64U
>  
>  #define AQ_CFG_MULTICAST_ADDRESS_MAX 32U
> diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c 
> b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> index f281392..24f573c 100644
> --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> @@ -119,6 +119,35 @@ int aq_nic_cfg_start(struct aq_nic_s *self)
>   return 0;
>  }
>  
> +static int aq_nic_update_link_status(struct aq_nic_s *self)
> +{
> + int err = self->aq_hw_ops.hw_get_link_status(self->aq_hw);
> +
> + if (err < 0)
> + return -1;


why not just return err?

> +
> + if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps)
> + pr_info("%s: link change old %d new %d\n",
> + AQ_CFG_DRV_NAME, self->link_status.mbps,
> + self->aq_hw->aq_link_status.mbps);

You has ndev in struct aq_nic_s *self, why not use netdev_*?


> +
> + self->link_status = self->aq_hw->aq_link_status;
> + if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) {
> + aq_utils_obj_set(>header.flags,
> +  AQ_NIC_FLAG_STARTED);
> + aq_utils_obj_clear(>header.flags,
> +AQ_NIC_LINK_DOWN);
> + netif_carrier_on(self->ndev);
> + netif_tx_wake_all_queues(self->ndev);
> + }
> + if (netif_carrier_ok(self->ndev) && !self->link_status.mbps) {
> + netif_carrier_off(self->ndev);
> + netif_tx_disable(self->ndev);
> + aq_utils_obj_set(>header.flags, AQ_NIC_LINK_DOWN);
> + }
> + return 0;
> +}
> +
>  static void aq_nic_service_timer_cb(unsigned long param)
>  {
>   struct aq_nic_s *self = (struct aq_nic_s *)param;
> @@ -131,26 +160,13 @@ static void aq_nic_service_timer_cb(unsigned long param)
>   if (aq_utils_obj_test(>header.flags, AQ_NIC_FLAGS_IS_NOT_READY))
>   goto err_exit;
>  
> - err = self->aq_hw_ops.hw_get_link_status(self->aq_hw);
> - if (err < 0)
> + err = aq_nic_update_link_status(self);
> + if (err)
>   goto err_exit;
>  
> - self->link_status = self->aq_hw->aq_link_status;
> -
>   self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw,
>   self->aq_nic_cfg.is_interrupt_moderation);
>  
> - if (self->link_status.mbps) {
> - aq_utils_obj_set(>header.flags,
> -  AQ_NIC_FLAG_STARTED);
> - aq_utils_obj_clear(>header.flags,
> -AQ_NIC_LINK_DOWN);
> - netif_carrier_on(self->ndev);
> - } else {
> - netif_carrier_off(self->ndev);
> - aq_utils_obj_set(>header.flags, AQ_NIC_LINK_DOWN);
> - }
> -
>   memset(_rx, 0U, sizeof(struct aq_ring_stats_rx_s));
>   memset(_tx, 0U, sizeof(struct aq_ring_stats_tx_s));
>   for (i = AQ_DIMOF(self->aq_vec); i--;) {
> @@ -240,7 +256,6 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct 
> net_device_ops *ndev_ops,
>  int aq_nic_ndev_register(struct aq_nic_s *self)
>  {
>   int err = 0;
> - unsigned int i = 0U;
>  
>   if (!self->ndev) {
>   err = -EINVAL;
> @@ -262,8 +277,7 @@ int aq_nic_ndev_register(struct aq_nic_s *self)
>  
>   

Re: [PATCH net-next 2/4] cxgb4: add basic tc flower offload support

2017-09-21 Thread Yunsheng Lin
Hi, Kumar

On 2017/9/21 15:33, Rahul Lakkireddy wrote:
> From: Kumar Sanghvi 
> 
> Add support to add/remove flows for offload.  Following match
> and action are supported for offloading a flow:
> 
> Match: ether-protocol, IPv4/IPv6 addresses, L4 ports (TCP/UDP)
> Action: drop, redirect to another port on the device.
> 
> The qualifying flows can have accompanying mask information.
> 
> Signed-off-by: Kumar Sanghvi 
> Signed-off-by: Rahul Lakkireddy 
> Signed-off-by: Ganesh Goudar 
> ---
>  drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |   3 +
>  drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c  |  26 ++
>  drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c|   2 +
>  .../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c   | 285 
> -
>  .../net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.h   |  17 ++
>  drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h |   1 +
>  6 files changed, 332 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h 
> b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
> index ea72d2d2e1b4..26eac599ab2c 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
> @@ -904,6 +904,9 @@ struct adapter {
>   /* TC u32 offload */
>   struct cxgb4_tc_u32_table *tc_u32;
>   struct chcr_stats_debug chcr_stats;
> +
> + /* TC flower offload */
> + DECLARE_HASHTABLE(flower_anymatch_tbl, 9);
>  };
>  
>  /* Support for "sched-class" command to allow a TX Scheduling Class to be
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c 
> b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
> index 45b5853ca2f1..07a4619e2164 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
> @@ -148,6 +148,32 @@ static int get_filter_steerq(struct net_device *dev,
>   return iq;
>  }
>  
> +int cxgb4_get_free_ftid(struct net_device *dev, int family)
> +{
> + struct adapter *adap = netdev2adap(dev);
> + struct tid_info *t = >tids;
> + int ftid;
> +
> + spin_lock_bh(>ftid_lock);
> + if (family == PF_INET) {
> + ftid = find_first_zero_bit(t->ftid_bmap, t->nftids);
> + if (ftid >= t->nftids)
> + ftid = -1;
> + } else {
> + ftid = bitmap_find_free_region(t->ftid_bmap, t->nftids, 2);
> + if (ftid < 0) {
> + ftid = -1;

ftid = -1 is not needed?

> + goto out_unlock;
> + }
> +
> + /* this is only a lookup, keep the found region unallocated */
> + bitmap_release_region(t->ftid_bmap, ftid, 2);
> + }
> +out_unlock:
> + spin_unlock_bh(>ftid_lock);
> + return ftid;
> +}
> +
>  static int cxgb4_set_ftid(struct tid_info *t, int fidx, int family)
>  {
>   spin_lock_bh(>ftid_lock);
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c 
> b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> index 8923affbdaf8..3ba4e1ff8486 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
> @@ -5105,6 +5105,8 @@ static int init_one(struct pci_dev *pdev, const struct 
> pci_device_id *ent)
>   if (!adapter->tc_u32)
>   dev_warn(>dev,
>"could not offload tc u32, continuing\n");
> +
> + cxgb4_init_tc_flower(adapter);
>   }
>  
>   if (is_offload(adapter)) {
> diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c 
> b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> index 16dff71e4d02..1af01101faaf 100644
> --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
> @@ -38,16 +38,292 @@
>  #include "cxgb4.h"
>  #include "cxgb4_tc_flower.h"
>  
> +static struct ch_tc_flower_entry *allocate_flower_entry(void)
> +{
> + struct ch_tc_flower_entry *new = kzalloc(sizeof(*new), GFP_KERNEL);
> + return new;
> +}
> +
> +/* Must be called with either RTNL or rcu_read_lock */
> +static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap,
> +unsigned long flower_cookie)
> +{
> + struct ch_tc_flower_entry *flower_entry;
> +
> + hash_for_each_possible_rcu(adap->flower_anymatch_tbl, flower_entry,
> +link, flower_cookie)
> + if (flower_entry->tc_flower_cookie == flower_cookie)
> + return flower_entry;
> + return NULL;
> +}
> +
> +static void cxgb4_process_flow_match(struct net_device *dev,
> +  struct tc_cls_flower_offload *cls,
> +  struct ch_filter_specification *fs)
> +{
> + u16 addr_type = 0;
> +
> + if (dissector_uses_key(cls->dissector, 

[PATCH net 1/9] net: hns3: Cleanup for ROCE capability flag in ae_dev

2017-09-20 Thread Yunsheng Lin
This patch add the ROCE supported flag in the driver_data
field of pci_device_id, delete roce_pci_tbl and change
HNAE_DEV_SUPPORT_ROCE_B to HNAE3_DEV_SUPPORT_ROCE_B.
This cleanup is done in order to support adding capability
in pci_device_id and to fix initialization failure when
cmd is not supported.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  5 -
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 25 --
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 16 +-
 3 files changed, 19 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index b2f28ae..0f7b61a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -49,7 +49,10 @@
 #define HNAE3_CLASS_NAME_SIZE 16
 
 #define HNAE3_DEV_INITED_B 0x0
-#define HNAE_DEV_SUPPORT_ROCE_B0x1
+#define HNAE3_DEV_SUPPORT_ROCE_B   0x1
+
+#define hnae3_dev_roce_supported(hdev) \
+   hnae_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)
 
 #define ring_ptr_move_fw(ring, p) \
((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 44c722a..eb78c23 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -46,17 +46,7 @@ static int hclge_set_mta_filter_mode(struct hclge_dev *hdev,
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0},
-   /* Required last entry */
-   {0, }
-};
-
-static const struct pci_device_id roce_pci_tbl[] = {
-   {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA), 0},
-   {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA_MACSEC), 0},
-   {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA), 0},
-   {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC), 0},
-   {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), 0},
-   /* Required last entry */
+   /* required last entry */
{0, }
 };
 
@@ -894,7 +884,7 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev)
hdev->num_tqps = __le16_to_cpu(req->tqp_num);
hdev->pkt_buf_size = __le16_to_cpu(req->buf_size) << HCLGE_BUF_UNIT_S;
 
-   if (hnae_get_bit(hdev->ae_dev->flag, HNAE_DEV_SUPPORT_ROCE_B)) {
+   if (hnae3_dev_roce_supported(hdev)) {
hdev->num_roce_msix =
hnae_get_field(__le16_to_cpu(req->pf_intr_vector_number),
   HCLGE_PF_VEC_NUM_M, HCLGE_PF_VEC_NUM_S);
@@ -3931,8 +3921,7 @@ static int hclge_init_client_instance(struct hnae3_client 
*client,
goto err;
 
if (hdev->roce_client &&
-   hnae_get_bit(hdev->ae_dev->flag,
-HNAE_DEV_SUPPORT_ROCE_B)) {
+   hnae3_dev_roce_supported(hdev)) {
struct hnae3_client *rc = hdev->roce_client;
 
ret = hclge_init_roce_base_info(vport);
@@ -3955,8 +3944,7 @@ static int hclge_init_client_instance(struct hnae3_client 
*client,
 
break;
case HNAE3_CLIENT_ROCE:
-   if (hnae_get_bit(hdev->ae_dev->flag,
-HNAE_DEV_SUPPORT_ROCE_B)) {
+   if (hnae3_dev_roce_supported(hdev)) {
hdev->roce_client = client;
vport->roce.client = client;
}
@@ -4068,7 +4056,6 @@ static void hclge_pci_uninit(struct hclge_dev *hdev)
 static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
 {
struct pci_dev *pdev = ae_dev->pdev;
-   const struct pci_device_id *id;
struct hclge_dev *hdev;
int ret;
 
@@ -4083,10 +4070,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
hdev->ae_dev = ae_dev;
ae_dev->priv = hdev;
 
-   id = pci_match_id(roce_pci_tbl, ae_dev->pdev);
-   if (id)
-   hnae_set_bit(ae_dev->flag, HNAE_DEV_SUPPORT_ROCE_B, 1);
-
ret = hclge_pci_init(hdev);
if (ret) {
dev_err(>dev, "PCI init failed\n");
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 4d68d6e..94d8bb5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -41,11 +41,16 @@
 static const struct 

[PATCH net 2/9] net: hns3: Fix initialization when cmd is not supported

2017-09-20 Thread Yunsheng Lin
When ae_dev doesn't support DCB, rx_priv_wl_config,
common_thrd_config and tm_qs_bp_cfg can't be called, otherwise
cmd return fail, which causes the hclge module initialization
process to fail.
This patch fix it by adding a DCB capability flag to check if
the ae_dev support DCB.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  7 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 26 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  4 
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c | 10 -
 4 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 0f7b61a..ad685f5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -50,10 +50,17 @@
 
 #define HNAE3_DEV_INITED_B 0x0
 #define HNAE3_DEV_SUPPORT_ROCE_B   0x1
+#define HNAE3_DEV_SUPPORT_DCB_B0x2
+
+#define HNAE3_DEV_SUPPORT_ROCE_DCB_BITS (BIT(HNAE3_DEV_SUPPORT_DCB_B) |\
+   BIT(HNAE3_DEV_SUPPORT_ROCE_B))
 
 #define hnae3_dev_roce_supported(hdev) \
hnae_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)
 
+#define hnae3_dev_dcb_supported(hdev) \
+   hnae_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_DCB_B)
+
 #define ring_ptr_move_fw(ring, p) \
((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
 #define ring_ptr_move_bw(ring, p) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index eb78c23..c515b84 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1772,18 +1772,22 @@ int hclge_buffer_alloc(struct hclge_dev *hdev)
return ret;
}
 
-   ret = hclge_rx_priv_wl_config(hdev);
-   if (ret) {
-   dev_err(>pdev->dev,
-   "could not configure rx private waterline %d\n", ret);
-   return ret;
-   }
+   if (hnae3_dev_dcb_supported(hdev)) {
+   ret = hclge_rx_priv_wl_config(hdev);
+   if (ret) {
+   dev_err(>pdev->dev,
+   "could not configure rx private waterline %d\n",
+   ret);
+   return ret;
+   }
 
-   ret = hclge_common_thrd_config(hdev);
-   if (ret) {
-   dev_err(>pdev->dev,
-   "could not configure common threshold %d\n", ret);
-   return ret;
+   ret = hclge_common_thrd_config(hdev);
+   if (ret) {
+   dev_err(>pdev->dev,
+   "could not configure common threshold %d\n",
+   ret);
+   return ret;
+   }
}
 
ret = hclge_common_wl_config(hdev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index 1c577d2..c91dbf1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -976,6 +976,10 @@ int hclge_pause_setup_hw(struct hclge_dev *hdev)
if (ret)
return ret;
 
+   /* Only DCB-supported dev supports qset back pressure setting */
+   if (!hnae3_dev_dcb_supported(hdev))
+   return 0;
+
for (i = 0; i < hdev->tm_info.num_tc; i++) {
ret = hclge_tm_qs_bp_cfg(hdev, i);
if (ret)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
index 94d8bb5..35369e1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c
@@ -42,15 +42,15 @@
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_GE), 0},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE), 0},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA),
-BIT(HNAE3_DEV_SUPPORT_ROCE_B)},
+HNAE3_DEV_SUPPORT_ROCE_DCB_BITS},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_25GE_RDMA_MACSEC),
-BIT(HNAE3_DEV_SUPPORT_ROCE_B)},
+HNAE3_DEV_SUPPORT_ROCE_DCB_BITS},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA),
-BIT(HNAE3_DEV_SUPPORT_ROCE_B)},
+HNAE3_DEV_SUPPORT_ROCE_DCB_BITS},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_50GE_RDMA_MACSEC),
-BIT(HNAE3_DEV_SUPPORT_ROCE_B)},
+HNAE3_DEV_SUPPORT_ROCE_DCB_BITS},
{PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC),
-BIT(HNAE

[PATCH net 7/9] net: hns3: Fix typo error for feild in hclge_tm

2017-09-20 Thread Yunsheng Lin
This patch fixes a typo error for feild, which should be field.

Fixes: 848440544b41f ("net: hns3: Add support of TX Scheduler & Shaper to HNS3 
driver")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c| 20 ++--
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h|  4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index c91dbf1..fe659f7 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -280,11 +280,11 @@ static int hclge_tm_pg_shapping_cfg(struct hclge_dev 
*hdev,
 
shap_cfg_cmd->pg_id = pg_id;
 
-   hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, IR_B, ir_b);
-   hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, IR_U, ir_u);
-   hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, IR_S, ir_s);
-   hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, BS_B, bs_b);
-   hclge_tm_set_feild(shap_cfg_cmd->pg_shapping_para, BS_S, bs_s);
+   hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_B, ir_b);
+   hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_U, ir_u);
+   hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_S, ir_s);
+   hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, BS_B, bs_b);
+   hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, BS_S, bs_s);
 
return hclge_cmd_send(>hw, , 1);
 }
@@ -307,11 +307,11 @@ static int hclge_tm_pri_shapping_cfg(struct hclge_dev 
*hdev,
 
shap_cfg_cmd->pri_id = pri_id;
 
-   hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, IR_B, ir_b);
-   hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, IR_U, ir_u);
-   hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, IR_S, ir_s);
-   hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, BS_B, bs_b);
-   hclge_tm_set_feild(shap_cfg_cmd->pri_shapping_para, BS_S, bs_s);
+   hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_B, ir_b);
+   hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_U, ir_u);
+   hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_S, ir_s);
+   hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, BS_B, bs_b);
+   hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, BS_S, bs_s);
 
return hclge_cmd_send(>hw, , 1);
 }
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
index 7e67337..85158b0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
@@ -94,10 +94,10 @@ struct hclge_bp_to_qs_map_cmd {
u32 rsvd1;
 };
 
-#define hclge_tm_set_feild(dest, string, val) \
+#define hclge_tm_set_field(dest, string, val) \
hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH), val)
-#define hclge_tm_get_feild(src, string) \
+#define hclge_tm_get_field(src, string) \
hnae_get_field((src), (HCLGE_TM_SHAP_##string##_MSK), \
   (HCLGE_TM_SHAP_##string##_LSH))
 
-- 
1.9.1



[PATCH net 0/9] TM related bugfixes for the HNS3 Ethernet Driver

2017-09-20 Thread Yunsheng Lin
This patch set contains a few bugfixes related to hclge_tm module.

Yunsheng Lin (9):
  net: hns3: Cleanup for ROCE capability flag in ae_dev
  net: hns3: Fix initialization when cmd is not supported
  net: hns3: Fix for DEFAULT_DV when dev doesn't support DCB
  net: hns3: Fix for not setting rx private buffer size to zero
  net: hns3: Fix for rx_priv_buf_alloc not setting rx shared buffer
  net: hns3: Fix for rx priv buf allocation when DCB is not supported
  net: hns3: Fix typo error for feild in hclge_tm
  net: hns3: Fix for setting rss_size incorrectly
  net: hns3: Fix for pri to tc mapping in TM

 drivers/net/ethernet/hisilicon/hns3/hnae3.h|  15 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h |   4 +-
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 163 +++--
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|   3 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  41 +++---
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h  |   4 +-
 .../net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c |  16 +-
 7 files changed, 143 insertions(+), 103 deletions(-)

-- 
1.9.1



[PATCH net 3/9] net: hns3: Fix for DEFAULT_DV when dev doesn't support DCB

2017-09-20 Thread Yunsheng Lin
When ae_dev doesn't support DCB, DEFAULT_DV must be set to
a lower value, otherwise the buffer allocation process will
fail.
This patch fix it by setting it to 30K bytes.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h  | 1 +
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 6 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index c2b613b..30e2ad5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -688,6 +688,7 @@ struct hclge_reset_tqp_queue {
 #define HCLGE_DEFAULT_TX_BUF   0x4000   /* 16k  bytes */
 #define HCLGE_TOTAL_PKT_BUF0x108000 /* 1.03125M bytes */
 #define HCLGE_DEFAULT_DV   0xA000   /* 40k byte */
+#define HCLGE_DEFAULT_NON_DCB_DV   0x7800  /* 30K byte */
 
 #define HCLGE_TYPE_CRQ 0
 #define HCLGE_TYPE_CSQ 1
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index c515b84..1876418 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1444,7 +1444,11 @@ static bool  hclge_is_rx_buf_ok(struct hclge_dev *hdev, 
u32 rx_all)
tc_num = hclge_get_tc_num(hdev);
pfc_enable_num = hclge_get_pfc_enalbe_num(hdev);
 
-   shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV;
+   if (hnae3_dev_dcb_supported(hdev))
+   shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV;
+   else
+   shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_NON_DCB_DV;
+
shared_buf_tc = pfc_enable_num * hdev->mps +
(tc_num - pfc_enable_num) * hdev->mps / 2 +
hdev->mps;
-- 
1.9.1



[PATCH net 8/9] net: hns3: Fix for setting rss_size incorrectly

2017-09-20 Thread Yunsheng Lin
rss_size is 1, 2, 4, 8, 16, 32, 64, 128, but acutal tc queue
size can be any u16 less than 128. If tc queue size is 5, we
set the rss_size to 8, indirection table will be used to limit
the size of actual queue size.
It may cause dropping of receiving packet in hardware if
rss_size is not set correctly.
For now, each TC has the same rss size.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c| 76 ++
 .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h|  1 +
 .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c  |  1 +
 3 files changed, 38 insertions(+), 40 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 1e15ce1..d27618b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2606,6 +2606,7 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
u16 tc_valid[HCLGE_MAX_TC_NUM];
u16 tc_size[HCLGE_MAX_TC_NUM];
u32 *rss_indir = NULL;
+   u16 rss_size = 0, roundup_size;
const u8 *key;
int i, ret, j;
 
@@ -2620,7 +2621,13 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
for (j = 0; j < hdev->num_vmdq_vport + 1; j++) {
for (i = 0; i < HCLGE_RSS_IND_TBL_SIZE; i++) {
vport[j].rss_indirection_tbl[i] =
-   i % hdev->rss_size_max;
+   i % vport[j].alloc_rss_size;
+
+   /* vport 0 is for PF */
+   if (j != 0)
+   continue;
+
+   rss_size = vport[j].alloc_rss_size;
rss_indir[i] = vport[j].rss_indirection_tbl[i];
}
}
@@ -2637,42 +2644,31 @@ static int hclge_rss_init_hw(struct hclge_dev *hdev)
if (ret)
goto err;
 
+   /* Each TC have the same queue size, and tc_size set to hardware is
+* the log2 of roundup power of two of rss_size, the acutal queue
+* size is limited by indirection table.
+*/
+   if (rss_size > HCLGE_RSS_TC_SIZE_7 || rss_size == 0) {
+   dev_err(>pdev->dev,
+   "Configure rss tc size failed, invalid TC_SIZE = %d\n",
+   rss_size);
+   return -EINVAL;
+   }
+
+   roundup_size = roundup_pow_of_two(rss_size);
+   roundup_size = ilog2(roundup_size);
+
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
-   if (hdev->hw_tc_map & BIT(i))
-   tc_valid[i] = 1;
-   else
-   tc_valid[i] = 0;
+   tc_valid[i] = 0;
 
-   switch (hdev->rss_size_max) {
-   case HCLGE_RSS_TC_SIZE_0:
-   tc_size[i] = 0;
-   break;
-   case HCLGE_RSS_TC_SIZE_1:
-   tc_size[i] = 1;
-   break;
-   case HCLGE_RSS_TC_SIZE_2:
-   tc_size[i] = 2;
-   break;
-   case HCLGE_RSS_TC_SIZE_3:
-   tc_size[i] = 3;
-   break;
-   case HCLGE_RSS_TC_SIZE_4:
-   tc_size[i] = 4;
-   break;
-   case HCLGE_RSS_TC_SIZE_5:
-   tc_size[i] = 5;
-   break;
-   case HCLGE_RSS_TC_SIZE_6:
-   tc_size[i] = 6;
-   break;
-   case HCLGE_RSS_TC_SIZE_7:
-   tc_size[i] = 7;
-   break;
-   default:
-   break;
-   }
-   tc_offset[i] = hdev->rss_size_max * i;
+   if (!(hdev->hw_tc_map & BIT(i)))
+   continue;
+
+   tc_valid[i] = 1;
+   tc_size[i] = roundup_size;
+   tc_offset[i] = rss_size * i;
}
+
ret = hclge_set_rss_tc_mode(hdev, tc_valid, tc_size, tc_offset);
 
 err:
@@ -4166,12 +4162,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
 
-   ret = hclge_rss_init_hw(hdev);
-   if (ret) {
-   dev_err(>dev, "Rss init fail, ret =%d\n", ret);
-   return  ret;
-   }
-
ret = hclge_init_vlan_config(hdev);
if (ret) {
dev_err(>dev, "VLAN init fail, ret =%d\n", ret);
@@ -4184,6 +4174,12 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
return ret;
}
 
+   ret = hclge_rss_init_hw(hdev);
+   if (ret) {
+   dev_err(>dev, "

[PATCH net 5/9] net: hns3: Fix for rx_priv_buf_alloc not setting rx shared buffer

2017-09-20 Thread Yunsheng Lin
rx_priv_buf_alloc is used to tell hardware how much buffer is
used for rx direction, right now only the private buffer is
assigned.
For ae_dev that doesn't support DCB, private rx buffer is assigned
to zero, only shared rx buffer is used. So not setting the shared
rx buffer cause dropping of packet in SSU.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h  | 3 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 4 
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index 30e2ad5..758cf39 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -270,7 +270,8 @@ struct hclge_tx_buff_alloc {
 
 struct hclge_rx_priv_buff {
__le16 buf_num[HCLGE_TC_NUM];
-   u8 rsv[8];
+   __le16 shared_buf;
+   u8 rsv[6];
 };
 
 struct hclge_query_version {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index bf3179a..c08c41f 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1622,6 +1622,10 @@ static int hclge_rx_priv_buf_alloc(struct hclge_dev 
*hdev)
cpu_to_le16(true << HCLGE_TC0_PRI_BUF_EN_B);
}
 
+   req->shared_buf =
+   cpu_to_le16((hdev->s_buf.buf_size >> HCLGE_BUF_UNIT_S) |
+   (1 << HCLGE_TC0_PRI_BUF_EN_B));
+
ret = hclge_cmd_send(>hw, , 1);
if (ret) {
dev_err(>pdev->dev,
-- 
1.9.1



[PATCH net 6/9] net: hns3: Fix for rx priv buf allocation when DCB is not supported

2017-09-20 Thread Yunsheng Lin
When hdev doesn't support DCB, rx private buffer is not allocated,
otherwise there is not enough buffer for rx shared buffer, causing
buffer allocation process to fail.
This patch fixes by checking the dcb capability in
hclge_rx_buffer_calc.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index c08c41f..1e15ce1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1489,6 +1489,16 @@ int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 
tx_size)
struct hclge_priv_buf *priv;
int i;
 
+   /* When DCB is not supported, rx private
+* buffer is not allocated.
+*/
+   if (!hnae3_dev_dcb_supported(hdev)) {
+   if (!hclge_is_rx_buf_ok(hdev, rx_all))
+   return -ENOMEM;
+
+   return 0;
+   }
+
/* step 1, try to alloc private buffer for all enabled tc */
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
priv = >priv_buf[i];
-- 
1.9.1



[PATCH net 9/9] net: hns3: Fix for pri to tc mapping in TM

2017-09-20 Thread Yunsheng Lin
Current mapping between pri and tc is one to one,
so user can't map multi priorities to the same tc.
This patch changes the mapping to many to one.

Fixes: 848440544b41f ("net: hns3: Add support of TX Scheduler & Shaper to HNS3 
driver")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hnae3.h |  3 ++-
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h |  2 +-
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c   | 16 +---
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h 
b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index ad685f5..1a01cad 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -376,12 +376,12 @@ struct hnae3_ae_algo {
 struct hnae3_tc_info {
u16 tqp_offset; /* TQP offset from base TQP */
u16 tqp_count;  /* Total TQPs */
-   u8  up; /* user priority */
u8  tc; /* TC index */
boolenable; /* If this TC is enable or not */
 };
 
 #define HNAE3_MAX_TC   8
+#define HNAE3_MAX_USER_PRIO8
 struct hnae3_knic_private_info {
struct net_device *netdev; /* Set by KNIC client when init instance */
u16 rss_size;  /* Allocated RSS queues */
@@ -389,6 +389,7 @@ struct hnae3_knic_private_info {
u16 num_desc;
 
u8 num_tc; /* Total number of enabled TCs */
+   u8 prio_tc[HNAE3_MAX_USER_PRIO];  /* TC indexed by prio */
struct hnae3_tc_info tc_info[HNAE3_MAX_TC]; /* Idx of array is HW TC */
 
u16 num_tqps; /* total number of TQPs in this handle */
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index 7f8dd12..9fcfd93 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -176,7 +176,6 @@ struct hclge_pg_info {
 struct hclge_tc_info {
u8 tc_id;
u8 tc_sch_mode; /* 0: sp; 1: dwrr */
-   u8 up;
u8 pgid;
u32 bw_limit;
 };
@@ -197,6 +196,7 @@ struct hclge_tm_info {
u8 num_tc;
u8 num_pg;  /* It must be 1 if vNET-Base schd */
u8 pg_dwrr[HCLGE_PG_NUM];
+   u8 prio_tc[HNAE3_MAX_USER_PRIO];
struct hclge_pg_info pg_info[HCLGE_PG_NUM];
struct hclge_tc_info tc_info[HNAE3_MAX_TC];
enum hclge_fc_mode fc_mode;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
index b7ba7aa..73a75d7 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
@@ -128,9 +128,7 @@ static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 
*pri, u8 pri_id)
 {
u8 tc;
 
-   for (tc = 0; tc < hdev->tm_info.num_tc; tc++)
-   if (hdev->tm_info.tc_info[tc].up == pri_id)
-   break;
+   tc = hdev->tm_info.prio_tc[pri_id];
 
if (tc >= hdev->tm_info.num_tc)
return -EINVAL;
@@ -158,7 +156,7 @@ static int hclge_up_to_tc_map(struct hclge_dev *hdev)
 
hclge_cmd_setup_basic_desc(, HCLGE_OPC_PRI_TO_TC_MAPPING, false);
 
-   for (pri_id = 0; pri_id < hdev->tm_info.num_tc; pri_id++) {
+   for (pri_id = 0; pri_id < HNAE3_MAX_USER_PRIO; pri_id++) {
ret = hclge_fill_pri_array(hdev, pri, pri_id);
if (ret)
return ret;
@@ -405,16 +403,17 @@ static void hclge_tm_vport_tc_info_update(struct 
hclge_vport *vport)
kinfo->tc_info[i].tqp_offset = i * kinfo->rss_size;
kinfo->tc_info[i].tqp_count = kinfo->rss_size;
kinfo->tc_info[i].tc = i;
-   kinfo->tc_info[i].up = hdev->tm_info.tc_info[i].up;
} else {
/* Set to default queue if TC is disable */
kinfo->tc_info[i].enable = false;
kinfo->tc_info[i].tqp_offset = 0;
kinfo->tc_info[i].tqp_count = 1;
kinfo->tc_info[i].tc = 0;
-   kinfo->tc_info[i].up = 0;
}
}
+
+   memcpy(kinfo->prio_tc, hdev->tm_info.prio_tc,
+  FIELD_SIZEOF(struct hnae3_knic_private_info, prio_tc));
 }
 
 static void hclge_tm_vport_info_update(struct hclge_dev *hdev)
@@ -436,12 +435,15 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
for (i = 0; i < hdev->tm_info.num_tc; i++) {
hdev->tm_info.tc_info[i].tc_id = i;
hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR;
-   hdev->tm_info.tc_in

[PATCH net 4/9] net: hns3: Fix for not setting rx private buffer size to zero

2017-09-20 Thread Yunsheng Lin
When rx private buffer is disabled, there may be some case that
the rx private buffer is not set to zero, which may cause buffer
allocation process to fail.
This patch fixes this problem by setting priv->enable to 0 and
priv->buf_size to zero when rx private buffer is disabled.

Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility 
Layer Support")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c 
b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 1876418..bf3179a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1504,6 +1504,11 @@ int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 
tx_size)
priv->wl.high = 2 * hdev->mps;
priv->buf_size = priv->wl.high;
}
+   } else {
+   priv->enable = 0;
+   priv->wl.low = 0;
+   priv->wl.high = 0;
+   priv->buf_size = 0;
}
}
 
@@ -1516,8 +1521,15 @@ int hclge_rx_buffer_calc(struct hclge_dev *hdev, u32 
tx_size)
for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
priv = >priv_buf[i];
 
-   if (hdev->hw_tc_map & BIT(i))
-   priv->enable = 1;
+   priv->enable = 0;
+   priv->wl.low = 0;
+   priv->wl.high = 0;
+   priv->buf_size = 0;
+
+   if (!(hdev->hw_tc_map & BIT(i)))
+   continue;
+
+   priv->enable = 1;
 
if (hdev->tm_info.hw_pfc_map & BIT(i)) {
priv->wl.low = 128;
-- 
1.9.1



[PATCH net-next] net: hns: Fix for __udivdi3 compiler error

2017-08-04 Thread Yunsheng Lin
This patch fixes the __udivdi3 undefined error reported by
test robot.

Fixes: b8c17f708831 ("net: hns: Add self-adaptive interrupt coalesce support in 
hns driver")
Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index 832f277..3652063 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -847,7 +847,8 @@ static void hns_update_rx_rate(struct hnae_ring *ring)
 
total_bytes = ring->stats.rx_bytes - ring->coal_last_rx_bytes;
time_passed_ms = jiffies_to_msecs(jiffies - ring->coal_last_jiffies);
-   ring->coal_rx_rate = (total_bytes / time_passed_ms) >> 10;
+   do_div(total_bytes, time_passed_ms);
+   ring->coal_rx_rate = total_bytes >> 10;
 
ring->coal_last_rx_bytes = ring->stats.rx_bytes;
ring->coal_last_jiffies = jiffies;
-- 
1.9.1



  1   2   >