RE: [PATCH] net: dsa: ksz: Increase the tag alignment

2018-12-07 Thread Tristram.Ha
> - padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len;
> + padlen = (skb->len >= VLAN_ETH_ZLEN) ? 0 : VLAN_ETH_ZLEN - skb-
> >len;

The requirement is the tail tag should be at the end of frame before FCS.
When the length is less than 60 the MAC controller will pad the frame to
legal size.  That is why this function makes sure the padding is done
manually.  Increasing the size just increases the length of the frame and the
chance to allocate new socket buffer.

Example of using ping size of 18 will have the sizes of request and response
differ by 4 bytes.  Not that it matters much.

Are you concerned the MAC controller will remove the VLAN tag and so the frame
will not be sent? Or the switch removes the VLAN tag and is not able to send?



RE: [PATCH] net: dsa: ksz: Fix port membership

2018-12-07 Thread Tristram.Ha
> Do you have a git tree with all the KSZ patches based on -next
> somewhere, so I don't have to look for them in random MLs ?

I just sent it this Monday and the subject for that patch is
"[PATCH RFC 6/6] net: dsa: microchip: Add switch offload forwarding support."



RE: [PATCH] net: dsa: ksz: Fix port membership

2018-12-07 Thread Tristram.Ha
> > I think if you do this without setting offload_fwd_mark you will
> > receive duplicate frame.
> 
> I don't think it will, at least not in the normal case. The hardware
> should know the egress port, so there is no need to forward a copy to
> the CPU. The only time it should forward to the CPU is when the egress
> port is not known, so it floods. Without offload_fwd_mark set, the SW
> bridge will flood it back out the ports causing duplication. But that
> is not too bad. The Marvell driver did this for a while and nothing
> bad was reported.

For unicast frames it is okay as the CPU port does not see it after the first
one.  For multicast frames there will be duplicates, and it is tolerated?



RE: [PATCH] net: dsa: ksz: Fix port membership

2018-12-07 Thread Tristram.Ha
> >> If two ports are in the same bridge and in forwarding state, the packets
> >> must be able to pass between them in both directions. The current code
> >> only configures this bridge membership for a port newly added to the
> >> bridge, but does not update all the other ports. Thus, ingress packets
> >> on the new port will be forwarded, but ingress packets on other ports
> >> destined for the new port (eg. a reply) will not be forwarded back to
> >> the new port, because they are not configured to do so. This patch fixes
> >> that by updating the membership registers of all ports.
> >>
> >> Signed-off-by: Marek Vasut 
> >> Cc: Vivien Didelot 
> >> Cc: Woojung Huh 
> >> Cc: David S. Miller 
> >> Cc: Tristram Ha 
> >> ---
> >>  drivers/net/dsa/microchip/ksz9477.c | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/net/dsa/microchip/ksz9477.c
> >> b/drivers/net/dsa/microchip/ksz9477.c
> >> index 0684657fbf9a9..e24dd14ccde77 100644
> >> --- a/drivers/net/dsa/microchip/ksz9477.c
> >> +++ b/drivers/net/dsa/microchip/ksz9477.c
> >> @@ -396,7 +396,7 @@ static void ksz9477_port_stp_state_set(struct
> >> dsa_switch *ds, int port,
> >>struct ksz_device *dev = ds->priv;
> >>struct ksz_port *p = >ports[port];
> >>u8 data;
> >> -  int member = -1;
> >> +  int i, member = -1;
> >>
> >>ksz_pread8(dev, port, P_STP_CTRL, );
> >>data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE |
> >> PORT_LEARN_DISABLE);
> >> @@ -454,8 +454,8 @@ static void ksz9477_port_stp_state_set(struct
> >> dsa_switch *ds, int port,
> >>dev->tx_ports &= ~(1 << port);
> >>
> >>/* Port membership may share register with STP state. */
> >> -  if (member >= 0 && member != p->member)
> >> -  ksz9477_cfg_port_member(dev, port, (u8)member);
> >> +  for (i = 0; i < SWITCH_PORT_NUM; i++)
> >> +  ksz9477_cfg_port_member(dev, i, (u8)member);
> >>
> >>/* Check if forwarding needs to be updated. */
> >>if (state != BR_STATE_FORWARDING) {
> >
> > The original DSA model did not have a way to tell the bridge device not to
> > forward the frame, so the switch driver always setup the membership to
> > disable forwarding between ports.
> >
> > When lan devices are setup they act like individual devices.  A bridge 
> > device
> > adding them under it will forward the frames.
> >
> > The new switchdev model adds the offload_fwd_mark bit to tell the bridge
> not to
> > forward frame.
> >
> > The ksz_update_port_member function in ksz_common.c is doing this
> membership
> > setup for all forwarding ports.  It was finally enabled in one of the RFC
> patches I
> > submitted recently (Add switch forward offloading support).
> >
> > I think if you do this without setting offload_fwd_mark you will receive
> duplicate
> > frame.
> >
> 
> Either I am misreading Marek's patch, or I don't quite understand your
> response, but what is happening when you enslave a switch port into a
> bridge is that you need to make sure that:
> 
> - the switch port being enslaved will be part of the same forwarding
> group as any other switch port already in the bridge
> - any existing switch port already enslaved in the bridge must now also
> be allowed to forward to the port that is being enslaved
> 
> That is to me, exactly what Marek's patch is fixing, your response is
> about something slightly orthogonal here.

I got confused here as the code is obviously wrong and should not work,
so I found out why it works in the bridge device situation.  There is actually
a bug in the driver that enables this behavior.  The port_vlan_filtering 
function
turns off the port membership enforcement.  Fixing this problem should be
easy, but this port_vlan_filtering function is also not implemented right.  It 
treats the
operation as a simple VLAN on/off, but it is more complex than that.

Anyway it seems to work in the bridge device situation, but it does not work
in the default situation:

Assume there are two port devices lan1 and lan2.  The device lan1 is assigned
an IP address and can talk to outside.  Enabling and disabling lan2 by doing
"ifconfig lan2 up" and "ifconfig lan2 down."  The device lan1 is no longer 
working.

Create a bridge device and add a child device by doing "brctl addbr br0" and
"brctl addif br0 lan1."  This will call port_vlan_filtering and then the feature
UNICAST_VLAN_BOUNDARY is disabled.  This causes port membership to have no
effect on unicast packets and so it does not matter what member value is used.
The device lan1 can start working again.

The fix is to avoid disabling UNICAST_VLAN_BOUNDARY and it should be set all
the time.  In this switch the default is on.


RE: [PATCH] net: dsa: ksz: Fix port membership

2018-12-07 Thread Tristram.Ha
> If two ports are in the same bridge and in forwarding state, the packets
> must be able to pass between them in both directions. The current code
> only configures this bridge membership for a port newly added to the
> bridge, but does not update all the other ports. Thus, ingress packets
> on the new port will be forwarded, but ingress packets on other ports
> destined for the new port (eg. a reply) will not be forwarded back to
> the new port, because they are not configured to do so. This patch fixes
> that by updating the membership registers of all ports.
> 
> Signed-off-by: Marek Vasut 
> Cc: Vivien Didelot 
> Cc: Woojung Huh 
> Cc: David S. Miller 
> Cc: Tristram Ha 
> ---
>  drivers/net/dsa/microchip/ksz9477.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/dsa/microchip/ksz9477.c
> b/drivers/net/dsa/microchip/ksz9477.c
> index 0684657fbf9a9..e24dd14ccde77 100644
> --- a/drivers/net/dsa/microchip/ksz9477.c
> +++ b/drivers/net/dsa/microchip/ksz9477.c
> @@ -396,7 +396,7 @@ static void ksz9477_port_stp_state_set(struct
> dsa_switch *ds, int port,
>   struct ksz_device *dev = ds->priv;
>   struct ksz_port *p = >ports[port];
>   u8 data;
> - int member = -1;
> + int i, member = -1;
> 
>   ksz_pread8(dev, port, P_STP_CTRL, );
>   data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE |
> PORT_LEARN_DISABLE);
> @@ -454,8 +454,8 @@ static void ksz9477_port_stp_state_set(struct
> dsa_switch *ds, int port,
>   dev->tx_ports &= ~(1 << port);
> 
>   /* Port membership may share register with STP state. */
> - if (member >= 0 && member != p->member)
> - ksz9477_cfg_port_member(dev, port, (u8)member);
> + for (i = 0; i < SWITCH_PORT_NUM; i++)
> + ksz9477_cfg_port_member(dev, i, (u8)member);
> 
>   /* Check if forwarding needs to be updated. */
>   if (state != BR_STATE_FORWARDING) {

The original DSA model did not have a way to tell the bridge device not to
forward the frame, so the switch driver always setup the membership to
disable forwarding between ports.

When lan devices are setup they act like individual devices.  A bridge device
adding them under it will forward the frames.

The new switchdev model adds the offload_fwd_mark bit to tell the bridge not to
forward frame.

The ksz_update_port_member function in ksz_common.c is doing this membership
setup for all forwarding ports.  It was finally enabled in one of the RFC 
patches I
submitted recently (Add switch forward offloading support).

I think if you do this without setting offload_fwd_mark you will receive 
duplicate
frame.



RE: [PATCH RFC 1/6] net: dsa: microchip: Prepare PHY for proper advertisement

2018-12-06 Thread Tristram.Ha
> > +static void ksz9477_phy_setup(struct ksz_device *dev, int port,
> > + struct phy_device *phy)
> > +{
> > +   if (port < dev->phy_port_cnt) {
> > +   /* SUPPORTED_Asym_Pause and SUPPORTED_Pause can be
> removed to
> > +* disable flow control when rate limiting is used.
> > +*/
> > +   }
> 
> Hi Tristram
> 
> Is this meant to be a TODO comment?
> 
> What is supposed to happen here is that all forms of pause are disable
> by default. The MAC driver needs to enable what it supports by calling
> phy_support_sym_pause() or phy_support_asym_pause().
> 
> Ah, is this because there is not a real PHY driver?

The kernel has been changed so I am not sure about the current behavior.
I would like to turn on flow control by default.  Before I just assigned
"supported" to "advertising."  I know linkmode_copy is being used now for that.
But last time I checked "advertising" is already the same as "supported."

There will be a situation that flow control should not be turned on as the 
switch
uses bandwidth control to limit outgoing traffic.

The issue is actually becoming more complex as KSZ9477 has a variant which
does not support gigabit speed, although the same PHY device id is being used.
That means the driver has to fake it by returning a different id and also 
registering
a different PHY driver to handle that.  Marketing also likes to display the 
correct chip
name during kernel booting so that users do not get confused.



RE: [PATCH RFC 2/6] net: dsa: microchip: Add MIB counter reading support

2018-12-06 Thread Tristram.Ha
> > +static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
> > + u64 *cnt)
> > +{
> > +   u32 data;
> > +   int timeout;
> > +   struct ksz_port *p = >ports[port];
> > +
> > +   /* retain the flush/freeze bit */
> > +   data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
> > +   data |= MIB_COUNTER_READ;
> > +   data |= (addr << MIB_COUNTER_INDEX_S);
> > +   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
> > +
> > +   timeout = 1000;
> > +   do {
> > +   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
> > +   );
> > +   usleep_range(1, 10);
> > +   if (!(data & MIB_COUNTER_READ))
> > +   break;
> > +   } while (timeout-- > 0);
> 
> Could you use readx_poll_timeout() here?
> 
> > +void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf)
> > +{
> > +   struct ksz_device *dev = ds->priv;
> > +   struct ksz_port_mib *mib;
> > +
> > +   mib = >ports[port].mib;
> > +
> > +   /* freeze MIB counters if supported */
> > +   if (dev->dev_ops->freeze_mib)
> > +   dev->dev_ops->freeze_mib(dev, port, true);
> > +   mutex_lock(>cnt_mutex);
> > +   port_r_cnt(dev, port);
> > +   mutex_unlock(>cnt_mutex);
> > +   if (dev->dev_ops->freeze_mib)
> > +   dev->dev_ops->freeze_mib(dev, port, false);
> 
> Should the freeze be protected by the mutex as well?
> 
> > +   memcpy(buf, mib->counters, dev->mib_cnt * sizeof(u64));
> 
> I wonder if this memcpy should also be protected by the mutex. As soon
> as the mutex is dropped, the scheduled work could start updating
> mib->counters in non-atomic ways?
>

I will update as suggested.
 
> > +}
> > +
> >  int ksz_port_bridge_join(struct dsa_switch *ds, int port,
> >  struct net_device *br)
> >  {
> > @@ -255,6 +349,7 @@ int ksz_enable_port(struct dsa_switch *ds, int port,
> struct phy_device *phy)
> > /* setup slave port */
> > dev->dev_ops->port_setup(dev, port, false);
> > dev->dev_ops->phy_setup(dev, port, phy);
> > +   dev->dev_ops->port_init_cnt(dev, port);
> 
> This is probably not the correct place to do this. MIB counters should
> not be cleared by an ifdown/ifup cycle. They should only be cleared
> when the driver is probed.

I wonder what is the official way to clear the counters.  For network debugging
It is good to clear the counters to start fresh to see which frame is not
being sent or received.  Typically the device is reset when it is shutdown as 
there
are hardware problems.  I would think it is the job of applications like SNMP 
Manager
to keep track of MIB counters throughout the life of a running system.


RE: [PATCH RFC 5/6] net: dsa: microchip: Update tag_ksz.c to access switch driver

2018-12-06 Thread Tristram.Ha
> >>> Update tag_ksz.c to access switch driver's tail tagging operations.
> >>
> >> Hi Tristram
> >>
> >> Humm, i'm not sure we want this, the tagging spit into two places.  I
> >> need to take a closer look at the previous patch, to see why it cannot
> >> be done here.
> >
> > O.K, i think i get what is going on.
> >
> > I would however implement it differently.
> >
> > One net/dsa/tag_X.c file can export two dsa_device_ops structures,
> > allowing you to share common code for the two taggers. You could call
> > these DSA_TAG_PROTO_KSZ_1_BYTE, and DSA_TAG_PROTO_KSZ_2_BYTE,
> and the
> > .get_tag_protocol call would then return the correct one for the
> > switch.
> 
> Agreed, that is what is done by net/dsa/tag_brcm.c because there are two
> formats for the Broadcom tag:
> 
> - TAG_BRCM: the 4-bytes Broadcom tag is between MAC SA and Ethertype
> - TAG_BRCM_PREPEND: the 4-bytes Broadcom tag is before the MAC DA
>

I did try to implement this way.  But the other switches do not have the same
format even though the length is the same.  Then I need to change the following
files for any new KSZ switch: include/linux/dsa.h, net/dsa/dsa.c, 
net/dsa/dsa_priv.h,
and finally net/dsa/tag_ksz.c.

Even then it will not work if Microchip wants to add 1588 PTP capability to the 
switches.

For KSZ9477 the length of the tail tag changes when the PTP function is enabled.
Typically this function is either enabled or disabled all the time, but if 
users want to
change that during normal operation to see how the switch behaves, the transmit
function completely stops working correctly.

Older driver implementation is to monitor that register change and adjust the 
length
dynamically.

Another problem is the tail tag needs to include the timestamp for the 1-step
Pdelay_Resp to have accurate turnaround time when that message is sent out by 
the
switch.  This will require access to the main switch driver which will keep 
track of those
PTP messages.

PTP handles transmit timestamp in skb_tx_timestamp, which is typically called 
after the
frame is sent, so it is too late.  DSA calls dsa_skb_tx_timestamp before 
sending, but it
only provides a clone to the driver that supports port_txstamp and so the 
switch driver
may not be able to do anything.
 
> And the code to process them is basically using relative offsets from
> the start of the frame to access correct data.
> 
> This is done largely for performance reasons because we have 1/2
> Gigabit/secs capable CPU ports and so we want to avoid as little cache
> trashing as possible and immediately get the right rcv() function to
> process the packets.
> 

The SoC I used for this driver development actually has problem sending
Gigabit traffic so I do not see the effect of any slowdown, and the updated
MAC driver change for a hardware problem does not help and greatly
degrades the transmit performance.

> >
> > It might also be possible to merge in tag_trailer, or at least share
> > some code.
> >

Actually in previous old DSA implementation I just hijacked this file to
add the tail tag operations without creating a new file like tag_ksz.c.

> > What i don't yet understand is how you are passing PTP information
> > around. The commit messages need to explain that, since it is not
> > obvious, and it is the first time we have needed PTP info in a tag
> > driver.

It seems the official 1588 PTP timestamp API for a PHY driver is only 
implemented
in only PHY driver, net/phy/dp83640.c, in the whole kernel.  DSA uses similar
mechanism to support 1588 PTP.  In dsa_switch_rcv() the CPU receive function is 
called
first before dsa_skb_defer_rx_timestamp().  That means the receive tail tag 
operation
has to be done first to retrieve the receive timestamp so that it can be passed 
later.

It is probably not good to change the socket buffer length inside the 
port_rxtstamp
function, and I do not see any other way to insert that transmit timestamp.

A customer has already inquired about implementing 1588 PTP in the DSA driver.  
I hope
this mechanism is approved so that I can start doing that.



[PATCH RFC 2/6] net: dsa: microchip: Add MIB counter reading support

2018-12-03 Thread Tristram.Ha
From: Tristram Ha 

Add MIB counter reading support.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz9477.c| 121 ++---
 drivers/net/dsa/microchip/ksz_common.c | 101 +++
 drivers/net/dsa/microchip/ksz_common.h |   2 +
 drivers/net/dsa/microchip/ksz_priv.h   |   7 +-
 4 files changed, 186 insertions(+), 45 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 98aa25e..bd1ca33 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -259,6 +259,76 @@ static int ksz9477_reset_switch(struct ksz_device *dev)
return 0;
 }
 
+static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
+ u64 *cnt)
+{
+   u32 data;
+   int timeout;
+   struct ksz_port *p = >ports[port];
+
+   /* retain the flush/freeze bit */
+   data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+   data |= MIB_COUNTER_READ;
+   data |= (addr << MIB_COUNTER_INDEX_S);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
+
+   timeout = 1000;
+   do {
+   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+   );
+   usleep_range(1, 10);
+   if (!(data & MIB_COUNTER_READ))
+   break;
+   } while (timeout-- > 0);
+
+   /* failed to read MIB. get out of loop */
+   if (!timeout) {
+   dev_dbg(dev->dev, "Failed to get MIB\n");
+   return;
+   }
+
+   /* count resets upon read */
+   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
+   *cnt += data;
+}
+
+static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
+ u64 *dropped, u64 *cnt)
+{
+   addr = ksz9477_mib_names[addr].index;
+   ksz9477_r_mib_cnt(dev, port, addr, cnt);
+}
+
+static void ksz9477_freeze_mib(struct ksz_device *dev, int port, bool freeze)
+{
+   struct ksz_port *p = >ports[port];
+   u32 val = freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+
+   /* enable/disable the port for flush/freeze function */
+   mutex_lock(>mib.cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, val);
+
+   /* used by MIB counter reading code to know freeze is enabled */
+   p->freeze = freeze;
+   mutex_unlock(>mib.cnt_mutex);
+}
+
+static void ksz9477_port_init_cnt(struct ksz_device *dev, int port)
+{
+   struct ksz_port_mib *mib = >ports[port].mib;
+
+   /* flush all enabled port MIB counters */
+   mutex_lock(>cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+MIB_COUNTER_FLUSH_FREEZE);
+   ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0);
+   mutex_unlock(>cnt_mutex);
+
+   mib->cnt_ptr = 0;
+   memset(mib->counters, 0, dev->mib_cnt * sizeof(u64));
+}
+
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
  int port)
 {
@@ -342,47 +412,6 @@ static void ksz9477_get_strings(struct dsa_switch *ds, int 
port,
}
 }
 
-static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *buf)
-{
-   struct ksz_device *dev = ds->priv;
-   int i;
-   u32 data;
-   int timeout;
-
-   mutex_lock(>stats_mutex);
-
-   for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
-   data = MIB_COUNTER_READ;
-   data |= ((ksz9477_mib_names[i].index & 0xFF) <<
-   MIB_COUNTER_INDEX_S);
-   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
-
-   timeout = 1000;
-   do {
-   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
-   );
-   usleep_range(1, 10);
-   if (!(data & MIB_COUNTER_READ))
-   break;
-   } while (timeout-- > 0);
-
-   /* failed to read MIB. get out of loop */
-   if (!timeout) {
-   dev_dbg(dev->dev, "Failed to get MIB\n");
-   break;
-   }
-
-   /* count resets upon read */
-   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
-
-   dev->mib_value[i] += (uint64_t)data;
-   buf[i] = dev->mib_value[i];
-   }
-
-   mutex_unlock(>stats_mutex);
-}
-
 static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
u8 member)
 {
@@ -1150,9 +1179,14 @@ static int ksz9477_setup(struct dsa_switch *ds)
/* queue based egress rate limit */
ksz_cfg(dev, REG_SW_MAC_CTRL_5, SW_OUT_RATE_LIMIT_QUEUE_BASED, true);
 
+   /* enable global MIB counter 

[PATCH RFC 5/6] net: dsa: microchip: Update tag_ksz.c to access switch driver

2018-12-03 Thread Tristram.Ha
From: Tristram Ha 

Update tag_ksz.c to access switch driver's tail tagging operations.

Signed-off-by: Tristram Ha 
---
 net/dsa/tag_ksz.c | 44 
 1 file changed, 20 insertions(+), 24 deletions(-)

diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 0f62eff..307e58b 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -11,37 +11,25 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "dsa_priv.h"
 
-/* For Ingress (Host -> KSZ), 2 bytes are added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
- * ---
- * tag0 : Prioritization (not used now)
- * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
- *
- * For Egress (KSZ -> Host), 1 byte is added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|FCS(4bytes)
- * ---
- * tag0 : zero-based value represents port
- *   (eg, 0x00=port1, 0x02=port3, 0x06=port7)
- */
-
-#defineKSZ_INGRESS_TAG_LEN 2
 #defineKSZ_EGRESS_TAG_LEN  1
 
 static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
 {
struct dsa_port *dp = dsa_slave_to_port(dev);
+   struct ksz_device *sw = dp->ds->priv;
struct sk_buff *nskb;
+   int len;
int padlen;
-   u8 *tag;
+
+   len = sw->tag_ops->get_len(sw);
 
padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len;
 
-   if (skb_tailroom(skb) >= padlen + KSZ_INGRESS_TAG_LEN) {
+   if (skb_tailroom(skb) >= padlen + len) {
/* Let dsa_slave_xmit() free skb */
if (__skb_put_padto(skb, skb->len + padlen, false))
return NULL;
@@ -49,7 +37,7 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct 
net_device *dev)
nskb = skb;
} else {
nskb = alloc_skb(NET_IP_ALIGN + skb->len +
-padlen + KSZ_INGRESS_TAG_LEN, GFP_ATOMIC);
+padlen + len, GFP_ATOMIC);
if (!nskb)
return NULL;
skb_reserve(nskb, NET_IP_ALIGN);
@@ -70,9 +58,8 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct 
net_device *dev)
consume_skb(skb);
}
 
-   tag = skb_put(nskb, KSZ_INGRESS_TAG_LEN);
-   tag[0] = 0;
-   tag[1] = 1 << dp->index; /* destination port */
+   sw->tag_ops->set_tag(sw, skb_put(nskb, len), skb_mac_header(nskb),
+dp->index);
 
return nskb;
 }
@@ -80,18 +67,27 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct 
net_device *dev)
 static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev,
   struct packet_type *pt)
 {
+   struct dsa_port *cpu_dp = dev->dsa_ptr;
+   struct dsa_switch_tree *dst = cpu_dp->dst;
+   struct dsa_switch *ds = dst->ds[0];
+   struct ksz_device *sw;
u8 *tag;
+   int len;
int source_port;
 
+   if (!ds)
+   return NULL;
+   sw = ds->priv;
+
tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
 
-   source_port = tag[0] & 7;
+   len = sw->tag_ops->get_tag(sw, tag, _port);
 
skb->dev = dsa_master_find_slave(dev, 0, source_port);
if (!skb->dev)
return NULL;
 
-   pskb_trim_rcsum(skb, skb->len - KSZ_EGRESS_TAG_LEN);
+   pskb_trim_rcsum(skb, skb->len - len);
 
return skb;
 }
-- 
1.9.1



[PATCH RFC 6/6] net: dsa: microchip: Add switch offload forwarding support

2018-12-03 Thread Tristram.Ha
From: Tristram Ha 

The flag offload_fwd_mark is set as the switch can forward frames by
itself.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz9477.c | 7 ---
 net/dsa/tag_ksz.c   | 2 ++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index c690c2b2..ca9199a 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -434,6 +434,7 @@ static void ksz9477_port_stp_state_set(struct dsa_switch 
*ds, int port,
struct ksz_port *p = >ports[port];
u8 data;
int member = -1;
+   int forward = dev->member;
 
ksz_pread8(dev, port, P_STP_CTRL, );
data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
@@ -501,10 +502,10 @@ static void ksz9477_port_stp_state_set(struct dsa_switch 
*ds, int port,
}
 
/* When topology has changed the function ksz_update_port_member
-* should be called to modify port forwarding behavior.  However
-* as the offload_fwd_mark indication cannot be reported here
-* the switch forwarding function is not enabled.
+* should be called to modify port forwarding behavior.
 */
+   if (forward != dev->member)
+   ksz_update_port_member(dev, port);
 }
 
 static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 307e58b..50511c2 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -89,6 +89,8 @@ static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct 
net_device *dev,
 
pskb_trim_rcsum(skb, skb->len - len);
 
+   skb->offload_fwd_mark = 1;
+
return skb;
 }
 
-- 
1.9.1



[PATCH RFC 3/6] net: dsa: microchip: Break ksz_priv.h into two files

2018-12-03 Thread Tristram.Ha
From: Tristram Ha 

Break ksz_priv.h into two files: private and public.  The public one is
put in include/linux/dsa/ksz_dsa.h.

This allows the tail tagging code tag_ksz.c to access the switch driver
as the tail tag format can be different when certain switch functions are
enabled.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz_priv.h | 86 +-
 include/linux/dsa/ksz_dsa.h  | 90 
 2 files changed, 92 insertions(+), 84 deletions(-)
 create mode 100644 include/linux/dsa/ksz_dsa.h

diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 1955ea6..5d93822 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0
  *
- * Microchip KSZ series switch common definitions
+ * Microchip KSZ series switch private definitions
  *
  * Copyright (C) 2017-2018 Microchip Technology Inc.
  */
@@ -13,89 +13,7 @@
 #include 
 #include 
 #include 
-
-struct ksz_io_ops;
-
-struct vlan_table {
-   u32 table[3];
-};
-
-struct ksz_port_mib {
-   struct mutex cnt_mutex; /* structure access */
-   u8 cnt_ptr;
-   u64 *counters;
-};
-
-struct ksz_port {
-   u16 member;
-   u16 vid_member;
-   int stp_state;
-   struct phy_device phydev;
-
-   u32 on:1;   /* port is not disabled by hardware */
-   u32 phy:1;  /* port has a PHY */
-   u32 fiber:1;/* port is fiber */
-   u32 sgmii:1;/* port is SGMII */
-   u32 force:1;
-   u32 link_just_down:1;   /* link just goes down */
-   u32 freeze:1;   /* MIB counter freeze is enabled */
-
-   struct ksz_port_mib mib;
-};
-
-struct ksz_device {
-   struct dsa_switch *ds;
-   struct ksz_platform_data *pdata;
-   const char *name;
-
-   struct mutex reg_mutex; /* register access */
-   struct mutex stats_mutex;   /* status access */
-   struct mutex alu_mutex; /* ALU access */
-   struct mutex vlan_mutex;/* vlan access */
-   const struct ksz_io_ops *ops;
-   const struct ksz_dev_ops *dev_ops;
-
-   struct device *dev;
-
-   void *priv;
-
-   /* chip specific data */
-   u32 chip_id;
-   int num_vlans;
-   int num_alus;
-   int num_statics;
-   int cpu_port;   /* port connected to CPU */
-   int cpu_ports;  /* port bitmap can be cpu port */
-   int phy_port_cnt;
-   int port_cnt;
-   int reg_mib_cnt;
-   int mib_cnt;
-   int mib_port_cnt;
-   int last_port;  /* ports after that not used */
-   phy_interface_t interface;
-   u32 regs_size;
-
-   struct vlan_table *vlan_cache;
-
-   u8 *txbuf;
-
-   struct ksz_port *ports;
-   struct timer_list mib_read_timer;
-   struct work_struct mib_read;
-   unsigned long mib_read_interval;
-   u16 br_member;
-   u16 member;
-   u16 live_ports;
-   u16 on_ports;   /* ports enabled by DSA */
-   u16 rx_ports;
-   u16 tx_ports;
-   u16 mirror_rx;
-   u16 mirror_tx;
-   u32 features;   /* chip specific features */
-   u32 overrides;  /* chip functions set by user */
-   u16 host_mask;
-   u16 port_mask;
-};
+#include 
 
 struct ksz_io_ops {
int (*read8)(struct ksz_device *dev, u32 reg, u8 *value);
diff --git a/include/linux/dsa/ksz_dsa.h b/include/linux/dsa/ksz_dsa.h
new file mode 100644
index 000..3148cae
--- /dev/null
+++ b/include/linux/dsa/ksz_dsa.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Microchip KSZ series switch common definitions
+ *
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
+ */
+
+#include 
+
+struct vlan_table {
+   u32 table[3];
+};
+
+struct ksz_port_mib {
+   struct mutex cnt_mutex; /* structure access */
+   u8 cnt_ptr;
+   u64 *counters;
+};
+
+struct ksz_port {
+   u16 member;
+   u16 vid_member;
+   int stp_state;
+   struct phy_device phydev;
+
+   u32 on:1;   /* port is not disabled by hardware */
+   u32 phy:1;  /* port has a PHY */
+   u32 fiber:1;/* port is fiber */
+   u32 sgmii:1;/* port is SGMII */
+   u32 force:1;
+   u32 link_just_down:1;   /* link just goes down */
+   u32 freeze:1;   /* MIB counter freeze is enabled */
+
+   struct ksz_port_mib mib;
+};
+
+struct ksz_device {
+   struct dsa_switch *ds;
+   struct ksz_platform_data *pdata;
+   const char *name;
+
+   struct mutex reg_mutex; /* register access */
+   struct mutex stats_mutex;   /* status access */
+   struct mutex alu_mutex; /* 

[PATCH RFC 4/6] net: dsa: microchip: Each switch driver has its own tail tagging operations

2018-12-03 Thread Tristram.Ha
From: Tristram Ha 

The tail tagging operations are implemented in each switch driver so that
the main tail tagging code tag_ksz.c does not need to be changed after
modification to support that mechanism is made.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz9477.c| 78 +-
 drivers/net/dsa/microchip/ksz_common.c |  4 +-
 drivers/net/dsa/microchip/ksz_priv.h   |  3 +-
 include/linux/dsa/ksz_dsa.h|  9 
 4 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index bd1ca33..c690c2b2 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -21,6 +21,14 @@
 #include "ksz_common.h"
 #include "ksz9477_reg.h"
 
+/* features flags */
+#define GBIT_SUPPORT   BIT(0)
+#define NEW_XMII   BIT(1)
+#define IS_9893BIT(2)
+
+/* overrides flags */
+#define PTP_TAGBIT(0)
+
 static const struct {
int index;
char string[ETH_GSTRING_LEN];
@@ -1356,9 +1364,77 @@ static void ksz9477_switch_exit(struct ksz_device *dev)
.exit = ksz9477_switch_exit,
 };
 
+/* For Ingress (Host -> KSZ), 2 bytes are added before FCS.
+ * ---
+ * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
+ * ---
+ * tag0 : Prioritization (not used now)
+ * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
+ *
+ * For switch with 3 ports only one byte is needed.
+ * When PTP function is enabled additional 4 bytes are needed.
+ *
+ * For Egress (KSZ -> Host), 1 byte is added before FCS.
+ * ---
+ * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|FCS(4bytes)
+ * ---
+ * tag0 : zero-based value represents port
+ *   (eg, 0x00=port1, 0x02=port3, 0x06=port7)
+ *
+ * When PTP function is enabled BIT 7 indicates the received frame is a PTP
+ * message and so there are 4 additional bytes for the receive timestamp.
+ */
+
+static int ksz9477_get_len(struct ksz_device *dev)
+{
+   int len = 1;
+
+   if (!(dev->features & IS_9893))
+   len += 1;
+   if (dev->overrides & PTP_TAG)
+   len += 4;
+   return len;
+}
+
+static int ksz9477_get_tag(struct ksz_device *dev, u8 *tag, int *port)
+{
+   int len = 1;
+
+   if (tag[0] & BIT(7))
+   len += 4;
+   *port = tag[0] & 7;
+   return len;
+}
+
+static void ksz9477_set_tag(struct ksz_device *dev, void *ptr, u8 *addr, int p)
+{
+   if (dev->overrides & PTP_TAG) {
+   u32 *timestamp = (u32 *)ptr;
+
+   *timestamp = 0;
+   ptr = timestamp + 1;
+   }
+   if (dev->features & IS_9893) {
+   u8 *tag = (u8 *)ptr;
+
+   *tag = 1 << p;
+   } else {
+   u16 *tag = (u16 *)ptr;
+
+   *tag = 1 << p;
+   *tag = cpu_to_be16(*tag);
+   }
+}
+
+static const struct ksz_tag_ops ksz9477_tag_ops = {
+   .get_len = ksz9477_get_len,
+   .get_tag = ksz9477_get_tag,
+   .set_tag = ksz9477_set_tag,
+};
+
 int ksz9477_switch_register(struct ksz_device *dev)
 {
-   return ksz_switch_register(dev, _dev_ops);
+   return ksz_switch_register(dev, _dev_ops, _tag_ops);
 }
 EXPORT_SYMBOL(ksz9477_switch_register);
 
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 7b8f57b..a72659b 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -399,7 +399,8 @@ struct ksz_device *ksz_switch_alloc(struct device *base,
 EXPORT_SYMBOL(ksz_switch_alloc);
 
 int ksz_switch_register(struct ksz_device *dev,
-   const struct ksz_dev_ops *ops)
+   const struct ksz_dev_ops *ops,
+   const struct ksz_tag_ops *tag_ops)
 {
int ret;
 
@@ -412,6 +413,7 @@ int ksz_switch_register(struct ksz_device *dev,
mutex_init(>vlan_mutex);
 
dev->dev_ops = ops;
+   dev->tag_ops = tag_ops;
 
if (dev->dev_ops->detect(dev))
return -EINVAL;
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 5d93822..d020c1e 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -78,7 +78,8 @@ struct ksz_dev_ops {
 struct ksz_device *ksz_switch_alloc(struct device *base,
const struct ksz_io_ops *ops, void *priv);
 int ksz_switch_register(struct ksz_device *dev,
-   const struct ksz_dev_ops *ops);
+   const struct 

[PATCH RFC 0/6] net: dsa: microchip: Modify KSZ9477 DSA driver to support different tail tag formats

2018-12-03 Thread Tristram.Ha
From: Tristram Ha 

This series of patches is to modify the KSZ9477 DSA driver to support
different tail tag formats such that other new KSZ switch drivers can be
added without changing the base tail tagging code.

Tristram Ha (6):
  net: dsa: microchip: Prepare PHY for proper advertisement
  net: dsa: microchip: Add MIB counter reading support
  net: dsa: microchip: Break ksz_priv.h into two files
  net: dsa: microchip: Each switch driver has its own tail tagging
operations
  net: dsa: microchip: Update tag_ksz.c to access switch driver
  net: dsa: microchip: Add switch offload forwarding support

 drivers/net/dsa/microchip/ksz9477.c| 218 ++---
 drivers/net/dsa/microchip/ksz_common.c | 122 +-
 drivers/net/dsa/microchip/ksz_common.h |   4 +
 drivers/net/dsa/microchip/ksz_priv.h   |  94 ++
 include/linux/dsa/ksz_dsa.h|  99 +++
 net/dsa/tag_ksz.c  |  46 ---
 6 files changed, 426 insertions(+), 157 deletions(-)
 create mode 100644 include/linux/dsa/ksz_dsa.h

-- 
1.9.1



[PATCH RFC 1/6] net: dsa: microchip: Prepare PHY for proper advertisement

2018-12-03 Thread Tristram.Ha
From: Tristram Ha 

Prepare PHY for proper advertisement and get link status for the port.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz9477.c| 12 
 drivers/net/dsa/microchip/ksz_common.c | 17 +
 drivers/net/dsa/microchip/ksz_common.h |  2 ++
 drivers/net/dsa/microchip/ksz_priv.h   |  2 ++
 4 files changed, 33 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 0684657..98aa25e 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -969,6 +969,16 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, 
int port,
 PORT_MIRROR_SNIFFER, false);
 }
 
+static void ksz9477_phy_setup(struct ksz_device *dev, int port,
+ struct phy_device *phy)
+{
+   if (port < dev->phy_port_cnt) {
+   /* SUPPORTED_Asym_Pause and SUPPORTED_Pause can be removed to
+* disable flow control when rate limiting is used.
+*/
+   }
+}
+
 static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
@@ -1151,6 +1161,7 @@ static int ksz9477_setup(struct dsa_switch *ds)
.setup  = ksz9477_setup,
.phy_read   = ksz9477_phy_read16,
.phy_write  = ksz9477_phy_write16,
+   .adjust_link= ksz_adjust_link,
.port_enable= ksz_enable_port,
.port_disable   = ksz_disable_port,
.get_strings= ksz9477_get_strings,
@@ -1298,6 +1309,7 @@ static void ksz9477_switch_exit(struct ksz_device *dev)
.get_port_addr = ksz9477_get_port_addr,
.cfg_port_member = ksz9477_cfg_port_member,
.flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,
+   .phy_setup = ksz9477_phy_setup,
.port_setup = ksz9477_port_setup,
.shutdown = ksz9477_reset_switch,
.detect = ksz9477_switch_detect,
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 9705808..39adc57 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -61,6 +61,22 @@ int ksz_phy_write16(struct dsa_switch *ds, int addr, int 
reg, u16 val)
 }
 EXPORT_SYMBOL_GPL(ksz_phy_write16);
 
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev)
+{
+   struct ksz_device *dev = ds->priv;
+   struct ksz_port *p = >ports[port];
+
+   if (phydev->link) {
+   dev->live_ports |= (1 << port) & dev->on_ports;
+   } else if (p->phydev.link) {
+   p->link_just_down = 1;
+   dev->live_ports &= ~(1 << port);
+   }
+   p->phydev = *phydev;
+}
+EXPORT_SYMBOL_GPL(ksz_adjust_link);
+
 int ksz_sset_count(struct dsa_switch *ds, int port, int sset)
 {
struct ksz_device *dev = ds->priv;
@@ -238,6 +254,7 @@ int ksz_enable_port(struct dsa_switch *ds, int port, struct 
phy_device *phy)
 
/* setup slave port */
dev->dev_ops->port_setup(dev, port, false);
+   dev->dev_ops->phy_setup(dev, port, phy);
 
/* port_stp_state_set() will be called after to enable the port so
 * there is no need to do anything.
diff --git a/drivers/net/dsa/microchip/ksz_common.h 
b/drivers/net/dsa/microchip/ksz_common.h
index 2dd832d..206b313 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -13,6 +13,8 @@
 
 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev);
 int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
 struct net_device *br);
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index a38ff08..fcb75a8 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -135,6 +135,8 @@ struct ksz_dev_ops {
u32 (*get_port_addr)(int port, int offset);
void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member);
void (*flush_dyn_mac_table)(struct ksz_device *dev, int port);
+   void (*phy_setup)(struct ksz_device *dev, int port,
+ struct phy_device *phy);
void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port);
void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);
void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val);
-- 
1.9.1



RE: [PATCH v4 net-next 5/6] net: dsa: microchip: break KSZ9477 DSA driver into two files

2018-12-03 Thread Tristram.Ha
> From: Sørensen, Stefan 
> Sent: Monday, December 03, 2018 5:50 AM
> To: da...@davemloft.net; Tristram Ha - C24268
> 
> Cc: netdev@vger.kernel.org; pa...@ucw.cz; f.faine...@gmail.com;
> UNGLinuxDriver ; and...@lunn.ch
> Subject: Re: [PATCH v4 net-next 5/6] net: dsa: microchip: break KSZ9477 DSA
> driver into two files
> 
> On Tue, 2018-11-20 at 15:55 -0800, tristram...@microchip.com wrote:
> > From: Tristram Ha 
> >
> > Break KSZ9477 DSA driver into two files in preparation to add more
> > KSZ switch drivers.
> > Add common functions in ksz_common.h so that other KSZ switch drivers
> > can access code in ksz_common.c.
> > Add ksz_spi.h for common functions used by KSZ switch SPI drivers.
> 
> With this patch, the ethernet on my EVB-KSZ9477 is now completely non-
> functional, link is detected on the LAN ports, but no packets are
> forwarded to/from the CPU port.
> 
> Looking through the patch, it does much more than splitting up the
> existing code, e.g. the PORT_VLAN_MEMBERSHIP register is now written to
> - I suspect that change may be responsible for the problem.
> 

It is more likely the RGMII interface is not set properly.  There are upcoming
patches that address this issue.  The primary way to set RGMII delay is to set
phy-mode to "rgmii-txid" inside the device tree under the ksz9477 definition.
The chip can be set to MII/RMII with strap options, but there is no way to
change RGMII delay settings.

The patch will try to get the mode from hardware first.  When it is not set in
device tree this mode will be used.  When it is different from the one set a
warning will be displayed.  The one from device tree will be the one to use.

This will patch will support KSZ9893, a 3-port variant of KSZ9477.  It shares
most of the registers but has a different tail tag format, and uses a different
RGMII setting in the evaluation board.

Or do you use a different CPU port rather than the default port 6?



RE: [PATCH v1 net] lan743x: fix return value for lan743x_tx_napi_poll

2018-11-20 Thread Tristram.Ha
Slightly out of topic I am not sure why NAPI is used on the transmit side.
Originally NAPI was designed to fix the receive interrupt happening on each
receive frame problem, so on transmit side it is to avoid the transmit
done interrupt on each transmit frame?  Typically hardware has a way
to trigger transmit done interrupt or not in each transmit frame.

NAPI may have other uses in newer kernels that I am not aware of.

I notice 2 problems in the driver:

1. netif_napi_add is used instead of netif_tx_napi_add.
2. In all other drivers that use netif_tx_napi_add most do not call 
napi_complete_done.
They all call napi_complete directly and return 0.

freescale/gianfar.c
rocker/rocker_main.c
ti/cpsw.c

virtio_net.c does use napi_complete_done but it also passes 0 as a parameter.


> -Original Message-
> From: Florian Fainelli 
> Sent: Tuesday, November 20, 2018 2:12 PM
> To: Bryan Whitehead - C21958 ;
> and...@lunn.ch
> Cc: da...@davemloft.net; netdev@vger.kernel.org; UNGLinuxDriver
> 
> Subject: Re: [PATCH v1 net] lan743x: fix return value for
> lan743x_tx_napi_poll
> 
> On 11/20/18 1:39 PM, bryan.whiteh...@microchip.com wrote:
> >> -Original Message-
> >> From: Andrew Lunn 
> >> Sent: Tuesday, November 20, 2018 2:31 PM
> >> To: Bryan Whitehead - C21958 
> >> Cc: da...@davemloft.net; netdev@vger.kernel.org; UNGLinuxDriver
> >> 
> >> Subject: Re: [PATCH v1 net] lan743x: fix return value for
> >> lan743x_tx_napi_poll
> >>
> >> On Tue, Nov 20, 2018 at 01:26:43PM -0500, Bryan Whitehead wrote:
> >>> It has been noticed that under stress the lan743x driver will
> >>> sometimes hang or cause a kernel panic. It has been noticed that
> >>> returning '0' instead of 'weight' fixes this issue.
> >>>
> >>> fixes: rare kernel panic under heavy traffic load.
> >>> Signed-off-by: Bryan Whitehead 
> >>
> >> Hi Bryan
> >>
> >> This sounds like a band aid over something which is broken, not a real fix.
> >>
> >> Can you show us the stack trace from the panic?
> >>
> >> Andrew
> >
> > Andrew,
> >
> > Admittedly, my knowledge of what the kernel is doing behind the scenes is
> limited.
> >
> > But according to documentation found on
> > https://wiki.linuxfoundation.org/networking/napi
> >
> > It states the following
> > "The poll() function may also process TX completions, in which case if it
> processes
> > the entire TX ring then it should count that work as the rest of the budget.
> > Otherwise, TX completions are not counted."
> >
> > So based on that, the original driver was returning the full budget. But I 
> > was
> having
> > Issues with it. And the above documentation seems to suggest that I could
> return 0
> > As in "not counted" from above.
> >
> > I tried it, and my lock up issues disappeared.
> >
> > Regarding the kernel panic stack trace. So far its very hard to replicate 
> > that
> on the
> > latest kernel. I've seen it more frequently when back porting to older
> kernels such
> > as 4.14, and 4.9. This same fix caused those kernel panics to disappear.
> > Are you interested in seeing a stack dump from older kernels?
> >
> > In the latest kernel the issue manifests as a kernel message which states
> > "[  945.021101] enp48s0: Budget exhausted after napi rescheduled"
> >
> > I'm not sure what that means. But it does not lock up immediately after
> seeing that
> > Message. But it usually locks up with in a minute of seeing that message.
> >
> > And the sometimes I get the following warning
> > [ 1240.425020] [ cut here ]
> > [ 1240.426014] NETDEV WATCHDOG: enp0s25 (e1000e): transmit queue 0
> timed out
> > [ 1240.430027] WARNING: CPU: 0 PID: 0 at net/sched/sch_generic.c:461
> dev_watchdog+0x1ef/0x200
> > [ 1240.430027] Modules linked in: lan743x
> > [ 1240.430027] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G  I   
> > 4.19.2 #1
> > [ 1240.430027] Hardware name: Hewlett-Packard HP Compaq dc7900
> Convertible Minitower/3032h, BIOS 786G1 v01.16 03/05/2009
> > [ 1240.430027] RIP: 0010:dev_watchdog+0x1ef/0x200
> > [ 1240.430027] Code: 00 48 63 4d e0 eb 93 4c 89 e7 c6 05 68 30 b3 00 01 e8 
> > 25
> 3d fd ff 89 d9 48 89 c2 4c 89 e6 48 c7 c7 98 92 48 ab e8 f1 28 87 ff <0f> 0b 
> eb c0
> 0f 1f 00 66 2e 0f 1f 84 00 00 00 00 00 48 c7 47 08 00
> > [ 1240.430027] RSP: 0018:98490be03e90 EFLAGS: 00010282
> > [ 1240.430027] RAX:  RBX:  RCX:
> 
> > [ 1240.497168] RDX: 00040400 RSI: 00f6 RDI:
> 0300
> > [ 1240.497168] RBP: 984908574440 R08:  R09:
> 03a4
> > [ 1240.497168] R10: 0020 R11: abc928ed R12:
> 984908574000
> > [ 1240.497168] R13:  R14:  R15:
> 98490be195b0
> > [ 1240.497168] FS:  () GS:98490be0()
> knlGS:
> > [ 1240.497168] CS:  0010 DS:  ES:  CR0: 80050033
> > [ 1240.497168] CR2: 7f31cd4c CR3: 000109bca000 CR4:
> 

[PATCH v4 net-next 5/6] net: dsa: microchip: break KSZ9477 DSA driver into two files

2018-11-20 Thread Tristram.Ha
From: Tristram Ha 

Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.
Add common functions in ksz_common.h so that other KSZ switch drivers
can access code in ksz_common.c.
Add ksz_spi.h for common functions used by KSZ switch SPI drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Kconfig   |4 +
 drivers/net/dsa/microchip/Makefile  |3 +-
 drivers/net/dsa/microchip/ksz9477.c | 1316 +++
 drivers/net/dsa/microchip/ksz9477_spi.c |  143 ++--
 drivers/net/dsa/microchip/ksz_common.c  | 1170 ---
 drivers/net/dsa/microchip/ksz_common.h  |  214 +
 drivers/net/dsa/microchip/ksz_priv.h|  226 +++---
 drivers/net/dsa/microchip/ksz_spi.h |   69 ++
 8 files changed, 1903 insertions(+), 1242 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index 4e25fe4..a8caf92 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,7 +1,11 @@
+config NET_DSA_MICROCHIP_KSZ_COMMON
+   tristate
+
 menuconfig NET_DSA_MICROCHIP_KSZ9477
tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
select NET_DSA_TAG_KSZ
+   select NET_DSA_MICROCHIP_KSZ_COMMON
help
  This driver adds support for Microchip KSZ9477 switch chips.
 
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 9393e73..3142c18 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,3 @@
-obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON) += ksz_common.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477)+= ksz9477.o
 obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI)+= ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
new file mode 100644
index 000..80df6c0
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -0,0 +1,1316 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Microchip KSZ9477 switch driver main logic
+ *
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz_9477_reg.h"
+
+static const struct {
+   int index;
+   char string[ETH_GSTRING_LEN];
+} ksz9477_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { 0x00, "rx_hi" },
+   { 0x01, "rx_undersize" },
+   { 0x02, "rx_fragments" },
+   { 0x03, "rx_oversize" },
+   { 0x04, "rx_jabbers" },
+   { 0x05, "rx_symbol_err" },
+   { 0x06, "rx_crc_err" },
+   { 0x07, "rx_align_err" },
+   { 0x08, "rx_mac_ctrl" },
+   { 0x09, "rx_pause" },
+   { 0x0A, "rx_bcast" },
+   { 0x0B, "rx_mcast" },
+   { 0x0C, "rx_ucast" },
+   { 0x0D, "rx_64_or_less" },
+   { 0x0E, "rx_65_127" },
+   { 0x0F, "rx_128_255" },
+   { 0x10, "rx_256_511" },
+   { 0x11, "rx_512_1023" },
+   { 0x12, "rx_1024_1522" },
+   { 0x13, "rx_1523_2000" },
+   { 0x14, "rx_2001" },
+   { 0x15, "tx_hi" },
+   { 0x16, "tx_late_col" },
+   { 0x17, "tx_pause" },
+   { 0x18, "tx_bcast" },
+   { 0x19, "tx_mcast" },
+   { 0x1A, "tx_ucast" },
+   { 0x1B, "tx_deferred" },
+   { 0x1C, "tx_total_col" },
+   { 0x1D, "tx_exc_col" },
+   { 0x1E, "tx_single_col" },
+   { 0x1F, "tx_mult_col" },
+   { 0x80, "rx_total" },
+   { 0x81, "tx_total" },
+   { 0x82, "rx_discards" },
+   { 0x83, "tx_discards" },
+};
+
+static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
+{
+   u32 data;
+
+   ksz_read32(dev, addr, );
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+   ksz_write32(dev, addr, data);
+}
+
+static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,
+  u32 bits, bool set)
+{
+   u32 addr;
+   u32 data;
+
+   addr = PORT_CTRL_ADDR(port, offset);
+   ksz_read32(dev, addr, );
+
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+
+   ksz_write32(dev, addr, data);
+}
+
+static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev, u32 waiton,
+   int timeout)
+{
+   u8 data;
+
+   do {
+   ksz_read8(dev, REG_SW_VLAN_CTRL, );
+   if (!(data & waiton))
+   break;
+   usleep_range(1, 10);
+   } while 

[PATCH v4 net-next 2/6] net: dsa: microchip: clean up code

2018-11-20 Thread Tristram.Ha
From: Tristram Ha 

Clean up code according to patch check suggestions.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_common.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index d47d03b..eb833df 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -890,9 +890,9 @@ static void ksz_port_mdb_add(struct dsa_switch *ds, int 
port,
 
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
@@ -963,9 +963,9 @@ static int ksz_port_mdb_del(struct dsa_switch *ds, int port,
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
 
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
-- 
1.9.1



[PATCH v4 net-next 3/6] net: dsa: microchip: rename some functions with ksz9477 prefix

2018-11-20 Thread Tristram.Ha
From: Tristram Ha 

Rename some functions with ksz9477 prefix to separate chip specific code
from common code.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_common.c | 116 +
 1 file changed, 59 insertions(+), 57 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index eb833df..50b24dc 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -253,9 +253,8 @@ static int wait_alu_sta_ready(struct ksz_device *dev, u32 
waiton, int timeout)
return 0;
 }
 
-static int ksz_reset_switch(struct dsa_switch *ds)
+static int ksz9477_reset_switch(struct ksz_device *dev)
 {
-   struct ksz_device *dev = ds->priv;
u8 data8;
u16 data16;
u32 data32;
@@ -288,7 +287,7 @@ static int ksz_reset_switch(struct dsa_switch *ds)
return 0;
 }
 
-static void port_setup(struct ksz_device *dev, int port, bool cpu_port)
+static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
u16 data16;
@@ -334,7 +333,7 @@ static void port_setup(struct ksz_device *dev, int port, 
bool cpu_port)
ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, );
 }
 
-static void ksz_config_cpu_port(struct dsa_switch *ds)
+static void ksz9477_config_cpu_port(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int i;
@@ -346,12 +345,12 @@ static void ksz_config_cpu_port(struct dsa_switch *ds)
dev->cpu_port = i;
 
/* enable cpu port */
-   port_setup(dev, i, true);
+   ksz9477_port_setup(dev, i, true);
}
}
 }
 
-static int ksz_setup(struct dsa_switch *ds)
+static int ksz9477_setup(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int ret = 0;
@@ -361,7 +360,7 @@ static int ksz_setup(struct dsa_switch *ds)
if (!dev->vlan_cache)
return -ENOMEM;
 
-   ret = ksz_reset_switch(ds);
+   ret = ksz9477_reset_switch(dev);
if (ret) {
dev_err(ds->dev, "failed to reset switch\n");
return ret;
@@ -370,7 +369,7 @@ static int ksz_setup(struct dsa_switch *ds)
/* accept packet up to 2000bytes */
ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true);
 
-   ksz_config_cpu_port(ds);
+   ksz9477_config_cpu_port(ds);
 
ksz_cfg(dev, REG_SW_MAC_CTRL_1, MULTICAST_STORM_DISABLE, true);
 
@@ -383,13 +382,13 @@ static int ksz_setup(struct dsa_switch *ds)
return 0;
 }
 
-static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
- int port)
+static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
+ int port)
 {
return DSA_TAG_PROTO_KSZ;
 }
 
-static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
+static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
 {
struct ksz_device *dev = ds->priv;
u16 val = 0;
@@ -399,7 +398,8 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, 
int reg)
return val;
 }
 
-static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
+static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg,
+  u16 val)
 {
struct ksz_device *dev = ds->priv;
 
@@ -414,7 +414,7 @@ static int ksz_enable_port(struct dsa_switch *ds, int port,
struct ksz_device *dev = ds->priv;
 
/* setup slave port */
-   port_setup(dev, port, false);
+   ksz9477_port_setup(dev, port, false);
 
return 0;
 }
@@ -436,8 +436,8 @@ static int ksz_sset_count(struct dsa_switch *ds, int port, 
int sset)
return TOTAL_SWITCH_COUNTER_NUM;
 }
 
-static void ksz_get_strings(struct dsa_switch *ds, int port,
-   u32 stringset, uint8_t *buf)
+static void ksz9477_get_strings(struct dsa_switch *ds, int port,
+   u32 stringset, uint8_t *buf)
 {
int i;
 
@@ -490,7 +490,8 @@ static void ksz_get_ethtool_stats(struct dsa_switch *ds, 
int port,
mutex_unlock(>stats_mutex);
 }
 
-static void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
+  u8 state)
 {
struct ksz_device *dev = ds->priv;
u8 data;
@@ -535,7 +536,8 @@ static void ksz_port_fast_age(struct dsa_switch *ds, int 
port)
ksz_write8(dev, REG_SW_LUE_CTRL_1, data8);
 }
 
-static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag)
+static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
+ 

[PATCH v4 net-next 6/6] net: dsa: microchip: rename ksz_9477_reg.h to ksz9477_reg.h

2018-11-20 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz9477.c | 2 +-
 drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} | 0
 drivers/net/dsa/microchip/ksz_priv.h| 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (100%)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 80df6c0..0684657 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -19,7 +19,7 @@
 
 #include "ksz_priv.h"
 #include "ksz_common.h"
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 static const struct {
int index;
diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz9477_reg.h
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_9477_reg.h
rename to drivers/net/dsa/microchip/ksz9477_reg.h
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 74c5c1a..a38ff08 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -14,7 +14,7 @@
 #include 
 #include 
 
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 struct ksz_io_ops;
 
-- 
1.9.1



[PATCH v4 net-next 1/6] net: dsa: microchip: replace license with GPL

2018-11-20 Thread Tristram.Ha
From: Tristram Ha 

Replace license with GPL.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Andrew Lunn 
Acked-by: Pavel Machek 
---
 drivers/net/dsa/microchip/ksz_9477_reg.h | 17 +++--
 drivers/net/dsa/microchip/ksz_common.c   | 15 ++-
 drivers/net/dsa/microchip/ksz_priv.h | 17 +++--
 drivers/net/dsa/microchip/ksz_spi.c  | 15 ++-
 4 files changed, 10 insertions(+), 54 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz_9477_reg.h
index 6aa6752..2938e89 100644
--- a/drivers/net/dsa/microchip/ksz_9477_reg.h
+++ b/drivers/net/dsa/microchip/ksz_9477_reg.h
@@ -1,19 +1,8 @@
-/*
- * Microchip KSZ9477 register definitions
- *
- * Copyright (C) 2017
+/* SPDX-License-Identifier: GPL-2.0
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Microchip KSZ9477 register definitions
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
  */
 
 #ifndef __KSZ9477_REGS_H
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 86b6464..d47d03b 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Microchip switch driver main logic
  *
- * Copyright (C) 2017
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
  */
 
 #include 
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 2a98dbd..6a27933 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -1,19 +1,8 @@
-/*
- * Microchip KSZ series switch common definitions
- *
- * Copyright (C) 2017
+/* SPDX-License-Identifier: GPL-2.0
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * Microchip KSZ series switch common definitions
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
  */
 
 #ifndef __KSZ_PRIV_H
diff --git a/drivers/net/dsa/microchip/ksz_spi.c 
b/drivers/net/dsa/microchip/ksz_spi.c
index 8c1778b..dc70f48 100644
--- a/drivers/net/dsa/microchip/ksz_spi.c
+++ b/drivers/net/dsa/microchip/ksz_spi.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Microchip KSZ series register access through SPI
  *
- * Copyright (C) 2017
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 

[PATCH v4 net-next 0/6] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2018-11-20 Thread Tristram.Ha
From: Tristram Ha 

This series of patches is to modify the original KSZ9477 DSA driver so
that other KSZ switch drivers can be added and use the common code.

There are several steps to accomplish this achievement.  First is to
rename some function names with a prefix to indicate chip specific
function.  Second is to move common code into header that can be shared.
Last is to modify tag_ksz.c so that it can handle many tail tag formats
used by different KSZ switch drivers.

ksz_common.c will contain the common code used by all KSZ switch drivers.
ksz9477.c will contain KSZ9477 code from the original ksz_common.c.
ksz9477_spi.c is renamed from ksz_spi.c.
ksz9477_reg.h is renamed from ksz_9477_reg.h.
ksz_common.h is added to provide common code access to KSZ switch
drivers.
ksz_spi.h is added to provide common SPI access functions to KSZ SPI
drivers.

v4
- Patches were removed to concentrate on changing driver structure without
adding new code.

v3
- The phy_device structure is used to hold port link information
- A structure is passed in ksz_xmit and ksz_rcv instead of function pointer
- Switch offload forwarding is supported

v2
- Initialize reg_mutex before use
- The alu_mutex is only used inside chip specific functions

v1
- Each patch in the set is self-contained
- Use ksz9477 prefix to indicate KSZ9477 specific code

Tristram Ha (6):
  net: dsa: microchip: replace license with GPL
  net: dsa: microchip: clean up code
  net: dsa: microchip: rename some functions with ksz9477 prefix
  net: dsa: microchip: rename ksz_spi.c to ksz9477_spi.c
  net: dsa: microchip: break KSZ9477 DSA driver into two files
  net: dsa: microchip: rename ksz_9477_reg.h to ksz9477_reg.h

 drivers/net/dsa/microchip/Kconfig  |   16 +-
 drivers/net/dsa/microchip/Makefile |5 +-
 drivers/net/dsa/microchip/ksz9477.c| 1316 
 .../microchip/{ksz_9477_reg.h => ksz9477_reg.h}|   17 +-
 drivers/net/dsa/microchip/ksz9477_spi.c|  177 +++
 drivers/net/dsa/microchip/ksz_common.c | 1183 +++---
 drivers/net/dsa/microchip/ksz_common.h |  214 
 drivers/net/dsa/microchip/ksz_priv.h   |  245 ++--
 drivers/net/dsa/microchip/ksz_spi.c|  217 
 drivers/net/dsa/microchip/ksz_spi.h|   69 +
 10 files changed, 2039 insertions(+), 1420 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (98%)
 create mode 100644 drivers/net/dsa/microchip/ksz9477_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 delete mode 100644 drivers/net/dsa/microchip/ksz_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

-- 
1.9.1



[PATCH v4 net-next 4/6] net: dsa: microchip: rename ksz_spi.c to ksz9477_spi.c

2018-11-20 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to add
more KSZ switch drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Kconfig  | 12 ++--
 drivers/net/dsa/microchip/Makefile |  4 ++--
 drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} |  0
 3 files changed, 8 insertions(+), 8 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} (100%)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index a8b8f59..4e25fe4 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,12 +1,12 @@
-menuconfig MICROCHIP_KSZ
-   tristate "Microchip KSZ series switch support"
+menuconfig NET_DSA_MICROCHIP_KSZ9477
+   tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
select NET_DSA_TAG_KSZ
help
- This driver adds support for Microchip KSZ switch chips.
+ This driver adds support for Microchip KSZ9477 switch chips.
 
-config MICROCHIP_KSZ_SPI_DRIVER
-   tristate "KSZ series SPI connected switch driver"
-   depends on MICROCHIP_KSZ && SPI
+config NET_DSA_MICROCHIP_KSZ9477_SPI
+   tristate "KSZ9477 series SPI connected switch driver"
+   depends on NET_DSA_MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index ed335e2..9393e73 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ)+= ksz_common.o
-obj-$(CONFIG_MICROCHIP_KSZ_SPI_DRIVER) += ksz_spi.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI)+= ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz_spi.c 
b/drivers/net/dsa/microchip/ksz9477_spi.c
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_spi.c
rename to drivers/net/dsa/microchip/ksz9477_spi.c
-- 
1.9.1



[PATCH v2 net] net: dsa: microchip: initialize mutex before use

2018-11-02 Thread Tristram.Ha
From: Tristram Ha 

Initialize mutex before use.  Avoid kernel complaint when
CONFIG_DEBUG_LOCK_ALLOC is enabled.

Fixes: b987e98e50ab90e5 ("dsa: add DSA switch driver for Microchip KSZ9477")
Signed-off-by: Tristram Ha 
Reviewed-by: Pavel Machek 
Reviewed-by: Andrew Lunn 
Reviewed-by: Florian Fainelli 
---
v2
- Add endorsements

v1
- Remove comment

 drivers/net/dsa/microchip/ksz_common.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 54e0ca6..86b6464 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1117,11 +1117,6 @@ static int ksz_switch_init(struct ksz_device *dev)
 {
int i;
 
-   mutex_init(>reg_mutex);
-   mutex_init(>stats_mutex);
-   mutex_init(>alu_mutex);
-   mutex_init(>vlan_mutex);
-
dev->ds->ops = _switch_ops;
 
for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {
@@ -1206,6 +1201,11 @@ int ksz_switch_register(struct ksz_device *dev)
if (dev->pdata)
dev->chip_id = dev->pdata->chip_id;
 
+   mutex_init(>reg_mutex);
+   mutex_init(>stats_mutex);
+   mutex_init(>alu_mutex);
+   mutex_init(>vlan_mutex);
+
if (ksz_switch_detect(dev))
return -EINVAL;
 
-- 
1.9.1



[PATCH v2 net] net: dsa: microchip: initialize mutex before use

2018-11-01 Thread Tristram.Ha
From: Tristram Ha 

Initialize mutex before use.  Avoid kernel complaint when
CONFIG_DEBUG_LOCK_ALLOC is enabled.

Fixes: b987e98e50ab90e5 ("dsa: add DSA switch driver for Microchip KSZ9477")
Signed-off-by: Tristram Ha 
Reviewed-by: Pavel Machek 
Reviewed-by: Andrew Lunn 
---
v2
- Add endorsements

v1
- Remove comment

 drivers/net/dsa/microchip/ksz_common.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 54e0ca6..86b6464 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1117,11 +1117,6 @@ static int ksz_switch_init(struct ksz_device *dev)
 {
int i;
 
-   mutex_init(>reg_mutex);
-   mutex_init(>stats_mutex);
-   mutex_init(>alu_mutex);
-   mutex_init(>vlan_mutex);
-
dev->ds->ops = _switch_ops;
 
for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {
@@ -1206,6 +1201,11 @@ int ksz_switch_register(struct ksz_device *dev)
if (dev->pdata)
dev->chip_id = dev->pdata->chip_id;
 
+   mutex_init(>reg_mutex);
+   mutex_init(>stats_mutex);
+   mutex_init(>alu_mutex);
+   mutex_init(>vlan_mutex);
+
if (ksz_switch_detect(dev))
return -EINVAL;
 
-- 
1.9.1



[PATCH v1 net] net: dsa: microchip: initialize mutex before use

2018-10-31 Thread Tristram.Ha
From: Tristram Ha 

Initialize mutex before use.  Avoid kernel complaint when
CONFIG_DEBUG_LOCK_ALLOC is enabled.

Fixes: b987e98e50ab90e5 ("dsa: add DSA switch driver for Microchip KSZ9477")
Signed-off-by: Tristram Ha 
---
v1
- Remove comment

 drivers/net/dsa/microchip/ksz_common.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 54e0ca6..86b6464 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1117,11 +1117,6 @@ static int ksz_switch_init(struct ksz_device *dev)
 {
int i;
 
-   mutex_init(>reg_mutex);
-   mutex_init(>stats_mutex);
-   mutex_init(>alu_mutex);
-   mutex_init(>vlan_mutex);
-
dev->ds->ops = _switch_ops;
 
for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {
@@ -1206,6 +1201,11 @@ int ksz_switch_register(struct ksz_device *dev)
if (dev->pdata)
dev->chip_id = dev->pdata->chip_id;
 
+   mutex_init(>reg_mutex);
+   mutex_init(>stats_mutex);
+   mutex_init(>alu_mutex);
+   mutex_init(>vlan_mutex);
+
if (ksz_switch_detect(dev))
return -EINVAL;
 
-- 
1.9.1



[PATCH net] net: dsa: microchip: initialize mutex before use

2018-10-30 Thread Tristram.Ha
From: Tristram Ha 

Initialize mutex before use.  Avoid kernel complaint when
CONFIG_DEBUG_LOCK_ALLOC is enabled.

Fixes: b987e98e50ab90e5 ("dsa: add DSA switch driver for Microchip KSZ9477")
Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz_common.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 54e0ca6..f6f0662 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1117,11 +1117,6 @@ static int ksz_switch_init(struct ksz_device *dev)
 {
int i;
 
-   mutex_init(>reg_mutex);
-   mutex_init(>stats_mutex);
-   mutex_init(>alu_mutex);
-   mutex_init(>vlan_mutex);
-
dev->ds->ops = _switch_ops;
 
for (i = 0; i < ARRAY_SIZE(ksz_switch_chips); i++) {
@@ -1206,6 +1201,12 @@ int ksz_switch_register(struct ksz_device *dev)
if (dev->pdata)
dev->chip_id = dev->pdata->chip_id;
 
+   /* mutex is used in next function call. */
+   mutex_init(>reg_mutex);
+   mutex_init(>stats_mutex);
+   mutex_init(>alu_mutex);
+   mutex_init(>vlan_mutex);
+
if (ksz_switch_detect(dev))
return -EINVAL;
 
-- 
1.9.1



RE: [PATCH net] net: ethernet: cadence: fix socket buffer corruption problem

2018-10-30 Thread Tristram.Ha
> Could you check on your side that applying this on top of your patch, your
> scenario is still working?
> 
> diff --git a/drivers/net/ethernet/cadence/macb_main.c
> b/drivers/net/ethernet/cadence/macb_main.c
> index 1d86b4d5645a..e1347d6d1b50 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -1702,12 +1702,8 @@ static int macb_pad_and_fcs(struct sk_buff **skb,
> struct net_device *ndev)
> *skb = nskb;
> }
> 
> -   if (padlen) {
> -   if (padlen >= ETH_FCS_LEN)
> -   skb_put_zero(*skb, padlen - ETH_FCS_LEN);
> -   else
> -   skb_trim(*skb, ETH_FCS_LEN - padlen);
> -   }
> +   if (padlen > ETH_FCS_LEN)
> +   skb_put_zero(*skb, padlen - ETH_FCS_LEN);

I think it is okay but I need to check all paths are covered.
 
> It was reported in [1] that UDP checksum is offloaded to hardware no matter
> the application previously computed it.
> 
> The code should be executed only for packets that has checksum computed
> by
> applications ((*skb)->ip_summed != CHECKSUM_PARTIAL). The idea was to
> not
> recompute checksum for packets with checksum already computed. To do
> so,
> while hardware checksum is enabled (NETIF_F_HW_CSUM), TX_NOCRC bit
> should
> be set on buffer descriptor. But to do so, packets must have a minimum size
> of 64 and FCS to be computed.
> 
> The NETIF_F_HW_CSUM check was placed there because the issue
> described in
> [1] is reproducible because hardware checksum is enabled and overrides the
> checksum provided by applications.
> 
> [1] https://www.spinics.net/lists/netdev/msg505065.html

I understand the issue now.  It is weird that the transmit descriptor does not
have direct control over turning on checksum generation or not, but it wastes
3 bits returning the error codes of such generation.  What can the driver do
with such information?

In my opinion then hardware transmit checksumming cannot be supported
In Linux.

> > NETIF_F_SG is not enabled in the MAC I used, so enabling
> NETIF_IF_HW_CSUM
> > is rather pointless.  With the padding code the transmit throughput cannot
> get
> > higher than 100Mbps in a gigabit connection.
> >
> > I would recommend to add this option to disable manual padding in one of
> those
> > macb_config structures.
> 
> In this way the user would have to know from the beginning what kind of
> packets are used.
> 

The kernel already does a good job of calculating checksum.  Using hardware to
do that does not improve performance much.

Alternative is to use ethtool to disable hardware tx checksum so that software 
can
intentionally send wrong checksums.



RE: [PATCH net] net: ethernet: cadence: fix socket buffer corruption problem

2018-10-29 Thread Tristram.Ha
> Could you, please, tell me if the above variable was false in your case?
> 
> bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb);
> 
> If yes, then, the proper fix would be as follows:
> 
> diff --git a/drivers/net/ethernet/cadence/macb_main.c
> b/drivers/net/ethernet/cadence/macb_main.c
> index 8f5bf9166c11..492a8e1a34cd 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -1690,7 +1690,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb,
> struct net_device *ndev)
> padlen += ETH_FCS_LEN;
> }
> 
> -   if (!cloned && headroom + tailroom >= padlen) {
> +   if (!cloned && headroom + tailroom >= ETH_FCS_LEN) {
> (*skb)->data = memmove((*skb)->head, (*skb)->data, 
> (*skb)->len);
> skb_set_tail_pointer(*skb, (*skb)->len);
> } else {
> 
> Could you please check if it works in your case (and without your patch)?
> 

Actually doing that reveals another bug:

if (padlen) {
if (padlen >= ETH_FCS_LEN)
skb_put_zero(*skb, padlen - ETH_FCS_LEN);
else
skb_trim(*skb, ETH_FCS_LEN - padlen);
}

My fix calls skb_put_zero with zero length.  Your change calls skb_trim which
actually sets the socket buffer length to 1!

When this problem happens headroom is 2, tailroom is 1, skb->len is 61, and
padlen is 3.

DSA driver is being used.  That is why the length is already padded to 60 bytes
and 1-byte tail tag is added.

BTW, I am not sure while this macb_pad_and_fcs function was added.  Is it to
workaround some hardware bugs?  The code is executed only when
NETIF_IF_HW_CSUM is used.  But if hardware tx checksumming is enabled why
not also use the hardware to calculate CRC?

NETIF_F_SG is not enabled in the MAC I used, so enabling NETIF_IF_HW_CSUM
is rather pointless.  With the padding code the transmit throughput cannot get
higher than 100Mbps in a gigabit connection.

I would recommend to add this option to disable manual padding in one of those
macb_config structures.



[PATCH net] net: ethernet: cadence: fix socket buffer corruption problem

2018-10-24 Thread Tristram.Ha
From: Tristram Ha 

Socket buffer is not re-created when headroom is 2 and tailroom is 1.

Signed-off-by: Tristram Ha 
---
 drivers/net/ethernet/cadence/macb_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/cadence/macb_main.c 
b/drivers/net/ethernet/cadence/macb_main.c
index 8f5bf91..1d86b4d 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1684,7 +1684,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct 
net_device *ndev)
padlen = 0;
/* No room for FCS, need to reallocate skb. */
else
-   padlen = ETH_FCS_LEN - tailroom;
+   padlen = ETH_FCS_LEN;
} else {
/* Add room for FCS. */
padlen += ETH_FCS_LEN;
-- 
1.9.1



[PATCH v3 net-next 05/11] net: dsa: microchip: Rename ksz_spi.c to ksz9477_spi.c

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to add
more KSZ switch drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Kconfig  | 12 ++--
 drivers/net/dsa/microchip/Makefile |  4 ++--
 drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} |  0
 3 files changed, 8 insertions(+), 8 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} (100%)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index a8b8f59..4e25fe4 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,12 +1,12 @@
-menuconfig MICROCHIP_KSZ
-   tristate "Microchip KSZ series switch support"
+menuconfig NET_DSA_MICROCHIP_KSZ9477
+   tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
select NET_DSA_TAG_KSZ
help
- This driver adds support for Microchip KSZ switch chips.
+ This driver adds support for Microchip KSZ9477 switch chips.
 
-config MICROCHIP_KSZ_SPI_DRIVER
-   tristate "KSZ series SPI connected switch driver"
-   depends on MICROCHIP_KSZ && SPI
+config NET_DSA_MICROCHIP_KSZ9477_SPI
+   tristate "KSZ9477 series SPI connected switch driver"
+   depends on NET_DSA_MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index ed335e2..9393e73 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ)+= ksz_common.o
-obj-$(CONFIG_MICROCHIP_KSZ_SPI_DRIVER) += ksz_spi.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI)+= ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz_spi.c 
b/drivers/net/dsa/microchip/ksz9477_spi.c
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_spi.c
rename to drivers/net/dsa/microchip/ksz9477_spi.c
-- 
1.9.1



[PATCH v3 net-next 03/11] net: dsa: microchip: Initialize mutex before use

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Initialize mutex before use.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz_common.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 8c5853e..88e8d2a 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1118,7 +1118,6 @@ static int ksz_switch_init(struct ksz_device *dev)
 {
int i;
 
-   mutex_init(>reg_mutex);
mutex_init(>stats_mutex);
mutex_init(>alu_mutex);
mutex_init(>vlan_mutex);
@@ -1207,6 +1206,9 @@ int ksz_switch_register(struct ksz_device *dev)
if (dev->pdata)
dev->chip_id = dev->pdata->chip_id;
 
+   /* mutex is used in next function call. */
+   mutex_init(>reg_mutex);
+
if (ksz_switch_detect(dev))
return -EINVAL;
 
-- 
1.9.1



[PATCH v3 net-next 01/11] net: dsa: microchip: Replace license with GPL

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Replace license with GPL.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_9477_reg.h | 23 ---
 drivers/net/dsa/microchip/ksz_common.c   | 23 ---
 drivers/net/dsa/microchip/ksz_priv.h | 23 ---
 drivers/net/dsa/microchip/ksz_spi.c  | 23 ---
 4 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz_9477_reg.h
index 6aa6752..6d63442 100644
--- a/drivers/net/dsa/microchip/ksz_9477_reg.h
+++ b/drivers/net/dsa/microchip/ksz_9477_reg.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ9477 register definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #ifndef __KSZ9477_REGS_H
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 54e0ca6..fe95b9f 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1,19 +1,20 @@
 /*
  * Microchip switch driver main logic
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #include 
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 2a98dbd..824ed57 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ series switch common definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE 

[PATCH v3 net-next 08/11] net: dsa: microchip: Rename ksz_9477_reg.h to ksz9477_reg.h

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz9477.c | 2 +-
 drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} | 0
 drivers/net/dsa/microchip/ksz_priv.h| 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (100%)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 72042b0..afbe90a 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -31,7 +31,7 @@
 
 #include "ksz_priv.h"
 #include "ksz_common.h"
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 static const struct {
int index;
diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz9477_reg.h
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_9477_reg.h
rename to drivers/net/dsa/microchip/ksz9477_reg.h
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 708eef4..748231e 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -26,7 +26,7 @@
 #include 
 #include 
 
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 struct ksz_io_ops;
 
-- 
1.9.1



[PATCH v3 net-next 06/11] net: dsa: microchip: Break KSZ9477 DSA driver into two files

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.
Add common functions in ksz_common.h so that other KSZ switch drivers
can access code in ksz_common.c.
Add ksz_spi.h for common functions used by KSZ switch SPI drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Kconfig   |4 +
 drivers/net/dsa/microchip/Makefile  |3 +-
 drivers/net/dsa/microchip/ksz9477.c | 1332 +++
 drivers/net/dsa/microchip/ksz9477_spi.c |  143 ++--
 drivers/net/dsa/microchip/ksz_common.c  | 1174 ---
 drivers/net/dsa/microchip/ksz_common.h  |  227 ++
 drivers/net/dsa/microchip/ksz_priv.h|  226 +++---
 drivers/net/dsa/microchip/ksz_spi.h |   82 ++
 8 files changed, 1945 insertions(+), 1246 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index 4e25fe4..a8caf92 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,7 +1,11 @@
+config NET_DSA_MICROCHIP_KSZ_COMMON
+   tristate
+
 menuconfig NET_DSA_MICROCHIP_KSZ9477
tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
select NET_DSA_TAG_KSZ
+   select NET_DSA_MICROCHIP_KSZ_COMMON
help
  This driver adds support for Microchip KSZ9477 switch chips.
 
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 9393e73..3142c18 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,3 @@
-obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON) += ksz_common.o
+obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477)+= ksz9477.o
 obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI)+= ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
new file mode 100644
index 000..df3a189
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -0,0 +1,1332 @@
+/*
+ * Microchip KSZ9477 switch driver main logic
+ *
+ * Copyright (C) 2017-2018 Microchip Technology Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz_9477_reg.h"
+
+static const struct {
+   int index;
+   char string[ETH_GSTRING_LEN];
+} ksz9477_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { 0x00, "rx_hi" },
+   { 0x01, "rx_undersize" },
+   { 0x02, "rx_fragments" },
+   { 0x03, "rx_oversize" },
+   { 0x04, "rx_jabbers" },
+   { 0x05, "rx_symbol_err" },
+   { 0x06, "rx_crc_err" },
+   { 0x07, "rx_align_err" },
+   { 0x08, "rx_mac_ctrl" },
+   { 0x09, "rx_pause" },
+   { 0x0A, "rx_bcast" },
+   { 0x0B, "rx_mcast" },
+   { 0x0C, "rx_ucast" },
+   { 0x0D, "rx_64_or_less" },
+   { 0x0E, "rx_65_127" },
+   { 0x0F, "rx_128_255" },
+   { 0x10, "rx_256_511" },
+   { 0x11, "rx_512_1023" },
+   { 0x12, "rx_1024_1522" },
+   { 0x13, "rx_1523_2000" },
+   { 0x14, "rx_2001" },
+   { 0x15, "tx_hi" },
+   { 0x16, "tx_late_col" },
+   { 0x17, "tx_pause" },
+   { 0x18, "tx_bcast" },
+   { 0x19, "tx_mcast" },
+   { 0x1A, "tx_ucast" },
+   { 0x1B, "tx_deferred" },
+   { 0x1C, "tx_total_col" },
+   { 0x1D, "tx_exc_col" },
+   { 0x1E, "tx_single_col" },
+   { 0x1F, "tx_mult_col" },
+   { 0x80, "rx_total" },
+   { 0x81, "tx_total" },
+   { 0x82, "rx_discards" },
+   { 0x83, "tx_discards" },
+};
+
+static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
+{
+   u32 data;
+
+   ksz_read32(dev, addr, );
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+   ksz_write32(dev, addr, data);
+}
+
+static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,
+  

[PATCH v3 net-next 11/11] net: dsa: microchip: Add switch offload forwarding support

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Add switch offload forwarding support.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz9477.c | 3 +++
 net/dsa/tag_ksz.c   | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index c399fa2..f7d0bbe 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -438,6 +438,7 @@ static void ksz9477_port_stp_state_set(struct dsa_switch 
*ds, int port,
struct ksz_port *p = >ports[port];
u8 data;
int member = -1;
+   int forward = dev->member;
 
ksz_pread8(dev, port, P_STP_CTRL, );
data &= ~(PORT_TX_ENABLE | PORT_RX_ENABLE | PORT_LEARN_DISABLE);
@@ -509,6 +510,8 @@ static void ksz9477_port_stp_state_set(struct dsa_switch 
*ds, int port,
 * as the offload_fwd_mark indication cannot be reported here
 * the switch forwarding function is not enabled.
 */
+   if (forward != dev->member)
+   ksz_update_port_member(dev, port);
 }
 
 static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port)
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index e2c5dd4..47a3b91 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -84,6 +84,8 @@ static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct 
net_device *dev,
 
pskb_trim_rcsum(skb, skb->len - len);
 
+   skb->offload_fwd_mark = 1;
+
return skb;
 }
 
-- 
1.9.1



[PATCH v3 net-next 04/11] net: dsa: microchip: Rename some functions with ksz9477 prefix

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Rename some functions with ksz9477 prefix to separate chip specific code
from common code.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_common.c | 116 +
 1 file changed, 59 insertions(+), 57 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 88e8d2a..8475907 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -265,9 +265,8 @@ static int wait_alu_sta_ready(struct ksz_device *dev, u32 
waiton, int timeout)
return 0;
 }
 
-static int ksz_reset_switch(struct dsa_switch *ds)
+static int ksz9477_reset_switch(struct ksz_device *dev)
 {
-   struct ksz_device *dev = ds->priv;
u8 data8;
u16 data16;
u32 data32;
@@ -300,7 +299,7 @@ static int ksz_reset_switch(struct dsa_switch *ds)
return 0;
 }
 
-static void port_setup(struct ksz_device *dev, int port, bool cpu_port)
+static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
u16 data16;
@@ -346,7 +345,7 @@ static void port_setup(struct ksz_device *dev, int port, 
bool cpu_port)
ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, );
 }
 
-static void ksz_config_cpu_port(struct dsa_switch *ds)
+static void ksz9477_config_cpu_port(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int i;
@@ -358,12 +357,12 @@ static void ksz_config_cpu_port(struct dsa_switch *ds)
dev->cpu_port = i;
 
/* enable cpu port */
-   port_setup(dev, i, true);
+   ksz9477_port_setup(dev, i, true);
}
}
 }
 
-static int ksz_setup(struct dsa_switch *ds)
+static int ksz9477_setup(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int ret = 0;
@@ -373,7 +372,7 @@ static int ksz_setup(struct dsa_switch *ds)
if (!dev->vlan_cache)
return -ENOMEM;
 
-   ret = ksz_reset_switch(ds);
+   ret = ksz9477_reset_switch(dev);
if (ret) {
dev_err(ds->dev, "failed to reset switch\n");
return ret;
@@ -382,7 +381,7 @@ static int ksz_setup(struct dsa_switch *ds)
/* accept packet up to 2000bytes */
ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true);
 
-   ksz_config_cpu_port(ds);
+   ksz9477_config_cpu_port(ds);
 
ksz_cfg(dev, REG_SW_MAC_CTRL_1, MULTICAST_STORM_DISABLE, true);
 
@@ -395,13 +394,13 @@ static int ksz_setup(struct dsa_switch *ds)
return 0;
 }
 
-static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
- int port)
+static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
+ int port)
 {
return DSA_TAG_PROTO_KSZ;
 }
 
-static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
+static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
 {
struct ksz_device *dev = ds->priv;
u16 val = 0;
@@ -411,7 +410,8 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, 
int reg)
return val;
 }
 
-static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
+static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg,
+  u16 val)
 {
struct ksz_device *dev = ds->priv;
 
@@ -426,7 +426,7 @@ static int ksz_enable_port(struct dsa_switch *ds, int port,
struct ksz_device *dev = ds->priv;
 
/* setup slave port */
-   port_setup(dev, port, false);
+   ksz9477_port_setup(dev, port, false);
 
return 0;
 }
@@ -448,8 +448,8 @@ static int ksz_sset_count(struct dsa_switch *ds, int port, 
int sset)
return TOTAL_SWITCH_COUNTER_NUM;
 }
 
-static void ksz_get_strings(struct dsa_switch *ds, int port,
-   u32 stringset, uint8_t *buf)
+static void ksz9477_get_strings(struct dsa_switch *ds, int port,
+   u32 stringset, uint8_t *buf)
 {
int i;
 
@@ -502,7 +502,8 @@ static void ksz_get_ethtool_stats(struct dsa_switch *ds, 
int port,
mutex_unlock(>stats_mutex);
 }
 
-static void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
+  u8 state)
 {
struct ksz_device *dev = ds->priv;
u8 data;
@@ -547,7 +548,8 @@ static void ksz_port_fast_age(struct dsa_switch *ds, int 
port)
ksz_write8(dev, REG_SW_LUE_CTRL_1, data8);
 }
 
-static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag)
+static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
+ 

[PATCH v3 net-next 00/11] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

This series of patches is to modify the original KSZ9477 DSA driver so
that other KSZ switch drivers can be added and use the common code.

There are several steps to accomplish this achievement.  First is to
rename some function names with a prefix to indicate chip specific
function.  Second is to move common code into header that can be shared.
Last is to modify tag_ksz.c so that it can handle many tail tag formats
used by different KSZ switch drivers.

ksz_common.c will contain the common code used by all KSZ switch drivers.
ksz9477.c will contain KSZ9477 code from the original ksz_common.c.
ksz9477_spi.c is renamed from ksz_spi.c.
ksz9477_reg.h is renamed from ksz_9477_reg.h.
ksz_common.h is added to provide common code access to KSZ switch
drivers.
ksz_spi.h is added to provide common SPI access functions to KSZ SPI
drivers.

v3
- The phy_device structure is used to hold port link information
- A structure is passed in ksz_xmit and ksz_rcv instead of function pointer
- Switch offload forwarding is supported

v2
- Initialize reg_mutex before use
- The alu_mutex is only used inside chip specific functions

v1
- Each patch in the set is self-contained
- Use ksz9477 prefix to indicate KSZ9477 specific code

Tristram Ha (11):
  Replace license with GPL.
  Clean up code according to patch check suggestions.
  Initialize mutex before use.
  Rename some functions with ksz9477 prefix to separate chip specific
code from common code.
  Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to
add more KSZ switch drivers.
  Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers. Add common functions in ksz_common.h so that
other KSZ switch drivers can access code in ksz_common.c.
Add ksz_spi.h for common functions used by KSZ switch SPI drivers.
  Prepare PHY for proper advertisement and get link status for the port.
  Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.
  Add MIB counter reading support.
  Modify tag_ksz.c so that tail tag code can be used by other KSZ switch
drivers.
  Add switch offload forwarding support.

 drivers/net/dsa/microchip/Kconfig  |   18 +-
 drivers/net/dsa/microchip/Makefile |5 +-
 drivers/net/dsa/microchip/ksz9477.c| 1387 
 .../microchip/{ksz_9477_reg.h => ksz9477_reg.h}|   23 +-
 drivers/net/dsa/microchip/ksz9477_spi.c|  189 +++
 drivers/net/dsa/microchip/ksz_common.c | 1253 --
 drivers/net/dsa/microchip/ksz_common.h |  231 
 drivers/net/dsa/microchip/ksz_priv.h   |  256 ++--
 drivers/net/dsa/microchip/ksz_spi.c|  217 ---
 drivers/net/dsa/microchip/ksz_spi.h|   82 ++
 include/net/dsa.h  |2 +-
 net/dsa/Kconfig|4 +
 net/dsa/dsa.c  |8 +-
 net/dsa/dsa_priv.h |2 +-
 net/dsa/tag_ksz.c  |  101 +-
 15 files changed, 2354 insertions(+), 1424 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (98%)
 create mode 100644 drivers/net/dsa/microchip/ksz9477_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 delete mode 100644 drivers/net/dsa/microchip/ksz_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

-- 
1.9.1



[PATCH v3 net-next 10/11] net: dsa: microchip: Modify tag_ksz.c so that tail tag code can be used by other KSZ switch drivers

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Modify tag_ksz.c so that tail tag code can be used by other KSZ switch
drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/Kconfig   |  2 +-
 drivers/net/dsa/microchip/ksz9477.c |  2 +-
 include/net/dsa.h   |  2 +-
 net/dsa/Kconfig |  4 ++
 net/dsa/dsa.c   |  8 +--
 net/dsa/dsa_priv.h  |  2 +-
 net/dsa/tag_ksz.c   | 99 ++---
 7 files changed, 81 insertions(+), 38 deletions(-)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index a8caf92..bea29fd 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -4,7 +4,7 @@ config NET_DSA_MICROCHIP_KSZ_COMMON
 menuconfig NET_DSA_MICROCHIP_KSZ9477
tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
-   select NET_DSA_TAG_KSZ
+   select NET_DSA_TAG_KSZ9477
select NET_DSA_MICROCHIP_KSZ_COMMON
help
  This driver adds support for Microchip KSZ9477 switch chips.
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 7b810af..c399fa2 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -344,7 +344,7 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, 
int port)
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
  int port)
 {
-   return DSA_TAG_PROTO_KSZ;
+   return DSA_TAG_PROTO_KSZ9477;
 }
 
 static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 23690c4..8e54a4c 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -36,7 +36,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_DSA,
DSA_TAG_PROTO_EDSA,
DSA_TAG_PROTO_GSWIP,
-   DSA_TAG_PROTO_KSZ,
+   DSA_TAG_PROTO_KSZ9477,
DSA_TAG_PROTO_LAN9303,
DSA_TAG_PROTO_MTK,
DSA_TAG_PROTO_QCA,
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index 48c4191..91e5297 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -44,6 +44,10 @@ config NET_DSA_TAG_GSWIP
 config NET_DSA_TAG_KSZ
bool
 
+config NET_DSA_TAG_KSZ9477
+   bool
+   select NET_DSA_TAG_KSZ
+
 config NET_DSA_TAG_LAN9303
bool
 
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index a69c179..aee909b 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -55,8 +55,8 @@ static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff 
*skb,
 #ifdef CONFIG_NET_DSA_TAG_GSWIP
[DSA_TAG_PROTO_GSWIP] = _netdev_ops,
 #endif
-#ifdef CONFIG_NET_DSA_TAG_KSZ
-   [DSA_TAG_PROTO_KSZ] = _netdev_ops,
+#ifdef CONFIG_NET_DSA_TAG_KSZ9477
+   [DSA_TAG_PROTO_KSZ9477] = _netdev_ops,
 #endif
 #ifdef CONFIG_NET_DSA_TAG_LAN9303
[DSA_TAG_PROTO_LAN9303] = _netdev_ops,
@@ -91,8 +91,8 @@ const char *dsa_tag_protocol_to_str(const struct 
dsa_device_ops *ops)
 #ifdef CONFIG_NET_DSA_TAG_GSWIP
[DSA_TAG_PROTO_GSWIP] = "gswip",
 #endif
-#ifdef CONFIG_NET_DSA_TAG_KSZ
-   [DSA_TAG_PROTO_KSZ] = "ksz",
+#ifdef CONFIG_NET_DSA_TAG_KSZ9477
+   [DSA_TAG_PROTO_KSZ9477] = "ksz9477",
 #endif
 #ifdef CONFIG_NET_DSA_TAG_LAN9303
[DSA_TAG_PROTO_LAN9303] = "lan9303",
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 9e4fd04..026a057 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -210,7 +210,7 @@ static inline struct dsa_port *dsa_slave_to_port(const 
struct net_device *dev)
 extern const struct dsa_device_ops gswip_netdev_ops;
 
 /* tag_ksz.c */
-extern const struct dsa_device_ops ksz_netdev_ops;
+extern const struct dsa_device_ops ksz9477_netdev_ops;
 
 /* tag_lan9303.c */
 extern const struct dsa_device_ops lan9303_netdev_ops;
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 0f62eff..e2c5dd4 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -1,6 +1,6 @@
 /*
  * net/dsa/tag_ksz.c - Microchip KSZ Switch tag format handling
- * Copyright (c) 2017 Microchip Technology
+ * Copyright (c) 2017-2018 Microchip Technology
  *
  * 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
@@ -14,34 +14,25 @@
 #include 
 #include "dsa_priv.h"
 
-/* For Ingress (Host -> KSZ), 2 bytes are added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
- * ---
- * tag0 : Prioritization (not used now)
- * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
- *
- * For Egress (KSZ -> Host), 1 byte is added before FCS.
- * ---
- * 

[PATCH v3 net-next 09/11] net: dsa: microchip: Add MIB counter reading support

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Add MIB counter reading support.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz9477.c| 121 ++---
 drivers/net/dsa/microchip/ksz_common.c | 101 +++
 drivers/net/dsa/microchip/ksz_common.h |   2 +
 drivers/net/dsa/microchip/ksz_priv.h   |   7 +-
 4 files changed, 186 insertions(+), 45 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index afbe90a..7b810af 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -271,6 +271,76 @@ static int ksz9477_reset_switch(struct ksz_device *dev)
return 0;
 }
 
+static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
+ u64 *cnt)
+{
+   u32 data;
+   int timeout;
+   struct ksz_port *p = >ports[port];
+
+   /* retain the flush/freeze bit */
+   data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+   data |= MIB_COUNTER_READ;
+   data |= (addr << MIB_COUNTER_INDEX_S);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
+
+   timeout = 1000;
+   do {
+   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+   );
+   usleep_range(1, 10);
+   if (!(data & MIB_COUNTER_READ))
+   break;
+   } while (timeout-- > 0);
+
+   /* failed to read MIB. get out of loop */
+   if (!timeout) {
+   dev_dbg(dev->dev, "Failed to get MIB\n");
+   return;
+   }
+
+   /* count resets upon read */
+   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
+   *cnt += data;
+}
+
+static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
+ u64 *dropped, u64 *cnt)
+{
+   addr = ksz9477_mib_names[addr].index;
+   ksz9477_r_mib_cnt(dev, port, addr, cnt);
+}
+
+static void ksz9477_freeze_mib(struct ksz_device *dev, int port, bool freeze)
+{
+   struct ksz_port *p = >ports[port];
+   u32 val = freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+
+   /* enable/disable the port for flush/freeze function */
+   mutex_lock(>mib.cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, val);
+
+   /* used by MIB counter reading code to know freeze is enabled */
+   p->freeze = freeze;
+   mutex_unlock(>mib.cnt_mutex);
+}
+
+static void ksz9477_port_init_cnt(struct ksz_device *dev, int port)
+{
+   struct ksz_port_mib *mib = >ports[port].mib;
+
+   /* flush all enabled port MIB counters */
+   mutex_lock(>cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+MIB_COUNTER_FLUSH_FREEZE);
+   ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0);
+   mutex_unlock(>cnt_mutex);
+
+   mib->cnt_ptr = 0;
+   memset(mib->counters, 0, dev->mib_cnt * sizeof(u64));
+}
+
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
  int port)
 {
@@ -354,47 +424,6 @@ static void ksz9477_get_strings(struct dsa_switch *ds, int 
port,
}
 }
 
-static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *buf)
-{
-   struct ksz_device *dev = ds->priv;
-   int i;
-   u32 data;
-   int timeout;
-
-   mutex_lock(>stats_mutex);
-
-   for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
-   data = MIB_COUNTER_READ;
-   data |= ((ksz9477_mib_names[i].index & 0xFF) <<
-   MIB_COUNTER_INDEX_S);
-   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
-
-   timeout = 1000;
-   do {
-   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
-   );
-   usleep_range(1, 10);
-   if (!(data & MIB_COUNTER_READ))
-   break;
-   } while (timeout-- > 0);
-
-   /* failed to read MIB. get out of loop */
-   if (!timeout) {
-   dev_dbg(dev->dev, "Failed to get MIB\n");
-   break;
-   }
-
-   /* count resets upon read */
-   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
-
-   dev->mib_value[i] += (uint64_t)data;
-   buf[i] = dev->mib_value[i];
-   }
-
-   mutex_unlock(>stats_mutex);
-}
-
 static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
u8 member)
 {
@@ -1163,9 +1192,14 @@ static int ksz9477_setup(struct dsa_switch *ds)
/* queue based egress rate limit */
ksz_cfg(dev, REG_SW_MAC_CTRL_5, SW_OUT_RATE_LIMIT_QUEUE_BASED, true);
 
+   /* enable global MIB counter 

[PATCH v3 net-next 07/11] net: dsa: microchip: Prepare PHY for proper advertisement

2018-10-22 Thread Tristram.Ha
From: Tristram Ha 

Prepare PHY for proper advertisement and get link status for the port.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz9477.c| 13 +
 drivers/net/dsa/microchip/ksz_common.c | 17 +
 drivers/net/dsa/microchip/ksz_common.h |  2 ++
 drivers/net/dsa/microchip/ksz_priv.h   |  2 ++
 4 files changed, 34 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index df3a189..72042b0 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -981,6 +981,17 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, 
int port,
 PORT_MIRROR_SNIFFER, false);
 }
 
+static void ksz9477_phy_setup(struct ksz_device *dev, int port,
+ struct phy_device *phy)
+{
+   if (port < dev->phy_port_cnt) {
+   /* SUPPORTED_Asym_Pause and SUPPORTED_Pause can be removed to
+* disable flow control when rate limiting is used.
+*/
+   phy->advertising = phy->supported;
+   }
+}
+
 static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
@@ -1163,6 +1174,7 @@ static int ksz9477_setup(struct dsa_switch *ds)
.setup  = ksz9477_setup,
.phy_read   = ksz9477_phy_read16,
.phy_write  = ksz9477_phy_write16,
+   .adjust_link= ksz_adjust_link,
.port_enable= ksz_enable_port,
.port_disable   = ksz_disable_port,
.get_strings= ksz9477_get_strings,
@@ -1314,6 +1326,7 @@ static void ksz9477_switch_exit(struct ksz_device *dev)
.get_port_addr = ksz9477_get_port_addr,
.cfg_port_member = ksz9477_cfg_port_member,
.flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,
+   .phy_setup = ksz9477_phy_setup,
.port_setup = ksz9477_port_setup,
.shutdown = ksz9477_reset_switch,
.detect = ksz9477_switch_detect,
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 9130685..a2f06ef 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -73,6 +73,22 @@ int ksz_phy_write16(struct dsa_switch *ds, int addr, int 
reg, u16 val)
 }
 EXPORT_SYMBOL_GPL(ksz_phy_write16);
 
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev)
+{
+   struct ksz_device *dev = ds->priv;
+   struct ksz_port *p = >ports[port];
+
+   if (phydev->link) {
+   dev->live_ports |= (1 << port) & dev->on_ports;
+   } else if (p->phydev.link) {
+   p->link_just_down = 1;
+   dev->live_ports &= ~(1 << port);
+   }
+   p->phydev = *phydev;
+}
+EXPORT_SYMBOL_GPL(ksz_adjust_link);
+
 int ksz_sset_count(struct dsa_switch *ds, int port, int sset)
 {
struct ksz_device *dev = ds->priv;
@@ -250,6 +266,7 @@ int ksz_enable_port(struct dsa_switch *ds, int port, struct 
phy_device *phy)
 
/* setup slave port */
dev->dev_ops->port_setup(dev, port, false);
+   dev->dev_ops->phy_setup(dev, port, phy);
 
/* port_stp_state_set() will be called after to enable the port so
 * there is no need to do anything.
diff --git a/drivers/net/dsa/microchip/ksz_common.h 
b/drivers/net/dsa/microchip/ksz_common.h
index 49638ce..e25a60b 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -26,6 +26,8 @@
 
 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev);
 int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
 struct net_device *br);
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 1f20982..708eef4 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -147,6 +147,8 @@ struct ksz_dev_ops {
u32 (*get_port_addr)(int port, int offset);
void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member);
void (*flush_dyn_mac_table)(struct ksz_device *dev, int port);
+   void (*phy_setup)(struct ksz_device *dev, int port,
+ struct phy_device *phy);
void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port);
void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);
void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val);
-- 
1.9.1



RE: [PATCH v2 net-next 0/8] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2018-08-16 Thread Tristram.Ha
> -Original Message-
> From: Florian Fainelli 
> Sent: Wednesday, August 15, 2018 5:29 PM
> To: Tristram Ha - C24268 ; Andrew Lunn
> ; Pavel Machek ; Ruediger Schmitt
> 
> Cc: Arkadi Sharshevsky ; UNGLinuxDriver
> ; netdev@vger.kernel.org
> Subject: Re: [PATCH v2 net-next 0/8] net: dsa: microchip: Modify KSZ9477
> DSA driver in preparation to add other KSZ switch drivers
> 
> On 12/05/2017 05:46 PM, tristram...@microchip.com wrote:
> > From: Tristram Ha 
> >
> > This series of patches is to modify the original KSZ9477 DSA driver so
> > that other KSZ switch drivers can be added and use the common code.
> >
> > There are several steps to accomplish this achievement.  First is to
> > rename some function names with a prefix to indicate chip specific
> > function.  Second is to move common code into header that can be shared.
> > Last is to modify tag_ksz.c so that it can handle many tail tag formats
> > used by different KSZ switch drivers.
> >
> > ksz_common.c will contain the common code used by all KSZ switch drivers.
> > ksz9477.c will contain KSZ9477 code from the original ksz_common.c.
> > ksz9477_spi.c is renamed from ksz_spi.c.
> > ksz9477_reg.h is renamed from ksz_9477_reg.h.
> > ksz_common.h is added to provide common code access to KSZ switch
> > drivers.
> > ksz_spi.h is added to provide common SPI access functions to KSZ SPI
> > drivers.
> 
> Is something gating this series from getting included? It's been nearly
> 8 months now and this has not been include nor resubmitted, any plans to
> rebase that patch series and work towards inclusion in net-next when it
> opens back again?
> 
> Thank you!

Sorry for the long delay.  I will restart my kernel submission effort next month
after finishing the work on current development project.



RE: [PATCH net-next 1/1] net: dsa: microchip: Add Microchip KSZ8895 DSA driver

2017-12-08 Thread Tristram.Ha
> Ok, let me retry:
> 
> > One thing to debug this problem is to dump the MIB counters.  Use the
> ethtool
> > utility to show MIB counters of both ports:
> >
> > ethtool -S lan3
> > ethtool -S eth0
> >
> > Assuming eth0 is the MAC controller that drives the switch, the receive
> counters of
> > the host port of the switch should match the transmit counters of
> > lan3, and vice versa.
> 
> Hmm. I'm getting some "interesting" results from mii-tool:
> 
> root@miro:~# mii-tool lan3
> lan3: negotiated 1000baseT-HD flow-control, link ok
> 
> But IIRC the switch is 100mbit? And dmesg does get it right. Its just
> mii-tool that is confused.
> 
> Link detection seems to work
> 
> root@miro:/sys/bus/spi/devices/spi2.0# mii-tool lan1
> lan1: negotiated 1000baseT-HD flow-control, link ok
> root@miro:/sys/bus/spi/devices/spi2.0# mii-tool lan1
> lan1: no link
> 
> (But that really should be 100baseT, not 1000baseT).

ethtool lan3 should also report the correct setting.

> Is there register dump available somewhere? I was using
> /sys/bus/spi/devices/spi32766.0/registers but this does not seem to be
> available.

There is a patch to add that functionality.  It is very simple and I will send 
it
to you later.  Without that it is hard to debug the DSA driver if there is
something wrong.

I also have a simple utility to communicate with that registers file to 
read/write
register individually.  Is there a standard Linux utility for that function?

> I tried that ethtool -S, and counters do not seem to match:
> root@miro:~# ethtool -S eth0
> NIC statistics:
>  tx_dropped: 0
>  tx_packets: 55
>  tx_broadcast: 35
>  tx_multicast: 20
>  tx_crc_errors: 0
>  tx_undersize: 0
>  tx_oversize: 0
>  tx_fragment: 0
>  tx_jabber: 0
>  tx_collision: 0
>  tx_64byte: 0
>  tx_65to127byte: 35
>  tx_128to255byte: 0
>  tx_256to511byte: 20
>  tx_512to1023byte: 0
>  tx_1024to2047byte: 0
>  tx_GTE2048byte: 0
>  tx_octets: 9576
>  IEEE_tx_drop: 0
>  IEEE_tx_frame_ok: 55
>  IEEE_tx_1col: 0
>  IEEE_tx_mcol: 0
>  IEEE_tx_def: 0
>  IEEE_tx_lcol: 0
>  IEEE_tx_excol: 0
>  IEEE_tx_macerr: 0
>  IEEE_tx_cserr: 0
>  IEEE_tx_sqe: 0
>  IEEE_tx_fdxfc: 0
>  IEEE_tx_octets_ok: 9576
>  rx_packets: 0
>  rx_broadcast: 0
>  rx_multicast: 0
>  rx_crc_errors: 0
>  rx_undersize: 0
>  rx_oversize: 0
>  rx_fragment: 0
>  rx_jabber: 0
>  rx_64byte: 0
>  rx_65to127byte: 0
>  rx_128to255byte: 0
>  rx_256to511byte: 0
>  rx_512to1023byte: 0
>  rx_1024to2047byte: 0
>  rx_GTE2048byte: 0
>  rx_octets: 0
>  IEEE_rx_drop: 0
>  IEEE_rx_frame_ok: 0
>  IEEE_rx_crc: 0
>  IEEE_rx_align: 0
>  IEEE_rx_macerr: 0
>  IEEE_rx_fdxfc: 0
>  IEEE_rx_octets_ok: 0

These are the MIB counters from the switch host port:

>  p04_rx: 660
>  p04_rx_hi: 0
>  p04_rx_undersize: 0
>  p04_rx_fragments: 20

This indicates a problem with the MAC.  Are you using a MII or RMII version?

>  p04_rx_oversize: 0
>  p04_rx_jabbers: 0
>  p04_rx_symbol_err: 0
>  p04_rx_crc_err: 0
>  p04_rx_align_err: 0
>  p04_rx_mac_ctrl: 0
>  p04_rx_pause: 0
>  p04_rx_bcast: 0
>  p04_rx_mcast: 0
>  p04_rx_ucast: 0
>  p04_rx_64_or_less: 0
>  p04_rx_65_127: 0
>  p04_rx_128_255: 0
>  p04_rx_256_511: 0
>  p04_rx_512_1023: 0
>  p04_rx_1024_1522: 0
>  p04_tx: 388
>  p04_tx_hi: 0
>  p04_tx_late_col: 0
>  p04_tx_pause: 0
>  p04_tx_bcast: 0
>  p04_tx_mcast: 3

This indicates the host port tried to send frames to the MAC.

>  p04_tx_ucast: 0
>  p04_tx_deferred: 0
>  p04_tx_total_col: 0
>  p04_tx_exc_col: 0
>  p04_tx_single_col: 0
>  p04_tx_mult_col: 0
>  p04_rx_discards: 0
>  p04_tx_discards: 0
> root@miro:~# ethtool -S lan3
> NIC statistics:
>  tx_packets: 24
>  tx_bytes: 1356
>  rx_packets: 0
>  rx_bytes: 0

The previous counters are from DSA.  The rest are MIB counters of the port.

>  rx: 566
>  rx_hi: 0
>  rx_undersize: 0
>  rx_fragments: 0
>  rx_oversize: 0
>  rx_jabbers: 0
>  rx_symbol_err: 0
>  rx_crc_err: 0
>  rx_align_err: 0
>  rx_mac_ctrl: 0
>  rx_pause: 0
>  rx_bcast: 0
>  rx_mcast: 4
>  rx_ucast: 0
>  rx_64_or_less: 0
>  rx_65_127: 1
>  rx_128_255: 3
>  rx_256_511: 0
>  rx_512_1023: 0
>  rx_1024_1522: 0
>  tx: 0
>  tx_hi: 0
>  tx_late_col: 0
>  tx_pause: 0
>  tx_bcast: 0
>  tx_mcast: 0
>  tx_ucast: 0
>  tx_deferred: 0
>  tx_total_col: 0
>  tx_exc_col: 0
>  tx_single_col: 0
>  tx_mult_col: 0
>  rx_discards: 0
>  tx_discards: 0

They just reported frames are received from the port.  Because of problem with
the host port there is no transmission coming from the host port.



RE: dsa: dsa_slave_port_obj_del calls multiple times with SWITCHDEV_OBJ_ID_HOST_MDB obj id

2017-12-06 Thread Tristram.Ha
> SWITCHDEV_OBJ_ID_HOST_MDB is used, when there is a join/leave on the
> bridge interface. It happens for each interface in the bridge, and it
> means, packets which match the group that ingress on that interface
> should be forwarded to the CPU.
> 
> > As the base driver cannot find an entry with that host port, it returns an
> error
> > and so users will see a lot of failures from the DSA switch.
> 
> You have a few options:
> 
> 1) Just forward all multicast traffic to the cpu, and ignore
>SWITCHDEV_OBJ_ID_HOST_MDB.
> 
> 2) Implement SWITCHDEV_OBJ_ID_HOST_MDB so you setup your tables to
>just forward the requested multicast to the cpu.
> 
> 3) You can also forward a bit too much, e.g. if you cannot set filters
>per ingress port, just send all the traffic for the group from any
>port.
> 
> 
> The bridge will discard whatever it does not need.
> 
> > Is this a new behavior and the driver needs to handle that?  In previous
> versions
> > I do not think I saw that.
> 
> SWITCHDEV_OBJ_ID_HOST_MDB is new. However,
> dsa_slave_port_obj_del()
> can be called for all sorts of objects, and you should only be
> reacting on those your support. So adding a new object should not of
> changed anything.
> 
> > Typical operation is a PC connected to a port in a switch wants to send
> multicast
> > packets.  It broadcasts an IGMP membership join message.  Function
> > dsa_slave_port_obj_add is called to setup an entry in the lookup table.
> When
> > IGMP membership leave message is received dsa_slave_port_obj_del will
> be
> > called after a delay.  But then it is called for each port with host port 
> > as the
> > parameter.
> 
> Correct. switchdev is a generic API. It also needs to work for Top of
> Rack switches, which generally have a match/action architecture. I can
> imagine that this match/action happens per port, so we need to call
> switchdev per port. However, switches supported by DSA tend to have
> central management of all ports, so one call would be sufficient. With
> a DSA driver, you just need to expect redundant calls, and do the
> right thing.

The base DSA driver only knows about port_mdb_add and port_mdb_del.
It does not really know about SWITCHDEV_OBJ_ID_HOST_MDB.

It is fine to use port_mdb_add and port_mdb_del for
SWITCHDEV_OBJ_ID_HOST_MDB as hardware can program an entry for
the host port, but receiving many port_mdb_del calls with the same
parameter makes it difficult to handle.  Example:

port_mdb_add 2 xx:xx:xx:xx:xx:xx
port_mdb_del 2 xx:xx:xx:xx:xx:xx
port_mdb_del 4 xx:xx:xx:xx:xx:xx; lan1
port_mdb_del 4 xx:xx:xx:xx:xx:xx; lan2
port_mdb_del 4 xx:xx:xx:xx:xx:xx; lan3

There is no indication in the port_mdb_del call to show this call is for
port 1, 2, and so on.

port_mdb_add can be used to add an entry for the host.  Again it is
called as many times as number of ports.  I think the port_mdb_* call
needs an extra parameter to make it useful in this situation.

An easy fix is not to return any error in port_mdb_del, or ignore host port.

It seems port_mdb_prepare is used to indicate an entry can be added
before the actual port_mdb_add call, which returns void and so cannot
indicate failure to add.  Currently there is no implementation for that
port_mdb_prepare call and the Marvell driver just displays a warning
inside its port_mdb_add function.



dsa: dsa_slave_port_obj_del calls multiple times with SWITCHDEV_OBJ_ID_HOST_MDB obj id

2017-12-05 Thread Tristram.Ha
I found the latest net-next kernel calls dsa_slave_port_obj_del() multiple 
times,
one for each port, with host port as the parameter.

As the base driver cannot find an entry with that host port, it returns an error
and so users will see a lot of failures from the DSA switch.

Is this a new behavior and the driver needs to handle that?  In previous 
versions
I do not think I saw that.

Typical operation is a PC connected to a port in a switch wants to send 
multicast
packets.  It broadcasts an IGMP membership join message.  Function
dsa_slave_port_obj_add is called to setup an entry in the lookup table.  When
IGMP membership leave message is received dsa_slave_port_obj_del will be
called after a delay.  But then it is called for each port with host port as the
parameter.

Another issue is the host port can setup an entry for IPv6 neighbor discovery 
like
33:33:FF:??:??:??.  When it leaves a failure message will be displayed for lan2,
lan3, and so on.  It seems the first deletion is coming from lan1.



[PATCH v1 net-next 0/1] net: dsa: microchip: Add Microchip KSZ8895 DSA driver

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

This patch requires the previous patch for Microchip KSZ8795 DSA driver.

v1
- For latest KSZ8795 v3 patch

Tristram Ha (1):
  Add Microchip KSZ8895 DSA driver.

 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8895.c | 1274 +++
 drivers/net/dsa/microchip/ksz8895_reg.h |  824 
 drivers/net/dsa/microchip/ksz8895_spi.c |  157 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 6 files changed, 2275 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8895.c
 create mode 100644 drivers/net/dsa/microchip/ksz8895_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8895_spi.c

-- 
1.9.1



[PATCH v3 net-next] net: dsa: Modify tag_ksz.c so that tail tag code can be used by other KSZ switch drivers

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Modify tag_ksz.c so that tail tag code can be used by other KSZ switch
drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
v3
- For latest KSZ9477 patch

v2
- No new feature is introduced

v1
- Switch driver code is not accessed from tag_ksz.c

 drivers/net/dsa/microchip/Kconfig   |  2 +-
 drivers/net/dsa/microchip/ksz9477.c |  2 +-
 include/net/dsa.h   |  2 +-
 net/dsa/Kconfig |  4 ++
 net/dsa/dsa.c   |  4 +-
 net/dsa/dsa_priv.h  |  2 +-
 net/dsa/tag_ksz.c   | 90 -
 7 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index 5a8660d..ab8f9f6 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,7 +1,7 @@
 menuconfig MICROCHIP_KSZ9477
tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
-   select NET_DSA_TAG_KSZ
+   select NET_DSA_TAG_KSZ9477
help
  This driver adds support for Microchip KSZ9477 switch chips.
 
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 8bae36b1..ca1ccea 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -344,7 +344,7 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, 
int port)
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
  int port)
 {
-   return DSA_TAG_PROTO_KSZ;
+   return DSA_TAG_PROTO_KSZ9477;
 }
 
 static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 8198efc..2b1a222 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -32,7 +32,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_BRCM_PREPEND,
DSA_TAG_PROTO_DSA,
DSA_TAG_PROTO_EDSA,
-   DSA_TAG_PROTO_KSZ,
+   DSA_TAG_PROTO_KSZ9477,
DSA_TAG_PROTO_LAN9303,
DSA_TAG_PROTO_MTK,
DSA_TAG_PROTO_QCA,
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index 03c3bdf..809b0e2 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -32,6 +32,10 @@ config NET_DSA_TAG_EDSA
 config NET_DSA_TAG_KSZ
bool
 
+config NET_DSA_TAG_KSZ9477
+   bool
+   select NET_DSA_TAG_KSZ
+
 config NET_DSA_TAG_LAN9303
bool
 
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 6a9d0f5..92056a7 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -53,8 +53,8 @@ static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff 
*skb,
 #ifdef CONFIG_NET_DSA_TAG_EDSA
[DSA_TAG_PROTO_EDSA] = _netdev_ops,
 #endif
-#ifdef CONFIG_NET_DSA_TAG_KSZ
-   [DSA_TAG_PROTO_KSZ] = _netdev_ops,
+#ifdef CONFIG_NET_DSA_TAG_KSZ9477
+   [DSA_TAG_PROTO_KSZ9477] = _netdev_ops,
 #endif
 #ifdef CONFIG_NET_DSA_TAG_LAN9303
[DSA_TAG_PROTO_LAN9303] = _netdev_ops,
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 7d03669..a2955a8 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -200,7 +200,7 @@ static inline struct dsa_port *dsa_slave_to_port(const 
struct net_device *dev)
 extern const struct dsa_device_ops edsa_netdev_ops;
 
 /* tag_ksz.c */
-extern const struct dsa_device_ops ksz_netdev_ops;
+extern const struct dsa_device_ops ksz9477_netdev_ops;
 
 /* tag_lan9303.c */
 extern const struct dsa_device_ops lan9303_netdev_ops;
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 0f62eff..7343270 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -14,34 +14,21 @@
 #include 
 #include "dsa_priv.h"
 
-/* For Ingress (Host -> KSZ), 2 bytes are added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
- * ---
- * tag0 : Prioritization (not used now)
- * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
- *
- * For Egress (KSZ -> Host), 1 byte is added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|FCS(4bytes)
- * ---
- * tag0 : zero-based value represents port
- *   (eg, 0x00=port1, 0x02=port3, 0x06=port7)
- */
-
-#defineKSZ_INGRESS_TAG_LEN 2
-#defineKSZ_EGRESS_TAG_LEN  1
+/* Usually only one byte is used for tail tag. */
+#define KSZ_INGRESS_TAG_LEN1
+#define KSZ_EGRESS_TAG_LEN 1
 
-static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
+static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev,
+   int len,
+  

[PATCH v3 net-next 0/1] net: dsa: microchip: Add Microchip KSZ8795 DSA driver

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

This patch requires the previous patches for Microchip KSZ9477 DSA driver.

v3
- For latest KSZ9477 v2 patch

v2
- No new feature is introduced in tag_ksz.c

v1
- Return error codes instead of numbers
- Add more comments to clarify operation
- Use ksz8795 prefix to indicate KSZ8795 specific code
- Simplify MIB counter reading code
- Switch driver code is not accessed from tag_ksz.c

Tristram Ha (1):
  Add Microchip KSZ8795 DSA driver.

 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8795.c | 1363 +++
 drivers/net/dsa/microchip/ksz8795_reg.h | 1016 +++
 drivers/net/dsa/microchip/ksz8795_spi.c |  166 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 include/net/dsa.h   |1 +
 net/dsa/Kconfig |4 +
 net/dsa/dsa.c   |3 +
 net/dsa/dsa_priv.h  |1 +
 net/dsa/tag_ksz.c   |   32 +
 11 files changed, 2606 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8795.c
 create mode 100644 drivers/net/dsa/microchip/ksz8795_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8795_spi.c

-- 
1.9.1



[PATCH v1 net-next 1/1] net: dsa: microchip: Add Microchip KSZ8895 DSA driver

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Add Microchip KSZ8895 DSA driver.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8895.c | 1274 +++
 drivers/net/dsa/microchip/ksz8895_reg.h |  824 
 drivers/net/dsa/microchip/ksz8895_spi.c |  157 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 6 files changed, 2275 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8895.c
 create mode 100644 drivers/net/dsa/microchip/ksz8895_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8895_spi.c

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index cb95d3d..b854c4b 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -27,3 +27,20 @@ config MICROCHIP_KSZ8795_SPI_DRIVER
 
  It is required to use the KSZ8795 switch driver as the only access
  is through SPI.
+
+menuconfig MICROCHIP_KSZ8895
+   tristate "Microchip KSZ8895 series switch support"
+   depends on NET_DSA
+   select NET_DSA_TAG_KSZ8795
+   help
+ This driver adds support for Microchip KSZ8895 switch chips.
+
+config MICROCHIP_KSZ8895_SPI_DRIVER
+   tristate "KSZ8895 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ8895 && SPI
+   default y
+   help
+ This driver accesses KSZ8895 chip through SPI.
+
+ It is required to use the KSZ8895 switch driver as the only access
+ is through SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 99a283e..8dd6312 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -2,3 +2,5 @@ obj-$(CONFIG_MICROCHIP_KSZ9477) += ksz9477.o 
ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
 obj-$(CONFIG_MICROCHIP_KSZ8795)+= ksz8795.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ8795_SPI_DRIVER) += ksz8795_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ8895)+= ksz8895.o ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ8895_SPI_DRIVER) += ksz8895_spi.o
diff --git a/drivers/net/dsa/microchip/ksz8895.c 
b/drivers/net/dsa/microchip/ksz8895.c
new file mode 100644
index 000..d6d2ecc
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz8895.c
@@ -0,0 +1,1274 @@
+/*
+ * Microchip KSZ8895 switch driver
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ * Tristram Ha 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz8895_reg.h"
+
+static const struct {
+   char string[ETH_GSTRING_LEN];
+} ksz8895_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { "rx" },
+   { "rx_hi" },
+   { "rx_undersize" },
+   { "rx_fragments" },
+   { "rx_oversize" },
+   { "rx_jabbers" },
+   { "rx_symbol_err" },
+   { "rx_crc_err" },
+   { "rx_align_err" },
+   { "rx_mac_ctrl" },
+   { "rx_pause" },
+   { "rx_bcast" },
+   { "rx_mcast" },
+   { "rx_ucast" },
+   { "rx_64_or_less" },
+   { "rx_65_127" },
+   { "rx_128_255" },
+   { "rx_256_511" },
+   { "rx_512_1023" },
+   { "rx_1024_1522" },
+   { "tx" },
+   { "tx_hi" },
+   { "tx_late_col" },
+   { "tx_pause" },
+   { "tx_bcast" },
+   { "tx_mcast" },
+   { "tx_ucast" },
+   { "tx_deferred" },
+   { "tx_total_col" },
+   { "tx_exc_col" },
+   { "tx_single_col" },
+   { "tx_mult_col" },
+   { "rx_discards" },
+   { "tx_discards" },
+};
+
+static int ksz8895_reset_switch(struct ksz_device *dev)
+{
+   /* reset switch */
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1,
+  SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
+
+   return 0;
+}
+
+static void ksz8895_set_prio_queue(struct ksz_device *dev, int port, int queue)
+{
+   u8 hi;
+   u8 lo;
+
+   /* Number of queues can only be 1, 2, or 4. */
+   switch (queue) {
+  

[PATCH v3 net-next 1/1] net: dsa: microchip: Add Microchip KSZ8795 DSA driver

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Add Microchip KSZ8795 DSA driver.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8795.c | 1363 +++
 drivers/net/dsa/microchip/ksz8795_reg.h | 1016 +++
 drivers/net/dsa/microchip/ksz8795_spi.c |  166 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 include/net/dsa.h   |1 +
 net/dsa/Kconfig |4 +
 net/dsa/dsa.c   |3 +
 net/dsa/dsa_priv.h  |1 +
 net/dsa/tag_ksz.c   |   32 +
 11 files changed, 2606 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8795.c
 create mode 100644 drivers/net/dsa/microchip/ksz8795_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8795_spi.c

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index ab8f9f6..cb95d3d 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -10,3 +10,20 @@ config MICROCHIP_KSZ9477_SPI_DRIVER
depends on MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
+
+menuconfig MICROCHIP_KSZ8795
+   tristate "Microchip KSZ8795 series switch support"
+   depends on NET_DSA
+   select NET_DSA_TAG_KSZ8795
+   help
+ This driver adds support for Microchip KSZ8795 switch chips.
+
+config MICROCHIP_KSZ8795_SPI_DRIVER
+   tristate "KSZ8795 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ8795 && SPI
+   default y
+   help
+ This driver accesses KSZ8795 chip through SPI.
+
+ It is required to use the KSZ8795 switch driver as the only access
+ is through SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 13dd8f0..99a283e 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,4 @@
 obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz9477.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ8795)+= ksz8795.o ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ8795_SPI_DRIVER) += ksz8795_spi.o
diff --git a/drivers/net/dsa/microchip/ksz8795.c 
b/drivers/net/dsa/microchip/ksz8795.c
new file mode 100644
index 000..fc68034
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz8795.c
@@ -0,0 +1,1363 @@
+/*
+ * Microchip KSZ8795 switch driver
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ * Tristram Ha 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz8795_reg.h"
+
+static const struct {
+   char string[ETH_GSTRING_LEN];
+} ksz8795_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { "rx_hi" },
+   { "rx_undersize" },
+   { "rx_fragments" },
+   { "rx_oversize" },
+   { "rx_jabbers" },
+   { "rx_symbol_err" },
+   { "rx_crc_err" },
+   { "rx_align_err" },
+   { "rx_mac_ctrl" },
+   { "rx_pause" },
+   { "rx_bcast" },
+   { "rx_mcast" },
+   { "rx_ucast" },
+   { "rx_64_or_less" },
+   { "rx_65_127" },
+   { "rx_128_255" },
+   { "rx_256_511" },
+   { "rx_512_1023" },
+   { "rx_1024_1522" },
+   { "rx_1523_2000" },
+   { "rx_2001" },
+   { "tx_hi" },
+   { "tx_late_col" },
+   { "tx_pause" },
+   { "tx_bcast" },
+   { "tx_mcast" },
+   { "tx_ucast" },
+   { "tx_deferred" },
+   { "tx_total_col" },
+   { "tx_exc_col" },
+   { "tx_single_col" },
+   { "tx_mult_col" },
+   { "rx_total" },
+   { "tx_total" },
+   { "rx_discards" },
+   { "tx_discards" },
+};
+
+static int ksz8795_reset_switch(struct ksz_device *dev)
+{
+   /* reset switch */
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1,
+  SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
+

[PATCH v2 net-next 3/8] net: dsa: microchip: Initialize mutex before use

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Initialize mutex before use.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz_common.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 435c463..e656615 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1102,7 +1102,6 @@ static int ksz_switch_init(struct ksz_device *dev)
 {
int i;
 
-   mutex_init(>reg_mutex);
mutex_init(>stats_mutex);
mutex_init(>alu_mutex);
mutex_init(>vlan_mutex);
@@ -1191,6 +1190,9 @@ int ksz_switch_register(struct ksz_device *dev)
if (dev->pdata)
dev->chip_id = dev->pdata->chip_id;
 
+   /* mutex is used in next function call. */
+   mutex_init(>reg_mutex);
+
if (ksz_switch_detect(dev))
return -EINVAL;
 
-- 
1.9.1



[PATCH v2 net-next 1/8] net: dsa: microchip: Replace license with GPL

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Replace license with GPL.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_9477_reg.h | 23 ---
 drivers/net/dsa/microchip/ksz_common.c   | 23 ---
 drivers/net/dsa/microchip/ksz_priv.h | 23 ---
 drivers/net/dsa/microchip/ksz_spi.c  | 23 ---
 4 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz_9477_reg.h
index 6aa6752..26a0e4b 100644
--- a/drivers/net/dsa/microchip/ksz_9477_reg.h
+++ b/drivers/net/dsa/microchip/ksz_9477_reg.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ9477 register definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #ifndef __KSZ9477_REGS_H
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 663b0d5..d662a9a 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1,19 +1,20 @@
 /*
  * Microchip switch driver main logic
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #include 
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 2a98dbd..d461468 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ series switch common definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS 

[PATCH v2 net-next 0/8] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

This series of patches is to modify the original KSZ9477 DSA driver so
that other KSZ switch drivers can be added and use the common code.

There are several steps to accomplish this achievement.  First is to
rename some function names with a prefix to indicate chip specific
function.  Second is to move common code into header that can be shared.
Last is to modify tag_ksz.c so that it can handle many tail tag formats
used by different KSZ switch drivers.

ksz_common.c will contain the common code used by all KSZ switch drivers.
ksz9477.c will contain KSZ9477 code from the original ksz_common.c.
ksz9477_spi.c is renamed from ksz_spi.c.
ksz9477_reg.h is renamed from ksz_9477_reg.h.
ksz_common.h is added to provide common code access to KSZ switch
drivers.
ksz_spi.h is added to provide common SPI access functions to KSZ SPI
drivers.

v2
- Initialize reg_mutex before use
- The alu_mutex is only used inside chip specific functions

v1
- Each patch in the set is self-contained
- Use ksz9477 prefix to indicate KSZ9477 specific code

Tristram Ha (8):
  Replace license with GPL.
  Clean up code according to patch check suggestions.
  Initialize mutex before use.
  Rename some functions with ksz9477 prefix to separate chip specific
code from common code.
  Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to
add more KSZ switch drivers.
  Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.  Add common functions in ksz_common.h so that other
KSZ switch drivers can access code in ksz_common.c.  Add ksz_spi.h
for common functions used by KSZ switch SPI drivers.
  Prepare PHY for proper advertisement and get link status for the port.
  Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.

 drivers/net/dsa/microchip/Kconfig  |   12 +-
 drivers/net/dsa/microchip/Makefile |4 +-
 drivers/net/dsa/microchip/ksz9477.c| 1331 
 .../microchip/{ksz_9477_reg.h => ksz9477_reg.h}|   23 +-
 drivers/net/dsa/microchip/ksz9477_spi.c|  188 +++
 drivers/net/dsa/microchip/ksz_common.c | 1176 +++--
 drivers/net/dsa/microchip/ksz_common.h |  229 
 drivers/net/dsa/microchip/ksz_priv.h   |  256 ++--
 drivers/net/dsa/microchip/ksz_spi.c|  216 
 drivers/net/dsa/microchip/ksz_spi.h|   82 ++
 10 files changed, 2122 insertions(+), 1395 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (98%)
 create mode 100644 drivers/net/dsa/microchip/ksz9477_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 delete mode 100644 drivers/net/dsa/microchip/ksz_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

-- 
1.9.1



[PATCH v3 net-next] net: dsa: microchip: Add MIB counter reading support

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Add MIB counter reading support.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
v3
- Use new timer_setup API

v2
- Only MIB counter related code in patch

v1
- Simplify MIB counter reading code

 drivers/net/dsa/microchip/ksz9477.c| 121 ++---
 drivers/net/dsa/microchip/ksz_common.c | 100 +++
 drivers/net/dsa/microchip/ksz_common.h |   2 +
 drivers/net/dsa/microchip/ksz_priv.h   |   7 +-
 4 files changed, 185 insertions(+), 45 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 801117a..8bae36b1 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -271,6 +271,76 @@ static int ksz9477_reset_switch(struct ksz_device *dev)
return 0;
 }
 
+static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
+ u64 *cnt)
+{
+   u32 data;
+   int timeout;
+   struct ksz_port *p = >ports[port];
+
+   /* retain the flush/freeze bit */
+   data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+   data |= MIB_COUNTER_READ;
+   data |= (addr << MIB_COUNTER_INDEX_S);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
+
+   timeout = 1000;
+   do {
+   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+   );
+   usleep_range(1, 10);
+   if (!(data & MIB_COUNTER_READ))
+   break;
+   } while (timeout-- > 0);
+
+   /* failed to read MIB. get out of loop */
+   if (!timeout) {
+   dev_dbg(dev->dev, "Failed to get MIB\n");
+   return;
+   }
+
+   /* count resets upon read */
+   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
+   *cnt += data;
+}
+
+static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
+ u64 *dropped, u64 *cnt)
+{
+   addr = ksz9477_mib_names[addr].index;
+   ksz9477_r_mib_cnt(dev, port, addr, cnt);
+}
+
+static void ksz9477_freeze_mib(struct ksz_device *dev, int port, bool freeze)
+{
+   struct ksz_port *p = >ports[port];
+   u32 val = freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+
+   /* enable/disable the port for flush/freeze function */
+   mutex_lock(>mib.cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, val);
+
+   /* used by MIB counter reading code to know freeze is enabled */
+   p->freeze = freeze;
+   mutex_unlock(>mib.cnt_mutex);
+}
+
+static void ksz9477_port_init_cnt(struct ksz_device *dev, int port)
+{
+   struct ksz_port_mib *mib = >ports[port].mib;
+
+   /* flush all enabled port MIB counters */
+   mutex_lock(>cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+MIB_COUNTER_FLUSH_FREEZE);
+   ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0);
+   mutex_unlock(>cnt_mutex);
+
+   mib->cnt_ptr = 0;
+   memset(mib->counters, 0, dev->mib_cnt * sizeof(u64));
+}
+
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
  int port)
 {
@@ -350,47 +420,6 @@ static void ksz9477_get_strings(struct dsa_switch *ds, int 
port, uint8_t *buf)
}
 }
 
-static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *buf)
-{
-   struct ksz_device *dev = ds->priv;
-   int i;
-   u32 data;
-   int timeout;
-
-   mutex_lock(>stats_mutex);
-
-   for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
-   data = MIB_COUNTER_READ;
-   data |= ((ksz9477_mib_names[i].index & 0xFF) <<
-   MIB_COUNTER_INDEX_S);
-   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
-
-   timeout = 1000;
-   do {
-   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
-   );
-   usleep_range(1, 10);
-   if (!(data & MIB_COUNTER_READ))
-   break;
-   } while (timeout-- > 0);
-
-   /* failed to read MIB. get out of loop */
-   if (!timeout) {
-   dev_dbg(dev->dev, "Failed to get MIB\n");
-   break;
-   }
-
-   /* count resets upon read */
-   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
-
-   dev->mib_value[i] += (uint64_t)data;
-   buf[i] = dev->mib_value[i];
-   }
-
-   mutex_unlock(>stats_mutex);
-}
-
 static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
u8 member)
 {
@@ -1159,9 +1188,14 @@ 

[PATCH v2 net-next 6/8] net: dsa: microchip: Break KSZ9477 DSA driver into two files

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.
Add common functions in ksz_common.h so that other KSZ switch drivers
can access code in ksz_common.c.
Add ksz_spi.h for common functions used by KSZ switch SPI drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Makefile  |2 +-
 drivers/net/dsa/microchip/ksz9477.c | 1318 +++
 drivers/net/dsa/microchip/ksz9477_spi.c |  143 ++--
 drivers/net/dsa/microchip/ksz_common.c  | 1139 +++---
 drivers/net/dsa/microchip/ksz_common.h  |  227 ++
 drivers/net/dsa/microchip/ksz_priv.h|  229 +++---
 drivers/net/dsa/microchip/ksz_spi.h |   82 ++
 7 files changed, 1911 insertions(+), 1229 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 5b6325b..13dd8f0 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz9477.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
new file mode 100644
index 000..2c407bd
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -0,0 +1,1318 @@
+/*
+ * Microchip KSZ9477 switch driver main logic
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz_9477_reg.h"
+
+static const struct {
+   int index;
+   char string[ETH_GSTRING_LEN];
+} ksz9477_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { 0x00, "rx_hi" },
+   { 0x01, "rx_undersize" },
+   { 0x02, "rx_fragments" },
+   { 0x03, "rx_oversize" },
+   { 0x04, "rx_jabbers" },
+   { 0x05, "rx_symbol_err" },
+   { 0x06, "rx_crc_err" },
+   { 0x07, "rx_align_err" },
+   { 0x08, "rx_mac_ctrl" },
+   { 0x09, "rx_pause" },
+   { 0x0A, "rx_bcast" },
+   { 0x0B, "rx_mcast" },
+   { 0x0C, "rx_ucast" },
+   { 0x0D, "rx_64_or_less" },
+   { 0x0E, "rx_65_127" },
+   { 0x0F, "rx_128_255" },
+   { 0x10, "rx_256_511" },
+   { 0x11, "rx_512_1023" },
+   { 0x12, "rx_1024_1522" },
+   { 0x13, "rx_1523_2000" },
+   { 0x14, "rx_2001" },
+   { 0x15, "tx_hi" },
+   { 0x16, "tx_late_col" },
+   { 0x17, "tx_pause" },
+   { 0x18, "tx_bcast" },
+   { 0x19, "tx_mcast" },
+   { 0x1A, "tx_ucast" },
+   { 0x1B, "tx_deferred" },
+   { 0x1C, "tx_total_col" },
+   { 0x1D, "tx_exc_col" },
+   { 0x1E, "tx_single_col" },
+   { 0x1F, "tx_mult_col" },
+   { 0x80, "rx_total" },
+   { 0x81, "tx_total" },
+   { 0x82, "rx_discards" },
+   { 0x83, "tx_discards" },
+};
+
+static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
+{
+   u32 data;
+
+   ksz_read32(dev, addr, );
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+   ksz_write32(dev, addr, data);
+}
+
+static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,
+  u32 bits, bool set)
+{
+   u32 addr;
+   u32 data;
+
+   addr = PORT_CTRL_ADDR(port, offset);
+   ksz_read32(dev, addr, );
+
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+
+   ksz_write32(dev, addr, data);
+}
+
+static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev, u32 waiton,
+   int timeout)
+{
+   u8 data;
+
+   do {
+   ksz_read8(dev, REG_SW_VLAN_CTRL, );
+   if (!(data & waiton))
+ 

[PATCH v2 net-next 4/8] net: dsa: microchip: Rename some functions with ksz9477 prefix

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Rename some functions with ksz9477 prefix to separate chip specific code
from common code.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_common.c | 114 +
 1 file changed, 58 insertions(+), 56 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index e656615..009ee5f 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -265,9 +265,8 @@ static int wait_alu_sta_ready(struct ksz_device *dev, u32 
waiton, int timeout)
return 0;
 }
 
-static int ksz_reset_switch(struct dsa_switch *ds)
+static int ksz9477_reset_switch(struct ksz_device *dev)
 {
-   struct ksz_device *dev = ds->priv;
u8 data8;
u16 data16;
u32 data32;
@@ -300,7 +299,7 @@ static int ksz_reset_switch(struct dsa_switch *ds)
return 0;
 }
 
-static void port_setup(struct ksz_device *dev, int port, bool cpu_port)
+static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
u16 data16;
@@ -346,7 +345,7 @@ static void port_setup(struct ksz_device *dev, int port, 
bool cpu_port)
ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, );
 }
 
-static void ksz_config_cpu_port(struct dsa_switch *ds)
+static void ksz9477_config_cpu_port(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int i;
@@ -358,12 +357,12 @@ static void ksz_config_cpu_port(struct dsa_switch *ds)
dev->cpu_port = i;
 
/* enable cpu port */
-   port_setup(dev, i, true);
+   ksz9477_port_setup(dev, i, true);
}
}
 }
 
-static int ksz_setup(struct dsa_switch *ds)
+static int ksz9477_setup(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int ret = 0;
@@ -373,7 +372,7 @@ static int ksz_setup(struct dsa_switch *ds)
if (!dev->vlan_cache)
return -ENOMEM;
 
-   ret = ksz_reset_switch(ds);
+   ret = ksz9477_reset_switch(dev);
if (ret) {
dev_err(ds->dev, "failed to reset switch\n");
return ret;
@@ -382,7 +381,7 @@ static int ksz_setup(struct dsa_switch *ds)
/* accept packet up to 2000bytes */
ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true);
 
-   ksz_config_cpu_port(ds);
+   ksz9477_config_cpu_port(ds);
 
ksz_cfg(dev, REG_SW_MAC_CTRL_1, MULTICAST_STORM_DISABLE, true);
 
@@ -395,13 +394,13 @@ static int ksz_setup(struct dsa_switch *ds)
return 0;
 }
 
-static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
- int port)
+static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
+ int port)
 {
return DSA_TAG_PROTO_KSZ;
 }
 
-static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
+static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
 {
struct ksz_device *dev = ds->priv;
u16 val = 0;
@@ -411,7 +410,8 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, 
int reg)
return val;
 }
 
-static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
+static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg,
+  u16 val)
 {
struct ksz_device *dev = ds->priv;
 
@@ -426,7 +426,7 @@ static int ksz_enable_port(struct dsa_switch *ds, int port,
struct ksz_device *dev = ds->priv;
 
/* setup slave port */
-   port_setup(dev, port, false);
+   ksz9477_port_setup(dev, port, false);
 
return 0;
 }
@@ -445,7 +445,7 @@ static int ksz_sset_count(struct dsa_switch *ds)
return TOTAL_SWITCH_COUNTER_NUM;
 }
 
-static void ksz_get_strings(struct dsa_switch *ds, int port, uint8_t *buf)
+static void ksz9477_get_strings(struct dsa_switch *ds, int port, uint8_t *buf)
 {
int i;
 
@@ -495,7 +495,8 @@ static void ksz_get_ethtool_stats(struct dsa_switch *ds, 
int port,
mutex_unlock(>stats_mutex);
 }
 
-static void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
+  u8 state)
 {
struct ksz_device *dev = ds->priv;
u8 data;
@@ -540,7 +541,8 @@ static void ksz_port_fast_age(struct dsa_switch *ds, int 
port)
ksz_write8(dev, REG_SW_LUE_CTRL_1, data8);
 }
 
-static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag)
+static int ksz9477_port_vlan_filtering(struct 

[PATCH v2 net-next 8/8] net: dsa: microchip: Rename ksz_9477_reg.h to ksz9477_reg.h

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz9477.c | 2 +-
 drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} | 0
 drivers/net/dsa/microchip/ksz_priv.h| 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (100%)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 537342a..801117a 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -31,7 +31,7 @@
 
 #include "ksz_priv.h"
 #include "ksz_common.h"
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 static const struct {
int index;
diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz9477_reg.h
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_9477_reg.h
rename to drivers/net/dsa/microchip/ksz9477_reg.h
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index d92a7c1..bfe9066 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -26,7 +26,7 @@
 #include 
 #include 
 
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 struct ksz_io_ops;
 
-- 
1.9.1



[PATCH v2 net-next 2/8] net: dsa: microchip: Clean up code according to patch check suggestions

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Clean up code according to patch check suggestions.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_common.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index d662a9a..435c463 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -895,9 +895,9 @@ static void ksz_port_mdb_add(struct dsa_switch *ds, int 
port,
 
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
@@ -968,9 +968,9 @@ static int ksz_port_mdb_del(struct dsa_switch *ds, int port,
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
 
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
-- 
1.9.1



[PATCH v2 net-next 7/8] net: dsa: microchip: Prepare PHY for proper advertisement

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Prepare PHY for proper advertisement and get link status for the port.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz9477.c| 13 +
 drivers/net/dsa/microchip/ksz_common.c | 20 
 drivers/net/dsa/microchip/ksz_common.h |  2 ++
 drivers/net/dsa/microchip/ksz_priv.h   |  2 ++
 4 files changed, 37 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 2c407bd..537342a 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -978,6 +978,17 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, 
int port,
 PORT_MIRROR_SNIFFER, false);
 }
 
+static void ksz9477_phy_setup(struct ksz_device *dev, int port,
+ struct phy_device *phy)
+{
+   if (port < dev->phy_port_cnt) {
+   /* SUPPORTED_Asym_Pause and SUPPORTED_Pause can be removed to
+* disable flow control when rate limiting is used.
+*/
+   phy->advertising = phy->supported;
+   }
+}
+
 static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
@@ -1159,6 +1170,7 @@ static int ksz9477_setup(struct dsa_switch *ds)
.setup  = ksz9477_setup,
.phy_read   = ksz9477_phy_read16,
.phy_write  = ksz9477_phy_write16,
+   .adjust_link= ksz_adjust_link,
.port_enable= ksz_enable_port,
.port_disable   = ksz_disable_port,
.get_strings= ksz9477_get_strings,
@@ -1300,6 +1312,7 @@ static void ksz9477_switch_exit(struct ksz_device *dev)
.get_port_addr = ksz9477_get_port_addr,
.cfg_port_member = ksz9477_cfg_port_member,
.flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,
+   .phy_setup = ksz9477_phy_setup,
.port_setup = ksz9477_port_setup,
.shutdown = ksz9477_reset_switch,
.detect = ksz9477_switch_detect,
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index b535544..624abdd 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -69,6 +69,25 @@ int ksz_phy_write16(struct dsa_switch *ds, int addr, int 
reg, u16 val)
return 0;
 }
 
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev)
+{
+   struct ksz_device *dev = ds->priv;
+   struct ksz_port *p = >ports[port];
+
+   if (phydev->link) {
+   p->speed = phydev->speed;
+   p->duplex = phydev->duplex;
+   p->flow_ctrl = phydev->pause;
+   p->link_up = 1;
+   dev->live_ports |= (1 << port) & dev->on_ports;
+   } else if (p->link_up) {
+   p->link_up = 0;
+   p->link_down = 1;
+   dev->live_ports &= ~(1 << port);
+   }
+}
+
 int ksz_sset_count(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
@@ -235,6 +254,7 @@ int ksz_enable_port(struct dsa_switch *ds, int port, struct 
phy_device *phy)
 
/* setup slave port */
dev->dev_ops->port_setup(dev, port, false);
+   dev->dev_ops->phy_setup(dev, port, phy);
 
/* port_stp_state_set() will be called after to enable the port so
 * there is no need to do anything.
diff --git a/drivers/net/dsa/microchip/ksz_common.h 
b/drivers/net/dsa/microchip/ksz_common.h
index dd2a468..599d4e5 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -26,6 +26,8 @@
 
 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev);
 int ksz_sset_count(struct dsa_switch *ds);
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
 struct net_device *br);
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 4126749..d92a7c1 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -150,6 +150,8 @@ struct ksz_dev_ops {
u32 (*get_port_addr)(int port, int offset);
void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member);
void (*flush_dyn_mac_table)(struct ksz_device *dev, int port);
+   void (*phy_setup)(struct ksz_device *dev, int port,
+ struct phy_device *phy);
void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port);
void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);
void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val);
-- 
1.9.1



[PATCH v2 net-next 5/8] net: dsa: microchip: Rename ksz_spi.c to ksz9477_spi.c

2017-12-05 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to add
more KSZ switch drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Kconfig  | 12 ++--
 drivers/net/dsa/microchip/Makefile |  4 ++--
 drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} |  0
 3 files changed, 8 insertions(+), 8 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} (100%)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index a8b8f59..5a8660d 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,12 +1,12 @@
-menuconfig MICROCHIP_KSZ
-   tristate "Microchip KSZ series switch support"
+menuconfig MICROCHIP_KSZ9477
+   tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
select NET_DSA_TAG_KSZ
help
- This driver adds support for Microchip KSZ switch chips.
+ This driver adds support for Microchip KSZ9477 switch chips.
 
-config MICROCHIP_KSZ_SPI_DRIVER
-   tristate "KSZ series SPI connected switch driver"
-   depends on MICROCHIP_KSZ && SPI
+config MICROCHIP_KSZ9477_SPI_DRIVER
+   tristate "KSZ9477 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index ed335e2..5b6325b 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ)+= ksz_common.o
-obj-$(CONFIG_MICROCHIP_KSZ_SPI_DRIVER) += ksz_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz_spi.c 
b/drivers/net/dsa/microchip/ksz9477_spi.c
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_spi.c
rename to drivers/net/dsa/microchip/ksz9477_spi.c
-- 
1.9.1



RE: [PATCH net-next 1/1] net: dsa: microchip: Add Microchip KSZ8895 DSA driver

2017-12-05 Thread Tristram.Ha
> > Sorry to be this late for the reply.  I finally got hold of a KSZ8895 board 
> > that
> > works with my SoC board to confirm the network communication.
> >
> > As expected the KSZ8895 board works correctly as the chip uses the same
> > tail tagging feature in KSZ8795, and I did verify that board is working.
> >
> > One thing to debug this problem is to dump the MIB counters.  Use the
> ethtool
> > utility to show MIB counters of both ports:
> >
> > ethtool -S lan3
> > ethtool -S eth0
> >
> > Assuming eth0 is the MAC controller that drives the switch, the receive
> counters of
> > the host port of the switch should match the transmit counters of
> > lan3, and vice versa.
> 
> Thanks for reply. I'll get to the tests shortly. Could I get .dts
> snippet that works for you and commands you are using for testing?
> 

You said your previous patch works, so I do not think there is anything wrong
with the device tree, unless you are using a completely different one.

The tricky part of network communication is the RMII/MII interface where the
host port connects to the MAC controller.  But again your patch works so there 
is
nothing wrong with the hardware.

I also use a simple setup to test the network:

ifconfig eth0 up
ifconfig lan1 192.168.0.1
ping -c 2 192.168.0.100

If I want a complete test I setup a bridge:

ifconfig eth0 up
ifconfig lan1 up
ifconfig lan2 up
ifconfig lan3 up
ifconfig lan4 up
brctl addbr br0
brctl addif br0 lan1
brctl addif br0 lan2
brctl addif br0 lan3
brctl addif br0 lan4
ifconfig br0 192.168.0.1
ping -c 2 192.168.0.100



RE: [PATCH net-next 1/1] net: dsa: microchip: Add Microchip KSZ8895 DSA driver

2017-12-05 Thread Tristram.Ha
> Thanks for patches. I installed whole series on top of net-next.
> 
> Hardware is:
> 
> root@miro:~# cat /proc/cpuinfo
> model name   : ARM926EJ-S rev 5 (v5l)
> Hardware: Freescale MXS (Device Tree)
> 
> I added devicetree chunks, and enabled DSA in the config. It seems
> switch is detected:
> 
> [4.775934] Micrel KSZ8051 dsa-0.0:00: attached PHY driver [Micrel
> KSZ8051] (mii_bus:phy_addr=dsa-0.0:00, irq=POLL)
> [4.885952] Micrel KSZ8051 dsa-0.0:01: attached PHY driver [Micrel
> KSZ8051] (mii_bus:phy_addr=dsa-0.0:01, irq=POLL)
> [4.995934] Micrel KSZ8051 dsa-0.0:02: attached PHY driver [Micrel
> KSZ8051] (mii_bus:phy_addr=dsa-0.0:02, irq=POLL)
> [5.011484] DSA: tree 0 setup
> 
> root@miro:~# ifconfig lan3 192.168.20.103 netmask 255.255.0.0 up
> [  131.196667] IPv6: ADDRCONF(NETDEV_UP): lan3: link is not ready
> root@miro:~# [  132.225863] ksz8895-switch spi2.0 lan3: Link is Up -
> 100Mbps/Full - flow control rx/tx
> [  132.233939] IPv6: ADDRCONF(NETDEV_CHANGE): lan3: link becomes ready
> 
> root@miro:~# ping 192.168.1.1
> PING 192.168.1.1 (192.168.1.1): 56 data bytes
> ^C
> --- 192.168.1.1 ping statistics ---
> 7 packets transmitted, 0 packets received, 100% packet loss
> root@miro:~# ifconfig [  149.904234] random: crng init done
> 
> But packets do not go through, and there is nothing helpful in
> dmesg. Dts part is:
> 
> spi@0 {
>   compatible = "microchip,ksz8895";
> spi-max-frequency = <2500>;
> reg = <0>;
>   // reset-gpios = < 8 0>;
> status = "okay";
> 
> spi-cpha;
>   spi-cpol;
>ports {
>  #address-cells = <1>;
>  #size-cells = <0>;
>  port@0 {
> reg = <0>;
> label = "lan1";
>  };
>  port@1 {
> reg = <1>;
> label = "lan2";
>  };
>  port@2 {
> reg = <2>;
> label = "lan3";
>  };
>  port@4 {
> reg = <4>;
> label = "cpu";
> ethernet = <>;
> fixed-link {
>speed = <100>;
>full-duplex;
> };
>  };
>};
>   };
> 
> I went back to my version of dsa patches, and test above works as
> expected.

Sorry to be this late for the reply.  I finally got hold of a KSZ8895 board that
works with my SoC board to confirm the network communication.

As expected the KSZ8895 board works correctly as the chip uses the same
tail tagging feature in KSZ8795, and I did verify that board is working.

One thing to debug this problem is to dump the MIB counters.  Use the ethtool
utility to show MIB counters of both ports:

ethtool -S lan3
ethtool -S eth0

Assuming eth0 is the MAC controller that drives the switch, the receive 
counters of
the host port of the switch should match the transmit counters of lan3, and 
vice versa.



RE: [PATCH v1 net-next 0/7] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2017-11-18 Thread Tristram.Ha
> > I really need to monitor the DSA discussion to better contribute to its
> success.
> > I just found out the DSA API set_addr was removed last month due to not
> > everybody is using it.  It cited the Marvell switch was the only switch 
> > using
> that
> > API and found a new way to program the MAC address.  But looking at that
> > driver I found it simply uses a randomized MAC address.
> >
> > For big switch with many ports where the main function is forwarding that
> MAC
> > address may not matter.  For small switch with 2 ports it acts more like an
> Ethernet
> > controller where the switch is mainly used for daisy chaining in a ring
> network the MAC
> > address can be used in feature like source address filtering.
> 
> Hi Tristram
> 
> The MAC address set by set_addr was only used for pause
> frames. Nothing else. So a random address is fine.
> 
> The switch itself should not be sending any other frames.
> 

Yes, generally that is the main purpose.

For new protocols like High-availability Seamless Redundancy (HSR) and
Device Level Ring (DLR) that operate in a ring network, the switch needs
to know the MAC address of the host so that it can filter the frame it sends.

There is an experimental implementation of HSR in the kernel.



RE: [PATCH v1 net-next 0/7] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2017-11-17 Thread Tristram.Ha
> On Thu, Nov 16, 2017 at 06:41:24PM -0800, tristram...@microchip.com
> wrote:
> > From: Tristram Ha 
> >
> > This series of patches is to modify the original KSZ9477 DSA driver so
> > that other KSZ switch drivers can be added and use the common code.
> 
> Hi Tristram
> 
> http://vger.kernel.org/~davem/net-next.html
> 
> It is better to send an RFC patchset while netdev is closed and not
> send it to David. He will shout at you otherwise.

Noted.

I really need to monitor the DSA discussion to better contribute to its success.
I just found out the DSA API set_addr was removed last month due to not
everybody is using it.  It cited the Marvell switch was the only switch using 
that
API and found a new way to program the MAC address.  But looking at that
driver I found it simply uses a randomized MAC address.

For big switch with many ports where the main function is forwarding that MAC
address may not matter.  For small switch with 2 ports it acts more like an 
Ethernet
controller where the switch is mainly used for daisy chaining in a ring network 
the MAC
address can be used in feature like source address filtering.



[PATCH v2 net-next 0/1] net: dsa: microchip: Add Microchip KSZ8795 DSA driver

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

This patch requires the previous patches for Microchip KSZ9477 DSA driver.

v2
- No new feature is introduced in tag_ksz.c

v1
- Return error codes instead of numbers
- Add more comments to clarify operation
- Use ksz8795 prefix to indicate KSZ8795 specific code
- Simplify MIB counter reading code
- Switch driver code is not accessed from tag_ksz.c

Tristram Ha (1):
  Add Microchip KSZ8795 DSA driver.

 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8795.c | 1365 +++
 drivers/net/dsa/microchip/ksz8795_reg.h | 1016 +++
 drivers/net/dsa/microchip/ksz8795_spi.c |  166 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 include/net/dsa.h   |1 +
 net/dsa/Kconfig |4 +
 net/dsa/dsa.c   |3 +
 net/dsa/dsa_priv.h  |1 +
 net/dsa/tag_ksz.c   |   32 +
 11 files changed, 2608 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8795.c
 create mode 100644 drivers/net/dsa/microchip/ksz8795_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8795_spi.c

-- 
1.9.1



[PATCH v2 net-next] net: dsa: Modify tag_ksz.c so that tail tag code can be used by other KSZ switch drivers

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Modify tag_ksz.c so that tail tag code can be used by other KSZ switch
drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
v2
- No new feature is introduced

v1
- Switch driver code is not accessed from tag_ksz.c

 drivers/net/dsa/microchip/Kconfig   |  2 +-
 drivers/net/dsa/microchip/ksz9477.c |  2 +-
 include/net/dsa.h   |  2 +-
 net/dsa/Kconfig |  4 ++
 net/dsa/dsa.c   |  4 +-
 net/dsa/dsa_priv.h  |  2 +-
 net/dsa/tag_ksz.c   | 90 -
 7 files changed, 70 insertions(+), 36 deletions(-)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index 5a8660d..ab8f9f6 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,7 +1,7 @@
 menuconfig MICROCHIP_KSZ9477
tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
-   select NET_DSA_TAG_KSZ
+   select NET_DSA_TAG_KSZ9477
help
  This driver adds support for Microchip KSZ9477 switch chips.
 
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 4e998a4..c735dca 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -344,7 +344,7 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, 
int port)
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
  int port)
 {
-   return DSA_TAG_PROTO_KSZ;
+   return DSA_TAG_PROTO_KSZ9477;
 }
 
 static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 2a05738..3d23c0b 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -32,7 +32,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_BRCM_PREPEND,
DSA_TAG_PROTO_DSA,
DSA_TAG_PROTO_EDSA,
-   DSA_TAG_PROTO_KSZ,
+   DSA_TAG_PROTO_KSZ9477,
DSA_TAG_PROTO_LAN9303,
DSA_TAG_PROTO_MTK,
DSA_TAG_PROTO_QCA,
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index 03c3bdf..809b0e2 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -32,6 +32,10 @@ config NET_DSA_TAG_EDSA
 config NET_DSA_TAG_KSZ
bool
 
+config NET_DSA_TAG_KSZ9477
+   bool
+   select NET_DSA_TAG_KSZ
+
 config NET_DSA_TAG_LAN9303
bool
 
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 6a9d0f5..92056a7 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -53,8 +53,8 @@ static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff 
*skb,
 #ifdef CONFIG_NET_DSA_TAG_EDSA
[DSA_TAG_PROTO_EDSA] = _netdev_ops,
 #endif
-#ifdef CONFIG_NET_DSA_TAG_KSZ
-   [DSA_TAG_PROTO_KSZ] = _netdev_ops,
+#ifdef CONFIG_NET_DSA_TAG_KSZ9477
+   [DSA_TAG_PROTO_KSZ9477] = _netdev_ops,
 #endif
 #ifdef CONFIG_NET_DSA_TAG_LAN9303
[DSA_TAG_PROTO_LAN9303] = _netdev_ops,
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 7d03669..a2955a8 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -200,7 +200,7 @@ static inline struct dsa_port *dsa_slave_to_port(const 
struct net_device *dev)
 extern const struct dsa_device_ops edsa_netdev_ops;
 
 /* tag_ksz.c */
-extern const struct dsa_device_ops ksz_netdev_ops;
+extern const struct dsa_device_ops ksz9477_netdev_ops;
 
 /* tag_lan9303.c */
 extern const struct dsa_device_ops lan9303_netdev_ops;
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 0f62eff..7343270 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -14,34 +14,21 @@
 #include 
 #include "dsa_priv.h"
 
-/* For Ingress (Host -> KSZ), 2 bytes are added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
- * ---
- * tag0 : Prioritization (not used now)
- * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
- *
- * For Egress (KSZ -> Host), 1 byte is added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|FCS(4bytes)
- * ---
- * tag0 : zero-based value represents port
- *   (eg, 0x00=port1, 0x02=port3, 0x06=port7)
- */
-
-#defineKSZ_INGRESS_TAG_LEN 2
-#defineKSZ_EGRESS_TAG_LEN  1
+/* Usually only one byte is used for tail tag. */
+#define KSZ_INGRESS_TAG_LEN1
+#define KSZ_EGRESS_TAG_LEN 1
 
-static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
+static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev,
+   int len,
+   void 

[PATCH net-next 1/1] net: dsa: microchip: Add Microchip KSZ8895 DSA driver

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Add Microchip KSZ8895 DSA driver.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8895.c | 1276 +++
 drivers/net/dsa/microchip/ksz8895_reg.h |  824 
 drivers/net/dsa/microchip/ksz8895_spi.c |  157 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 6 files changed, 2277 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8895.c
 create mode 100644 drivers/net/dsa/microchip/ksz8895_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8895_spi.c

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index cb95d3d..b854c4b 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -27,3 +27,20 @@ config MICROCHIP_KSZ8795_SPI_DRIVER
 
  It is required to use the KSZ8795 switch driver as the only access
  is through SPI.
+
+menuconfig MICROCHIP_KSZ8895
+   tristate "Microchip KSZ8895 series switch support"
+   depends on NET_DSA
+   select NET_DSA_TAG_KSZ8795
+   help
+ This driver adds support for Microchip KSZ8895 switch chips.
+
+config MICROCHIP_KSZ8895_SPI_DRIVER
+   tristate "KSZ8895 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ8895 && SPI
+   default y
+   help
+ This driver accesses KSZ8895 chip through SPI.
+
+ It is required to use the KSZ8895 switch driver as the only access
+ is through SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 99a283e..8dd6312 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -2,3 +2,5 @@ obj-$(CONFIG_MICROCHIP_KSZ9477) += ksz9477.o 
ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
 obj-$(CONFIG_MICROCHIP_KSZ8795)+= ksz8795.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ8795_SPI_DRIVER) += ksz8795_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ8895)+= ksz8895.o ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ8895_SPI_DRIVER) += ksz8895_spi.o
diff --git a/drivers/net/dsa/microchip/ksz8895.c 
b/drivers/net/dsa/microchip/ksz8895.c
new file mode 100644
index 000..e04643c
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz8895.c
@@ -0,0 +1,1276 @@
+/*
+ * Microchip KSZ8895 switch driver
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ * Tristram Ha 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz8895_reg.h"
+
+static const struct {
+   char string[ETH_GSTRING_LEN];
+} ksz8895_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { "rx" },
+   { "rx_hi" },
+   { "rx_undersize" },
+   { "rx_fragments" },
+   { "rx_oversize" },
+   { "rx_jabbers" },
+   { "rx_symbol_err" },
+   { "rx_crc_err" },
+   { "rx_align_err" },
+   { "rx_mac_ctrl" },
+   { "rx_pause" },
+   { "rx_bcast" },
+   { "rx_mcast" },
+   { "rx_ucast" },
+   { "rx_64_or_less" },
+   { "rx_65_127" },
+   { "rx_128_255" },
+   { "rx_256_511" },
+   { "rx_512_1023" },
+   { "rx_1024_1522" },
+   { "tx" },
+   { "tx_hi" },
+   { "tx_late_col" },
+   { "tx_pause" },
+   { "tx_bcast" },
+   { "tx_mcast" },
+   { "tx_ucast" },
+   { "tx_deferred" },
+   { "tx_total_col" },
+   { "tx_exc_col" },
+   { "tx_single_col" },
+   { "tx_mult_col" },
+   { "rx_discards" },
+   { "tx_discards" },
+};
+
+static int ksz8895_reset_switch(struct ksz_device *dev)
+{
+   /* reset switch */
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1,
+  SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
+
+   return 0;
+}
+
+static void ksz8895_set_prio_queue(struct ksz_device *dev, int port, int queue)
+{
+   u8 hi;
+   u8 lo;
+
+   /* Number of queues can only be 1, 2, or 4. */
+   switch (queue) {
+  

[PATCH v2 net-next 1/1] net: dsa: microchip: Add Microchip KSZ8795 DSA driver

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Add Microchip KSZ8795 DSA driver.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8795.c | 1365 +++
 drivers/net/dsa/microchip/ksz8795_reg.h | 1016 +++
 drivers/net/dsa/microchip/ksz8795_spi.c |  166 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 include/net/dsa.h   |1 +
 net/dsa/Kconfig |4 +
 net/dsa/dsa.c   |3 +
 net/dsa/dsa_priv.h  |1 +
 net/dsa/tag_ksz.c   |   32 +
 11 files changed, 2608 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8795.c
 create mode 100644 drivers/net/dsa/microchip/ksz8795_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8795_spi.c

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index ab8f9f6..cb95d3d 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -10,3 +10,20 @@ config MICROCHIP_KSZ9477_SPI_DRIVER
depends on MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
+
+menuconfig MICROCHIP_KSZ8795
+   tristate "Microchip KSZ8795 series switch support"
+   depends on NET_DSA
+   select NET_DSA_TAG_KSZ8795
+   help
+ This driver adds support for Microchip KSZ8795 switch chips.
+
+config MICROCHIP_KSZ8795_SPI_DRIVER
+   tristate "KSZ8795 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ8795 && SPI
+   default y
+   help
+ This driver accesses KSZ8795 chip through SPI.
+
+ It is required to use the KSZ8795 switch driver as the only access
+ is through SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 13dd8f0..99a283e 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,4 @@
 obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz9477.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ8795)+= ksz8795.o ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ8795_SPI_DRIVER) += ksz8795_spi.o
diff --git a/drivers/net/dsa/microchip/ksz8795.c 
b/drivers/net/dsa/microchip/ksz8795.c
new file mode 100644
index 000..bdec1ed
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz8795.c
@@ -0,0 +1,1365 @@
+/*
+ * Microchip KSZ8795 switch driver
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ * Tristram Ha 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz8795_reg.h"
+
+static const struct {
+   char string[ETH_GSTRING_LEN];
+} ksz8795_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { "rx_hi" },
+   { "rx_undersize" },
+   { "rx_fragments" },
+   { "rx_oversize" },
+   { "rx_jabbers" },
+   { "rx_symbol_err" },
+   { "rx_crc_err" },
+   { "rx_align_err" },
+   { "rx_mac_ctrl" },
+   { "rx_pause" },
+   { "rx_bcast" },
+   { "rx_mcast" },
+   { "rx_ucast" },
+   { "rx_64_or_less" },
+   { "rx_65_127" },
+   { "rx_128_255" },
+   { "rx_256_511" },
+   { "rx_512_1023" },
+   { "rx_1024_1522" },
+   { "rx_1523_2000" },
+   { "rx_2001" },
+   { "tx_hi" },
+   { "tx_late_col" },
+   { "tx_pause" },
+   { "tx_bcast" },
+   { "tx_mcast" },
+   { "tx_ucast" },
+   { "tx_deferred" },
+   { "tx_total_col" },
+   { "tx_exc_col" },
+   { "tx_single_col" },
+   { "tx_mult_col" },
+   { "rx_total" },
+   { "tx_total" },
+   { "rx_discards" },
+   { "tx_discards" },
+};
+
+static int ksz8795_reset_switch(struct ksz_device *dev)
+{
+   /* reset switch */
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1,
+  SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
+

[PATCH net-next 0/1] net: dsa: microchip: Add Microchip KSZ8895 DSA driver

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

This patch requires the previous patch for Microchip KSZ8795 DSA driver.

Tristram Ha (1):
  Add Microchip KSZ8895 DSA driver.

 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8895.c | 1276 +++
 drivers/net/dsa/microchip/ksz8895_reg.h |  824 
 drivers/net/dsa/microchip/ksz8895_spi.c |  157 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 6 files changed, 2277 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8895.c
 create mode 100644 drivers/net/dsa/microchip/ksz8895_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8895_spi.c

-- 
1.9.1



[PATCH v2 net-next] net: dsa: microchip: Add MIB counter reading support

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Add MIB counter reading support.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
v2
- Only MIB counter related code in patch

v1
- Simplify MIB counter reading code

 drivers/net/dsa/microchip/ksz9477.c| 121 ++---
 drivers/net/dsa/microchip/ksz_common.c | 100 +++
 drivers/net/dsa/microchip/ksz_common.h |   2 +
 drivers/net/dsa/microchip/ksz_priv.h   |   7 +-
 4 files changed, 185 insertions(+), 45 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 22a4b34..4e998a4 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -271,6 +271,76 @@ static int ksz9477_reset_switch(struct ksz_device *dev)
return 0;
 }
 
+static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
+ u64 *cnt)
+{
+   u32 data;
+   int timeout;
+   struct ksz_port *p = >ports[port];
+
+   /* retain the flush/freeze bit */
+   data = p->freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+   data |= MIB_COUNTER_READ;
+   data |= (addr << MIB_COUNTER_INDEX_S);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
+
+   timeout = 1000;
+   do {
+   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+   );
+   usleep_range(1, 10);
+   if (!(data & MIB_COUNTER_READ))
+   break;
+   } while (timeout-- > 0);
+
+   /* failed to read MIB. get out of loop */
+   if (!timeout) {
+   dev_dbg(dev->dev, "Failed to get MIB\n");
+   return;
+   }
+
+   /* count resets upon read */
+   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
+   *cnt += data;
+}
+
+static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
+ u64 *dropped, u64 *cnt)
+{
+   addr = ksz9477_mib_names[addr].index;
+   ksz9477_r_mib_cnt(dev, port, addr, cnt);
+}
+
+static void ksz9477_freeze_mib(struct ksz_device *dev, int port, bool freeze)
+{
+   struct ksz_port *p = >ports[port];
+   u32 val = freeze ? MIB_COUNTER_FLUSH_FREEZE : 0;
+
+   /* enable/disable the port for flush/freeze function */
+   mutex_lock(>mib.cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, val);
+
+   /* used by MIB counter reading code to know freeze is enabled */
+   p->freeze = freeze;
+   mutex_unlock(>mib.cnt_mutex);
+}
+
+static void ksz9477_port_init_cnt(struct ksz_device *dev, int port)
+{
+   struct ksz_port_mib *mib = >ports[port].mib;
+
+   /* flush all enabled port MIB counters */
+   mutex_lock(>cnt_mutex);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+MIB_COUNTER_FLUSH_FREEZE);
+   ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0);
+   mutex_unlock(>cnt_mutex);
+
+   mib->cnt_ptr = 0;
+   memset(mib->counters, 0, dev->mib_cnt * sizeof(u64));
+}
+
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
  int port)
 {
@@ -350,47 +420,6 @@ static void ksz9477_get_strings(struct dsa_switch *ds, int 
port, uint8_t *buf)
}
 }
 
-static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *buf)
-{
-   struct ksz_device *dev = ds->priv;
-   int i;
-   u32 data;
-   int timeout;
-
-   mutex_lock(>stats_mutex);
-
-   for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
-   data = MIB_COUNTER_READ;
-   data |= ((ksz9477_mib_names[i].index & 0xFF) <<
-   MIB_COUNTER_INDEX_S);
-   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
-
-   timeout = 1000;
-   do {
-   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
-   );
-   usleep_range(1, 10);
-   if (!(data & MIB_COUNTER_READ))
-   break;
-   } while (timeout-- > 0);
-
-   /* failed to read MIB. get out of loop */
-   if (!timeout) {
-   dev_dbg(dev->dev, "Failed to get MIB\n");
-   break;
-   }
-
-   /* count resets upon read */
-   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
-
-   dev->mib_value[i] += (uint64_t)data;
-   buf[i] = dev->mib_value[i];
-   }
-
-   mutex_unlock(>stats_mutex);
-}
-
 static void ksz9477_cfg_port_member(struct ksz_device *dev, int port,
u8 member)
 {
@@ -1161,9 +1190,14 @@ static int ksz9477_setup(struct 

[PATCH v1 net-next 7/7] net: dsa: microchip: Rename ksz_9477_reg.h to ksz9477_reg.h

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz9477.c | 2 +-
 drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} | 0
 drivers/net/dsa/microchip/ksz_priv.h| 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (100%)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 05fa859..22a4b34 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -31,7 +31,7 @@
 
 #include "ksz_priv.h"
 #include "ksz_common.h"
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 static const struct {
int index;
diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz9477_reg.h
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_9477_reg.h
rename to drivers/net/dsa/microchip/ksz9477_reg.h
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index d92a7c1..bfe9066 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -26,7 +26,7 @@
 #include 
 #include 
 
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 struct ksz_io_ops;
 
-- 
1.9.1



[PATCH v1 net-next 5/7] net: dsa: microchip: Break KSZ9477 DSA driver into two files

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.
Add common functions in ksz_common.h so that other KSZ switch drivers
can access code in ksz_common.c.
Add ksz_spi.h for common functions used by KSZ switch SPI drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Makefile  |2 +-
 drivers/net/dsa/microchip/ksz9477.c | 1321 +++
 drivers/net/dsa/microchip/ksz9477_spi.c |  143 ++--
 drivers/net/dsa/microchip/ksz_common.c  | 1134 +++---
 drivers/net/dsa/microchip/ksz_common.h  |  230 ++
 drivers/net/dsa/microchip/ksz_priv.h|  229 +++---
 drivers/net/dsa/microchip/ksz_spi.h |   82 ++
 7 files changed, 1919 insertions(+), 1222 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 5b6325b..13dd8f0 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz9477.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
new file mode 100644
index 000..080cb76
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -0,0 +1,1321 @@
+/*
+ * Microchip KSZ9477 switch driver main logic
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz_9477_reg.h"
+
+static const struct {
+   int index;
+   char string[ETH_GSTRING_LEN];
+} ksz9477_mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { 0x00, "rx_hi" },
+   { 0x01, "rx_undersize" },
+   { 0x02, "rx_fragments" },
+   { 0x03, "rx_oversize" },
+   { 0x04, "rx_jabbers" },
+   { 0x05, "rx_symbol_err" },
+   { 0x06, "rx_crc_err" },
+   { 0x07, "rx_align_err" },
+   { 0x08, "rx_mac_ctrl" },
+   { 0x09, "rx_pause" },
+   { 0x0A, "rx_bcast" },
+   { 0x0B, "rx_mcast" },
+   { 0x0C, "rx_ucast" },
+   { 0x0D, "rx_64_or_less" },
+   { 0x0E, "rx_65_127" },
+   { 0x0F, "rx_128_255" },
+   { 0x10, "rx_256_511" },
+   { 0x11, "rx_512_1023" },
+   { 0x12, "rx_1024_1522" },
+   { 0x13, "rx_1523_2000" },
+   { 0x14, "rx_2001" },
+   { 0x15, "tx_hi" },
+   { 0x16, "tx_late_col" },
+   { 0x17, "tx_pause" },
+   { 0x18, "tx_bcast" },
+   { 0x19, "tx_mcast" },
+   { 0x1A, "tx_ucast" },
+   { 0x1B, "tx_deferred" },
+   { 0x1C, "tx_total_col" },
+   { 0x1D, "tx_exc_col" },
+   { 0x1E, "tx_single_col" },
+   { 0x1F, "tx_mult_col" },
+   { 0x80, "rx_total" },
+   { 0x81, "tx_total" },
+   { 0x82, "rx_discards" },
+   { 0x83, "tx_discards" },
+};
+
+static void ksz9477_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
+{
+   u32 data;
+
+   ksz_read32(dev, addr, );
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+   ksz_write32(dev, addr, data);
+}
+
+static void ksz9477_port_cfg32(struct ksz_device *dev, int port, int offset,
+  u32 bits, bool set)
+{
+   u32 addr;
+   u32 data;
+
+   addr = PORT_CTRL_ADDR(port, offset);
+   ksz_read32(dev, addr, );
+
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+
+   ksz_write32(dev, addr, data);
+}
+
+static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev, u32 waiton,
+   int timeout)
+{
+   u8 data;
+
+   do {
+   ksz_read8(dev, REG_SW_VLAN_CTRL, );
+   if (!(data & waiton))
+ 

[PATCH v1 net-next 6/7] net: dsa: microchip: Prepare PHY for proper advertisement

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Prepare PHY for proper advertisement and get link status for the port.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz9477.c| 13 +
 drivers/net/dsa/microchip/ksz_common.c | 20 
 drivers/net/dsa/microchip/ksz_common.h |  2 ++
 drivers/net/dsa/microchip/ksz_priv.h   |  2 ++
 4 files changed, 37 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 080cb76..05fa859 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -980,6 +980,17 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, 
int port,
 PORT_MIRROR_SNIFFER, false);
 }
 
+static void ksz9477_phy_setup(struct ksz_device *dev, int port,
+ struct phy_device *phy)
+{
+   if (port < dev->phy_port_cnt) {
+   /* SUPPORTED_Asym_Pause and SUPPORTED_Pause can be removed to
+* disable flow control when rate limiting is used.
+*/
+   phy->advertising = phy->supported;
+   }
+}
+
 static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
@@ -1161,6 +1172,7 @@ static int ksz9477_setup(struct dsa_switch *ds)
.setup  = ksz9477_setup,
.phy_read   = ksz9477_phy_read16,
.phy_write  = ksz9477_phy_write16,
+   .adjust_link= ksz_adjust_link,
.port_enable= ksz_enable_port,
.port_disable   = ksz_disable_port,
.get_strings= ksz9477_get_strings,
@@ -1303,6 +1315,7 @@ static void ksz9477_switch_exit(struct ksz_device *dev)
.get_port_addr = ksz9477_get_port_addr,
.cfg_port_member = ksz9477_cfg_port_member,
.flush_dyn_mac_table = ksz9477_flush_dyn_mac_table,
+   .phy_setup = ksz9477_phy_setup,
.port_setup = ksz9477_port_setup,
.shutdown = ksz9477_reset_switch,
.detect = ksz9477_switch_detect,
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 1c9c4c5..e50ea56 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -69,6 +69,25 @@ int ksz_phy_write16(struct dsa_switch *ds, int addr, int 
reg, u16 val)
return 0;
 }
 
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev)
+{
+   struct ksz_device *dev = ds->priv;
+   struct ksz_port *p = >ports[port];
+
+   if (phydev->link) {
+   p->speed = phydev->speed;
+   p->duplex = phydev->duplex;
+   p->flow_ctrl = phydev->pause;
+   p->link_up = 1;
+   dev->live_ports |= (1 << port) & dev->on_ports;
+   } else if (p->link_up) {
+   p->link_up = 0;
+   p->link_down = 1;
+   dev->live_ports &= ~(1 << port);
+   }
+}
+
 int ksz_sset_count(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
@@ -249,6 +268,7 @@ int ksz_enable_port(struct dsa_switch *ds, int port, struct 
phy_device *phy)
 
/* setup slave port */
dev->dev_ops->port_setup(dev, port, false);
+   dev->dev_ops->phy_setup(dev, port, phy);
 
/* port_stp_state_set() will be called after to enable the port so
 * there is no need to do anything.
diff --git a/drivers/net/dsa/microchip/ksz_common.h 
b/drivers/net/dsa/microchip/ksz_common.h
index 1c1cbad..9d71387 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -26,6 +26,8 @@
 
 int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg);
 int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val);
+void ksz_adjust_link(struct dsa_switch *ds, int port,
+struct phy_device *phydev);
 int ksz_sset_count(struct dsa_switch *ds);
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
 struct net_device *br);
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 4126749..d92a7c1 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -150,6 +150,8 @@ struct ksz_dev_ops {
u32 (*get_port_addr)(int port, int offset);
void (*cfg_port_member)(struct ksz_device *dev, int port, u8 member);
void (*flush_dyn_mac_table)(struct ksz_device *dev, int port);
+   void (*phy_setup)(struct ksz_device *dev, int port,
+ struct phy_device *phy);
void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port);
void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);
void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val);
-- 
1.9.1



[PATCH net-next] dt-bindings: net: dsa: Document additional Microchip KSZ family switches

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Document additional Microchip KSZ family switches.

Signed-off-by: Tristram Ha 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
---
 Documentation/devicetree/bindings/net/dsa/ksz.txt | 189 --
 1 file changed, 136 insertions(+), 53 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/ksz.txt 
b/Documentation/devicetree/bindings/net/dsa/ksz.txt
index fd23904..705f9d9 100644
--- a/Documentation/devicetree/bindings/net/dsa/ksz.txt
+++ b/Documentation/devicetree/bindings/net/dsa/ksz.txt
@@ -3,8 +3,15 @@ Microchip KSZ Series Ethernet switches
 
 Required properties:
 
-- compatible: For external switch chips, compatible string must be exactly one
-  of: "microchip,ksz9477"
+- compatible: "microchip,ksz9477",
+ "microchip,ksz8795",
+ "microchip,ksz8794",
+ "microchip,ksz8765",
+ "microchip,ksz8895",
+ "microchip,ksz8864",
+ "microchip,ksz8873",
+ "microchip,ksz8863",
+ "microchip,ksz8463"
 
 See Documentation/devicetree/bindings/dsa/dsa.txt for a list of additional
 required and optional properties.
@@ -13,58 +20,134 @@ Examples:
 
 Ethernet switch connected via SPI to the host, CPU port wired to eth0:
 
- eth0: ethernet@10001000 {
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
+   eth0: ethernet@10001000 {
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+   };
 
- spi1: spi@f8008000 {
- pinctrl-0 = <_spi_ksz>;
- cs-gpios = < 25 0>;
- id = <1>;
+   spi1: spi@f8008000 {
+   cs-gpios = < 25 0>;
+   id = <1>;
 
- ksz9477: ksz9477@0 {
- compatible = 
"microchip,ksz9477";
- reg = <0>;
+   ksz9477: ksz9477@0 {
+   compatible = "microchip,ksz9477";
+   reg = <0>;
 
- spi-max-frequency 
= <4400>;
- spi-cpha;
- spi-cpol;
+   spi-max-frequency = <4400>;
+   spi-cpha;
+   spi-cpol;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   port@0 {
+   reg = <0>;
+   label = "lan1";
+   };
+   port@1 {
+   reg = <1>;
+   label = "lan2";
+   };
+   port@2 {
+   reg = <2>;
+   label = "lan3";
+   };
+   port@3 {
+   reg = <3>;
+   label = "lan4";
+   };
+   port@4 {
+   reg = <4>;
+   label = "lan5";
+   };
+   port@5 {
+   reg = <5>;
+   label = "cpu";
+   ethernet = <>;
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+   };
+   port@6 {
+   reg = <6>;
+   label = "lan6";
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+   };
+   };
+   };
+   ksz8794: ksz8794@0 {
+   compatible = 

[PATCH v1 net-next 4/7] net: dsa: microchip: Rename ksz_spi.c to ksz9477_spi.c

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to add
more KSZ switch drivers.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/Kconfig  | 12 ++--
 drivers/net/dsa/microchip/Makefile |  4 ++--
 drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} |  0
 3 files changed, 8 insertions(+), 8 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} (100%)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index a8b8f59..5a8660d 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,12 +1,12 @@
-menuconfig MICROCHIP_KSZ
-   tristate "Microchip KSZ series switch support"
+menuconfig MICROCHIP_KSZ9477
+   tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
select NET_DSA_TAG_KSZ
help
- This driver adds support for Microchip KSZ switch chips.
+ This driver adds support for Microchip KSZ9477 switch chips.
 
-config MICROCHIP_KSZ_SPI_DRIVER
-   tristate "KSZ series SPI connected switch driver"
-   depends on MICROCHIP_KSZ && SPI
+config MICROCHIP_KSZ9477_SPI_DRIVER
+   tristate "KSZ9477 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index ed335e2..5b6325b 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ)+= ksz_common.o
-obj-$(CONFIG_MICROCHIP_KSZ_SPI_DRIVER) += ksz_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz_spi.c 
b/drivers/net/dsa/microchip/ksz9477_spi.c
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_spi.c
rename to drivers/net/dsa/microchip/ksz9477_spi.c
-- 
1.9.1



[PATCH v1 net-next 2/7] net: dsa: microchip: Clean up code according to patch check suggestions

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Clean up code according to patch check suggestions.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_common.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index ed67ef6..1388f1a 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -899,9 +899,9 @@ static void ksz_port_mdb_add(struct dsa_switch *ds, int 
port,
 
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
@@ -972,9 +972,9 @@ static int ksz_port_mdb_del(struct dsa_switch *ds, int port,
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
 
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
-- 
1.9.1



[PATCH v1 net-next 0/7] net: dsa: microchip: Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

This series of patches is to modify the original KSZ9477 DSA driver so
that other KSZ switch drivers can be added and use the common code.

There are several steps to accomplish this achievement.  First is to
rename some function names with a prefix to indicate chip specific
function.  Second is to move common code into header that can be shared.
Last is to modify tag_ksz.c so that it can handle many tail tag formats
used by different KSZ switch drivers.

ksz_common.c will contain the common code used by all KSZ switch drivers.
ksz9477.c will contain KSZ9477 code from the original ksz_common.c.
ksz9477_spi.c is renamed from ksz_spi.c.
ksz9477_reg.h is renamed from ksz_9477_reg.h.
ksz_common.h is added to provide common code access to KSZ switch
drivers.
ksz_spi.h is added to provide common SPI access functions to KSZ SPI
drivers.

v1
- Each patch in the set is self-contained
- Use ksz9477 prefix to indicate KSZ9477 specific code

Tristram Ha (7):
  Replace license with GPL.
  Clean up code according to patch check suggestions.
  Rename some functions with ksz9477 prefix to separate chip specific
code from common code.
  Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to
add more KSZ switch drivers.
  Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.   Add common functions in ksz_common.h so that other
KSZ switch drivers can access code in ksz_common.c.   Add ksz_spi.h
for common functions used by KSZ switch SPI drivers.
  Prepare PHY for proper advertisement and get link status for the port.
  Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.

 drivers/net/dsa/microchip/Kconfig  |   12 +-
 drivers/net/dsa/microchip/Makefile |4 +-
 drivers/net/dsa/microchip/ksz9477.c| 1334 
 .../microchip/{ksz_9477_reg.h => ksz9477_reg.h}|   23 +-
 drivers/net/dsa/microchip/ksz9477_spi.c|  188 +++
 drivers/net/dsa/microchip/ksz_common.c | 1167 +++--
 drivers/net/dsa/microchip/ksz_common.h |  232 
 drivers/net/dsa/microchip/ksz_priv.h   |  256 ++--
 drivers/net/dsa/microchip/ksz_spi.c|  216 
 drivers/net/dsa/microchip/ksz_spi.h|   82 ++
 10 files changed, 2127 insertions(+), 1387 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (98%)
 create mode 100644 drivers/net/dsa/microchip/ksz9477_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 delete mode 100644 drivers/net/dsa/microchip/ksz_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

-- 
1.9.1



[PATCH v1 net-next 3/7] net: dsa: microchip: Rename some functions with ksz9477 prefix chip specific code from common code.

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Rename some functions with ksz9477 prefix to separate chip specific code
from common code.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
Reviewed-by: Pavel Machek 
Reviewed-by: Florian Fainelli 
Reviewed-by: Andrew Lunn 
---
 drivers/net/dsa/microchip/ksz_common.c | 118 +
 1 file changed, 60 insertions(+), 58 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 1388f1a..06227ef 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -265,9 +265,8 @@ static int wait_alu_sta_ready(struct ksz_device *dev, u32 
waiton, int timeout)
return 0;
 }
 
-static int ksz_reset_switch(struct dsa_switch *ds)
+static int ksz9477_reset_switch(struct ksz_device *dev)
 {
-   struct ksz_device *dev = ds->priv;
u8 data8;
u16 data16;
u32 data32;
@@ -300,7 +299,7 @@ static int ksz_reset_switch(struct dsa_switch *ds)
return 0;
 }
 
-static void port_setup(struct ksz_device *dev, int port, bool cpu_port)
+static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
u16 data16;
@@ -346,7 +345,7 @@ static void port_setup(struct ksz_device *dev, int port, 
bool cpu_port)
ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, );
 }
 
-static void ksz_config_cpu_port(struct dsa_switch *ds)
+static void ksz9477_config_cpu_port(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int i;
@@ -358,12 +357,12 @@ static void ksz_config_cpu_port(struct dsa_switch *ds)
dev->cpu_port = i;
 
/* enable cpu port */
-   port_setup(dev, i, true);
+   ksz9477_port_setup(dev, i, true);
}
}
 }
 
-static int ksz_setup(struct dsa_switch *ds)
+static int ksz9477_setup(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int ret = 0;
@@ -373,7 +372,7 @@ static int ksz_setup(struct dsa_switch *ds)
if (!dev->vlan_cache)
return -ENOMEM;
 
-   ret = ksz_reset_switch(ds);
+   ret = ksz9477_reset_switch(dev);
if (ret) {
dev_err(ds->dev, "failed to reset switch\n");
return ret;
@@ -382,7 +381,7 @@ static int ksz_setup(struct dsa_switch *ds)
/* accept packet up to 2000bytes */
ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true);
 
-   ksz_config_cpu_port(ds);
+   ksz9477_config_cpu_port(ds);
 
ksz_cfg(dev, REG_SW_MAC_CTRL_1, MULTICAST_STORM_DISABLE, true);
 
@@ -395,13 +394,13 @@ static int ksz_setup(struct dsa_switch *ds)
return 0;
 }
 
-static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds,
- int port)
+static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,
+ int port)
 {
return DSA_TAG_PROTO_KSZ;
 }
 
-static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
+static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
 {
struct ksz_device *dev = ds->priv;
u16 val = 0;
@@ -411,7 +410,8 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, 
int reg)
return val;
 }
 
-static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
+static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg,
+  u16 val)
 {
struct ksz_device *dev = ds->priv;
 
@@ -426,7 +426,7 @@ static int ksz_enable_port(struct dsa_switch *ds, int port,
struct ksz_device *dev = ds->priv;
 
/* setup slave port */
-   port_setup(dev, port, false);
+   ksz9477_port_setup(dev, port, false);
 
return 0;
 }
@@ -445,7 +445,7 @@ static int ksz_sset_count(struct dsa_switch *ds)
return TOTAL_SWITCH_COUNTER_NUM;
 }
 
-static void ksz_get_strings(struct dsa_switch *ds, int port, uint8_t *buf)
+static void ksz9477_get_strings(struct dsa_switch *ds, int port, uint8_t *buf)
 {
int i;
 
@@ -495,7 +495,8 @@ static void ksz_get_ethtool_stats(struct dsa_switch *ds, 
int port,
mutex_unlock(>stats_mutex);
 }
 
-static void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
+  u8 state)
 {
struct ksz_device *dev = ds->priv;
u8 data;
@@ -540,7 +541,8 @@ static void ksz_port_fast_age(struct dsa_switch *ds, int 
port)
ksz_write8(dev, REG_SW_LUE_CTRL_1, data8);
 }
 
-static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag)
+static int ksz9477_port_vlan_filtering(struct 

[PATCH v1 net-next 1/7] net: dsa: microchip: Replace license with GPL

2017-11-16 Thread Tristram.Ha
From: Tristram Ha 

Replace license with GPL.

Signed-off-by: Tristram Ha 
Reviewed-by: Woojung Huh 
---
 drivers/net/dsa/microchip/ksz_9477_reg.h | 23 ---
 drivers/net/dsa/microchip/ksz_common.c   | 23 ---
 drivers/net/dsa/microchip/ksz_priv.h | 23 ---
 drivers/net/dsa/microchip/ksz_spi.c  | 23 ---
 4 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz_9477_reg.h
index 6aa6752..26a0e4b 100644
--- a/drivers/net/dsa/microchip/ksz_9477_reg.h
+++ b/drivers/net/dsa/microchip/ksz_9477_reg.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ9477 register definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #ifndef __KSZ9477_REGS_H
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index b5be93a..ed67ef6 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1,19 +1,20 @@
 /*
  * Microchip switch driver main logic
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #include 
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 2a98dbd..d461468 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ series switch common definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 

RE: Microchip KSZ* DSA drivers Re: [PATCH v1 RFC 1/1] Add Microchip KSZ8795 DSA driver

2017-11-13 Thread Tristram.Ha
> Subject: Microchip KSZ* DSA drivers Re: [PATCH v1 RFC 1/1] Add Microchip
> KSZ8795 DSA driver
> 
> Hi!
> 
> Are there any news here? Is there new release planned? Is there a git
> tree somewhere? I probably should get it working, soon.. so I guess I
> can help with testing.
> 

Reviewed patches will be submitted formally to net-next within this week.

BTW, how is the KSZ8895 driver working for you?  Are there some issues that
prevent you from using it?



RE: [PATCH v1 RFC 7/7] Modify tag_ksz.c so that tail tag code can be used by other KSZ switch drivers

2017-10-18 Thread Tristram.Ha
> > +#define KSZ9477_INGRESS_TAG_LEN2
> > +#define KSZ9477_PTP_TAG_LEN4
> > +#define KSZ9477_PTP_TAG_INDICATION 0x80
> > +
> > +#define KSZ9477_TAIL_TAG_OVERRIDE  BIT(9)
> > +#define KSZ9477_TAIL_TAG_LOOKUPBIT(10)
> > +
> > +static int ksz9477_get_tag(u8 *tag, int *port)
> > +{
> > +   int len = KSZ_EGRESS_TAG_LEN;
> > +
> > +   /* Extra 4-bytes PTP timestamp */
> > +   if (tag[0] & KSZ9477_PTP_TAG_INDICATION)
> > +   len += KSZ9477_PTP_TAG_LEN;
> > +   *port = tag[0] & 7;
> > +   return len;
> > +}
> > +
> > +static void ksz9477_set_tag(void *ptr, u8 *addr, int p)
> > +{
> > +   u16 *tag = (u16 *)ptr;
> > +
> > +   *tag = 1 << p;
> > +   if (!memcmp(addr, special_mult_addr, ETH_ALEN))
> > +   *tag |= KSZ9477_TAIL_TAG_OVERRIDE;
> > +   *tag = cpu_to_be16(*tag);
> > +}
> 
> These are new features that were not there before, right?

Although it is the correct procedure, they will be removed until
this tail tag code has access to the main switch driver.



RE: [PATCH v1 RFC 1/1] Add Microchip KSZ8795 DSA driver

2017-10-18 Thread Tristram.Ha
> > +static void ksz8795_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
> > + u64 *cnt)
> > +{
> > +   u32 data;
> > +   u16 ctrl_addr;
> > +   u8 check;
> > +   int loop;
> > +
> > +   ctrl_addr = addr + SWITCH_COUNTER_NUM * port;
> > +   ctrl_addr |= IND_ACC_TABLE(TABLE_MIB | TABLE_READ);
> > +
> > +   mutex_lock(>alu_mutex);
> > +   ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
> > +
> > +   /* It is almost guaranteed to always read the valid bit because of
> > +* slow SPI speed.
> > +*/
> > +   for (loop = 2; loop > 0; loop--) {
> > +   ksz_read8(dev, REG_IND_MIB_CHECK, );
> > +
> > +   if (check & MIB_COUNTER_VALID) {
> > +   ksz_read32(dev, REG_IND_DATA_LO, );
> > +   if (check & MIB_COUNTER_OVERFLOW)
> > +   *cnt += MIB_COUNTER_VALUE + 1;
> > +   *cnt += data & MIB_COUNTER_VALUE;
> > +   break;
> > +   }
> > +   }
> 
> Hmm. Maybe, but should not this at least warn if if it can not get
> valid counter?
>

The checking of valid bit is implemented because of the chip datasheet.
But in my experience it never happens.   A warning will be added, although I
do not see any benefit of it.  It this warning ever comes up it just means
somehow the SPI access is completely broken down.
 
> > +   /* It is almost guaranteed to always read the valid bit because of
> > +* slow SPI speed.
> > +*/
> > +   for (loop = 2; loop > 0; loop--) {
> > +   ksz_read8(dev, REG_IND_MIB_CHECK, );
> > +
> > +   if (check & MIB_COUNTER_VALID) {
> > +   ksz_read32(dev, REG_IND_DATA_LO, );
> > +   if (addr < 2) {
> > +   u64 total;
> > +
> > +   total = check & MIB_TOTAL_BYTES_H;
> > +   total <<= 32;
> > +   *cnt += total;
> > +   *cnt += data;
> > +   if (check & MIB_COUNTER_OVERFLOW) {
> > +   total = MIB_TOTAL_BYTES_H + 1;
> > +   total <<= 32;
> > +   *cnt += total;
> > +   }
> > +   } else {
> > +   if (check & MIB_COUNTER_OVERFLOW)
> > +   *cnt += MIB_PACKET_DROPPED + 1;
> > +   *cnt += data & MIB_PACKET_DROPPED;
> > +   }
> > +   break;
> > +   }
> > +   }
> 
> Same here. Plus, is overflow handling correct? There may be more than
> MIB_PACKET_DROPPED + 1 packets dropped between the checks.
> 

MIB_PACKET_DROPPED is the maximum count like 0x.  Plus 1 means 0x1.
It is assumed the checking should be done fast enough  to avoid overflow.  This 
is
just assuming one overflow has been missed.  To tell you the truth this code is
never checked for correctness.

> > +static void ksz8795_r_table(struct ksz_device *dev, int table, u16 addr,
> > +   u64 *data)
> > +{
> > +   u16 ctrl_addr;
> > +
> > +   ctrl_addr = IND_ACC_TABLE(table | TABLE_READ) | addr;
> > +
> > +   mutex_lock(>alu_mutex);
> > +   ksz_write16(dev, REG_IND_CTRL_0, ctrl_addr);
> > +   ksz_get(dev, REG_IND_DATA_HI, data, sizeof(u64));
> > +   mutex_unlock(>alu_mutex);
> > +   *data = be64_to_cpu(*data);
> > +}
> 
> It would be a tiny bit nicer to have be64 temporary variable and use
> it; having *data change endianness at runtime is "interesting".

> > +   /* At least one valid entry in the table. */
> > +   } else {
> > +   u64 buf;
> > +   int cnt;
> > +
> > +   ksz_get(dev, REG_IND_DATA_HI, , sizeof(buf));
> > +   buf = be64_to_cpu(buf);
> 
> Would it make sense to convert endianness inside ksz_get?

The ksz_get function utilizes the chip's capability to automatically
increase the register index so that their values can be retrieved in
one SPI transfer.  It is mostly used for debugging for dumping chip
registers or programming MAC address (6 bytes).  Here it is also used for
reading 8 bytes.  If you do not want to see the conversion then another
access functions like ksz_read64 and ksz_write64 will need to be implemented.



RE: [PATCH v1 RFC 1/7] Replace license with GPL

2017-10-09 Thread Tristram.Ha
> From: tristram...@microchip.com
> > Sent: 06 October 2017 21:33
> > Replace license with GPL.
> 
> Don't you need permission from all the people who have updated
> the files in order to make this change?
> 
>   David

I am a little confused by your comment.  The 4 original KSZ9477 DSA
driver files were written by Woojung at Microchip Technology Inc.
There was a complaint the "AS IS" license is not exactly GPL.

It should be submitted formally to net-next instead of a RFC, but it
is probably pointless to do that when there is no code change.

I am hoping these drastic changes of KSZ9477 driver can be accepted
so that the patches can be submitted formally to net-next.



RE: [PATCH v1 RFC 1/1] Add Microchip KSZ8795 DSA driver

2017-10-09 Thread Tristram.Ha
> in previous version I see that transit traffic (ping) goes to cpu,
> then from cpu back to destination port. I.e. it works but with cpu
> involving. Is this version supposed to work like that?

Yes, it works in the old DSA way such that a software bridge is
responsible to forward every packet.

Now if the ksz_update_port_member function is called inside
the ksz8795_port_stp_state_set function the switch will forward
packets itself.  Because of that the offload_fwd_mark bit should be
set in the socket buffer so that the software bridge does not
forward the packet (mostly multicast) again.  However, that
indication cannot be set in the switch driver but in the tail tag code
in tag_ksz.c.  Right now there is no easy way for that code to know
the bit should be set because the switch is in forwarding mode.



[PATCH v1 RFC 0/7] Modify KSZ9477 DSA driver in preparation to add other KSZ switch drivers

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

This series of patches is to modify the original KSZ9477 DSA driver so
that other KSZ switch drivers can be added and use the common code.

There are several steps to accomplish this achievement.  First is to
rename some function names with a prefix to indicate chip specific
function.  Second is to move common code into header that can be shared.
Last is to modify tag_ksz.c so that it can handle many tail tag formats
used by different KSZ switch drivers.

ksz_common.c will contain the common code used by all KSZ switch drivers.
ksz9477.c will contain KSZ9477 code from the original ksz_common.c.
ksz9477_spi.c is renamed from ksz_spi.c.
ksz9477_reg.h is renamed from ksz_9477_reg.h.
ksz_common.h is added to provide common code access to KSZ switch
drivers.
ksz_spi.h is added to provide common SPI access functions to KSZ SPI
drivers.

v1
- Each patch in the set is self-contained
- Use ksz9477 prefix to indicate KSZ9477 specific code
- Simplify MIB counter reading code
- Switch driver code is not accessed from tag_ksz.c

Tristram Ha (7):
  Replace license with GPL.
  Clean up code according to patch check suggestions.
  Rename some functions with ksz9477 prefix to separate chip specific
code from common code.
  Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to
add more KSZ switch drivers.
  Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.  Add common functions in ksz_common.h so that other
KSZ switch drivers can access code in ksz_common.c.  Add ksz_spi.h
for common functions used by KSZ switch SPI drivers.
  Add MIB counter reading support.  Rename ksz_9477_reg.h to
ksz9477_reg.h for consistency as the product name is always KSZ.
Header file ksz_priv.h no longer contains any chip specific data.
  Modify tag_ksz.c so that tail tag code can be used by other KSZ switch
drivers.

 drivers/net/dsa/microchip/Kconfig  |   14 +-
 drivers/net/dsa/microchip/Makefile |4 +-
 drivers/net/dsa/microchip/ksz9477.c| 1376 
 .../microchip/{ksz_9477_reg.h => ksz9477_reg.h}|   23 +-
 drivers/net/dsa/microchip/ksz9477_spi.c|  188 +++
 drivers/net/dsa/microchip/ksz_common.c | 1210 -
 drivers/net/dsa/microchip/ksz_common.h |  234 
 drivers/net/dsa/microchip/ksz_priv.h   |  258 ++--
 drivers/net/dsa/microchip/ksz_spi.c|  216 ---
 drivers/net/dsa/microchip/ksz_spi.h|   82 ++
 include/net/dsa.h  |2 +-
 net/dsa/Kconfig|4 +
 net/dsa/dsa.c  |4 +-
 net/dsa/dsa_priv.h |2 +-
 net/dsa/tag_ksz.c  |  107 +-
 15 files changed, 2331 insertions(+), 1393 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (98%)
 create mode 100644 drivers/net/dsa/microchip/ksz9477_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 delete mode 100644 drivers/net/dsa/microchip/ksz_spi.c
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

-- 
1.9.1



[PATCH v1 RFC 1/7] Replace license with GPL

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Replace license with GPL.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz_9477_reg.h | 23 ---
 drivers/net/dsa/microchip/ksz_common.c   | 23 ---
 drivers/net/dsa/microchip/ksz_priv.h | 23 ---
 drivers/net/dsa/microchip/ksz_spi.c  | 23 ---
 4 files changed, 48 insertions(+), 44 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_9477_reg.h 
b/drivers/net/dsa/microchip/ksz_9477_reg.h
index 6aa6752..26a0e4b 100644
--- a/drivers/net/dsa/microchip/ksz_9477_reg.h
+++ b/drivers/net/dsa/microchip/ksz_9477_reg.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ9477 register definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #ifndef __KSZ9477_REGS_H
diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 56cd6d3..685dafd 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -1,19 +1,20 @@
 /*
  * Microchip switch driver main logic
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
  */
 
 #include 
diff --git a/drivers/net/dsa/microchip/ksz_priv.h 
b/drivers/net/dsa/microchip/ksz_priv.h
index 2a98dbd..d461468 100644
--- a/drivers/net/dsa/microchip/ksz_priv.h
+++ b/drivers/net/dsa/microchip/ksz_priv.h
@@ -1,19 +1,20 @@
 /*
  * Microchip KSZ series switch common definitions
  *
- * Copyright (C) 2017
+ * Copyright (C) 2017 Microchip Technology Inc.
  *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
+ * 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.
  *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL 

[PATCH v1 RFC 2/7] Clean up code according to patch check suggestions

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Clean up code according to patch check suggestions.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz_common.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index 685dafd..d72aad7 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -898,9 +898,9 @@ static void ksz_port_mdb_add(struct dsa_switch *ds, int 
port,
 
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
@@ -971,9 +971,9 @@ static int ksz_port_mdb_del(struct dsa_switch *ds, int port,
if (static_table[0] & ALU_V_STATIC_VALID) {
/* check this has same vid & mac address */
 
-   if (((static_table[2] >> ALU_V_FID_S) == (mdb->vid)) &&
+   if (((static_table[2] >> ALU_V_FID_S) == mdb->vid) &&
((static_table[2] & ALU_V_MAC_ADDR_HI) == mac_hi) &&
-   (static_table[3] == mac_lo)) {
+   static_table[3] == mac_lo) {
/* found matching one */
break;
}
-- 
1.9.1



[PATCH v1 RFC 3/7] Rename some functions with ksz9477 prefix

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Rename some functions with ksz9477 prefix to separate chip specific code
from common code.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz_common.c | 116 +
 1 file changed, 59 insertions(+), 57 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c 
b/drivers/net/dsa/microchip/ksz_common.c
index d72aad7..7a0d10f 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -265,9 +265,8 @@ static int wait_alu_sta_ready(struct ksz_device *dev, u32 
waiton, int timeout)
return 0;
 }
 
-static int ksz_reset_switch(struct dsa_switch *ds)
+static int ksz9477_reset_switch(struct ksz_device *dev)
 {
-   struct ksz_device *dev = ds->priv;
u8 data8;
u16 data16;
u32 data32;
@@ -300,7 +299,7 @@ static int ksz_reset_switch(struct dsa_switch *ds)
return 0;
 }
 
-static void port_setup(struct ksz_device *dev, int port, bool cpu_port)
+static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
 {
u8 data8;
u16 data16;
@@ -346,7 +345,7 @@ static void port_setup(struct ksz_device *dev, int port, 
bool cpu_port)
ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, );
 }
 
-static void ksz_config_cpu_port(struct dsa_switch *ds)
+static void ksz9477_config_cpu_port(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int i;
@@ -358,12 +357,12 @@ static void ksz_config_cpu_port(struct dsa_switch *ds)
dev->cpu_port = i;
 
/* enable cpu port */
-   port_setup(dev, i, true);
+   ksz9477_port_setup(dev, i, true);
}
}
 }
 
-static int ksz_setup(struct dsa_switch *ds)
+static int ksz9477_setup(struct dsa_switch *ds)
 {
struct ksz_device *dev = ds->priv;
int ret = 0;
@@ -373,7 +372,7 @@ static int ksz_setup(struct dsa_switch *ds)
if (!dev->vlan_cache)
return -ENOMEM;
 
-   ret = ksz_reset_switch(ds);
+   ret = ksz9477_reset_switch(dev);
if (ret) {
dev_err(ds->dev, "failed to reset switch\n");
return ret;
@@ -382,7 +381,7 @@ static int ksz_setup(struct dsa_switch *ds)
/* accept packet up to 2000bytes */
ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true);
 
-   ksz_config_cpu_port(ds);
+   ksz9477_config_cpu_port(ds);
 
ksz_cfg(dev, REG_SW_MAC_CTRL_1, MULTICAST_STORM_DISABLE, true);
 
@@ -395,12 +394,12 @@ static int ksz_setup(struct dsa_switch *ds)
return 0;
 }
 
-static enum dsa_tag_protocol ksz_get_tag_protocol(struct dsa_switch *ds)
+static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds)
 {
return DSA_TAG_PROTO_KSZ;
 }
 
-static int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg)
+static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
 {
struct ksz_device *dev = ds->priv;
u16 val = 0;
@@ -410,7 +409,8 @@ static int ksz_phy_read16(struct dsa_switch *ds, int addr, 
int reg)
return val;
 }
 
-static int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val)
+static int ksz9477_phy_write16(struct dsa_switch *ds, int addr, int reg,
+  u16 val)
 {
struct ksz_device *dev = ds->priv;
 
@@ -425,7 +425,7 @@ static int ksz_enable_port(struct dsa_switch *ds, int port,
struct ksz_device *dev = ds->priv;
 
/* setup slave port */
-   port_setup(dev, port, false);
+   ksz9477_port_setup(dev, port, false);
 
return 0;
 }
@@ -444,7 +444,7 @@ static int ksz_sset_count(struct dsa_switch *ds)
return TOTAL_SWITCH_COUNTER_NUM;
 }
 
-static void ksz_get_strings(struct dsa_switch *ds, int port, uint8_t *buf)
+static void ksz9477_get_strings(struct dsa_switch *ds, int port, uint8_t *buf)
 {
int i;
 
@@ -494,7 +494,8 @@ static void ksz_get_ethtool_stats(struct dsa_switch *ds, 
int port,
mutex_unlock(>stats_mutex);
 }
 
-static void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port,
+  u8 state)
 {
struct ksz_device *dev = ds->priv;
u8 data;
@@ -539,7 +540,8 @@ static void ksz_port_fast_age(struct dsa_switch *ds, int 
port)
ksz_write8(dev, REG_SW_LUE_CTRL_1, data8);
 }
 
-static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, bool flag)
+static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
+  bool flag)
 {
struct ksz_device *dev = ds->priv;
 
@@ -567,9 +569,9 @@ static int ksz_port_vlan_prepare(struct dsa_switch *ds, int 
port,
return 0;
 }
 
-static void ksz_port_vlan_add(struct dsa_switch *ds, int port,
-

[PATCH v1 RFC 4/7] Rename ksz_spi.c to ksz9477_spi.c

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Rename ksz_spi.c to ksz9477_spi.c and update Kconfig in preparation to add
more KSZ switch drivers.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/Kconfig  | 12 ++--
 drivers/net/dsa/microchip/Makefile |  4 ++--
 drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} |  0
 3 files changed, 8 insertions(+), 8 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_spi.c => ksz9477_spi.c} (100%)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index a8b8f59..5a8660d 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,12 +1,12 @@
-menuconfig MICROCHIP_KSZ
-   tristate "Microchip KSZ series switch support"
+menuconfig MICROCHIP_KSZ9477
+   tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
select NET_DSA_TAG_KSZ
help
- This driver adds support for Microchip KSZ switch chips.
+ This driver adds support for Microchip KSZ9477 switch chips.
 
-config MICROCHIP_KSZ_SPI_DRIVER
-   tristate "KSZ series SPI connected switch driver"
-   depends on MICROCHIP_KSZ && SPI
+config MICROCHIP_KSZ9477_SPI_DRIVER
+   tristate "KSZ9477 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index ed335e2..5b6325b 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ)+= ksz_common.o
-obj-$(CONFIG_MICROCHIP_KSZ_SPI_DRIVER) += ksz_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz_spi.c 
b/drivers/net/dsa/microchip/ksz9477_spi.c
similarity index 100%
rename from drivers/net/dsa/microchip/ksz_spi.c
rename to drivers/net/dsa/microchip/ksz9477_spi.c
-- 
1.9.1



[PATCH v1 RFC 5/7] Break KSZ9477 DSA driver into two files

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Break KSZ9477 DSA driver into two files in preparation to add more KSZ
switch drivers.
Add common functions in ksz_common.h so that other KSZ switch drivers
can access code in ksz_common.c.
Add ksz_spi.h for common functions used by KSZ switch SPI drivers.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/Makefile  |2 +-
 drivers/net/dsa/microchip/ksz9477.c | 1328 +++
 drivers/net/dsa/microchip/ksz9477_spi.c |  143 ++--
 drivers/net/dsa/microchip/ksz_common.c  | 1133 +++---
 drivers/net/dsa/microchip/ksz_common.h  |  230 ++
 drivers/net/dsa/microchip/ksz_priv.h|  229 +++---
 drivers/net/dsa/microchip/ksz_spi.h |   82 ++
 7 files changed, 1926 insertions(+), 1221 deletions(-)
 create mode 100644 drivers/net/dsa/microchip/ksz9477.c
 create mode 100644 drivers/net/dsa/microchip/ksz_common.h
 create mode 100644 drivers/net/dsa/microchip/ksz_spi.h

diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 5b6325b..13dd8f0 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,2 @@
-obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz9477.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
new file mode 100644
index 000..214d380
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -0,0 +1,1328 @@
+/*
+ * Microchip KSZ9477 switch driver main logic
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz_9477_reg.h"
+
+static const struct {
+   int index;
+   char string[ETH_GSTRING_LEN];
+} mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { 0x00, "rx_hi" },
+   { 0x01, "rx_undersize" },
+   { 0x02, "rx_fragments" },
+   { 0x03, "rx_oversize" },
+   { 0x04, "rx_jabbers" },
+   { 0x05, "rx_symbol_err" },
+   { 0x06, "rx_crc_err" },
+   { 0x07, "rx_align_err" },
+   { 0x08, "rx_mac_ctrl" },
+   { 0x09, "rx_pause" },
+   { 0x0A, "rx_bcast" },
+   { 0x0B, "rx_mcast" },
+   { 0x0C, "rx_ucast" },
+   { 0x0D, "rx_64_or_less" },
+   { 0x0E, "rx_65_127" },
+   { 0x0F, "rx_128_255" },
+   { 0x10, "rx_256_511" },
+   { 0x11, "rx_512_1023" },
+   { 0x12, "rx_1024_1522" },
+   { 0x13, "rx_1523_2000" },
+   { 0x14, "rx_2001" },
+   { 0x15, "tx_hi" },
+   { 0x16, "tx_late_col" },
+   { 0x17, "tx_pause" },
+   { 0x18, "tx_bcast" },
+   { 0x19, "tx_mcast" },
+   { 0x1A, "tx_ucast" },
+   { 0x1B, "tx_deferred" },
+   { 0x1C, "tx_total_col" },
+   { 0x1D, "tx_exc_col" },
+   { 0x1E, "tx_single_col" },
+   { 0x1F, "tx_mult_col" },
+   { 0x80, "rx_total" },
+   { 0x81, "tx_total" },
+   { 0x82, "rx_discards" },
+   { 0x83, "tx_discards" },
+};
+
+static void ksz_cfg32(struct ksz_device *dev, u32 addr, u32 bits, bool set)
+{
+   u32 data;
+
+   ksz_read32(dev, addr, );
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+   ksz_write32(dev, addr, data);
+}
+
+static void ksz_port_cfg32(struct ksz_device *dev, int port, int offset,
+  u32 bits, bool set)
+{
+   u32 addr;
+   u32 data;
+
+   addr = PORT_CTRL_ADDR(port, offset);
+   ksz_read32(dev, addr, );
+
+   if (set)
+   data |= bits;
+   else
+   data &= ~bits;
+
+   ksz_write32(dev, addr, data);
+}
+
+static int wait_vlan_ctrl_ready(struct ksz_device *dev, u32 waiton, int 
timeout)
+{
+   u8 data;
+
+   do {
+   ksz_read8(dev, REG_SW_VLAN_CTRL, );
+   if (!(data & waiton))
+   break;
+   usleep_range(1, 10);
+   } while (timeout-- > 0);
+
+   if (timeout <= 0)
+   return -ETIMEDOUT;
+
+   return 0;
+}
+
+static int get_vlan_table(struct dsa_switch *ds, u16 vid, u32 

[PATCH v1 RFC 0/1] Add Microchip KSZ8795 DSA driver

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

This patch requires the previous patches for Microchip KSZ9477 DSA driver.

v1
- Return error codes instead of numbers
- Add more comments to clarify operation
- Use ksz8795 prefix to indicate KSZ8795 specific code
- Simplify MIB counter reading code
- Switch driver code is not accessed from tag_ksz.c

Tristram Ha (1):
  Add Microchip KSZ8795 DSA driver.

 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8795.c | 1372 +++
 drivers/net/dsa/microchip/ksz8795_reg.h | 1016 +++
 drivers/net/dsa/microchip/ksz8795_spi.c |  166 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 include/net/dsa.h   |1 +
 net/dsa/Kconfig |4 +
 net/dsa/dsa.c   |3 +
 net/dsa/dsa_priv.h  |1 +
 net/dsa/tag_ksz.c   |   37 +
 11 files changed, 2620 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8795.c
 create mode 100644 drivers/net/dsa/microchip/ksz8795_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8795_spi.c

-- 
1.9.1



[PATCH RFC] Add Microchip KSZ8895 DSA driver

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Add Microchip KSZ8895 DSA driver.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8895.c | 1288 +++
 drivers/net/dsa/microchip/ksz8895_reg.h |  824 
 drivers/net/dsa/microchip/ksz8895_spi.c |  157 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 6 files changed, 2289 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8895.c
 create mode 100644 drivers/net/dsa/microchip/ksz8895_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8895_spi.c

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index cb95d3d..b854c4b 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -27,3 +27,20 @@ config MICROCHIP_KSZ8795_SPI_DRIVER
 
  It is required to use the KSZ8795 switch driver as the only access
  is through SPI.
+
+menuconfig MICROCHIP_KSZ8895
+   tristate "Microchip KSZ8895 series switch support"
+   depends on NET_DSA
+   select NET_DSA_TAG_KSZ8795
+   help
+ This driver adds support for Microchip KSZ8895 switch chips.
+
+config MICROCHIP_KSZ8895_SPI_DRIVER
+   tristate "KSZ8895 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ8895 && SPI
+   default y
+   help
+ This driver accesses KSZ8895 chip through SPI.
+
+ It is required to use the KSZ8895 switch driver as the only access
+ is through SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 99a283e..8dd6312 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -2,3 +2,5 @@ obj-$(CONFIG_MICROCHIP_KSZ9477) += ksz9477.o 
ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
 obj-$(CONFIG_MICROCHIP_KSZ8795)+= ksz8795.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ8795_SPI_DRIVER) += ksz8795_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ8895)+= ksz8895.o ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ8895_SPI_DRIVER) += ksz8895_spi.o
diff --git a/drivers/net/dsa/microchip/ksz8895.c 
b/drivers/net/dsa/microchip/ksz8895.c
new file mode 100644
index 000..947638b
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz8895.c
@@ -0,0 +1,1288 @@
+/*
+ * Microchip KSZ8895 switch driver
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ * Tristram Ha 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz8895_reg.h"
+
+static const struct {
+   char string[ETH_GSTRING_LEN];
+} mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { "rx" },
+   { "rx_hi" },
+   { "rx_undersize" },
+   { "rx_fragments" },
+   { "rx_oversize" },
+   { "rx_jabbers" },
+   { "rx_symbol_err" },
+   { "rx_crc_err" },
+   { "rx_align_err" },
+   { "rx_mac_ctrl" },
+   { "rx_pause" },
+   { "rx_bcast" },
+   { "rx_mcast" },
+   { "rx_ucast" },
+   { "rx_64_or_less" },
+   { "rx_65_127" },
+   { "rx_128_255" },
+   { "rx_256_511" },
+   { "rx_512_1023" },
+   { "rx_1024_1522" },
+   { "tx" },
+   { "tx_hi" },
+   { "tx_late_col" },
+   { "tx_pause" },
+   { "tx_bcast" },
+   { "tx_mcast" },
+   { "tx_ucast" },
+   { "tx_deferred" },
+   { "tx_total_col" },
+   { "tx_exc_col" },
+   { "tx_single_col" },
+   { "tx_mult_col" },
+   { "rx_discards" },
+   { "tx_discards" },
+};
+
+static int ksz8895_reset_switch(struct ksz_device *dev)
+{
+   /* reset switch */
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1,
+  SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
+
+   return 0;
+}
+
+static void ksz8895_set_prio_queue(struct ksz_device *dev, int port, int queue)
+{
+   u8 hi;
+   u8 lo;
+
+   /* Number of queues can only be 1, 2, or 4. */
+   switch (queue) {
+   case 4:
+   case 3:
+   queue = 

[PATCH v1 RFC 6/7] Add MIB counter reading support

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Add MIB counter reading support.
Rename ksz_9477_reg.h to ksz9477_reg.h for consistency as the product
name is always KSZ.
Header file ksz_priv.h no longer contains any chip specific data.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/ksz9477.c| 130 ++---
 .../microchip/{ksz_9477_reg.h => ksz9477_reg.h}|   0
 drivers/net/dsa/microchip/ksz_common.c | 122 +++
 drivers/net/dsa/microchip/ksz_common.h |   4 +
 drivers/net/dsa/microchip/ksz_priv.h   |   8 +-
 5 files changed, 219 insertions(+), 45 deletions(-)
 rename drivers/net/dsa/microchip/{ksz_9477_reg.h => ksz9477_reg.h} (100%)

diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 214d380..9579d03 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -31,7 +31,7 @@
 
 #include "ksz_priv.h"
 #include "ksz_common.h"
-#include "ksz_9477_reg.h"
+#include "ksz9477_reg.h"
 
 static const struct {
int index;
@@ -272,6 +272,74 @@ static int ksz9477_reset_switch(struct ksz_device *dev)
return 0;
 }
 
+static void ksz9477_r_mib_cnt(struct ksz_device *dev, int port, u16 addr,
+ u64 *cnt)
+{
+   u32 data;
+   int timeout;
+
+   /* retain the flush/freeze bit */
+   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4, );
+   data &= MIB_COUNTER_FLUSH_FREEZE;
+
+   data |= MIB_COUNTER_READ;
+   data |= (addr << MIB_COUNTER_INDEX_S);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
+
+   timeout = 1000;
+   do {
+   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+   );
+   usleep_range(1, 10);
+   if (!(data & MIB_COUNTER_READ))
+   break;
+   } while (timeout-- > 0);
+
+   /* failed to read MIB. get out of loop */
+   if (!timeout) {
+   dev_dbg(dev->dev, "Failed to get MIB\n");
+   return;
+   }
+
+   /* count resets upon read */
+   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
+   *cnt += data;
+}
+
+static void ksz9477_r_mib_pkt(struct ksz_device *dev, int port, u16 addr,
+ u64 *dropped, u64 *cnt)
+{
+   addr = mib_names[addr].index;
+   ksz9477_r_mib_cnt(dev, port, addr, cnt);
+}
+
+static void ksz9477_freeze_mib(struct ksz_device *dev, int port, bool freeze)
+{
+   /* enable the port for flush/freeze function */
+   if (freeze)
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+MIB_COUNTER_FLUSH_FREEZE);
+   ksz_cfg(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FREEZE, freeze);
+
+   /* disable the port after freeze is done */
+   if (!freeze)
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0);
+}
+
+static void ksz9477_port_init_cnt(struct ksz_device *dev, int port)
+{
+   struct ksz_port_mib *mib = >ports[port].mib;
+
+   /* flush all enabled port MIB counters */
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
+MIB_COUNTER_FLUSH_FREEZE);
+   ksz_write8(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FLUSH);
+   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, 0);
+
+   mib->cnt_ptr = 0;
+   memset(mib->counters, 0, dev->mib_cnt * sizeof(u64));
+}
+
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds)
 {
return DSA_TAG_PROTO_KSZ;
@@ -350,46 +418,6 @@ static void ksz9477_get_strings(struct dsa_switch *ds, int 
port, uint8_t *buf)
}
 }
 
-static void ksz_get_ethtool_stats(struct dsa_switch *ds, int port,
- uint64_t *buf)
-{
-   struct ksz_device *dev = ds->priv;
-   int i;
-   u32 data;
-   int timeout;
-
-   mutex_lock(>stats_mutex);
-
-   for (i = 0; i < TOTAL_SWITCH_COUNTER_NUM; i++) {
-   data = MIB_COUNTER_READ;
-   data |= ((mib_names[i].index & 0xFF) << MIB_COUNTER_INDEX_S);
-   ksz_pwrite32(dev, port, REG_PORT_MIB_CTRL_STAT__4, data);
-
-   timeout = 1000;
-   do {
-   ksz_pread32(dev, port, REG_PORT_MIB_CTRL_STAT__4,
-   );
-   usleep_range(1, 10);
-   if (!(data & MIB_COUNTER_READ))
-   break;
-   } while (timeout-- > 0);
-
-   /* failed to read MIB. get out of loop */
-   if (!timeout) {
-   dev_dbg(dev->dev, "Failed to get MIB\n");
-   break;
-   }
-
-   /* count resets upon read */
-   ksz_pread32(dev, port, REG_PORT_MIB_DATA, );
-
-   dev->mib_value[i] += (uint64_t)data;
-   buf[i] = dev->mib_value[i];
- 

[PATCH RFC 0/1] Add Microchip KSZ8895 DSA driver

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

This patch requires the previous patch for Microchip KSZ8795 DSA driver.

Tristram Ha (1):
  Add Microchip KSZ8895 DSA driver.

 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8895.c | 1288 +++
 drivers/net/dsa/microchip/ksz8895_reg.h |  824 
 drivers/net/dsa/microchip/ksz8895_spi.c |  157 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 6 files changed, 2289 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8895.c
 create mode 100644 drivers/net/dsa/microchip/ksz8895_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8895_spi.c

-- 
1.9.1



[PATCH v1 RFC 1/1] Add Microchip KSZ8795 DSA driver

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Add Microchip KSZ8795 DSA driver.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/Kconfig   |   17 +
 drivers/net/dsa/microchip/Makefile  |2 +
 drivers/net/dsa/microchip/ksz8795.c | 1372 +++
 drivers/net/dsa/microchip/ksz8795_reg.h | 1016 +++
 drivers/net/dsa/microchip/ksz8795_spi.c |  166 
 drivers/net/dsa/microchip/ksz_priv.h|1 +
 include/net/dsa.h   |1 +
 net/dsa/Kconfig |4 +
 net/dsa/dsa.c   |3 +
 net/dsa/dsa_priv.h  |1 +
 net/dsa/tag_ksz.c   |   37 +
 11 files changed, 2620 insertions(+)
 create mode 100644 drivers/net/dsa/microchip/ksz8795.c
 create mode 100644 drivers/net/dsa/microchip/ksz8795_reg.h
 create mode 100644 drivers/net/dsa/microchip/ksz8795_spi.c

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index ab8f9f6..cb95d3d 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -10,3 +10,20 @@ config MICROCHIP_KSZ9477_SPI_DRIVER
depends on MICROCHIP_KSZ9477 && SPI
help
  Select to enable support for registering switches configured through 
SPI.
+
+menuconfig MICROCHIP_KSZ8795
+   tristate "Microchip KSZ8795 series switch support"
+   depends on NET_DSA
+   select NET_DSA_TAG_KSZ8795
+   help
+ This driver adds support for Microchip KSZ8795 switch chips.
+
+config MICROCHIP_KSZ8795_SPI_DRIVER
+   tristate "KSZ8795 series SPI connected switch driver"
+   depends on MICROCHIP_KSZ8795 && SPI
+   default y
+   help
+ This driver accesses KSZ8795 chip through SPI.
+
+ It is required to use the KSZ8795 switch driver as the only access
+ is through SPI.
diff --git a/drivers/net/dsa/microchip/Makefile 
b/drivers/net/dsa/microchip/Makefile
index 13dd8f0..99a283e 100644
--- a/drivers/net/dsa/microchip/Makefile
+++ b/drivers/net/dsa/microchip/Makefile
@@ -1,2 +1,4 @@
 obj-$(CONFIG_MICROCHIP_KSZ9477)+= ksz9477.o ksz_common.o
 obj-$(CONFIG_MICROCHIP_KSZ9477_SPI_DRIVER) += ksz9477_spi.o
+obj-$(CONFIG_MICROCHIP_KSZ8795)+= ksz8795.o ksz_common.o
+obj-$(CONFIG_MICROCHIP_KSZ8795_SPI_DRIVER) += ksz8795_spi.o
diff --git a/drivers/net/dsa/microchip/ksz8795.c 
b/drivers/net/dsa/microchip/ksz8795.c
new file mode 100644
index 000..7e727d3
--- /dev/null
+++ b/drivers/net/dsa/microchip/ksz8795.c
@@ -0,0 +1,1372 @@
+/*
+ * Microchip KSZ8795 switch driver
+ *
+ * Copyright (C) 2017 Microchip Technology Inc.
+ * Tristram Ha 
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "ksz_priv.h"
+#include "ksz_common.h"
+#include "ksz8795_reg.h"
+
+static const struct {
+   char string[ETH_GSTRING_LEN];
+} mib_names[TOTAL_SWITCH_COUNTER_NUM] = {
+   { "rx_hi" },
+   { "rx_undersize" },
+   { "rx_fragments" },
+   { "rx_oversize" },
+   { "rx_jabbers" },
+   { "rx_symbol_err" },
+   { "rx_crc_err" },
+   { "rx_align_err" },
+   { "rx_mac_ctrl" },
+   { "rx_pause" },
+   { "rx_bcast" },
+   { "rx_mcast" },
+   { "rx_ucast" },
+   { "rx_64_or_less" },
+   { "rx_65_127" },
+   { "rx_128_255" },
+   { "rx_256_511" },
+   { "rx_512_1023" },
+   { "rx_1024_1522" },
+   { "rx_1523_2000" },
+   { "rx_2001" },
+   { "tx_hi" },
+   { "tx_late_col" },
+   { "tx_pause" },
+   { "tx_bcast" },
+   { "tx_mcast" },
+   { "tx_ucast" },
+   { "tx_deferred" },
+   { "tx_total_col" },
+   { "tx_exc_col" },
+   { "tx_single_col" },
+   { "tx_mult_col" },
+   { "rx_total" },
+   { "tx_total" },
+   { "rx_discards" },
+   { "tx_discards" },
+};
+
+static int ksz8795_reset_switch(struct ksz_device *dev)
+{
+   /* reset switch */
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1,
+  SW_SOFTWARE_POWER_DOWN << SW_POWER_MANAGEMENT_MODE_S);
+   ksz_write8(dev, REG_POWER_MANAGEMENT_1, 0);
+
+   return 0;
+}
+
+static void 

[PATCH RFC] Add other KSZ switch support so that patch check does not complain

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Add other KSZ switch support so that patch check does not complain.

Signed-off-by: Tristram Ha 
---
 Documentation/devicetree/bindings/net/dsa/ksz.txt | 189 --
 1 file changed, 136 insertions(+), 53 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/dsa/ksz.txt 
b/Documentation/devicetree/bindings/net/dsa/ksz.txt
index fd23904..705f9d9 100644
--- a/Documentation/devicetree/bindings/net/dsa/ksz.txt
+++ b/Documentation/devicetree/bindings/net/dsa/ksz.txt
@@ -3,8 +3,15 @@ Microchip KSZ Series Ethernet switches
 
 Required properties:
 
-- compatible: For external switch chips, compatible string must be exactly one
-  of: "microchip,ksz9477"
+- compatible: "microchip,ksz9477",
+ "microchip,ksz8795",
+ "microchip,ksz8794",
+ "microchip,ksz8765",
+ "microchip,ksz8895",
+ "microchip,ksz8864",
+ "microchip,ksz8873",
+ "microchip,ksz8863",
+ "microchip,ksz8463"
 
 See Documentation/devicetree/bindings/dsa/dsa.txt for a list of additional
 required and optional properties.
@@ -13,58 +20,134 @@ Examples:
 
 Ethernet switch connected via SPI to the host, CPU port wired to eth0:
 
- eth0: ethernet@10001000 {
- fixed-link {
- speed = <1000>;
- full-duplex;
- };
- };
+   eth0: ethernet@10001000 {
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+   };
 
- spi1: spi@f8008000 {
- pinctrl-0 = <_spi_ksz>;
- cs-gpios = < 25 0>;
- id = <1>;
+   spi1: spi@f8008000 {
+   cs-gpios = < 25 0>;
+   id = <1>;
 
- ksz9477: ksz9477@0 {
- compatible = 
"microchip,ksz9477";
- reg = <0>;
+   ksz9477: ksz9477@0 {
+   compatible = "microchip,ksz9477";
+   reg = <0>;
 
- spi-max-frequency 
= <4400>;
- spi-cpha;
- spi-cpol;
+   spi-max-frequency = <4400>;
+   spi-cpha;
+   spi-cpol;
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   port@0 {
+   reg = <0>;
+   label = "lan1";
+   };
+   port@1 {
+   reg = <1>;
+   label = "lan2";
+   };
+   port@2 {
+   reg = <2>;
+   label = "lan3";
+   };
+   port@3 {
+   reg = <3>;
+   label = "lan4";
+   };
+   port@4 {
+   reg = <4>;
+   label = "lan5";
+   };
+   port@5 {
+   reg = <5>;
+   label = "cpu";
+   ethernet = <>;
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+   };
+   port@6 {
+   reg = <6>;
+   label = "lan6";
+   fixed-link {
+   speed = <1000>;
+   full-duplex;
+   };
+   };
+   };
+   };
+   ksz8794: ksz8794@0 {
+   compatible = "microchip,ksz8794";
+   reg = <0>;
+
+   

[PATCH v1 RFC 7/7] Modify tag_ksz.c so that tail tag code can be used by other KSZ switch drivers

2017-10-06 Thread Tristram.Ha
From: Tristram Ha 

Modify tag_ksz.c so that tail tag code can be used by other KSZ switch
drivers.

Signed-off-by: Tristram Ha 
---
 drivers/net/dsa/microchip/Kconfig   |   2 +-
 drivers/net/dsa/microchip/ksz9477.c |   2 +-
 include/net/dsa.h   |   2 +-
 net/dsa/Kconfig |   4 ++
 net/dsa/dsa.c   |   4 +-
 net/dsa/dsa_priv.h  |   2 +-
 net/dsa/tag_ksz.c   | 107 ++--
 7 files changed, 88 insertions(+), 35 deletions(-)

diff --git a/drivers/net/dsa/microchip/Kconfig 
b/drivers/net/dsa/microchip/Kconfig
index 5a8660d..ab8f9f6 100644
--- a/drivers/net/dsa/microchip/Kconfig
+++ b/drivers/net/dsa/microchip/Kconfig
@@ -1,7 +1,7 @@
 menuconfig MICROCHIP_KSZ9477
tristate "Microchip KSZ9477 series switch support"
depends on NET_DSA
-   select NET_DSA_TAG_KSZ
+   select NET_DSA_TAG_KSZ9477
help
  This driver adds support for Microchip KSZ9477 switch chips.
 
diff --git a/drivers/net/dsa/microchip/ksz9477.c 
b/drivers/net/dsa/microchip/ksz9477.c
index 9579d03..e6d2956 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -342,7 +342,7 @@ static void ksz9477_port_init_cnt(struct ksz_device *dev, 
int port)
 
 static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds)
 {
-   return DSA_TAG_PROTO_KSZ;
+   return DSA_TAG_PROTO_KSZ9477;
 }
 
 static int ksz9477_phy_read16(struct dsa_switch *ds, int addr, int reg)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 10dcecc..28cdc5e 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -31,7 +31,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_BRCM,
DSA_TAG_PROTO_DSA,
DSA_TAG_PROTO_EDSA,
-   DSA_TAG_PROTO_KSZ,
+   DSA_TAG_PROTO_KSZ9477,
DSA_TAG_PROTO_LAN9303,
DSA_TAG_PROTO_MTK,
DSA_TAG_PROTO_QCA,
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index cc5f8f9..d2bbd21 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -28,6 +28,10 @@ config NET_DSA_TAG_EDSA
 config NET_DSA_TAG_KSZ
bool
 
+config NET_DSA_TAG_KSZ9477
+   bool
+   select NET_DSA_TAG_KSZ
+
 config NET_DSA_TAG_LAN9303
bool
 
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 51ca2a5..cc03a09 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -49,8 +49,8 @@ static struct sk_buff *dsa_slave_notag_xmit(struct sk_buff 
*skb,
 #ifdef CONFIG_NET_DSA_TAG_EDSA
[DSA_TAG_PROTO_EDSA] = _netdev_ops,
 #endif
-#ifdef CONFIG_NET_DSA_TAG_KSZ
-   [DSA_TAG_PROTO_KSZ] = _netdev_ops,
+#ifdef CONFIG_NET_DSA_TAG_KSZ9477
+   [DSA_TAG_PROTO_KSZ9477] = _netdev_ops,
 #endif
 #ifdef CONFIG_NET_DSA_TAG_LAN9303
[DSA_TAG_PROTO_LAN9303] = _netdev_ops,
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 2850077c..e0dc2d4 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -183,7 +183,7 @@ int dsa_port_vlan_del(struct dsa_port *dp,
 extern const struct dsa_device_ops edsa_netdev_ops;
 
 /* tag_ksz.c */
-extern const struct dsa_device_ops ksz_netdev_ops;
+extern const struct dsa_device_ops ksz9477_netdev_ops;
 
 /* tag_lan9303.c */
 extern const struct dsa_device_ops lan9303_netdev_ops;
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index b241c99..1bb5b7d 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -14,34 +14,28 @@
 #include 
 #include "dsa_priv.h"
 
-/* For Ingress (Host -> KSZ), 2 bytes are added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
- * ---
- * tag0 : Prioritization (not used now)
- * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
- *
- * For Egress (KSZ -> Host), 1 byte is added before FCS.
- * ---
- * DA(6bytes)|SA(6bytes)||Data(nbytes)|tag0(1byte)|FCS(4bytes)
- * ---
- * tag0 : zero-based value represents port
- *   (eg, 0x00=port1, 0x02=port3, 0x06=port7)
- */
+/* Typically only one byte is used for tail tag. */
+#defineKSZ_EGRESS_TAG_LEN  1
+#defineKSZ_INGRESS_TAG_LEN 1
 
-#defineKSZ_INGRESS_TAG_LEN 2
-#defineKSZ_EGRESS_TAG_LEN  1
+/* Frames with following addresse may need to be sent even when the port is
+ * closed.
+ */
+static const u8 special_mult_addr[] = {
+   0x01, 0x80, 0xC2, 0x00, 0x00, 0x00
+};
 
-static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
+static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev,
+   int len,
+   void (*set_tag)(void *ptr, u8 *addr, int p))
 {
   

RE: [PATCH RFC 3/5] Add KSZ8795 switch driver

2017-09-29 Thread Tristram.Ha
> > My concern is if a task is already running with SPI access to a lot
> > of registers like reading the 32 MIB counters in every port of the
> > switch, another register access has to wait until they are finished.
> 
> Why does it have to wait? Looking at the code in
> ksz_get_ethtool_stats(), you don't take any mutex which will prevent
> others from using the SPI bus. All there is is a mutex which prevents
> two sets of ksz_get_ethtool_stats() at the same time.
> 
> So a PTP read could happen in parallel, and will not be blocked by MIB
> reads. They should get interleaved access to the SPI bus.
> 

The MIB counters are read in the background.  For multiple CPU cores 2
tasks may run in the same time allowing SPI access one after another.
For single core I am not sure an SPI access like coming from an interrupt
routine can jump ahead from one in a background task.

I know nowadays SoCs are powerful enough to do amazing things.  It is
just I spent a long time using a low-powered SoC doing switch driver
development.



RE: [PATCH RFC 3/5] Add KSZ8795 switch driver

2017-09-29 Thread Tristram.Ha
> On Mon 2017-09-18 20:27:13, tristram...@microchip.com wrote:
> > > > +/**
> > > > + * Some counters do not need to be read too often because they are
> less
> > > likely
> > > > + * to increase much.
> > > > + */
> > >
> > > What does comment mean? Are you caching statistics, and updating
> > > different values at different rates?
> > >
> >
> > There are 34 counters.  In normal case using generic bus I/O or PCI to read
> them
> > is very quick, but the switch is mostly accessed using SPI, or even I2C.  As
> the SPI
> > access is very slow and cannot run in interrupt context I keep worrying
> reading
> > the MIB counters in a loop for 5 or more ports will prevent other critical
> hardware
> > access from executing soon enough.  These accesses can be getting 1588
> PTP
> > timestamps and opening/closing ports.  (RSTP Conformance Test sends test
> traffic
> > to port supposed to be closed/opened after receiving specific RSTP
> > BPDU.)
> 
> Hmm. Ok, interesting.
> 
> I wonder how well this is going to work if userspace actively 'does
> something' with the switch.
> 
> It seems to me that even if your statistics code is careful not to do
> 'a lot' of accesses at the same time, userspace can use other parts of
> the driver to do the same, and thus cause same unwanted effects...

If the user calls "ethtool -S" in a tight loop the system will waste a lot of
CPU time, but this is more like a user error.
Another solution is not to schedule to read the MIB counters in that
function call.  I think I was doing a favor to update the MIB counters
sooner as the user probably wants to find out what is wrong with the
switch by reading the MIB counters and checking them several times.
For system tracking like SNMP I think it is likely a separate mechanism
is used to gather those information.  If I am wrong that function definitely
needs to be modified.



  1   2   >