Netdev List
 help / color / mirror / Atom feed
* [PATCH] net: tcp response should set oif only if it is L3 master
From: David Ahern @ 2016-11-09 17:07 UTC (permalink / raw)
  To: netdev; +Cc: lorenzo, David Ahern

Lorenzo noted an Android unit test failed due to e0d56fdd7342:
"The expectation in the test was that the RST replying to a SYN sent to a
closed port should be generated with oif=0. In other words it should not
prefer the interface where the SYN came in on, but instead should follow
whatever the routing table says it should do."

Revert the change to ip_send_unicast_reply and tcp_v6_send_response such
that the oif in the flow is set to the skb_iif only if skb_iif is an L3
master.

Fixes: e0d56fdd7342 ("net: l3mdev: remove redundant calls")
Reported-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
---
 net/ipv4/ip_output.c | 3 ++-
 net/ipv6/tcp_ipv6.c  | 8 ++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 03e7f7310423..7cf627b0b248 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1579,7 +1579,8 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
 	}
 
 	oif = arg->bound_dev_if;
-	oif = oif ? : skb->skb_iif;
+	if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
+		oif = skb->skb_iif;
 
 	flowi4_init_output(&fl4, oif,
 			   IP4_REPLY_MARK(net, skb->mark),
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5a27ab4eab39..6ca23c2e76f7 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -818,8 +818,12 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
 	fl6.flowi6_proto = IPPROTO_TCP;
 	if (rt6_need_strict(&fl6.daddr) && !oif)
 		fl6.flowi6_oif = tcp_v6_iif(skb);
-	else
-		fl6.flowi6_oif = oif ? : skb->skb_iif;
+	else {
+		if (!oif && netif_index_is_l3_master(net, skb->skb_iif))
+			oif = skb->skb_iif;
+
+		fl6.flowi6_oif = oif;
+	}
 
 	fl6.flowi6_mark = IP6_REPLY_MARK(net, skb->mark);
 	fl6.fl6_dport = t1->dest;
-- 
2.1.4

^ permalink raw reply related

* Re: [Intel-wired-lan] [PATCH net] igb: re-assign hw address pointer on reset after PCI error
From: Alexander Duyck @ 2016-11-09 17:12 UTC (permalink / raw)
  To: Guilherme G. Piccoli; +Cc: intel-wired-lan, Netdev, Fujinaka, Todd
In-Reply-To: <1477944749-22822-1-git-send-email-gpiccoli@linux.vnet.ibm.com>

On Mon, Oct 31, 2016 at 1:12 PM, Guilherme G. Piccoli
<gpiccoli@linux.vnet.ibm.com> wrote:
> Whenever the igb driver detects the result of a read operation returns
> a value composed only by F's (like 0xFFFFFFFF), it will detach the
> net_device, clear the hw_addr pointer and warn to the user that adapter's
> link is lost - those steps happen on igb_rd32().
>
> In case a PCI error happens on Power architecture, there's a recovery
> mechanism called EEH, that will reset the PCI slot and call driver's
> handlers to reset the adapter and network functionality as well.
>
> We observed that once hw_addr is NULL after the error is detected on
> igb_rd32(), it's never assigned back, so in the process of resetting
> the network functionality we got a NULL pointer dereference in both
> igb_configure_tx_ring() and igb_configure_rx_ring(). In order to avoid
> such bug, we re-assign the hw_addr value in the beginning of the
> function igb_reset(), in case the hw_addr is NULL when we reach that
> path.
>
> Reported-by: Anthony H. Thai <ahthai@us.ibm.com>
> Reported-by: Harsha Thyagaraja <hathyaga@in.ibm.com>
> Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
> ---
>  drivers/net/ethernet/intel/igb/igb_main.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index edc9a6a..c19119c 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -1873,6 +1873,13 @@ void igb_reset(struct igb_adapter *adapter)
>         struct e1000_fc_info *fc = &hw->fc;
>         u32 pba, hwm;
>
> +       /* In case of PCI error, adapter might have lost its HW
> +        * address; if we reached this point after an error scenario,
> +        * we should re-assign the hw_addr based on the saved io_addr.
> +        */
> +       if (!hw->hw_addr)
> +               hw->hw_addr = adapter->io_addr;
> +
>         /* Repartition Pba for greater than 9k mtu
>          * To take effect CTRL.RST is required.
>          */

It seems like this would have the potential to get noisy pretty
quickly since every reset would retrigger this.

It might make more sense to move this line into igb_io_slot_reset and
igb_resume where the device would have gone through a reset of some
sort and then had the state of the device restored and the device
memory access was re-enabled via pci_enable_device_mem.  Also there is
no point in really doing the "if" since you should always be okay to
overwrite hw->hw_addr with adapter->io_addr.

Thanks.

- Alex

^ permalink raw reply

* RE: [PATCH net-next v6 02/10] dpaa_eth: add support for DPAA Ethernet
From: Madalin-Cristian Bucur @ 2016-11-09 17:16 UTC (permalink / raw)
  To: David Miller
  Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	linux-kernel@vger.kernel.org, oss@buserror.net,
	ppc@mindchasers.com, joe@perches.com, pebolle@tiscali.nl,
	joakim.tjernlund@transmode.se
In-Reply-To: <20161103.155816.642712588084106823.davem@davemloft.net>

> From: Madalin-Cristian Bucur
> Sent: Monday, November 07, 2016 5:43 PM
> 
> > From: David Miller [mailto:davem@davemloft.net]
> > Sent: Thursday, November 03, 2016 9:58 PM
> >
> > From: Madalin Bucur <madalin.bucur@nxp.com>
> > Date: Wed, 2 Nov 2016 22:17:26 +0200
> >
> > > This introduces the Freescale Data Path Acceleration Architecture
<snip>

> > > +	int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
> >  ...
> > > +		cpustats = (u64 *)&percpu_priv->stats;
> > > +
> > > +		for (j = 0; j < numstats; j++)
> > > +			netstats[j] += cpustats[j];
> >
> > This is a memcpy() on well-typed datastructures which requires no
> > casting or special handling whatsoever, so use memcpy instead of
> > needlessly open coding the operation.
> 
> Will fix.

Took a second look at this, it's not copying but adding the percpu
statistics into consolidated results.

Madalin

^ permalink raw reply

* Re: [PATCH net-next v6 02/10] dpaa_eth: add support for DPAA Ethernet
From: David Miller @ 2016-11-09 17:18 UTC (permalink / raw)
  To: madalin.bucur
  Cc: netdev, linuxppc-dev, linux-kernel, oss, ppc, joe, pebolle,
	joakim.tjernlund
In-Reply-To: <AM4PR04MB160440B1F671B4C86B238C2DECB90@AM4PR04MB1604.eurprd04.prod.outlook.com>

From: Madalin-Cristian Bucur <madalin.bucur@nxp.com>
Date: Wed, 9 Nov 2016 17:16:12 +0000

>> From: Madalin-Cristian Bucur
>> Sent: Monday, November 07, 2016 5:43 PM
>> 
>> > From: David Miller [mailto:davem@davemloft.net]
>> > Sent: Thursday, November 03, 2016 9:58 PM
>> >
>> > From: Madalin Bucur <madalin.bucur@nxp.com>
>> > Date: Wed, 2 Nov 2016 22:17:26 +0200
>> >
>> > > This introduces the Freescale Data Path Acceleration Architecture
> <snip>
> 
>> > > +	int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
>> >  ...
>> > > +		cpustats = (u64 *)&percpu_priv->stats;
>> > > +
>> > > +		for (j = 0; j < numstats; j++)
>> > > +			netstats[j] += cpustats[j];
>> >
>> > This is a memcpy() on well-typed datastructures which requires no
>> > casting or special handling whatsoever, so use memcpy instead of
>> > needlessly open coding the operation.
>> 
>> Will fix.
> 
> Took a second look at this, it's not copying but adding the percpu
> statistics into consolidated results.

Ok, then it looks fine, thanks for clarifying.

^ permalink raw reply

* Re: Ethernet not working on a different SoC with same eth HW
From: Mason @ 2016-11-09 17:38 UTC (permalink / raw)
  To: netdev
  Cc: Mans Rullgard, Florian Fainelli, Timur Tabi, Sergei Shtylyov,
	Zefir Kurtisi, Martin Blumenstingl, Andrew Lunn, Uwe Kleine-Konig,
	Daniel Mack, Sebastian Frias
In-Reply-To: <5821F223.5090508@free.fr>

On 08/11/2016 16:41, Mason wrote:

> On 31/10/2016 16:29, Mason wrote:
> 
>> I'm using these net drivers:
>>
>>   drivers/net/ethernet/aurora/nb8800.c
>>   drivers/net/phy/at803x.c
>>
>> With a smp8758 board, they work great.
>> I've been trying to use them on a different board:
>>
>>   same eth PHY (Atheros AR8035)
>>   same eth MAC (Aurora SSN8800)
>>   different SoC (same base address for MAC block)
>>
>> It doesn't work, and I'm not sure where to look first...
> 
> After oh-so-many days making increasingly random changes,
> hoping something would magically un-break, we did find a
> *local* commit for an exotic platform (chip emulator) that
> was causing the issue.

However... all is not well yet :-(

A) When the board is connected to a Gigabit switch, it is able to
complete the DHCP dance. But this takes around 5 seconds,
(with several requests timing out).

Whereas the same board running an ugly 3.4 kernel (which Mans called
"quite hideous even by evil vendor standards") completes the DHCP
dance in under a second.

B) When the board is connected to a Fast Ethernet switch, the DHCP
dance times out forever. (Whereas this works on the 3.4 kernel.)

C) When the board is connected to a Gigabit switch, then plugged
into the Fast Ethernet switch, then back into the Gigabit switch,
network connectivity is lost forever.

We've started examining the differences in phy and net frameworks
between 3.4 and 4.9 but that's an atom in a haystack.

To be continued...

Regards.

^ permalink raw reply

* Re: [PATCH] [RFC] net: phy: phy drivers should not set SUPPORTED_Pause or SUPPORTED_Asym_Pause
From: Timur Tabi @ 2016-11-09 17:34 UTC (permalink / raw)
  To: Florian Fainelli, David Miller, netdev
In-Reply-To: <26a8fde2-6403-b14e-a163-c3a1b6afeb4d@gmail.com>

On 11/09/2016 11:06 AM, Florian Fainelli wrote:

>> 1) PHY drivers and/or phylib sets the SUPPORTED_Pause |
>> SUPPORTED_AsymPause bits in phydev->supported.  This indicates that the
>> PHY supports pause frames.
>
> Agreed.

So I'm still not sure *where* phylib should set the bits in 
phydev->supported.  I previously thought that phy_sanitize_settings() 
would be a candidate, but that function is called only when 
autonegotiation is disabled.

So the only thing I can think of is to do this:

/* A mapping of all SUPPORTED settings to speed/duplex */
static const struct phy_setting settings[] = {
	{
		.speed = SPEED_10000,
		.duplex = DUPLEX_FULL,
-		.setting = SUPPORTED_10000baseKR_Full,
+		.setting = SUPPORTED_10000baseKR_Full |
+			SUPPORTED_Pause | SUPPORTED_Asym_Pause,

... for all of the entries in settings[]

But this seems excessive, and I don't know if all of these SPEED_xxx 
standards actually support pause frames.

 >> >3) When the link state changes, the MAC driver checks
>> >phydev->advertising, and if the bits are set, then it enables those
>> >features in the MAC.

> Almost, we need to see what the link partner advertised, by looking at
> phydev->pause / phydev->asym_pause and checking the local knobs whether
> flow control can be enabled, but other than that, this looks correct to me.

Yes, that's what I meant to write.  Fortunately, my EMAC driver already 
does this.

-- 
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.

^ permalink raw reply

* Re: [PATCH net] ipv4: update comment to document GSO fragmentation cases.
From: David Miller @ 2016-11-09 17:46 UTC (permalink / raw)
  To: lrichard; +Cc: netdev, shmulik.ladkani
In-Reply-To: <1478276558-10974-1-git-send-email-lrichard@redhat.com>

From: Lance Richardson <lrichard@redhat.com>
Date: Fri,  4 Nov 2016 12:22:38 -0400

> This is a follow-up to commit eb96202f1e34 ("ipv4: allow local
> fragmentation in ip_finish_output_gso()"), updating the comment
> documenting cases in which fragmentation is needed for egress
> GSO packets.
> 
> Suggested-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
> Signed-off-by: Lance Richardson <lrichard@redhat.com>

That commit ID doesn't look right.  It should be 9ee6c5dc816a

^ permalink raw reply

* Re: [PATCH net-next 0/2] RDS: TCP: bug fixes
From: David Miller @ 2016-11-09 17:48 UTC (permalink / raw)
  To: sowmini.varadhan; +Cc: netdev, rds-devel, santosh.shilimkar
In-Reply-To: <cover.1478276221.git.sowmini.varadhan@oracle.com>

From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
Date: Fri,  4 Nov 2016 10:04:10 -0700

> A couple of bug fixes identified during testing. 

Series applied, thanks.

^ permalink raw reply

* Re: [PATCH net-next 0/2] ARM64: Add Internal PHY support for Meson GXL
From: David Miller @ 2016-11-09 17:51 UTC (permalink / raw)
  To: narmstrong
  Cc: f.fainelli, carlo, khilman, andrew, netdev, linux-amlogic,
	linux-arm-kernel, linux-kernel
In-Reply-To: <1478274683-1503-1-git-send-email-narmstrong@baylibre.com>

From: Neil Armstrong <narmstrong@baylibre.com>
Date: Fri,  4 Nov 2016 16:51:21 +0100

> The Amlogic Meson GXL SoCs have an internal RMII PHY that is muxed with the
> external RGMII pins.
> 
> In order to support switching between the two PHYs links, extended registers
> size for mdio-mux-mmioreg must be added.
> 
> The DT related patches submitted as RFC in [3] will be sent in a separate
> patchset due to multiple patchsets and DTSI migrations.
> 
> Changes since v2 RFC patchset at : [3]
>  - Change phy Kconfig/Makefile alphabetic order
>  - GXL dtsi cleanup
> 
> Changes since original RFC patchset at : [2]
>  - Remove meson8b experimental phy switching
>  - Switch to mdio-mux-mmioreg with extennded size support
>  - Add internal phy support for S905x and p231
>  - Add external PHY support for p230
> 
> [1] http://lkml.kernel.org/r/1477932286-27482-1-git-send-email-narmstrong@baylibre.com
> [2] http://lkml.kernel.org/r/1477060838-14164-1-git-send-email-narmstrong@baylibre.com
> [3] http://lkml.kernel.org/r/1477932987-27871-1-git-send-email-narmstrong@baylibre.com

Series applied, thanks.

^ permalink raw reply

* Re: [PATCH] [RFC] net: phy: phy drivers should not set SUPPORTED_Pause or SUPPORTED_Asym_Pause
From: Florian Fainelli @ 2016-11-09 17:55 UTC (permalink / raw)
  To: Timur Tabi, David Miller, netdev
In-Reply-To: <58235E0A.2030305@codeaurora.org>

On 11/09/2016 09:34 AM, Timur Tabi wrote:
> On 11/09/2016 11:06 AM, Florian Fainelli wrote:
> 
>>> 1) PHY drivers and/or phylib sets the SUPPORTED_Pause |
>>> SUPPORTED_AsymPause bits in phydev->supported.  This indicates that the
>>> PHY supports pause frames.
>>
>> Agreed.
> 
> So I'm still not sure *where* phylib should set the bits in
> phydev->supported.  I previously thought that phy_sanitize_settings()
> would be a candidate, but that function is called only when
> autonegotiation is disabled.
> 
> So the only thing I can think of is to do this:
> 
> /* A mapping of all SUPPORTED settings to speed/duplex */
> static const struct phy_setting settings[] = {
>     {
>         .speed = SPEED_10000,
>         .duplex = DUPLEX_FULL,
> -        .setting = SUPPORTED_10000baseKR_Full,
> +        .setting = SUPPORTED_10000baseKR_Full |
> +            SUPPORTED_Pause | SUPPORTED_Asym_Pause,
> 
> ... for all of the entries in settings[]
> 
> But this seems excessive, and I don't know if all of these SPEED_xxx
> standards actually support pause frames.

You could set these bits in phy_probe() and later let the
phy_sanitize_settings() make sure that these bits do not get advertised
unless we have a full duplex link.

> 
>>> >3) When the link state changes, the MAC driver checks
>>> >phydev->advertising, and if the bits are set, then it enables those
>>> >features in the MAC.
> 
>> Almost, we need to see what the link partner advertised, by looking at
>> phydev->pause / phydev->asym_pause and checking the local knobs whether
>> flow control can be enabled, but other than that, this looks correct
>> to me.
> 
> Yes, that's what I meant to write.  Fortunately, my EMAC driver already
> does this.

OK, just making sure ;)
-- 
Florian

^ permalink raw reply

* Re: [PATCH/RFC net-next] ravb: Add dma_unmap_single in ravb_ring_free
From: Sergei Shtylyov @ 2016-11-09 18:00 UTC (permalink / raw)
  To: Simon Horman; +Cc: Magnus Damm, netdev, linux-renesas-soc
In-Reply-To: <1478532451-7296-1-git-send-email-horms+renesas@verge.net.au>

Hello.

On 11/07/2016 06:27 PM, Simon Horman wrote:

> From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
>
> The kernel panic occurs with "swiotlb buffer is full" message
> after repeating suspend and resume, because dma_map_single of
> ravb_ring_format and ravb_start_xmit is not released.

    The same issue must occur after several ifconfig up/down I think...
this is quite embarrassing actually, and I think this bug was inherited from 
sh_eth. Perhaps it was made more visible with adding PM support. :-/

> This patch adds dma_unmap_single in ravb_ring_free, and fixes
> its problem.

    Well, actually ravb_ring_free() was meant to undo what ravb_ring_init() 
does...

> Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> ---
> Sergei, this is a patch from the Gen3 3.3.2 BSP.

    I suspect the ravb driver there is greatly different from the upstream one...

> Please consider if it is appropriate for mainline.
> ---
>  drivers/net/ethernet/renesas/ravb_main.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)
>
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> index 27cfec3154c8..e44629b75c83 100644
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
> @@ -185,6 +185,9 @@ static void ravb_ring_free(struct net_device *ndev, int q)
>  	struct ravb_private *priv = netdev_priv(ndev);
>  	int ring_size;
>  	int i;
> +	struct ravb_ex_rx_desc *rx_desc;
> +	struct ravb_tx_desc *tx_desc;
> +	u32 size;

    DaveM prefers the local declarations in the reverse Xmas tree order; me 
too. :-)

[...]
> @@ -207,6 +210,16 @@ static void ravb_ring_free(struct net_device *ndev, int q)
>  	priv->tx_align[q] = NULL;
>
>  	if (priv->rx_ring[q]) {
> +		for (i = 0; i < priv->num_rx_ring[q]; i++) {
> +			rx_desc = &priv->rx_ring[q][i];
> +			if (rx_desc->dptr != 0) {

    This seems wrong. This driver uses RX descriptors with zero data size to 
indicate the failed DMA mapping. And anyway, I think you should have used 
dma_mapping_error() instead of a zero check... and '!= 0' was unnecessary.

> +				dma_unmap_single(ndev->dev.parent,
> +						 le32_to_cpu(rx_desc->dptr),
> +						 PKT_BUF_SZ,
> +						 DMA_FROM_DEVICE);
> +				rx_desc->dptr = 0;

    Hence I'd prefer:

				rx_desc->ds_cc = cpu_to_le16(0);

[...]
> @@ -215,6 +228,16 @@ static void ravb_ring_free(struct net_device *ndev, int q)
>  	}
>
>  	if (priv->tx_ring[q]) {
> +		for (i = 0; i < priv->num_tx_ring[q]; i++) {

    I'm afraid this is wrong. TX ring contains NUM_TX_DESC (2) descriptors per 
skb, so this loop only cleans the 1st half of the TX ring.

> +			tx_desc = &priv->tx_ring[q][i];
> +			size = le16_to_cpu(tx_desc->ds_tagl) & TX_DS;
> +			if (tx_desc->dptr != 0) {
> +				dma_unmap_single(ndev->dev.parent,
> +						 le32_to_cpu(tx_desc->dptr),
> +						 size, DMA_TO_DEVICE);
> +				tx_desc->dptr = 0;

    Again, I'm not fond of this... are you sure 0 is incorrect DMA address?

> +			}
> +		}

    BTW, can't we use ravb_tx_free() instead of this loop?

MBR, Sergei

^ permalink raw reply

* [PATCH 1/2] wcn36xx: Correct Kconfig dependency
From: Bjorn Andersson @ 2016-11-09 18:02 UTC (permalink / raw)
  To: Andy Gross, Eugene Krasnikov, Kalle Valo
  Cc: wcn36xx, linux-wireless, netdev, linux-kernel
In-Reply-To: <201611092150.OxpAuHow%fengguang.wu@intel.com>

In the case SMD or WCNSS_CTRL are compiled as modules, wcn36xx must be
compiled as module as well, so we need to mention this dependency.
But we still want allow the driver to be compiled in case either of
those are =n, for compile testing reasons.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---
 drivers/net/wireless/ath/wcn36xx/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/wcn36xx/Kconfig b/drivers/net/wireless/ath/wcn36xx/Kconfig
index 591ebaea8265..4b83e87f0b94 100644
--- a/drivers/net/wireless/ath/wcn36xx/Kconfig
+++ b/drivers/net/wireless/ath/wcn36xx/Kconfig
@@ -1,6 +1,8 @@
 config WCN36XX
 	tristate "Qualcomm Atheros WCN3660/3680 support"
 	depends on MAC80211 && HAS_DMA
+	depends on QCOM_WCNSS_CTRL || QCOM_WCNSS_CTRL=n
+	depends on QCOM_SMD || QCOM_SMD=n
 	---help---
 	  This module adds support for wireless adapters based on
 	  Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
-- 
2.5.0

^ permalink raw reply related

* [PATCH 2/2] soc: qcom: smem_state: Fix include for ERR_PTR()
From: Bjorn Andersson @ 2016-11-09 18:02 UTC (permalink / raw)
  To: Andy Gross, Eugene Krasnikov, Kalle Valo
  Cc: wcn36xx, linux-wireless, netdev, linux-kernel
In-Reply-To: <201611092150.OxpAuHow%fengguang.wu@intel.com>

The correct include file for getting errno constants and ERR_PTR() is
linux/err.h, rather than linux/errno.h, so fix the include.

Fixes: e8b123e60084 ("soc: qcom: smem_state: Add stubs for disabled smem_state")
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---

Andy, I don't see anything else going into v4.10 for smem_state.h. So if you
are okay I would like Kalle to pick this patch through his tree and be able to
merge my wcn36xx patches for v4.10.

 include/linux/soc/qcom/smem_state.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/soc/qcom/smem_state.h b/include/linux/soc/qcom/smem_state.h
index 7b88697929e9..b8478ee7a71f 100644
--- a/include/linux/soc/qcom/smem_state.h
+++ b/include/linux/soc/qcom/smem_state.h
@@ -1,7 +1,7 @@
 #ifndef __QCOM_SMEM_STATE__
 #define __QCOM_SMEM_STATE__
 
-#include <linux/errno.h>
+#include <linux/err.h>
 
 struct device_node;
 struct qcom_smem_state;
-- 
2.5.0

^ permalink raw reply related

* Re: [PATCH net-next 0/2] tcp: tcp_get_info() locking changes
From: David Miller @ 2016-11-09 18:03 UTC (permalink / raw)
  To: edumazet; +Cc: netdev, ncardwell, ycheng, soheil, eric.dumazet
In-Reply-To: <1478285672-3195-1-git-send-email-edumazet@google.com>

From: Eric Dumazet <edumazet@google.com>
Date: Fri,  4 Nov 2016 11:54:30 -0700

> This short series prepares tcp_get_info() for more detailed infos.
> 
> In order to not slow down fast path, our goal is to use the normal
> socket spinlock instead of custom synchronization.
> 
> All we need to ensure is that tcp_get_info() is not called with
> ehash lock, which might dead lock, since packet processing would acquire
> the spinlocks in reverse way.

Looks really nice, series applied, thanks Eric.

BTW, can we possibly use the netlink NOP trick to align the netlink
attribute data here and avoid these unaligned accesses?

Thanks again.

^ permalink raw reply

* Re: [PATCH net-next 0/2] sfc: enable 4-tuple UDP RSS hashing
From: David Miller @ 2016-11-09 18:09 UTC (permalink / raw)
  To: ecree; +Cc: netdev, linux-net-drivers
In-Reply-To: <2c97d90b-bbb3-2cdc-7a72-597fd3f5231a@solarflare.com>

From: Edward Cree <ecree@solarflare.com>
Date: Tue, 8 Nov 2016 13:02:05 +0000

> On 07/11/16 18:20, David Miller wrote:
>> From: Edward Cree <ecree@solarflare.com>
>> Date: Thu, 3 Nov 2016 22:10:31 +0000
>>
>>> EF10 based NICs have configurable RSS hash fields, and can be made to take the
>>> ports into the hash on UDP (they already do so for TCP).  This patch series
>>> enables this, in order to improve spreading of UDP traffic.
>> What does the chip do with fragmented traffic?
> Only the first fragment will be considered UDP, it will treat the rest as "other
> IP" and 2-tuple hash them, probably hitting a different queue.
> 
> My understanding is that while that will reduce performance, that shouldn't be a
> problem as performance-sensitive users will avoid fragmentation anyway.
> It could also lead to out-of-order packet delivery, but it's UDP so that's
> supposed to be OK.

Our software hashing never tries to inspect the ports for fragmented
frames.  And I'm pretty sure this is intentional.

We should minimize the difference between what we do in software, which
we fully control, and what we ask the hardware to offload for us.

If you can't configure the chip to skip the ports for fragmented frames
than I'm going to ask you to drop this.

^ permalink raw reply

* [PATCH net-next 00/17] Bug fixes & Code improvements in HNS driver
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm

This patch-set introduces some bug fixes and code improvements.
These have been identified during internal review or testing of
the driver by internal Hisilicon teams.

Daode Huang (3):
  net: hns: set default mac pause time to 0xffff
  net: hns: bug fix about restart auto-negotiation
  net: hns: fix to intimate the link-status change by adding LF/RF
    method

Kejian Yan (5):
  Doc: hisi: hns adds mc-mac-mask property
  net: hns: add fuzzy match of tcam table for hns
  net: hns: fix for promisc mode in HNS driver
  net: hns: add multicast tcam table clear
  net: hns: add the support to add/remove the ucast entry to/from table

Qianqian Xie (9):
  net: hns: delete redundant macro definition
  net: hns: modify ethtool statistics value error
  net: hns: modify buffer format of cpu data to le64
  net: hns: modify tcam table and set mac key
  net: hns: modify tcam table of mac uc-entry
  net: hns: modify table index to get mac entry
  net: hns: modify tcam table of mac mc-port
  net: hns: modify tcam table of mac mc-entry
  net: hns: modify tcam table of mask_key

 .../devicetree/bindings/net/hisilicon-hns-dsaf.txt |    8 +
 drivers/net/ethernet/hisilicon/hns/hnae.h          |   17 +-
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c  |   38 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c |    4 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  |   70 +++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |   17 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c |  411 +++++++++++++++++---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |   31 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c |   31 --
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |   13 +-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c    |   41 +-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h    |    5 +-
 drivers/net/ethernet/hisilicon/hns/hns_enet.c      |   30 ++
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c   |    3 +-
 14 files changed, 577 insertions(+), 142 deletions(-)

-- 
1.7.9.5

^ permalink raw reply

* [PATCH net-next 01/17] Doc: hisi: hns adds mc-mac-mask property
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Kejian Yan
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Kejian Yan <yankejian@huawei.com>

Since there is not enough tcam table entries for every vlan and multicast
address, HNS needs to add support of fuzzy matching of TCAM tables. Adding
the property to mask the bits to be fuzzy matched, so update the bindings
document

Signed-off-by: Kejian Yan <yankejian@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 .../devicetree/bindings/net/hisilicon-hns-dsaf.txt |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
index d4b7f2e..abfbeec 100644
--- a/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
+++ b/Documentation/devicetree/bindings/net/hisilicon-hns-dsaf.txt
@@ -45,6 +45,12 @@ Required properties:
   depends on the hardware user manual.
 - port-mode-offset: is offset of port mode field for each port in dsaf. Its
   value depends on the hardware user manual.
+- mc-mac-mask: mask of multicast address, determines bit in multicast address
+  to set:
+  1 stands for this bit will be precisely matched, TCAM will check this bit of
+    MAC address.
+  0 stands for this bit will be fuzzy matched, TCAM won't care about this bit
+    of MAC address.
 
 [1] Documentation/devicetree/bindings/net/phy.txt
 
@@ -74,10 +80,12 @@ dsaf0: dsa@c7000000 {
 		reg = 0;
 		phy-handle = <&phy0>;
 		serdes-syscon = <&serdes>;
+		mc-mac-mask = [ff f0 00 00 00 00];
 	};
 
 	port@1 {
                 reg = 1;
                 serdes-syscon = <&serdes>;
+		mc-mac-mask = [ff f0 00 00 00 00];
         };
 };
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 02/17] net: hns: add fuzzy match of tcam table for hns
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Kejian Yan
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Kejian Yan <yankejian@huawei.com>

Since there is not enough tcam table entries for vlan and multicast
address, HNSv2 needs to add support of fuzzy matching of TCAM tables.
To add fuzzy match of TCAM, we Add the property to mask the bits to
be fuzzy matched

Signed-off-by: Kejian Yan <yankejian@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  |   16 ++-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h  |    8 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c |  140 ++++++++++++++------
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |    6 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |    2 +
 5 files changed, 118 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 55cbb6c..2d64f53 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -335,8 +335,7 @@ static void hns_mac_param_get(struct mac_params *param,
 {
 	param->vaddr = (void *)mac_cb->vaddr;
 	param->mac_mode = hns_get_enet_interface(mac_cb);
-	memcpy(param->addr, mac_cb->addr_entry_idx[0].addr,
-	       MAC_NUM_OCTETS_PER_ADDR);
+	ether_addr_copy(param->addr, mac_cb->addr_entry_idx[0].addr);
 	param->mac_id = mac_cb->mac_id;
 	param->dev = mac_cb->dev;
 }
@@ -353,8 +352,7 @@ static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb,
 {
 	int ret;
 	struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
-	u8 addr[MAC_NUM_OCTETS_PER_ADDR]
-		= {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+	u8 addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 	struct dsaf_drv_mac_single_dest_entry mac_entry;
 
 	/* directy return ok in debug network mode */
@@ -389,8 +387,7 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable)
 	int ret;
 	struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
 	u8 port_num;
-	u8 addr[MAC_NUM_OCTETS_PER_ADDR]
-		= {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+	u8 addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 	struct mac_entry_idx *uc_mac_entry;
 	struct dsaf_drv_mac_single_dest_entry mac_entry;
 
@@ -868,6 +865,13 @@ static int  hns_mac_get_info(struct hns_mac_cb *mac_cb)
 		}
 	}
 
+	if (fwnode_property_read_u8_array(mac_cb->fw_port, "mc-mac-mask",
+					  mac_cb->mc_mask, ETH_ALEN)) {
+		dev_warn(mac_cb->dev,
+			 "no mc-mac-mask property, set to default value.\n");
+		eth_broadcast_addr(mac_cb->mc_mask);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index d3a1f72..1d941d5 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -56,9 +56,6 @@
 /*check mac addr multicast*/
 #define MAC_IS_MULTICAST(p)	((*((u8 *)((p) + 0)) & 0x01) ? (1) : (0))
 
-/**< Number of octets (8-bit bytes) in an ethernet address */
-#define MAC_NUM_OCTETS_PER_ADDR 6
-
 struct mac_priv {
 	void *mac;
 };
@@ -189,7 +186,7 @@ struct mac_statistics {
 
 /*mac para struct ,mac get param from nic or dsaf when initialize*/
 struct mac_params {
-	char addr[MAC_NUM_OCTETS_PER_ADDR];
+	char addr[ETH_ALEN];
 	void *vaddr; /*virtual address*/
 	struct device *dev;
 	u8 mac_id;
@@ -214,7 +211,7 @@ struct mac_info {
 };
 
 struct mac_entry_idx {
-	u8 addr[MAC_NUM_OCTETS_PER_ADDR];
+	u8 addr[ETH_ALEN];
 	u16 vlan_id:12;
 	u16 valid:1;
 	u16 qos:3;
@@ -317,6 +314,7 @@ struct hns_mac_cb {
 	u8 __iomem *serdes_vaddr;
 	struct regmap *serdes_ctrl;
 	struct regmap *cpld_ctrl;
+	char mc_mask[ETH_ALEN];
 	u32 cpld_ctrl_reg;
 	u32 port_rst_off;
 	u32 port_mode_off;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 8ea3d95..64f45ee 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -591,6 +591,16 @@ static void hns_dsaf_voq_bp_all_thrd_cfg(struct dsaf_device *dsaf_dev)
 	}
 }
 
+static void hns_dsaf_tbl_tcam_match_cfg(
+	struct dsaf_device *dsaf_dev,
+	struct dsaf_tbl_tcam_data *ptbl_tcam_data)
+{
+	dsaf_write_dev(dsaf_dev, DSAF_TBL_TCAM_MATCH_CFG_L_REG,
+		       ptbl_tcam_data->tbl_tcam_data_low);
+	dsaf_write_dev(dsaf_dev, DSAF_TBL_TCAM_MATCH_CFG_H_REG,
+		       ptbl_tcam_data->tbl_tcam_data_high);
+}
+
 /**
  * hns_dsaf_tbl_tcam_data_cfg - tbl
  * @dsaf_id: dsa fabric id
@@ -894,15 +904,16 @@ static void hns_dsaf_tcam_uc_cfg(
 }
 
 /**
- * hns_dsaf_tcam_mc_cfg - INT
- * @dsaf_id: dsa fabric id
- * @address,
- * @ptbl_tcam_data,
- * @ptbl_tcam_mcast,
+ * hns_dsaf_tcam_mc_cfg - cfg the tcam for mc
+ * @dsaf_dev: dsa fabric device struct pointer
+ * @address: tcam index
+ * @ptbl_tcam_data: tcam data struct pointer
+ * @ptbl_tcam_mcast: tcam mask struct pointer, it must be null for HNSv1
  */
 static void hns_dsaf_tcam_mc_cfg(
 	struct dsaf_device *dsaf_dev, u32 address,
 	struct dsaf_tbl_tcam_data *ptbl_tcam_data,
+	struct dsaf_tbl_tcam_data *ptbl_tcam_mask,
 	struct dsaf_tbl_tcam_mcast_cfg *ptbl_tcam_mcast)
 {
 	spin_lock_bh(&dsaf_dev->tcam_lock);
@@ -913,7 +924,11 @@ static void hns_dsaf_tcam_mc_cfg(
 	hns_dsaf_tbl_tcam_data_cfg(dsaf_dev, ptbl_tcam_data);
 	/*Write Tcam Mcast*/
 	hns_dsaf_tbl_tcam_mcast_cfg(dsaf_dev, ptbl_tcam_mcast);
-	/*Write Plus*/
+	/* Write Match Data */
+	if (ptbl_tcam_mask)
+		hns_dsaf_tbl_tcam_match_cfg(dsaf_dev, ptbl_tcam_mask);
+
+	/* Write Puls */
 	hns_dsaf_tbl_tcam_data_mcast_pul(dsaf_dev);
 
 	spin_unlock_bh(&dsaf_dev->tcam_lock);
@@ -1625,7 +1640,7 @@ int hns_dsaf_set_mac_mc_entry(
 
 	hns_dsaf_tcam_mc_cfg(
 		dsaf_dev, entry_index,
-		(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
+		(struct dsaf_tbl_tcam_data *)(&mac_key), NULL, &mac_data);
 
 	/* config software entry */
 	soft_mac_entry += entry_index;
@@ -1636,6 +1651,16 @@ int hns_dsaf_set_mac_mc_entry(
 	return 0;
 }
 
+static void hns_dsaf_mc_mask_bit_clear(char *dst, const char *src)
+{
+	u16 *a = (u16 *)dst;
+	const u16 *b = (const u16 *)src;
+
+	a[0] &= b[0];
+	a[1] &= b[1];
+	a[2] &= b[2];
+}
+
 /**
  * hns_dsaf_add_mac_mc_port - add mac mc-port
  * @dsaf_dev: dsa fabric device struct pointer
@@ -1646,11 +1671,14 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
 {
 	u16 entry_index = DSAF_INVALID_ENTRY_IDX;
 	struct dsaf_drv_tbl_tcam_key mac_key;
+	struct dsaf_drv_tbl_tcam_key mask_key;
+	struct dsaf_tbl_tcam_data *pmask_key = NULL;
 	struct dsaf_tbl_tcam_mcast_cfg mac_data;
-	struct dsaf_drv_priv *priv =
-	    (struct dsaf_drv_priv *)hns_dsaf_dev_priv(dsaf_dev);
+	struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
 	struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
-	struct dsaf_drv_tbl_tcam_key tmp_mac_key;
+	struct dsaf_tbl_tcam_data tcam_data;
+	u8 mc_addr[ETH_ALEN];
+	u8 *mc_mask;
 	int mskid;
 
 	/*chechk mac addr */
@@ -1660,14 +1688,28 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
 		return -EINVAL;
 	}
 
+	ether_addr_copy(mc_addr, mac_entry->addr);
+	mc_mask = dsaf_dev->mac_cb[mac_entry->in_port_num]->mc_mask;
+	if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) {
+		/* prepare for key data setting */
+		hns_dsaf_mc_mask_bit_clear(mc_addr, mc_mask);
+
+		/* config key mask */
+		hns_dsaf_set_mac_key(dsaf_dev, &mask_key,
+				     0x0,
+				     0xff,
+				     mc_mask);
+		pmask_key = (struct dsaf_tbl_tcam_data *)(&mask_key);
+	}
+
 	/*config key */
 	hns_dsaf_set_mac_key(
 		dsaf_dev, &mac_key, mac_entry->in_vlan_id,
-		mac_entry->in_port_num, mac_entry->addr);
+		mac_entry->in_port_num, mc_addr);
 
 	memset(&mac_data, 0, sizeof(struct dsaf_tbl_tcam_mcast_cfg));
 
-	/*check exist? */
+	/* check if the tcam is exist */
 	entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
 	if (entry_index == DSAF_INVALID_ENTRY_IDX) {
 		/*if hasnot , find a empty*/
@@ -1681,11 +1723,11 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
 			return -EINVAL;
 		}
 	} else {
-		/*if exist, add in */
-		hns_dsaf_tcam_mc_get(
-			dsaf_dev, entry_index,
-			(struct dsaf_tbl_tcam_data *)(&tmp_mac_key), &mac_data);
+		/* if exist, add in */
+		hns_dsaf_tcam_mc_get(dsaf_dev, entry_index, &tcam_data,
+				     &mac_data);
 	}
+
 	/* config hardware entry */
 	if (mac_entry->port_num < DSAF_SERVICE_NW_NUM) {
 		mskid = mac_entry->port_num;
@@ -1708,9 +1750,12 @@ int hns_dsaf_add_mac_mc_port(struct dsaf_device *dsaf_dev,
 		dsaf_dev->ae_dev.name, mac_key.high.val,
 		mac_key.low.val, entry_index);
 
-	hns_dsaf_tcam_mc_cfg(
-		dsaf_dev, entry_index,
-		(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
+	tcam_data.tbl_tcam_data_high = mac_key.high.val;
+	tcam_data.tbl_tcam_data_low = mac_key.low.val;
+
+	/* config mc entry with mask */
+	hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index, &tcam_data,
+			     pmask_key, &mac_data);
 
 	/*config software entry */
 	soft_mac_entry += entry_index;
@@ -1782,15 +1827,18 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
 {
 	u16 entry_index = DSAF_INVALID_ENTRY_IDX;
 	struct dsaf_drv_tbl_tcam_key mac_key;
-	struct dsaf_drv_priv *priv =
-	    (struct dsaf_drv_priv *)hns_dsaf_dev_priv(dsaf_dev);
+	struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
 	struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
 	u16 vlan_id;
 	u8 in_port_num;
 	struct dsaf_tbl_tcam_mcast_cfg mac_data;
-	struct dsaf_drv_tbl_tcam_key tmp_mac_key;
+	struct dsaf_tbl_tcam_data tcam_data;
 	int mskid;
 	const u8 empty_msk[sizeof(mac_data.tbl_mcast_port_msk)] = {0};
+	struct dsaf_drv_tbl_tcam_key mask_key;
+	struct dsaf_tbl_tcam_data *pmask_key = NULL;
+	u8 mc_addr[ETH_ALEN];
+	u8 *mc_mask;
 
 	if (!(void *)mac_entry) {
 		dev_err(dsaf_dev->dev,
@@ -1798,10 +1846,6 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
 		return -EINVAL;
 	}
 
-	/*get key info*/
-	vlan_id = mac_entry->in_vlan_id;
-	in_port_num = mac_entry->in_port_num;
-
 	/*check mac addr */
 	if (MAC_IS_ALL_ZEROS(mac_entry->addr)) {
 		dev_err(dsaf_dev->dev, "del_port failed, addr %pM!\n",
@@ -1809,11 +1853,28 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
 		return -EINVAL;
 	}
 
-	/*config key */
-	hns_dsaf_set_mac_key(dsaf_dev, &mac_key, vlan_id, in_port_num,
-			     mac_entry->addr);
+	/* always mask vlan_id field */
+	ether_addr_copy(mc_addr, mac_entry->addr);
+	mc_mask = dsaf_dev->mac_cb[mac_entry->in_port_num]->mc_mask;
 
-	/*check is exist? */
+	if (!AE_IS_VER1(dsaf_dev->dsaf_ver)) {
+		/* prepare for key data setting */
+		hns_dsaf_mc_mask_bit_clear(mc_addr, mc_mask);
+
+		/* config key mask */
+		hns_dsaf_set_mac_key(dsaf_dev, &mask_key, 0x00, 0xff, mc_addr);
+
+		pmask_key = (struct dsaf_tbl_tcam_data *)(&mask_key);
+	}
+
+	/* get key info */
+	vlan_id = mac_entry->in_vlan_id;
+	in_port_num = mac_entry->in_port_num;
+
+	/* config key */
+	hns_dsaf_set_mac_key(dsaf_dev, &mac_key, vlan_id, in_port_num, mc_addr);
+
+	/* check if the tcam entry is exist */
 	entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
 	if (entry_index == DSAF_INVALID_ENTRY_IDX) {
 		/*find none */
@@ -1829,10 +1890,8 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
 		dsaf_dev->ae_dev.name, mac_key.high.val,
 		mac_key.low.val, entry_index);
 
-	/*read entry*/
-	hns_dsaf_tcam_mc_get(
-		dsaf_dev, entry_index,
-		(struct dsaf_tbl_tcam_data *)(&tmp_mac_key), &mac_data);
+	/* read entry */
+	hns_dsaf_tcam_mc_get(dsaf_dev, entry_index, &tcam_data, &mac_data);
 
 	/*del the port*/
 	if (mac_entry->port_num < DSAF_SERVICE_NW_NUM) {
@@ -1857,10 +1916,13 @@ int hns_dsaf_del_mac_mc_port(struct dsaf_device *dsaf_dev,
 		/* del soft entry */
 		soft_mac_entry += entry_index;
 		soft_mac_entry->index = DSAF_INVALID_ENTRY_IDX;
-	} else { /* not zer, just del port, updata*/
-		hns_dsaf_tcam_mc_cfg(
-			dsaf_dev, entry_index,
-			(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
+	} else { /* not zero, just del port, update */
+		tcam_data.tbl_tcam_data_high = mac_key.high.val;
+		tcam_data.tbl_tcam_data_low = mac_key.low.val;
+
+		hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index,
+				     &tcam_data,
+				     pmask_key, &mac_data);
 	}
 
 	return 0;
@@ -1976,7 +2038,7 @@ int hns_dsaf_get_mac_entry_by_index(
 
 	struct dsaf_tbl_tcam_mcast_cfg mac_data;
 	struct dsaf_tbl_tcam_ucast_cfg mac_uc_data;
-	char mac_addr[MAC_NUM_OCTETS_PER_ADDR] = {0};
+	char mac_addr[ETH_ALEN] = {0};
 
 	if (entry_index >= DSAF_TCAM_SUM) {
 		/* find none, del error */
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index c494fc5..f832a32 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -35,8 +35,6 @@
 
 #define DSAF_CFG_READ_CNT   30
 
-#define MAC_NUM_OCTETS_PER_ADDR 6
-
 #define DSAF_DUMP_REGS_NUM 504
 #define DSAF_STATIC_NUM 28
 #define DSAF_V2_STATIC_NUM	44
@@ -165,7 +163,7 @@ enum dsaf_mode {
 /*mac entry, mc or uc entry*/
 struct dsaf_drv_mac_single_dest_entry {
 	/* mac addr, match the entry*/
-	u8 addr[MAC_NUM_OCTETS_PER_ADDR];
+	u8 addr[ETH_ALEN];
 	u16 in_vlan_id; /* value of VlanId */
 
 	/* the vld input port num, dsaf-mode fix 0, */
@@ -179,7 +177,7 @@ struct dsaf_drv_mac_single_dest_entry {
 /*only mc entry*/
 struct dsaf_drv_mac_multi_dest_entry {
 	/* mac addr, match the entry*/
-	u8 addr[MAC_NUM_OCTETS_PER_ADDR];
+	u8 addr[ETH_ALEN];
 	u16 in_vlan_id;
 	/* this mac addr output port,*/
 	/*	bit0-bit5 means Port0-Port5(1bit is vld)**/
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index 878950a..6826b28 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -297,6 +297,8 @@
 #define DSAF_TBL_LKUP_NUM_I_0_REG		0x50C0
 #define DSAF_TBL_LKUP_NUM_O_0_REG		0x50E0
 #define DSAF_TBL_UCAST_BCAST_MIS_INFO_0_0_REG	0x510C
+#define DSAF_TBL_TCAM_MATCH_CFG_H_REG		0x5130
+#define DSAF_TBL_TCAM_MATCH_CFG_L_REG		0x5134
 
 #define DSAF_INODE_FIFO_WL_0_REG		0x6000
 #define DSAF_ONODE_FIFO_WL_0_REG		0x6020
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 03/17] net: hns: fix for promisc mode in HNS driver
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Kejian Yan
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Kejian Yan <yankejian@huawei.com>

If set promisc mode when there is some traffic, The service nic will
cause system halted. We reserve the last 6 tcam entry for the 6 ports.
If promisc mode is enabled, we can config the relative tcam as fuzzy
matching and set to be valid, or set the tcam to be invalid

Signed-off-by: Kejian Yan <yankejian@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  |    2 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c |   63 ++++++++++++++++++--
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |    3 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |    3 +
 4 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
index 2d64f53..fc90260 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -1085,6 +1085,8 @@ void hns_mac_set_promisc(struct hns_mac_cb *mac_cb, u8 en)
 {
 	struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
 
+	hns_dsaf_set_promisc_tcam(mac_cb->dsaf_dev, mac_cb->mac_id, !!en);
+
 	if (mac_ctrl_drv->set_promiscuous)
 		mac_ctrl_drv->set_promiscuous(mac_ctrl_drv, en);
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 64f45ee..2721458 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -765,7 +765,7 @@ static void hns_dsaf_tbl_tcam_data_ucast_pul(
 
 void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en)
 {
-	if (!HNS_DSAF_IS_DEBUG(dsaf_dev))
+	if (AE_IS_VER1(dsaf_dev->dsaf_ver) && !HNS_DSAF_IS_DEBUG(dsaf_dev))
 		dsaf_set_dev_bit(dsaf_dev, DSAF_CFG_0_REG,
 				 DSAF_CFG_MIX_MODE_S, !!en);
 }
@@ -1384,6 +1384,12 @@ static int hns_dsaf_init(struct dsaf_device *dsaf_dev)
 	if (HNS_DSAF_IS_DEBUG(dsaf_dev))
 		return 0;
 
+	if (AE_IS_VER1(dsaf_dev->dsaf_ver))
+		dsaf_dev->tcam_max_num = DSAF_TCAM_SUM;
+	else
+		dsaf_dev->tcam_max_num =
+			DSAF_TCAM_SUM - DSAFV2_MAC_FUZZY_TCAM_NUM;
+
 	spin_lock_init(&dsaf_dev->tcam_lock);
 	ret = hns_dsaf_init_hw(dsaf_dev);
 	if (ret)
@@ -1439,7 +1445,7 @@ static u16 hns_dsaf_find_soft_mac_entry(
 	u32 i;
 
 	soft_mac_entry = priv->soft_mac_tbl;
-	for (i = 0; i < DSAF_TCAM_SUM; i++) {
+	for (i = 0; i < dsaf_dev->tcam_max_num; i++) {
 		/* invall tab entry */
 		if ((soft_mac_entry->index != DSAF_INVALID_ENTRY_IDX) &&
 		    (soft_mac_entry->tcam_key.high.val == mac_key->high.val) &&
@@ -1464,7 +1470,7 @@ static u16 hns_dsaf_find_empty_mac_entry(struct dsaf_device *dsaf_dev)
 	u32 i;
 
 	soft_mac_entry = priv->soft_mac_tbl;
-	for (i = 0; i < DSAF_TCAM_SUM; i++) {
+	for (i = 0; i < dsaf_dev->tcam_max_num; i++) {
 		/* inv all entry */
 		if (soft_mac_entry->index == DSAF_INVALID_ENTRY_IDX)
 			/* return find result --soft index */
@@ -2040,7 +2046,7 @@ int hns_dsaf_get_mac_entry_by_index(
 	struct dsaf_tbl_tcam_ucast_cfg mac_uc_data;
 	char mac_addr[ETH_ALEN] = {0};
 
-	if (entry_index >= DSAF_TCAM_SUM) {
+	if (entry_index >= dsaf_dev->tcam_max_num) {
 		/* find none, del error */
 		dev_err(dsaf_dev->dev, "get_uc_entry failed, %s\n",
 			dsaf_dev->ae_dev.name);
@@ -2732,6 +2738,55 @@ int hns_dsaf_get_regs_count(void)
 	return DSAF_DUMP_REGS_NUM;
 }
 
+/* Reserve the last TCAM entry for promisc support */
+#define dsaf_promisc_tcam_entry(port) \
+	(DSAF_TCAM_SUM - DSAFV2_MAC_FUZZY_TCAM_NUM + (port))
+void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
+			       u32 port, bool enable)
+{
+	struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
+	struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
+	u16 entry_index;
+	struct dsaf_drv_tbl_tcam_key tbl_tcam_data, tbl_tcam_mask;
+	struct dsaf_tbl_tcam_mcast_cfg mac_data = {0};
+
+	if ((AE_IS_VER1(dsaf_dev->dsaf_ver)) || HNS_DSAF_IS_DEBUG(dsaf_dev))
+		return;
+
+	/* find the tcam entry index for promisc */
+	entry_index = dsaf_promisc_tcam_entry(port);
+
+	/* config key mask */
+	if (enable) {
+		memset(&tbl_tcam_data, 0, sizeof(tbl_tcam_data));
+		memset(&tbl_tcam_mask, 0, sizeof(tbl_tcam_mask));
+		tbl_tcam_data.low.bits.port = port;
+		tbl_tcam_mask.low.bits.port = 0xf;  /* [3:0]: port id */
+
+		/* SUB_QID */
+		dsaf_set_bit(mac_data.tbl_mcast_port_msk[0],
+			     DSAF_SERVICE_NW_NUM, true);
+		mac_data.tbl_mcast_item_vld = true;	/* item_vld bit */
+	} else {
+		mac_data.tbl_mcast_item_vld = false;	/* item_vld bit */
+	}
+
+	dev_dbg(dsaf_dev->dev,
+		"set_promisc_entry, %s Mac key(%#x:%#x) entry_index%d\n",
+		dsaf_dev->ae_dev.name, tbl_tcam_data.high.val,
+		tbl_tcam_data.low.val, entry_index);
+
+	/* config promisc entry with mask */
+	hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index,
+			     (struct dsaf_tbl_tcam_data *)&tbl_tcam_data,
+			     (struct dsaf_tbl_tcam_data *)&tbl_tcam_mask,
+			     &mac_data);
+
+	/* config software entry */
+	soft_mac_entry += entry_index;
+	soft_mac_entry->index = enable ? entry_index : DSAF_INVALID_ENTRY_IDX;
+}
+
 /**
  * dsaf_probe - probo dsaf dev
  * @pdev: dasf platform device
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index f832a32..2cae6eb 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -341,6 +341,7 @@ struct dsaf_device {
 	enum hal_dsaf_mode dsaf_en;
 	enum hal_dsaf_tc_mode dsaf_tc_mode;
 	u32 dsaf_ver;
+	u16 tcam_max_num;	/* max TCAM entry for user except promisc */
 
 	struct ppe_common_cb *ppe_common[DSAF_COMM_DEV_NUM];
 	struct rcb_common_cb *rcb_common[DSAF_COMM_DEV_NUM];
@@ -459,6 +460,8 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port,
 void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data);
 int hns_dsaf_get_regs_count(void);
 void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en);
+void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
+			       u32 port, bool enable);
 
 void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
 				  u32 *en);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index 6826b28..3eb8b4d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -41,6 +41,9 @@
 #define DSAF_SW_PORT_NUM	8
 #define DSAF_TOTAL_QUEUE_NUM	129
 
+/* reserved a tcam entry for each port to support promisc by fuzzy match */
+#define DSAFV2_MAC_FUZZY_TCAM_NUM    DSAF_MAX_PORT_NUM
+
 #define DSAF_TCAM_SUM		512
 #define DSAF_LINE_SUM		(2048 * 14)
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 04/17] net: hns: set default mac pause time to 0xffff
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Daode Huang
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Daode Huang <huangdaode@hisilicon.com>

The default mac pause time set to 0xff which is too short for pausing,
this patch change it to the max value 0xffff.

Signed-off-by: Daode Huang <huangdaode@hisilicon.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Reviewed-by: lipeng <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index 1d941d5..a9b0cb3 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -31,7 +31,7 @@
 #define MAC_MIN_MTU		68
 #define MAC_MAX_MTU_DBG		MAC_DEFAULT_MTU
 
-#define MAC_DEFAULT_PAUSE_TIME 0xff
+#define MAC_DEFAULT_PAUSE_TIME 0xffff
 
 #define MAC_GMAC_IDX 0
 #define MAC_XGMAC_IDX 1
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 05/17] net: hns: bug fix about restart auto-negotiation
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Daode Huang
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Daode Huang <huangdaode@hisilicon.com>

When set auto-negotiation off and duplex half, if run "ethtool -r ethX"
on port with phy, then the port will be failed to work. It should
forbid to start auto-negotiation when auto-negotiate is off. This
patch add the limited condition.

Reported-by: Jinchuang Tian <tianjinchuang1@huawei.com>
Signed-off-by: Daode Huang <huangdaode@hisilicon.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Reviewed-by: lipeng <lipeng321@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_ethtool.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index 87d5c94..3ac2183 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
@@ -1178,7 +1178,8 @@ static int hns_nic_nway_reset(struct net_device *netdev)
 	struct phy_device *phy = netdev->phydev;
 
 	if (netif_running(netdev)) {
-		if (phy)
+		/* if autoneg is disabled, don't restart auto-negotiation */
+		if (phy && phy->autoneg == AUTONEG_ENABLE)
 			ret = genphy_restart_aneg(phy);
 	}
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 06/17] net: hns: delete redundant macro definition
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Qianqian Xie, Weiwei Deng
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Qianqian Xie <xieqianqian@huawei.com>

This patch deletes redundant macro definitions in hns drivers.
And change the .h file containing relation to make the layers
more clearly

Signed-off-by: Qianqian Xie <xieqianqian@huawei.com>
Signed-off-by: Weiwei Deng <dengweiwei@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |    3 ---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h |    2 +-
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h |    1 -
 3 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
index 2d0cb60..193248f 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
@@ -18,9 +18,6 @@
 #include "hns_dsaf_rcb.h"
 
 #define AE_NAME_PORT_ID_IDX 6
-#define ETH_STATIC_REG	 1
-#define ETH_DUMP_REG	 5
-#define ETH_GSTRING_LEN	32
 
 static struct hns_mac_cb *hns_get_mac_cb(struct hnae_handle *handle)
 {
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
index a9b0cb3..ca7e175 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
@@ -407,7 +407,7 @@ struct mac_driver {
 };
 
 struct mac_stats_string {
-	char desc[64];
+	char desc[ETH_GSTRING_LEN];
 	unsigned long offset;
 };
 
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index 3eb8b4d..f5505e8 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -314,7 +314,6 @@
 #define PPE_COM_INTEN_REG			0x110
 #define PPE_COM_RINT_REG			0x114
 #define PPE_COM_INTSTS_REG			0x118
-#define PPE_COM_COMMON_CNT_CLR_CE_REG		0x1120
 #define PPE_COM_HIS_RX_PKT_QID_DROP_CNT_REG	0x300
 #define PPE_COM_HIS_RX_PKT_QID_OK_CNT_REG	0x600
 #define PPE_COM_HIS_TX_PKT_QID_ERR_CNT_REG	0x900
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 08/17] net: hns: fix to intimate the link-status change by adding LF/RF method
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Daode Huang
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Daode Huang <huangdaode@hisilicon.com>

In current scenario, when the interface is disabled we reset the XGMAC
RX/TX functionality. This operation does not affects the PHY layer/SFP
and which appears UP to the remote end(this behaviour is unlike GMAC).
The result is remote end keeps on sending the packets which gets partly
processed by XMAC and dropped. Since these are partly processed these
appears as errored packets in the packet counter statistics.

This patch fixes this behaviour and adds local-fault and remote-fault
functionality which can be used to intimate the remote peer whenever
the state of the interface changes. This patch also removes the
existing hns_dsaf_xge_core_srst_by_port function which was being used
to reset the RX/TX functionality at XGE Core.

Reported-by: Jun He <hjat2005@huawei.com>
Signed-off-by: Daode Huang <huangdaode@hisilicon.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |    2 -
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c |   31 ---------------
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h  |    7 +++-
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c    |   41 ++++++++++++++------
 .../net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h    |    5 ++-
 5 files changed, 37 insertions(+), 49 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 2cae6eb..7f70f34 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -306,8 +306,6 @@ struct dsaf_misc_op {
 	/* reset series function, it will be reset if the dereset is 0 */
 	void (*dsaf_reset)(struct dsaf_device *dsaf_dev, bool dereset);
 	void (*xge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
-	void (*xge_core_srst)(struct dsaf_device *dsaf_dev, u32 port,
-			      bool dereset);
 	void (*ge_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
 	void (*ppe_srst)(struct dsaf_device *dsaf_dev, u32 port, bool dereset);
 	void (*ppe_comm_srst)(struct dsaf_device *dsaf_dev, bool dereset);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
index 67accce..a2c22d0 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c
@@ -23,7 +23,6 @@ enum _dsm_op_index {
 enum _dsm_rst_type {
 	HNS_DSAF_RESET_FUNC     = 0x1,
 	HNS_PPE_RESET_FUNC      = 0x2,
-	HNS_XGE_CORE_RESET_FUNC = 0x3,
 	HNS_XGE_RESET_FUNC      = 0x4,
 	HNS_GE_RESET_FUNC       = 0x5,
 	HNS_DSAF_CHN_RESET_FUNC = 0x6,
@@ -213,26 +212,6 @@ static void hns_dsaf_xge_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
 				   HNS_XGE_RESET_FUNC, port, dereset);
 }
 
-static void hns_dsaf_xge_core_srst_by_port(struct dsaf_device *dsaf_dev,
-					   u32 port, bool dereset)
-{
-	u32 reg_val = 0;
-	u32 reg_addr;
-
-	if (port >= DSAF_XGE_NUM)
-		return;
-
-	reg_val |= XGMAC_TRX_CORE_SRST_M
-		<< dsaf_dev->mac_cb[port]->port_rst_off;
-
-	if (!dereset)
-		reg_addr = DSAF_SUB_SC_XGE_RESET_REQ_REG;
-	else
-		reg_addr = DSAF_SUB_SC_XGE_RESET_DREQ_REG;
-
-	dsaf_write_sub(dsaf_dev, reg_addr, reg_val);
-}
-
 /**
  * hns_dsaf_srst_chns - reset dsaf channels
  * @dsaf_dev: dsaf device struct pointer
@@ -293,14 +272,6 @@ void hns_dsaf_roce_srst_acpi(struct dsaf_device *dsaf_dev, bool dereset)
 				   HNS_ROCE_RESET_FUNC, 0, dereset);
 }
 
-static void
-hns_dsaf_xge_core_srst_by_port_acpi(struct dsaf_device *dsaf_dev,
-				    u32 port, bool dereset)
-{
-	hns_dsaf_acpi_srst_by_port(dsaf_dev, HNS_OP_RESET_FUNC,
-				   HNS_XGE_CORE_RESET_FUNC, port, dereset);
-}
-
 static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port,
 				     bool dereset)
 {
@@ -597,7 +568,6 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
 
 		misc_op->dsaf_reset = hns_dsaf_rst;
 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port;
-		misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port;
 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port;
 		misc_op->ppe_srst = hns_ppe_srst_by_port;
 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
@@ -615,7 +585,6 @@ struct dsaf_misc_op *hns_misc_op_get(struct dsaf_device *dsaf_dev)
 
 		misc_op->dsaf_reset = hns_dsaf_rst_acpi;
 		misc_op->xge_srst = hns_dsaf_xge_srst_by_port_acpi;
-		misc_op->xge_core_srst = hns_dsaf_xge_core_srst_by_port_acpi;
 		misc_op->ge_srst = hns_dsaf_ge_srst_by_port_acpi;
 		misc_op->ppe_srst = hns_ppe_srst_by_port_acpi;
 		misc_op->ppe_comm_srst = hns_ppe_com_srst;
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
index f5505e8..8722668 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
@@ -702,8 +702,6 @@
 #define XGMAC_RX_SYMBOLERRPKTS			0x0210
 #define XGMAC_RX_FCSERRPKTS			0x0218
 
-#define XGMAC_TRX_CORE_SRST_M			0x2080
-
 #define DSAF_SRAM_INIT_OVER_M 0xff
 #define DSAFV2_SRAM_INIT_OVER_M 0x3ff
 #define DSAF_SRAM_INIT_OVER_S 0
@@ -982,6 +980,11 @@
 #define XGMAC_ENABLE_TX_B		0
 #define XGMAC_ENABLE_RX_B		1
 
+#define XGMAC_UNIDIR_EN_B		0
+#define XGMAC_RF_TX_EN_B		1
+#define XGMAC_LF_RF_INSERT_S		2
+#define XGMAC_LF_RF_INSERT_M		(0x3 << XGMAC_LF_RF_INSERT_S)
+
 #define XGMAC_CTL_TX_FCS_B		0
 #define XGMAC_CTL_TX_PAD_B		1
 #define XGMAC_CTL_TX_PREAMBLE_TRANS_B	3
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
index 8f4f0e8..aae830a 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.c
@@ -108,6 +108,31 @@ static void hns_xgmac_rx_enable(struct mac_driver *drv, u32 value)
 }
 
 /**
+ * hns_xgmac_tx_lf_rf_insert - insert lf rf control about xgmac
+ * @mac_drv: mac driver
+ * @mode: inserf rf or lf
+ */
+static void hns_xgmac_lf_rf_insert(struct mac_driver *mac_drv, u32 mode)
+{
+	dsaf_set_dev_field(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG,
+			   XGMAC_LF_RF_INSERT_M, XGMAC_LF_RF_INSERT_S, mode);
+}
+
+/**
+ * hns_xgmac__lf_rf_control_init - initial the lf rf control register
+ * @mac_drv: mac driver
+ */
+static void hns_xgmac_lf_rf_control_init(struct mac_driver *mac_drv)
+{
+	u32 val = 0;
+
+	dsaf_set_bit(val, XGMAC_UNIDIR_EN_B, 0);
+	dsaf_set_bit(val, XGMAC_RF_TX_EN_B, 1);
+	dsaf_set_field(val, XGMAC_LF_RF_INSERT_M, XGMAC_LF_RF_INSERT_S, 0);
+	dsaf_write_reg(mac_drv, XGMAC_MAC_TX_LF_RF_CONTROL_REG, val);
+}
+
+/**
  *hns_xgmac_enable - enable xgmac port
  *@drv: mac driver
  *@mode: mode of mac port
@@ -115,12 +140,8 @@ static void hns_xgmac_rx_enable(struct mac_driver *drv, u32 value)
 static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode)
 {
 	struct mac_driver *drv = (struct mac_driver *)mac_drv;
-	struct dsaf_device *dsaf_dev
-		= (struct dsaf_device *)dev_get_drvdata(drv->dev);
-	u32 port = drv->mac_id;
 
-	dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 1);
-	mdelay(10);
+	hns_xgmac_lf_rf_insert(drv, HNS_XGMAC_NO_LF_RF_INSERT);
 
 	/*enable XGE rX/tX */
 	if (mode == MAC_COMM_MODE_TX) {
@@ -143,9 +164,6 @@ static void hns_xgmac_enable(void *mac_drv, enum mac_commom_mode mode)
 static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
 {
 	struct mac_driver *drv = (struct mac_driver *)mac_drv;
-	struct dsaf_device *dsaf_dev
-		= (struct dsaf_device *)dev_get_drvdata(drv->dev);
-	u32 port = drv->mac_id;
 
 	if (mode == MAC_COMM_MODE_TX) {
 		hns_xgmac_tx_enable(drv, 0);
@@ -155,9 +173,7 @@ static void hns_xgmac_disable(void *mac_drv, enum mac_commom_mode mode)
 		hns_xgmac_tx_enable(drv, 0);
 		hns_xgmac_rx_enable(drv, 0);
 	}
-
-	mdelay(10);
-	dsaf_dev->misc_op->xge_core_srst(dsaf_dev, port, 0);
+	hns_xgmac_lf_rf_insert(drv, HNS_XGMAC_LF_INSERT);
 }
 
 /**
@@ -203,6 +219,7 @@ static void hns_xgmac_init(void *mac_drv)
 	dsaf_dev->misc_op->xge_srst(dsaf_dev, port, 1);
 
 	mdelay(100);
+	hns_xgmac_lf_rf_control_init(drv);
 	hns_xgmac_exc_irq_en(drv, 0);
 
 	hns_xgmac_pma_fec_enable(drv, 0x0, 0x0);
@@ -788,7 +805,7 @@ static int hns_xgmac_get_sset_count(int stringset)
  */
 static int hns_xgmac_get_regs_count(void)
 {
-	return ETH_XGMAC_DUMP_NUM;
+	return HNS_XGMAC_DUMP_NUM;
 }
 
 void *hns_xgmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param)
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h
index 139f729..da6c534 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_xgmac.h
@@ -10,6 +10,7 @@
 #ifndef _HNS_XGMAC_H
 #define _HNS_XGMAC_H
 
-#define ETH_XGMAC_DUMP_NUM		(214)
-
+#define HNS_XGMAC_DUMP_NUM		214
+#define HNS_XGMAC_NO_LF_RF_INSERT	0x0
+#define HNS_XGMAC_LF_INSERT		0x2
 #endif
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 10/17] net: hns: modify tcam table and set mac key
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Qianqian Xie
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Qianqian Xie <xieqianqian@huawei.com>

The current definition of dsaf_drv_tbl_tcam_key is only suitable for
Little-endian. If data is stored in Big-endian, this may lead to
error in data use. Shift operation can make it work normally in both
Big-endian and Little-endian.

Signed-off-by: Qianqian Xie <xieqianqian@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c |   16 ++++++++++++----
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h |   13 ++++++++-----
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index 2721458..db23eef 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -1509,8 +1509,12 @@ static void hns_dsaf_set_mac_key(
 	mac_key->high.bits.mac_3 = addr[3];
 	mac_key->low.bits.mac_4 = addr[4];
 	mac_key->low.bits.mac_5 = addr[5];
-	mac_key->low.bits.vlan = vlan_id;
-	mac_key->low.bits.port = port;
+	dsaf_set_field(mac_key->low.bits.port_vlan, DSAF_TBL_TCAM_KEY_VLAN_M,
+		       DSAF_TBL_TCAM_KEY_VLAN_S, vlan_id);
+	dsaf_set_field(mac_key->low.bits.port_vlan, DSAF_TBL_TCAM_KEY_PORT_M,
+		       DSAF_TBL_TCAM_KEY_PORT_S, port);
+
+	mac_key->low.bits.port_vlan = le16_to_cpu(mac_key->low.bits.port_vlan);
 }
 
 /**
@@ -2760,8 +2764,12 @@ void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
 	if (enable) {
 		memset(&tbl_tcam_data, 0, sizeof(tbl_tcam_data));
 		memset(&tbl_tcam_mask, 0, sizeof(tbl_tcam_mask));
-		tbl_tcam_data.low.bits.port = port;
-		tbl_tcam_mask.low.bits.port = 0xf;  /* [3:0]: port id */
+		dsaf_set_field(tbl_tcam_data.low.bits.port_vlan,
+			       DSAF_TBL_TCAM_KEY_PORT_M,
+			       DSAF_TBL_TCAM_KEY_PORT_S, port);
+		dsaf_set_field(tbl_tcam_mask.low.bits.port_vlan,
+			       DSAF_TBL_TCAM_KEY_PORT_M,
+			       DSAF_TBL_TCAM_KEY_PORT_S, 0xf);
 
 		/* SUB_QID */
 		dsaf_set_bit(mac_data.tbl_mcast_port_msk[0],
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
index 7f70f34..c68555b 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
@@ -357,6 +357,11 @@ static inline void *hns_dsaf_dev_priv(const struct dsaf_device *dsaf_dev)
 	return (void *)((u8 *)dsaf_dev + sizeof(*dsaf_dev));
 }
 
+#define DSAF_TBL_TCAM_KEY_PORT_S 0
+#define DSAF_TBL_TCAM_KEY_PORT_M (((1ULL << 4) - 1) << 0)
+#define DSAF_TBL_TCAM_KEY_VLAN_S 4
+#define DSAF_TBL_TCAM_KEY_VLAN_M (((1ULL << 12) - 1) << 4)
+
 struct dsaf_drv_tbl_tcam_key {
 	union {
 		struct {
@@ -370,11 +375,9 @@ struct dsaf_drv_tbl_tcam_key {
 	} high;
 	union {
 		struct {
-			u32 port:4; /* port id, */
-			/* dsaf-mode fixed 0, non-dsaf-mode port id*/
-			u32 vlan:12; /* vlan id */
-			u32 mac_5:8;
-			u32 mac_4:8;
+			u16 port_vlan;
+			u8 mac_5;
+			u8 mac_4;
 		} bits;
 
 		u32 val;
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH net-next 11/17] net: hns: modify tcam table of mac uc-entry
From: Salil Mehta @ 2016-11-09 18:13 UTC (permalink / raw)
  To: davem
  Cc: salil.mehta, yisen.zhuang, mehta.salil.lnk, netdev, linux-kernel,
	linuxarm, Qianqian Xie
In-Reply-To: <20161109181401.913728-1-salil.mehta@huawei.com>

From: Qianqian Xie <xieqianqian@huawei.com>

The current definition of mac_uc_entry is only suitable for
Little-endian. Thus it needs to modify tcam table of mac uc-entry
to support both Little-endian and Big-endian.

Signed-off-by: Qianqian Xie <xieqianqian@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
index db23eef..1713f8d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
@@ -1532,6 +1532,7 @@ int hns_dsaf_set_mac_uc_entry(
 	struct dsaf_drv_priv *priv =
 	    (struct dsaf_drv_priv *)hns_dsaf_dev_priv(dsaf_dev);
 	struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
+	struct dsaf_tbl_tcam_data tcam_data;
 
 	/* mac addr check */
 	if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
@@ -1573,9 +1574,10 @@ int hns_dsaf_set_mac_uc_entry(
 	/* default config dvc to 0 */
 	mac_data.tbl_ucast_dvc = 0;
 	mac_data.tbl_ucast_out_port = mac_entry->port_num;
-	hns_dsaf_tcam_uc_cfg(
-		dsaf_dev, entry_index,
-		(struct dsaf_tbl_tcam_data *)(&mac_key), &mac_data);
+	tcam_data.tbl_tcam_data_high = cpu_to_le32(mac_key.high.val);
+	tcam_data.tbl_tcam_data_low = cpu_to_le32(mac_key.low.val);
+
+	hns_dsaf_tcam_uc_cfg(dsaf_dev, entry_index, &tcam_data, &mac_data);
 
 	/* config software entry */
 	soft_mac_entry += entry_index;
@@ -1950,6 +1952,7 @@ int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
 	struct dsaf_drv_tbl_tcam_key mac_key;
 
 	struct dsaf_tbl_tcam_ucast_cfg mac_data;
+	struct dsaf_tbl_tcam_data tcam_data;
 
 	/* check macaddr */
 	if (MAC_IS_ALL_ZEROS(mac_entry->addr) ||
@@ -1978,9 +1981,12 @@ int hns_dsaf_get_mac_uc_entry(struct dsaf_device *dsaf_dev,
 		dsaf_dev->ae_dev.name, mac_key.high.val,
 		mac_key.low.val, entry_index);
 
-	/*read entry*/
-	hns_dsaf_tcam_uc_get(dsaf_dev, entry_index,
-			     (struct dsaf_tbl_tcam_data *)&mac_key, &mac_data);
+	/* read entry */
+	hns_dsaf_tcam_uc_get(dsaf_dev, entry_index, &tcam_data, &mac_data);
+
+	mac_key.high.val = le32_to_cpu(tcam_data.tbl_tcam_data_high);
+	mac_key.low.val = le32_to_cpu(tcam_data.tbl_tcam_data_low);
+
 	mac_entry->port_num = mac_data.tbl_ucast_out_port;
 
 	return 0;
-- 
1.7.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox