Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH bpf-next v5 0/6] xdp: Add devmap_hash map type
From: Toke Høiland-Jørgensen @ 2019-08-09 18:45 UTC (permalink / raw)
  To: Jesper Dangaard Brouer, Y Song
  Cc: Alexei Starovoitov, Daniel Borkmann, Alexei Starovoitov,
	Network Development, David Miller, Jakub Kicinski,
	Björn Töpel, Yonghong Song, brouer
In-Reply-To: <20190808220516.1adeca9a@carbon>

Jesper Dangaard Brouer <brouer@redhat.com> writes:

> On Thu, 8 Aug 2019 12:57:05 -0700
> Y Song <ys114321@gmail.com> wrote:
>
>> On Thu, Aug 8, 2019 at 12:43 PM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>> >
>> > Alexei Starovoitov <alexei.starovoitov@gmail.com> writes:
>> >  
>> > > On Fri, Jul 26, 2019 at 9:06 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:  
>> > >>
>> > >> This series adds a new map type, devmap_hash, that works like the existing
>> > >> devmap type, but using a hash-based indexing scheme. This is useful for the use
>> > >> case where a devmap is indexed by ifindex (for instance for use with the routing
>> > >> table lookup helper). For this use case, the regular devmap needs to be sized
>> > >> after the maximum ifindex number, not the number of devices in it. A hash-based
>> > >> indexing scheme makes it possible to size the map after the number of devices it
>> > >> should contain instead.
>> > >>
>> > >> This was previously part of my patch series that also turned the regular
>> > >> bpf_redirect() helper into a map-based one; for this series I just pulled out
>> > >> the patches that introduced the new map type.
>> > >>
>> > >> Changelog:
>> > >>
>> > >> v5:
>> > >>
>> > >> - Dynamically set the number of hash buckets by rounding up max_entries to the
>> > >>   nearest power of two (mirroring the regular hashmap), as suggested by Jesper.  
>> > >
>> > > fyi I'm waiting for Jesper to review this new version.  
>> >
>> > Ping Jesper? :)  
>> 
>> Toke, the patch set has been merged to net-next.
>> https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=d3406913561c322323ec2898cc58f55e79786be7
>> 
>
> Yes, and I did review this... :-)

Oops, my bad; seems I accidentally muted this thread and didn't see
Jesper's review and Alexei's message about merging it. Sorry about
that...

-Toke

^ permalink raw reply

* Re: [PATCH 3/3] tipc: fix issue of calling smp_processor_id() in preemptible
From: Jakub Kicinski @ 2019-08-09 18:49 UTC (permalink / raw)
  To: Ying Xue; +Cc: davem, netdev, jon.maloy, hdanton, tipc-discussion,
	syzkaller-bugs
In-Reply-To: <1565335017-21302-4-git-send-email-ying.xue@windriver.com>

On Fri, 9 Aug 2019 15:16:57 +0800, Ying Xue wrote:
> Fixes: e9c1a793210f ("tipc: add dst_cache support for udp media")
> syzbot+1a68504d96cd17b33a05@syzkaller.appspotmail.com
 ^
Reported-by: missing here?

> Signed-off-by: Hillf Danton <hdanton@sina.com>
> Signed-off-by: Ying Xue <ying.xue@windriver.com>


^ permalink raw reply

* Re: [net 01/12] net/mlx5e: Use flow keys dissector to parse packets for ARFS
From: Saeed Mahameed @ 2019-08-09 18:49 UTC (permalink / raw)
  To: jakub.kicinski@netronome.com
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Tariq Toukan,
	Maxim Mikityanskiy
In-Reply-To: <20190808181514.4cd68a37@cakuba.netronome.com>

On Thu, 2019-08-08 at 18:15 -0700, Jakub Kicinski wrote:
> On Thu, 8 Aug 2019 20:22:00 +0000, Saeed Mahameed wrote:
> > From: Maxim Mikityanskiy <maximmi@mellanox.com>
> > 
> > The current ARFS code relies on certain fields to be set in the SKB
> > (e.g. transport_header) and extracts IP addresses and ports by
> > custom
> > code that parses the packet. The necessary SKB fields, however, are
> > not
> > always set at that point, which leads to an out-of-bounds access.
> > Use
> > skb_flow_dissect_flow_keys() to get the necessary information
> > reliably,
> > fix the out-of-bounds access and reuse the code.
> 
> The whole series LGTM, FWIW.
> 
> I'd be curious to hear which path does not have the skb fully 
> set up, could you elaborate? (I'm certainly no aRFC expert this
> is pure curiosity).

In our regression we found two use cases that might lead aRFS using un-
initialized values.
1) GRO Disabled, Usually GRO fills the necessary fields.
2) Raw socket type of tests.

And i am sure there are many other use cases. So drivers must use
skb_flow_dissect_flow_keys() for aRFS parsing and eliminate all
uncertainties. 


^ permalink raw reply

* Re: [PATCH net-next] gso: enable udp gso for virtual devices
From: Josh Hunt @ 2019-08-09 18:58 UTC (permalink / raw)
  To: Willem de Bruijn, Jason Baron
  Cc: Alexander Duyck, David Miller, Netdev, Willem de Bruijn,
	Paolo Abeni
In-Reply-To: <CAF=yD-+zYGzTTYC-oYr392qugWiYpbgykMh1p8UrrgZ2ciR=aw@mail.gmail.com>

On 6/26/19 4:41 PM, Willem de Bruijn wrote:
> On Wed, Jun 26, 2019 at 3:17 PM Jason Baron <jbaron@akamai.com> wrote:
>>
>>
>>
>> On 6/14/19 4:53 PM, Jason Baron wrote:
>>>
>>>
>>> On 6/13/19 5:20 PM, Willem de Bruijn wrote:
>>>>>>> @@ -237,6 +237,7 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start)
>>>>>>>                                   NETIF_F_GSO_GRE_CSUM |                 \
>>>>>>>                                   NETIF_F_GSO_IPXIP4 |                   \
>>>>>>>                                   NETIF_F_GSO_IPXIP6 |                   \
>>>>>>> +                                NETIF_F_GSO_UDP_L4 |                   \
>>>>>>>                                   NETIF_F_GSO_UDP_TUNNEL |               \
>>>>>>>                                   NETIF_F_GSO_UDP_TUNNEL_CSUM)
>>>>>>
>>>>>> Are you adding this to NETIF_F_GSO_ENCAP_ALL? Wouldn't it make more
>>>>>> sense to add it to NETIF_F_GSO_SOFTWARE?
>>>>>>
>>>>>
>>>>> Yes, I'm adding to NETIF_F_GSO_ENCAP_ALL (not very clear from the
>>>>> context). I will fix the commit log.
>>>>>
>>>>> In: 83aa025 udp: add gso support to virtual devices, the support was
>>>>> also added to NETIF_F_GSO_ENCAP_ALL (although subsequently reverted due
>>>>> to UDP GRO not being in place), so I wonder what the reason was for that?
>>>>
>>>> That was probably just a bad choice on my part.
>>>>
>>>> It worked in practice, but if NETIF_F_GSO_SOFTWARE works the same
>>>> without unexpected side effects, then I agree that it is the better choice.
>>>>
>>>> That choice does appear to change behavior when sending over tunnel
>>>> devices. Might it send tunneled GSO packets over loopback?
>>>>
>>>>
>>>
>>> I set up a test case using fou tunneling through a bridge device using
>>> the udpgso_bench_tx test where packets are not received correctly if
>>> NETIF_F_GSO_UDP_L4 is added to NETIF_F_GSO_SOFTWARE. If I have it added
>>> to NETIF_F_GSO_ENCAP_ALL, it does work correctly. So there are more
>>> fixes required to include it in NETIF_F_GSO_SOFTWARE.
>>>
>>> The use-case I have only requires it to be in NETIF_F_GSO_ENCAP_ALL, but
>>> if it needs to go in NETIF_F_GSO_SOFTWARE, I can look at what's required
>>> more next week.
>>>
>>
>> Hi,
>>
>> I haven't had a chance to investigate what goes wrong with including
>> NETIF_F_GSO_UDP_L4 in NETIF_F_GSO_SOFTWARE - but I was just wondering if
>> people are ok with NETIF_F_GSO_UDP_L4 being added to
>> NETIF_F_GSO_ENCAP_ALL and not NETIF_F_GSO_SOFTWARE (ie the original
>> patch as posted)?
>>
>> As I mentioned that is sufficient for my use-case, and its how Willem
>> originally proposed this.
> 
> Indeed, based on the previous discussion this sounds fine to me.
> 

Willem

Are you OK to ACK this? If not, is there something else you'd rather see 
here?

Thanks
Josh

^ permalink raw reply

* Re: [net 01/12] net/mlx5e: Use flow keys dissector to parse packets for ARFS
From: Jakub Kicinski @ 2019-08-09 19:01 UTC (permalink / raw)
  To: Saeed Mahameed
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Tariq Toukan,
	Maxim Mikityanskiy
In-Reply-To: <02ebed305b6bb50f272c7f3decfa204dc72311f0.camel@mellanox.com>

On Fri, 9 Aug 2019 18:49:50 +0000, Saeed Mahameed wrote:
> On Thu, 2019-08-08 at 18:15 -0700, Jakub Kicinski wrote:
> > On Thu, 8 Aug 2019 20:22:00 +0000, Saeed Mahameed wrote:  
> > > From: Maxim Mikityanskiy <maximmi@mellanox.com>
> > > 
> > > The current ARFS code relies on certain fields to be set in the SKB
> > > (e.g. transport_header) and extracts IP addresses and ports by
> > > custom
> > > code that parses the packet. The necessary SKB fields, however, are
> > > not
> > > always set at that point, which leads to an out-of-bounds access.
> > > Use
> > > skb_flow_dissect_flow_keys() to get the necessary information
> > > reliably,
> > > fix the out-of-bounds access and reuse the code.  
> > 
> > The whole series LGTM, FWIW.
> > 
> > I'd be curious to hear which path does not have the skb fully 
> > set up, could you elaborate? (I'm certainly no aRFC expert this
> > is pure curiosity).  
> 
> In our regression we found two use cases that might lead aRFS using un-
> initialized values.
> 1) GRO Disabled, Usually GRO fills the necessary fields.
> 2) Raw socket type of tests.
> 
> And i am sure there are many other use cases. So drivers must use
> skb_flow_dissect_flow_keys() for aRFS parsing and eliminate all
> uncertainties. 

Looking at the code now it makes perfect sense. We could probably
refactor to call the dissector in the core at some point.

Thanks for the explanation!

^ permalink raw reply

* Re: [PATCH] dpaa2-ethsw: move the DPAA2 Ethernet Switch driver out of staging
From: Andrew Lunn @ 2019-08-09 19:04 UTC (permalink / raw)
  To: Ioana Ciornei
  Cc: davem, gregkh, linux-kernel, netdev, f.fainelli,
	ruxandra.radulescu
In-Reply-To: <1565366213-20063-1-git-send-email-ioana.ciornei@nxp.com>

Hi Ioana

> +static int
> +ethsw_get_link_ksettings(struct net_device *netdev,
> +			 struct ethtool_link_ksettings *link_ksettings)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	struct dpsw_link_state state = {0};
> +	int err = 0;
> +
> +	err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
> +				     port_priv->ethsw_data->dpsw_handle,
> +				     port_priv->idx,
> +				     &state);
> +	if (err) {
> +		netdev_err(netdev, "ERROR %d getting link state", err);
> +		goto out;
> +	}
> +
> +	/* At the moment, we have no way of interrogating the DPMAC
> +	 * from the DPSW side or there may not exist a DPMAC at all.

What use is a switch port without a MAC?

> +	 * Report only autoneg state, duplexity and speed.
> +	 */
> +	if (state.options & DPSW_LINK_OPT_AUTONEG)
> +		link_ksettings->base.autoneg = AUTONEG_ENABLE;
> +	if (!(state.options & DPSW_LINK_OPT_HALF_DUPLEX))
> +		link_ksettings->base.duplex = DUPLEX_FULL;
> +	link_ksettings->base.speed = state.rate;
> +
> +out:
> +	return err;
> +}
> +
> +static int
> +ethsw_set_link_ksettings(struct net_device *netdev,
> +			 const struct ethtool_link_ksettings *link_ksettings)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	struct dpsw_link_cfg cfg = {0};
> +	int err = 0;
> +
> +	netdev_dbg(netdev, "Setting link parameters...");
> +
> +	/* Due to a temporary MC limitation, the DPSW port must be down
> +	 * in order to be able to change link settings. Taking steps to let
> +	 * the user know that.
> +	 */
> +	if (netif_running(netdev)) {
> +		netdev_info(netdev, "Sorry, interface must be brought down first.\n");
> +		return -EACCES;
> +	}

This is quite common. The Marvell switches require the port is
disabled while reconfiguring the port. So we just disable it,
reconfigure it, and enable it again.

Why are you making the user do this?

> +
> +	cfg.rate = link_ksettings->base.speed;
> +	if (link_ksettings->base.autoneg == AUTONEG_ENABLE)
> +		cfg.options |= DPSW_LINK_OPT_AUTONEG;
> +	else
> +		cfg.options &= ~DPSW_LINK_OPT_AUTONEG;
> +	if (link_ksettings->base.duplex  == DUPLEX_HALF)
> +		cfg.options |= DPSW_LINK_OPT_HALF_DUPLEX;
> +	else
> +		cfg.options &= ~DPSW_LINK_OPT_HALF_DUPLEX;
> +
> +	err = dpsw_if_set_link_cfg(port_priv->ethsw_data->mc_io, 0,
> +				   port_priv->ethsw_data->dpsw_handle,
> +				   port_priv->idx,
> +				   &cfg);
> +	if (err)
> +		/* ethtool will be loud enough if we return an error; no point
> +		 * in putting our own error message on the console by default
> +		 */
> +		netdev_dbg(netdev, "ERROR %d setting link cfg", err);

Why even bother with a dbg message?

> +static void ethsw_ethtool_get_stats(struct net_device *netdev,
> +				    struct ethtool_stats *stats,
> +				    u64 *data)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	int i, err;
> +
> +	memset(data, 0,
> +	       sizeof(u64) * ETHSW_NUM_COUNTERS);

Is this really needed? It seems like the core should be doing this?

> +static int ethsw_add_vlan(struct ethsw_core *ethsw, u16 vid)
> +{
> +	int err;
> +
> +	struct dpsw_vlan_cfg	vcfg = {
> +		.fdb_id = 0,
> +	};
> +
> +	if (ethsw->vlans[vid]) {
> +		dev_err(ethsw->dev, "VLAN already configured\n");
> +		return -EEXIST;
> +	}

Can this happen? It seems like the core should be preventing this.

> +
> +	err = dpsw_vlan_add(ethsw->mc_io, 0,
> +			    ethsw->dpsw_handle, vid, &vcfg);
> +	if (err) {
> +		dev_err(ethsw->dev, "dpsw_vlan_add err %d\n", err);
> +		return err;
> +	}
> +	ethsw->vlans[vid] = ETHSW_VLAN_MEMBER;
> +
> +	return 0;
> +}
> +
> +static int ethsw_port_set_pvid(struct ethsw_port_priv *port_priv, u16 pvid)
> +{
> +	struct ethsw_core *ethsw = port_priv->ethsw_data;
> +	struct net_device *netdev = port_priv->netdev;
> +	struct dpsw_tci_cfg tci_cfg = { 0 };
> +	bool is_oper;
> +	int err, ret;
> +
> +	err = dpsw_if_get_tci(ethsw->mc_io, 0, ethsw->dpsw_handle,
> +			      port_priv->idx, &tci_cfg);
> +	if (err) {
> +		netdev_err(netdev, "dpsw_if_get_tci err %d\n", err);
> +		return err;
> +	}
> +
> +	tci_cfg.vlan_id = pvid;
> +
> +	/* Interface needs to be down to change PVID */
> +	is_oper = netif_oper_up(netdev);
> +	if (is_oper) {
> +		err = dpsw_if_disable(ethsw->mc_io, 0,
> +				      ethsw->dpsw_handle,
> +				      port_priv->idx);
> +		if (err) {
> +			netdev_err(netdev, "dpsw_if_disable err %d\n", err);
> +			return err;
> +		}
> +	}

Is this not inconsistent with ethsw_set_link_ksettings()?

> +
> +	err = dpsw_if_set_tci(ethsw->mc_io, 0, ethsw->dpsw_handle,
> +			      port_priv->idx, &tci_cfg);
> +	if (err) {
> +		netdev_err(netdev, "dpsw_if_set_tci err %d\n", err);
> +		goto set_tci_error;
> +	}
> +
> +	/* Delete previous PVID info and mark the new one */
> +	port_priv->vlans[port_priv->pvid] &= ~ETHSW_VLAN_PVID;
> +	port_priv->vlans[pvid] |= ETHSW_VLAN_PVID;
> +	port_priv->pvid = pvid;
> +
> +set_tci_error:
> +	if (is_oper) {
> +		ret = dpsw_if_enable(ethsw->mc_io, 0,
> +				     ethsw->dpsw_handle,
> +				     port_priv->idx);
> +		if (ret) {
> +			netdev_err(netdev, "dpsw_if_enable err %d\n", ret);
> +			return ret;
> +		}
> +	}
> +
> +	return err;
> +}
> +
> +static int ethsw_set_learning(struct ethsw_core *ethsw, u8 flag)
> +{

Seems like a bool would be better than u8 for flag. An call it enable?

> +	enum dpsw_fdb_learning_mode learn_mode;
> +	int err;
> +
> +	if (flag)
> +		learn_mode = DPSW_FDB_LEARNING_MODE_HW;
> +	else
> +		learn_mode = DPSW_FDB_LEARNING_MODE_DIS;
> +
> +	err = dpsw_fdb_set_learning_mode(ethsw->mc_io, 0, ethsw->dpsw_handle, 0,
> +					 learn_mode);
> +	if (err) {
> +		dev_err(ethsw->dev, "dpsw_fdb_set_learning_mode err %d\n", err);
> +		return err;
> +	}
> +	ethsw->learning = !!flag;
> +
> +	return 0;
> +}
> +
> +static int ethsw_port_set_flood(struct ethsw_port_priv *port_priv, u8 flag)
> +{

Another bool?

> +static int port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
> +			struct net_device *dev, const unsigned char *addr,
> +			u16 vid, u16 flags,
> +			struct netlink_ext_ack *extack)
> +{
> +	if (is_unicast_ether_addr(addr))
> +		return ethsw_port_fdb_add_uc(netdev_priv(dev),
> +					     addr);
> +	else
> +		return ethsw_port_fdb_add_mc(netdev_priv(dev),
> +					     addr);

Do you need to do anything special with link local MAC addresses?
Often they are considered as UC addresses.

> +static int port_carrier_state_sync(struct net_device *netdev)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	struct dpsw_link_state state;
> +	int err;
> +
> +	err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
> +				     port_priv->ethsw_data->dpsw_handle,
> +				     port_priv->idx, &state);
> +	if (err) {
> +		netdev_err(netdev, "dpsw_if_get_link_state() err %d\n", err);
> +		return err;
> +	}
> +
> +	WARN_ONCE(state.up > 1, "Garbage read into link_state");
> +
> +	if (state.up != port_priv->link_state) {
> +		if (state.up)
> +			netif_carrier_on(netdev);
> +		else
> +			netif_carrier_off(netdev);
> +		port_priv->link_state = state.up;
> +	}
> +	return 0;
> +}
> +
> +static int port_open(struct net_device *netdev)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	int err;
> +
> +	/* No need to allow Tx as control interface is disabled */
> +	netif_tx_stop_all_queues(netdev);
> +
> +	err = dpsw_if_enable(port_priv->ethsw_data->mc_io, 0,
> +			     port_priv->ethsw_data->dpsw_handle,
> +			     port_priv->idx);
> +	if (err) {
> +		netdev_err(netdev, "dpsw_if_enable err %d\n", err);
> +		return err;
> +	}
> +
> +	/* sync carrier state */
> +	err = port_carrier_state_sync(netdev);
> +	if (err) {
> +		netdev_err(netdev,`<
> +			   "port_carrier_state_sync err %d\n", err);

port_carrier_state_sync() already does a netdev_err(). There are a lot
of netdev_err() in this code. I wonder how many are really needed? And
how often you get a cascade of error message like this?

I think many of them can be downgraded to netdev_dbg(), or removed.

> +		goto err_carrier_sync;
> +	}
> +
> +	return 0;
> +
> +err_carrier_sync:
> +	dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
> +			port_priv->ethsw_data->dpsw_handle,
> +			port_priv->idx);
> +	return err;
> +}
> +
> +static int port_stop(struct net_device *netdev)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	int err;
> +
> +	err = dpsw_if_disable(port_priv->ethsw_data->mc_io, 0,
> +			      port_priv->ethsw_data->dpsw_handle,
> +			      port_priv->idx);
> +	if (err) {
> +		netdev_err(netdev, "dpsw_if_disable err %d\n", err);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static netdev_tx_t port_dropframe(struct sk_buff *skb,
> +				  struct net_device *netdev)
> +{
> +	/* we don't support I/O for now, drop the frame */
> +	dev_kfree_skb_any(skb);
> +

Ah. Does this also mean it cannot receive?

That makes some of this code pointless and untested.

I'm not sure we would be willing to move this out of staging until it
can transmit and receive. The whole idea is that switch ports are just
linux interfaces. Some actions can be accelerated using hardware, and
what cannot be accelerated the network stack does. However, if you
cannot receive and transmit, you break that whole model. The network
stack is mostly pointless.

> +static void ethsw_links_state_update(struct ethsw_core *ethsw)
> +{
> +	int i;
> +
> +	for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
> +		port_carrier_state_sync(ethsw->ports[i]->netdev);
> +}
> +
> +static irqreturn_t ethsw_irq0_handler_thread(int irq_num, void *arg)
> +{
> +	struct device *dev = (struct device *)arg;
> +	struct ethsw_core *ethsw = dev_get_drvdata(dev);
> +
> +	/* Mask the events and the if_id reserved bits to be cleared on read */
> +	u32 status = DPSW_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;
> +	int err;
> +
> +	err = dpsw_get_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
> +				  DPSW_IRQ_INDEX_IF, &status);
> +	if (err) {
> +		dev_err(dev, "Can't get irq status (err %d)", err);
> +
> +		err = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle,
> +					    DPSW_IRQ_INDEX_IF, 0xFFFFFFFF);
> +		if (err)
> +			dev_err(dev, "Can't clear irq status (err %d)", err);
> +		goto out;
> +	}
> +
> +	if (status & DPSW_IRQ_EVENT_LINK_CHANGED)
> +		ethsw_links_state_update(ethsw);

So there are no per-port events? You have no idea which port went
up/down, you have to poll them all?

> +
> +out:
> +	return IRQ_HANDLED;
> +}
> +
> +static int port_lookup_address(struct net_device *netdev, int is_uc,
> +			       const unsigned char *addr)
> +{
> +	struct netdev_hw_addr_list *list = (is_uc) ? &netdev->uc : &netdev->mc;
> +	struct netdev_hw_addr *ha;
> +
> +	netif_addr_lock_bh(netdev);
> +	list_for_each_entry(ha, &list->list, list) {
> +		if (ether_addr_equal(ha->addr, addr)) {
> +			netif_addr_unlock_bh(netdev);
> +			return 1;
> +		}
> +	}
> +	netif_addr_unlock_bh(netdev);
> +	return 0;

I know i have shot myself in the foot a few times with this structure
of returning in the middle of a loop while holding a lock, forgetting
to unlock, and then later deadlocking. I always do something like:

	ret = 0;
	netif_addr_lock_bh(netdev);
	list_for_each_entry(ha, &list->list, list) {
		if (ether_addr_equal(ha->addr, addr)) {
			ret = 1;
			break;
		}
	}
	netif_addr_unlock_bh(netdev);

	return ret;
}

Also, this function should probably return a bool, not int.

> +}
> +
> +static int port_mdb_add(struct net_device *netdev,
> +			const struct switchdev_obj_port_mdb *mdb,
> +			struct switchdev_trans *trans)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	int err;
> +
> +	if (switchdev_trans_ph_prepare(trans))
> +		return 0;
> +
> +	/* Check if address is already set on this port */
> +	if (port_lookup_address(netdev, 0, mdb->addr))
> +		return -EEXIST;

You are looking at core data structures to determine if the address is
already on the port. Is it possible for the core to ask you to add
this address, if the core has the information needed to determine
itself if the port already has the address.

This seems to be a general theme in this code. You don't trust the
core. If you have real examples of the core doing the wrong thing,
please point them out.

> +/* For the moment, only flood setting needs to be updated */
> +static int port_bridge_join(struct net_device *netdev,
> +			    struct net_device *upper_dev)
> +{
> +	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
> +	struct ethsw_core *ethsw = port_priv->ethsw_data;
> +	int i, err;
> +
> +	for (i = 0; i < ethsw->sw_attr.num_ifs; i++)
> +		if (ethsw->ports[i]->bridge_dev &&
> +		    (ethsw->ports[i]->bridge_dev != upper_dev)) {
> +			netdev_err(netdev,
> +				   "Another switch port is connected to %s\n",
> +				   ethsw->ports[i]->bridge_dev->name);
> +			return -EINVAL;
> +		}

Am i reading this correct? You only support a single bridge?  The
error message is not very informative. Also, i think you should be
returning EOPNOTSUPP, indicating the offload is not possible. Linux
will then do it in software. If it could actually receive/transmit the
frames....

> +static int ethsw_open(struct ethsw_core *ethsw)
> +{
> +	struct ethsw_port_priv *port_priv = NULL;
> +	int i, err;
> +
> +	err = dpsw_enable(ethsw->mc_io, 0, ethsw->dpsw_handle);
> +	if (err) {
> +		dev_err(ethsw->dev, "dpsw_enable err %d\n", err);
> +		return err;
> +	}
> +
> +	for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
> +		port_priv = ethsw->ports[i];
> +		err = dev_open(port_priv->netdev, NULL);
> +		if (err) {
> +			netdev_err(port_priv->netdev, "dev_open err %d\n", err);
> +			return err;
> +		}
> +	}

Why is this needed? When the user configures the interface up, won't
the core call dev_open()?

> +
> +	return 0;
> +}
> +
> +static int ethsw_stop(struct ethsw_core *ethsw)
> +{
> +	struct ethsw_port_priv *port_priv = NULL;
> +	int i, err;
> +
> +	for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
> +		port_priv = ethsw->ports[i];
> +		dev_close(port_priv->netdev);
> +	}
> +
> +	err = dpsw_disable(ethsw->mc_io, 0, ethsw->dpsw_handle);
> +	if (err) {
> +		dev_err(ethsw->dev, "dpsw_disable err %d\n", err);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ethsw_init(struct fsl_mc_device *sw_dev)
> +{
> +	stp_cfg.vlan_id = DEFAULT_VLAN_ID;
> +	stp_cfg.state = DPSW_STP_STATE_FORWARDING;
> +
> +	for (i = 0; i < ethsw->sw_attr.num_ifs; i++) {
> +		err = dpsw_if_set_stp(ethsw->mc_io, 0, ethsw->dpsw_handle, i,
> +				      &stp_cfg);

Maybe you should actually configure the STP state to blocked? You can
move it to forwarding when the interface is opened.

> +static int ethsw_port_init(struct ethsw_port_priv *port_priv, u16 port)
> +{
> +	const char def_mcast[ETH_ALEN] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x01};

There should be some explanation about what the MAC address is, and
why it needs adding.

> +static int ethsw_probe_port(struct ethsw_core *ethsw, u16 port_idx)
> +{
> +	struct ethsw_port_priv *port_priv;
> +	struct device *dev = ethsw->dev;
> +	struct net_device *port_netdev;
> +	int err;
> +
> +	port_netdev = alloc_etherdev(sizeof(struct ethsw_port_priv));
> +	if (!port_netdev) {
> +		dev_err(dev, "alloc_etherdev error\n");
> +		return -ENOMEM;
> +	}
> +
> +	port_priv = netdev_priv(port_netdev);
> +	port_priv->netdev = port_netdev;
> +	port_priv->ethsw_data = ethsw;
> +
> +	port_priv->idx = port_idx;
> +	port_priv->stp_state = BR_STATE_FORWARDING;
> +
> +	/* Flooding is implicitly enabled */
> +	port_priv->flood = true;
> +
> +	SET_NETDEV_DEV(port_netdev, dev);
> +	port_netdev->netdev_ops = &ethsw_port_ops;
> +	port_netdev->ethtool_ops = &ethsw_port_ethtool_ops;
> +
> +	/* Set MTU limits */
> +	port_netdev->min_mtu = ETH_MIN_MTU;
> +	port_netdev->max_mtu = ETHSW_MAX_FRAME_LENGTH;
> +
> +	err = register_netdev(port_netdev);
> +	if (err < 0) {
> +		dev_err(dev, "register_netdev error %d\n", err);
> +		goto err_register_netdev;
> +	}

At this point, the interface if live.

> +
> +	ethsw->ports[port_idx] = port_priv;
> +
> +	err = ethsw_port_init(port_priv, port_idx);
> +	if (err)
> +		goto err_ethsw_port_init;

What would happen if the interface was asked to do something before
these two happen? You should only call register_netdev() when you
really are ready to go.

> +static int ethsw_probe(struct fsl_mc_device *sw_dev)
> +{
> +
> +	/* Switch starts up enabled */
> +	rtnl_lock();
> +	err = ethsw_open(ethsw);
> +	rtnl_unlock();

What exactly do you mean by that?

     Andrew

^ permalink raw reply

* Re: [PATCH net-next v2 1/4] net: phy: simplify genphy_config_advert by using the linkmode_adv_to_xxx_t functions
From: Andrew Lunn @ 2019-08-09 19:07 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <6ba42ade-5874-9bc9-4f4d-b80f79c0deca@gmail.com>

On Fri, Aug 09, 2019 at 08:43:04PM +0200, Heiner Kallweit wrote:
> Using linkmode_adv_to_mii_adv_t and linkmode_adv_to_mii_ctrl1000_t
> allows to simplify the code. In addition avoiding the conversion to
> the legacy u32 advertisement format allows to remove the warning.
> 
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> Suggested-by: Andrew Lunn <andrew@lunn.ch>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* Re: [PATCH net-next v2 3/4] net: phy: add phy_modify_paged_changed
From: Andrew Lunn @ 2019-08-09 19:09 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <741a9493-e9a1-be4e-a2e9-e15294362005@gmail.com>

On Fri, Aug 09, 2019 at 08:44:22PM +0200, Heiner Kallweit wrote:
> Add helper function phy_modify_paged_changed, behavios is the same
> as for phy_modify_changed.
> 
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* Re: [PATCH net-next] gso: enable udp gso for virtual devices
From: Willem de Bruijn @ 2019-08-09 19:13 UTC (permalink / raw)
  To: Josh Hunt
  Cc: Willem de Bruijn, Jason Baron, Alexander Duyck, David Miller,
	Netdev, Paolo Abeni
In-Reply-To: <314b4ae8-ef99-e7a4-cb95-87b7ea74427f@akamai.com>

On Fri, Aug 9, 2019 at 2:58 PM Josh Hunt <johunt@akamai.com> wrote:
>
> On 6/26/19 4:41 PM, Willem de Bruijn wrote:
> > On Wed, Jun 26, 2019 at 3:17 PM Jason Baron <jbaron@akamai.com> wrote:
> >>
> >>
> >>
> >> On 6/14/19 4:53 PM, Jason Baron wrote:
> >>>
> >>>
> >>> On 6/13/19 5:20 PM, Willem de Bruijn wrote:
> >>>>>>> @@ -237,6 +237,7 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start)
> >>>>>>>                                   NETIF_F_GSO_GRE_CSUM |                 \
> >>>>>>>                                   NETIF_F_GSO_IPXIP4 |                   \
> >>>>>>>                                   NETIF_F_GSO_IPXIP6 |                   \
> >>>>>>> +                                NETIF_F_GSO_UDP_L4 |                   \
> >>>>>>>                                   NETIF_F_GSO_UDP_TUNNEL |               \
> >>>>>>>                                   NETIF_F_GSO_UDP_TUNNEL_CSUM)
> >>>>>>
> >>>>>> Are you adding this to NETIF_F_GSO_ENCAP_ALL? Wouldn't it make more
> >>>>>> sense to add it to NETIF_F_GSO_SOFTWARE?
> >>>>>>
> >>>>>
> >>>>> Yes, I'm adding to NETIF_F_GSO_ENCAP_ALL (not very clear from the
> >>>>> context). I will fix the commit log.
> >>>>>
> >>>>> In: 83aa025 udp: add gso support to virtual devices, the support was
> >>>>> also added to NETIF_F_GSO_ENCAP_ALL (although subsequently reverted due
> >>>>> to UDP GRO not being in place), so I wonder what the reason was for that?
> >>>>
> >>>> That was probably just a bad choice on my part.
> >>>>
> >>>> It worked in practice, but if NETIF_F_GSO_SOFTWARE works the same
> >>>> without unexpected side effects, then I agree that it is the better choice.
> >>>>
> >>>> That choice does appear to change behavior when sending over tunnel
> >>>> devices. Might it send tunneled GSO packets over loopback?
> >>>>
> >>>>
> >>>
> >>> I set up a test case using fou tunneling through a bridge device using
> >>> the udpgso_bench_tx test where packets are not received correctly if
> >>> NETIF_F_GSO_UDP_L4 is added to NETIF_F_GSO_SOFTWARE. If I have it added
> >>> to NETIF_F_GSO_ENCAP_ALL, it does work correctly. So there are more
> >>> fixes required to include it in NETIF_F_GSO_SOFTWARE.
> >>>
> >>> The use-case I have only requires it to be in NETIF_F_GSO_ENCAP_ALL, but
> >>> if it needs to go in NETIF_F_GSO_SOFTWARE, I can look at what's required
> >>> more next week.
> >>>
> >>
> >> Hi,
> >>
> >> I haven't had a chance to investigate what goes wrong with including
> >> NETIF_F_GSO_UDP_L4 in NETIF_F_GSO_SOFTWARE - but I was just wondering if
> >> people are ok with NETIF_F_GSO_UDP_L4 being added to
> >> NETIF_F_GSO_ENCAP_ALL and not NETIF_F_GSO_SOFTWARE (ie the original
> >> patch as posted)?
> >>
> >> As I mentioned that is sufficient for my use-case, and its how Willem
> >> originally proposed this.
> >
> > Indeed, based on the previous discussion this sounds fine to me.
> >
>
> Willem
>
> Are you OK to ACK this? If not, is there something else you'd rather see
> here?

Sure. Unless Alex still has objections, feel free to resubmit with my Acked-by.

^ permalink raw reply

* Re: [PATCH net-next v2 4/4] net: phy: realtek: add support for the 2.5Gbps PHY in RTL8125
From: Andrew Lunn @ 2019-08-09 19:18 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <49454e5b-465d-540e-cc01-07717a773e33@gmail.com>

> +	}, {
> +		PHY_ID_MATCH_EXACT(0x001cca50),

Hi Heiner

With the Marvell driver, i looked at the range of IDs the PHYs where
using. The switch, being MDIO based, also has ID values. The PHY range
and the switch range are well separated, and it seems unlikely Marvell
would reuse a switch ID in a PHY which was not compatible with the
PHY.

Could you explain why you picked this value for the PHY? What makes
you think it is not in use by another Realtek PHY? 

Thanks
    Andrew

^ permalink raw reply

* Re: Clause 73 and USXGMII
From: Russell King - ARM Linux admin @ 2019-08-09 19:25 UTC (permalink / raw)
  To: Jose Abreu
  Cc: netdev@vger.kernel.org, Andrew Lunn, Florian Fainelli,
	Heiner Kallweit
In-Reply-To: <BN8PR12MB32664B2DE18A30311A19E5B8D3D60@BN8PR12MB3266.namprd12.prod.outlook.com>

On Fri, Aug 09, 2019 at 06:42:39PM +0000, Jose Abreu wrote:
> From: Russell King - ARM Linux admin <linux@armlinux.org.uk>
> Date: Aug/08/2019, 13:09:03 (UTC+00:00)
> 
> > On Thu, Aug 08, 2019 at 11:45:29AM +0000, Jose Abreu wrote:
> > > From: Russell King - ARM Linux admin <linux@armlinux.org.uk>
> > > Date: Aug/08/2019, 10:23:13 (UTC+00:00)
> > > 
> > > > On Thu, Aug 08, 2019 at 09:02:57AM +0000, Jose Abreu wrote:
> > > > > From: Russell King - ARM Linux admin <linux@armlinux.org.uk>
> > > > > Date: Aug/08/2019, 09:26:26 (UTC+00:00)
> > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > Have you tried enabling debug mode in phylink (add #define DEBUG at the
> > > > > > top of the file) ?
> > > > > 
> > > > > Yes:
> > > > > 
> > > > > [ With > 2.5G modes removed ]
> > > > > # dmesg | grep -i phy
> > > > > libphy: stmmac: probed
> > > > > stmmaceth 0000:04:00.0 enp4s0: PHY [stmmac-1:00] driver [Synopsys 10G]
> > > > > stmmaceth 0000:04:00.0 enp4s0: phy: setting supported 
> > > > > 00,00000000,0002e040 advertising 00,00000000,0002e040
> > > > > stmmaceth 0000:04:00.0 enp4s0: configuring for phy/usxgmii link mode
> > > > > stmmaceth 0000:04:00.0 enp4s0: phylink_mac_config: 
> > > > > mode=phy/usxgmii/Unknown/Unknown adv=00,00000000,0002e040 pause=10 
> > > > > link=0 an=1
> > > > > stmmaceth 0000:04:00.0 enp4s0: phy link down usxgmii/Unknown/Unknown
> > > > 
> > > > This shows that the PHY isn't reporting that the link came up.  Did
> > > > the PHY negotiate link?  If so, why isn't it reporting that the link
> > > > came up?  Maybe something is mis-programming the capability bits in
> > > > the PHY?  Maybe disabling the 10G speeds disables everything faster
> > > > than 1G?
> > > 
> > > Autoneg was started but never finishes and disabling 10G modes is 
> > > causing autoneg to fail.
> > > 
> > > > 
> > > > > [ Without any limit ]
> > > > > # dmesg | grep -i phy
> > > > > libphy: stmmac: probed
> > > > > stmmaceth 0000:04:00.0 enp4s0: PHY [stmmac-1:00] driver [Synopsys 10G]
> > > > > stmmaceth 0000:04:00.0 enp4s0: phy: setting supported 
> > > > > 00,00000000,000ee040 advertising 00,00000000,000ee040
> > > > > stmmaceth 0000:04:00.0 enp4s0: configuring for phy/usxgmii link mode
> > > > > stmmaceth 0000:04:00.0 enp4s0: phylink_mac_config: 
> > > > > mode=phy/usxgmii/Unknown/Unknown adv=00,00000000,000ee040 pause=10 
> > > > > link=0 an=1
> > > > > stmmaceth 0000:04:00.0 enp4s0: phy link down usxgmii/Unknown/Unknown
> > > > > stmmaceth 0000:04:00.0 enp4s0: phy link up usxgmii/2.5Gbps/Full
> > > > > stmmaceth 0000:04:00.0 enp4s0: phylink_mac_config: 
> > > > > mode=phy/usxgmii/2.5Gbps/Full adv=00,00000000,00000000 pause=0f link=1 
> > > > > an=0
> > > > > 
> > > > > I'm thinking on whether this can be related with USXGMII. As link is 
> > > > > operating in 10G but I configure USXGMII for 2.5G maybe autoneg outcome 
> > > > > should always be 10G ?
> > > > 
> > > > As I understand USXGMII (which isn't very well, because the spec isn't
> > > > available) I believe that it operates in a similar way to SGMII where
> > > > data is replicated the appropriate number of times to achieve the link
> > > > speed.  So, the USXGMII link always operates at a bit rate equivalent
> > > > to 10G, but data is replicated twice for 5G, four times for 2.5G, ten
> > > > times for 1G, etc.
> > > > 
> > > > I notice that you don't say that you support any copper speeds, which
> > > > brings up the question about what the PHY's media is...
> > > 
> > > I just added the speeds that XPCS supports within Clause 73 
> > > specification:
> > > Technology Ability field. Indicates the supported technologies:
> > > 	A0: When this bit is set to 1, the 1000BASE-KX technology is supported
> > > 	A1: When this bit is set to 1, the 10GBASE-KX4 technology is supported
> > > 	A2: When this bit is set to 1, the 10GBASE-KR technology is supported
> > > 	A11: When this bit is set to 1, the 2.5GBASE-KX technology is supported
> > > 	A12: When this bit is set to 1, the 5GBASE-KR technology is supported
> > > 
> > > And, within USXGMII, XPCS supports the following:
> > > 	Single Port: 10G-SXGMII, 5G-SXGMII, 2.5G-SXGMII
> > > 	Dual Port: 10G-DXGMII, 5G-DXGMII
> > > 	Quad Port: 10G-XGMII
> > > 
> > > My HW is currently fixed for USXGMII at 2.5G.
> > 
> > So what do you actually have?
> > 
> > +-----+              +----------+
> > | STM |    USXGMII   | Synopsis |   ????????
> > | MAC | <----------> |   PHY    | <----------> ????
> > |     |     link     |          |
> > +-----+              +----------+ (media side)
> > 
> > Does the above refer to what the STM MAC and Synopsis PHY support for
> > the USXGMII link?  What about the media side?
> 
> This is my setup:
> 
> XGMAC <-> XPCS <-> Xilinx SERDES <-> SFP
> 
> I'm not sure about the media side. I use a passive SFP cable if that 
> helps ...

And at the other end of the passive SFP cable?  I guess some kind of
standard networking device.

If the SFP is running at 10G, the protocol to the SFP is expected to be
10GBASE-R - which is fixed at 10G speed.  Unless the Xilinx serdes
(which you previously stated was a PHY) is capable of speed conversion
between 2.5G to the XPCS over USXGMII and 10G to the SFP, then I don't
see how you can expect this setup to work - at least not in a standard
environment.

In any case, I don't think it is phylink causing your problems. Without
knowing more about the "phy", what the Xilinx serdes is capable of, and
how that is being programmed, I don't see how I can provide further
help.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up

^ permalink raw reply

* Re: [PATCH net-next v2 4/4] net: phy: realtek: add support for the 2.5Gbps PHY in RTL8125
From: Heiner Kallweit @ 2019-08-09 19:31 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <20190809191822.GZ27917@lunn.ch>

On 09.08.2019 21:18, Andrew Lunn wrote:
>> +	}, {
>> +		PHY_ID_MATCH_EXACT(0x001cca50),
> 
> Hi Heiner
> 
Hi Andrew,

> With the Marvell driver, i looked at the range of IDs the PHYs where
> using. The switch, being MDIO based, also has ID values. The PHY range
> and the switch range are well separated, and it seems unlikely Marvell
> would reuse a switch ID in a PHY which was not compatible with the
> PHY.
> 
> Could you explain why you picked this value for the PHY? What makes
> you think it is not in use by another Realtek PHY? 
> 
0x001cc800 being the Realtek OUI, I've seen only PHY's with ID
0x001cc8XX and 0x001cc9XX so far. Realtek doesn't seem to have such
a clear separation between PHY and switch PHY ID's.

Example:
0x001cc961 (RTL8366, switch)
0x001cc916 (RTL8211F, PHY)

Last digit of the model is used as model number.
I did the same and used 5 as model number (from RTL8125).
Revision number is set to 0 because RTL8125 is brand-new.

I chose a PHY ID in 0x001ccaXX range because it isn't used by
Realtek AFAIK.

> Thanks
>     Andrew
> 
Heiner

^ permalink raw reply

* Re: [PATCH 0/2 net,v4] flow_offload hardware priority fixes
From: David Miller @ 2019-08-09 19:37 UTC (permalink / raw)
  To: pablo
  Cc: netfilter-devel, netdev, marcelo.leitner, jiri, wenxu, saeedm,
	paulb, gerlitz.or, jakub.kicinski
In-Reply-To: <20190806160310.6663-1-pablo@netfilter.org>

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Tue,  6 Aug 2019 18:03:08 +0200

> This patchset contains two updates for the flow_offload users:
> 
> 1) Pass the major tc priority to drivers so they do not have to
>    lshift it. This is a preparation patch for the fix coming in
>    patch #2.
> 
> 2) Set the hardware priority from the netfilter basechain priority,
>    some drivers break when using the existing hardware priority
>    number that is set to zero.

Series applied.

^ permalink raw reply

* Re: [PATCH net-next 01/12] net: stmmac: Get correct timestamp values from XGMAC
From: David Miller @ 2019-08-09 19:43 UTC (permalink / raw)
  To: Jose.Abreu; +Cc: netdev, Joao.Pinto
In-Reply-To: <7acdee903b01dd5462f687c31163628cefa0e372.1565375521.git.joabreu@synopsys.com>

From: Jose Abreu <Jose.Abreu@synopsys.com>
Date: Fri,  9 Aug 2019 20:36:09 +0200

> +	void __iomem *ioaddr = hw->pcsr;
> +	int count = 0;
> +	u32 value;
> +
> +	do {
> +		if (readl_poll_timeout_atomic(ioaddr + XGMAC_TIMESTAMP_STATUS,
> +					      value, value & XGMAC_TXTSC,
> +					      100, 10000))
> +			break;
> +
> +		*ts = readl(ioaddr + XGMAC_TXTIMESTAMP_NSEC) & XGMAC_TXTSSTSLO;
> +		*ts += readl(ioaddr + XGMAC_TXTIMESTAMP_SEC) * 1000000000ULL;
> +	} while (count++);
> +
> +	if (count)
> +		return 0;
> +	return -EBUSY;

This is a very strange construct, the loop never executes more than once.
Simplified it is essentially:

	if (readl_poll_timeout_atomic(ioaddr + XGMAC_TIMESTAMP_STATUS,
				      value, value & XGMAC_TXTSC,
				      100, 10000))
		return -EBUSY;

	*ts = readl(ioaddr + XGMAC_TXTIMESTAMP_NSEC) & XGMAC_TXTSSTSLO;
	*ts += readl(ioaddr + XGMAC_TXTIMESTAMP_SEC) * 1000000000ULL;
	return 0;

Don't make the code more complicated than it needs to be, there is no
reason to use a loop here.  And using a loop makes it look like the
loop is the polling/timeout construct, when it isn't, because
readl_poll_timeout_atomic() is serving that purpose.


^ permalink raw reply

* Re: [PATCH net-next 04/12] net: stmmac: Add Split Header support and enable it in XGMAC cores
From: David Miller @ 2019-08-09 19:44 UTC (permalink / raw)
  To: Jose.Abreu; +Cc: netdev, Joao.Pinto
In-Reply-To: <c85acbe21eaf8ed11ceffe8adcae9ddf2643d66e.1565375521.git.joabreu@synopsys.com>

From: Jose Abreu <Jose.Abreu@synopsys.com>
Date: Fri,  9 Aug 2019 20:36:12 +0200

> Add the support for Split Header feature in the RX path and enable it in
> XGMAC cores.
> 
> Signed-off-by: Jose Abreu <joabreu@synopsys.com>

Well, what is the performance advantage/disadvantage of this mode?  Show
some numbers please to justify the use of the feature.

^ permalink raw reply

* Re: [PATCH net-next v2] ibmveth: Allow users to update reported speed and duplex
From: David Miller @ 2019-08-09 19:47 UTC (permalink / raw)
  To: jakub.kicinski; +Cc: tlfalcon, mpe, netdev, linuxppc-dev
In-Reply-To: <20190806151524.69d75f8d@cakuba.netronome.com>

From: Jakub Kicinski <jakub.kicinski@netronome.com>
Date: Tue, 6 Aug 2019 15:15:24 -0700

> On Tue,  6 Aug 2019 11:23:08 -0500, Thomas Falcon wrote:
>> Reported ethtool link settings for the ibmveth driver are currently
>> hardcoded and no longer reflect the actual capabilities of supported
>> hardware. There is no interface designed for retrieving this information
>> from device firmware nor is there any way to update current settings
>> to reflect observed or expected link speeds.
>> 
>> To avoid breaking existing configurations, retain current values as
>> default settings but let users update them to match the expected
>> capabilities of underlying hardware if needed. This update would
>> allow the use of configurations that rely on certain link speed
>> settings, such as LACP. This patch is based on the implementation
>> in virtio_net.
>> 
>> Signed-off-by: Thomas Falcon <tlfalcon@linux.ibm.com>
> 
> Looks like this is the third copy of the same code virtio and
> netvsc have :(  Is there a chance we could factor this out into
> helpers in the core?

Yeah, let's stop the duplication of code while we can.

Thomas please perform the consolidation and respin.

Thank you.

^ permalink raw reply

* Re: tcan4x5x on a Raspberry Pi
From: Wolfgang Grandegger @ 2019-08-09 19:49 UTC (permalink / raw)
  To: FIXED-TERM Buecheler Konstantin (ETAS-SEC/ECT-Mu), Dan Murphy,
	linux-can@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <ee351bd74b764759bb0258af3651bd4a@escrypt.com>

Hello Konstantin,

m 09.08.19 um 18:46 schrieb FIXED-TERM Buecheler Konstantin
(ETAS-SEC/ECT-Mu):
> 
>> Konstantin
> 
>>> On 7/29/19 6:19 AM, FIXED-TERM Buecheler Konstantin (ETAS-SEC/ECT-Mu) wrote:
>>> Hi all,
>>>
>>> I am currently working on a project where I am trying to use the tcan4550 chip with a Raspberry PI 3B.
>>> I am struggling to create a working device tree overlay file for the Raspberry Pi.
>>> Has anyone here tried this already? I would appreciate any help.
> 
>> Are you using the driver from net-next?
> 
>> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/drivers/net/can/m_can
> 
> Yes, I am using the driver from net-next. 
> 
> 
>> DT documentation here
> 
>> https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/tree/Documentation/devicetree/bindings/net/can/tcan4x5x.txt
> 
> I saw this documentation but it didn’t help much (As I said, I don’t have much experience with device trees) . My dts file currently looks like this:  
> 
> /dts-v1/;
> /plugin/;
> 
> / {
>     compatible = "brcm,bcm2835", "brcm,bcm2836", "brcm,bcm2708", "brcm,bcm2709";
>     fragment@0 {
>         target = <&spi0>;
> 	__overlay__ {
>             status = "okay";
> 	    spidev@0{
> 	        status = "disabled";
> 	    };
> 	};
>     };
> 
>     fragment@2 {
>         compatible = "bosch, m_can";
> 	target = <&spi0>;
> 	__overlay__ {
> 	    tcan4x5x: tcan4x5x@0 {
> 	             compatible = "ti,tcan4x5x";
>                           reg = <0>;
> 		#address-cells = <1>;
>                          #size-cells = <1>;
> 		spi-max-frequency = <10000000>;
>                          bosch,mram-cfg = <0x0 0 0 32 0 0 1 1>;
> 		data-ready-gpios = <&gpio 23 0>;
> 		device-wake-gpios = <&gpio 24 1>;
> 				
> 	    };		
> 	};
>     };
> };
> 
> 
> Checking dmesg I always see these errors:
> [    5.409051] tcan4x5x spi0.0: no clock found
> [    5.409064] tcan4x5x spi0.0: no CAN clock source defined
> [    5.409125] tcan4x5x spi0.0: data-ready gpio not defined
> [    5.409135] tcan4x5x spi0.0: Probe failed, err=-22
> 
> I already fixed the clock issue once by doing something like this:
> clocks = <&can0_osc>,
>               <&can0_osc>;
> clock-names = "hclk", "cclk";
> But that didn’t fix the " data-ready gpio not defined" error.
> 
> 
>> I did the development on a BeagleBone Black.

Before fiddling with the dynamic device tree, I would try to patch
normal device tree source files first.

Wolfgang

^ permalink raw reply

* Re: [PATCH 0/2 net,v4] flow_offload hardware priority fixes
From: David Miller @ 2019-08-09 19:57 UTC (permalink / raw)
  To: pablo
  Cc: netfilter-devel, netdev, marcelo.leitner, jiri, wenxu, saeedm,
	paulb, gerlitz.or, jakub.kicinski
In-Reply-To: <20190809.123741.733240603302377585.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Fri, 09 Aug 2019 12:37:41 -0700 (PDT)

> From: Pablo Neira Ayuso <pablo@netfilter.org>
> Date: Tue,  6 Aug 2019 18:03:08 +0200
> 
>> This patchset contains two updates for the flow_offload users:
>> 
>> 1) Pass the major tc priority to drivers so they do not have to
>>    lshift it. This is a preparation patch for the fix coming in
>>    patch #2.
>> 
>> 2) Set the hardware priority from the netfilter basechain priority,
>>    some drivers break when using the existing hardware priority
>>    number that is set to zero.
> 
> Series applied.

Sorry, I had to revert:

[davem@localhost net]$ make -s -j14
In file included from ./include/linux/list.h:9,
                 from ./include/linux/module.h:9,
                 from net/netfilter/nf_tables_offload.c:3:
net/netfilter/nf_tables_offload.c: In function ‘nft_chain_offload_priority’:
./include/linux/kernel.h:269:23: warning: overflow in conversion from ‘short int’ to ‘signed char’ changes value from ‘-32768’ to ‘0’ [-Woverflow]
  ({ signed type __x = (x); __x < 0 ? -__x : __x; }), other)
                       ^
./include/linux/kernel.h:256:16: note: in expansion of macro ‘__abs_choose_expr’
 #define abs(x) __abs_choose_expr(x, long long,    \
                ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:257:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, long,    \
   ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:258:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, int,    \
   ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:259:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, short,    \
   ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:260:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, char,    \
   ^~~~~~~~~~~~~~~~~
net/netfilter/nf_tables_offload.c:134:35: note: in expansion of macro ‘abs’
  return basechain->ops.priority + abs(SHRT_MIN);
                                   ^~~
./include/linux/kernel.h:263:31: warning: overflow in conversion from ‘short int’ to ‘signed char’ changes value from ‘-32768’ to ‘0’ [-Woverflow]
    (char)({ signed char __x = (x); __x<0?-__x:__x; }), \
                               ^
./include/linux/kernel.h:269:54: note: in definition of macro ‘__abs_choose_expr’
  ({ signed type __x = (x); __x < 0 ? -__x : __x; }), other)
                                                      ^~~~~
./include/linux/kernel.h:257:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, long,    \
   ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:258:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, int,    \
   ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:259:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, short,    \
   ^~~~~~~~~~~~~~~~~
./include/linux/kernel.h:260:3: note: in expansion of macro ‘__abs_choose_expr’
   __abs_choose_expr(x, char,    \
   ^~~~~~~~~~~~~~~~~
net/netfilter/nf_tables_offload.c:134:35: note: in expansion of macro ‘abs’
  return basechain->ops.priority + abs(SHRT_MIN);
                                   ^~~

^ permalink raw reply

* Re: [PATCH v2 1/2] tcp: add new tcp_mtu_probe_floor sysctl
From: David Miller @ 2019-08-09 19:59 UTC (permalink / raw)
  To: johunt; +Cc: netdev, edumazet, ncardwell
In-Reply-To: <1565221950-1376-1-git-send-email-johunt@akamai.com>

From: Josh Hunt <johunt@akamai.com>
Date: Wed,  7 Aug 2019 19:52:29 -0400

> The current implementation of TCP MTU probing can considerably
> underestimate the MTU on lossy connections allowing the MSS to get down to
> 48. We have found that in almost all of these cases on our networks these
> paths can handle much larger MTUs meaning the connections are being
> artificially limited. Even though TCP MTU probing can raise the MSS back up
> we have seen this not to be the case causing connections to be "stuck" with
> an MSS of 48 when heavy loss is present.
> 
> Prior to pushing out this change we could not keep TCP MTU probing enabled
> b/c of the above reasons. Now with a reasonble floor set we've had it
> enabled for the past 6 months.
> 
> The new sysctl will still default to TCP_MIN_SND_MSS (48), but gives
> administrators the ability to control the floor of MSS probing.
> 
> Signed-off-by: Josh Hunt <johunt@akamai.com>

Applied.

^ permalink raw reply

* Re: [PATCH v2 2/2] tcp: Update TCP_BASE_MSS comment
From: David Miller @ 2019-08-09 19:59 UTC (permalink / raw)
  To: johunt; +Cc: netdev, edumazet, ncardwell
In-Reply-To: <1565221950-1376-2-git-send-email-johunt@akamai.com>

From: Josh Hunt <johunt@akamai.com>
Date: Wed,  7 Aug 2019 19:52:30 -0400

> TCP_BASE_MSS is used as the default initial MSS value when MTU probing is
> enabled. Update the comment to reflect this.
> 
> Suggested-by: Neal Cardwell <ncardwell@google.com>
> Signed-off-by: Josh Hunt <johunt@akamai.com>

Applied.

^ permalink raw reply

* Re: [PATCH net] net: phy: rtl8211f: do a double read to get real time link status
From: Heiner Kallweit @ 2019-08-09 20:05 UTC (permalink / raw)
  To: Yonglong Liu, Andrew Lunn
  Cc: davem, netdev, linux-kernel, linuxarm, salil.mehta, yisen.zhuang,
	shiju.jose
In-Reply-To: <414c6809-86a3-506c-b7b0-a32b7cd72fd6@huawei.com>

On 09.08.2019 06:57, Yonglong Liu wrote:
> 
> 
> On 2019/8/9 4:34, Andrew Lunn wrote:
>> On Thu, Aug 08, 2019 at 10:01:39PM +0200, Heiner Kallweit wrote:
>>> On 08.08.2019 21:40, Andrew Lunn wrote:
>>>>> @@ -568,6 +568,11 @@ int phy_start_aneg(struct phy_device *phydev)
>>>>>  	if (err < 0)
>>>>>  		goto out_unlock;
>>>>>  
>>>>> +	/* The PHY may not yet have cleared aneg-completed and link-up bit
>>>>> +	 * w/o this delay when the following read is done.
>>>>> +	 */
>>>>> +	usleep_range(1000, 2000);
>>>>> +
>>>>
>>>> Hi Heiner
>>>>
>>>> Does 802.3 C22 say anything about this?
>>>>
>>> C22 says:
>>> "The Auto-Negotiation process shall be restarted by setting bit 0.9 to a logic one. This bit is self-
>>> clearing, and a PHY shall return a value of one in bit 0.9 until the Auto-Negotiation process has been
>>> initiated."
>>>
>>> Maybe we should read bit 0.9 in genphy_update_link() after having read BMSR and report
>>> aneg-complete and link-up as false (no matter of their current value) if 0.9 is set.
>>
>> Yes. That sounds sensible.
>>
>>      Andrew
>>
>> .
>>
> 
> Hi Heiner:
> 	I have test more than 50 times, it works. Previously less
> than 20 times must be recurrence. so I think this patch solved the
> problem.
> 	And I checked about 40 times of the time gap between read
> and autoneg started, all of them is more than 2ms, as below:
> 
>   kworker/u257:1-670   [015] ....    27.182632: mdio_access: mii-0000:bd:00.3 write phy:0x07 reg:0x00 val:0x1240
>   kworker/u257:1-670   [015] ....    27.184670: mdio_access: mii-0000:bd:00.3 read  phy:0x07 reg:0x01 val:0x7989
> 
> 

Instead of using this fixed delay, the following experimental patch
considers that fact that between triggering aneg start and actual
start of aneg (incl. clearing aneg-complete bit) Clause 22 requires
a PHY to keep bit 0.9 (aneg restart) set.
Could you please test this instead of the fixed-delay patch?

Thanks, Heiner

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index b039632de..163295dbc 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1741,7 +1741,17 @@ EXPORT_SYMBOL(genphy_aneg_done);
  */
 int genphy_update_link(struct phy_device *phydev)
 {
-	int status;
+	int status = 0, bmcr;
+
+	bmcr = phy_read(phydev, MII_BMCR);
+	if (bmcr < 0)
+		return bmcr;
+
+	/* Autoneg is being started, therefore disregard BMSR value and
+	 * report link as down.
+	 */
+	if (bmcr & BMCR_ANRESTART)
+		goto done;
 
 	/* The link state is latched low so that momentary link
 	 * drops can be detected. Do not double-read the status
-- 
2.22.0



^ permalink raw reply related

* Re: [PATCH net v2 0/2] Fix collisions in socket cookie generation
From: David Miller @ 2019-08-09 20:15 UTC (permalink / raw)
  To: daniel; +Cc: netdev, bpf, m, edumazet, ast, willemb
In-Reply-To: <20190808115726.31703-1-daniel@iogearbox.net>

From: Daniel Borkmann <daniel@iogearbox.net>
Date: Thu,  8 Aug 2019 13:57:24 +0200

> This change makes the socket cookie generator as a global counter
> instead of per netns in order to fix cookie collisions for BPF use
> cases we ran into. See main patch #1 for more details.
> 
> Given the change is small/trivial and fixes an issue we're seeing
> my preference would be net tree (though it cleanly applies to
> net-next as well). Went for net tree instead of bpf tree here given
> the main change is in net/core/sock_diag.c, but either way would be
> fine with me.
> 
> Thanks a lot!
> 
> v1 -> v2:
>   - Fix up commit description in patch #1, thanks Eric!

Series applied.

^ permalink raw reply

* Re: [net v2] ixgbe: fix possible deadlock in ixgbe_service_task()
From: David Miller @ 2019-08-09 20:17 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: ap420073, netdev, nhorman, sassmann, andrewx.bowers
In-Reply-To: <20190808163756.8753-1-jeffrey.t.kirsher@intel.com>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Thu,  8 Aug 2019 09:37:56 -0700

> From: Taehee Yoo <ap420073@gmail.com>
> 
> ixgbe_service_task() calls unregister_netdev() under rtnl_lock().
> But unregister_netdev() internally calls rtnl_lock().
> So deadlock would occur.
> 
> Fixes: 59dd45d550c5 ("ixgbe: firmware recovery mode")
> Signed-off-by: Taehee Yoo <ap420073@gmail.com>
> Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
> v2: removed unnecessary curly brackets

Applied, thanks everyone.

^ permalink raw reply

* Re: [PATCH net-next v6 3/3] net: phy: broadcom: add 1000Base-X support for BCM54616S
From: Heiner Kallweit @ 2019-08-09 20:21 UTC (permalink / raw)
  To: Tao Ren, Andrew Lunn, Florian Fainelli, David S . Miller,
	Arun Parameswaran, Justin Chen, Vladimir Oltean, netdev,
	linux-kernel, openbmc
In-Reply-To: <20190809054411.1015962-1-taoren@fb.com>

On 09.08.2019 07:44, Tao Ren wrote:
> The BCM54616S PHY cannot work properly in RGMII->1000Base-KX mode (for
> example, on Facebook CMM BMC platform), mainly because genphy functions
> are designed for copper links, and 1000Base-X (clause 37) auto negotiation
> needs to be handled differently.
> 
> This patch enables 1000Base-X support for BCM54616S by customizing 3
> driver callbacks:
> 
>   - probe: probe callback detects PHY's operation mode based on
>     INTERF_SEL[1:0] pins and 1000X/100FX selection bit in SerDES 100-FX
>     Control register.
> 
>   - config_aneg: calls genphy_c37_config_aneg when the PHY is running in
>     1000Base-X mode; otherwise, genphy_config_aneg will be called.
> 
>   - read_status: calls genphy_c37_read_status when the PHY is running in
>     1000Base-X mode; otherwise, genphy_read_status will be called.
> 
> Signed-off-by: Tao Ren <taoren@fb.com>
> ---
>  Changes in v6:
>   - nothing changed.
>  Changes in v5:
>   - include Heiner's patch "net: phy: add support for clause 37
>     auto-negotiation" into the series.
>   - use genphy_c37_config_aneg and genphy_c37_read_status in BCM54616S
>     PHY driver's callback when the PHY is running in 1000Base-X mode.
>  Changes in v4:
>   - add bcm54616s_config_aneg_1000bx() to deal with auto negotiation in
>     1000Base-X mode.
>  Changes in v3:
>   - rename bcm5482_read_status to bcm54xx_read_status so the callback can
>     be shared by BCM5482 and BCM54616S.
>  Changes in v2:
>   - Auto-detect PHY operation mode instead of passing DT node.
>   - move PHY mode auto-detect logic from config_init to probe callback.
>   - only set speed (not including duplex) in read_status callback.
>   - update patch description with more background to avoid confusion.
>   - patch #1 in the series ("net: phy: broadcom: set features explicitly
>     for BCM54616") is dropped: the fix should go to get_features callback
>     which may potentially depend on this patch.
> 
>  drivers/net/phy/broadcom.c | 54 +++++++++++++++++++++++++++++++++++---
>  include/linux/brcmphy.h    | 10 +++++--
>  2 files changed, 58 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
> index 937d0059e8ac..fbd76a31c142 100644
> --- a/drivers/net/phy/broadcom.c
> +++ b/drivers/net/phy/broadcom.c
> @@ -383,9 +383,9 @@ static int bcm5482_config_init(struct phy_device *phydev)
>  		/*
>  		 * Select 1000BASE-X register set (primary SerDes)
>  		 */
> -		reg = bcm_phy_read_shadow(phydev, BCM5482_SHD_MODE);
> -		bcm_phy_write_shadow(phydev, BCM5482_SHD_MODE,
> -				     reg | BCM5482_SHD_MODE_1000BX);
> +		reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
> +		bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE,
> +				     reg | BCM54XX_SHD_MODE_1000BX);
>  
>  		/*
>  		 * LED1=ACTIVITYLED, LED3=LINKSPD[2]
> @@ -451,12 +451,44 @@ static int bcm5481_config_aneg(struct phy_device *phydev)
>  	return ret;
>  }
>  
> +static int bcm54616s_probe(struct phy_device *phydev)
> +{
> +	int val, intf_sel;
> +
> +	val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
> +	if (val < 0)
> +		return val;
> +
> +	/* The PHY is strapped in RGMII to fiber mode when INTERF_SEL[1:0]
> +	 * is 01b.
> +	 */
> +	intf_sel = (val & BCM54XX_SHD_INTF_SEL_MASK) >> 1;
> +	if (intf_sel == 1) {
> +		val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
> +		if (val < 0)
> +			return val;
> +
> +		/* Bit 0 of the SerDes 100-FX Control register, when set
> +		 * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
> +		 * When this bit is set to 0, it sets the GMII/RGMII ->
> +		 * 1000BASE-X configuration.
> +		 */
> +		if (!(val & BCM54616S_100FX_MODE))
> +			phydev->dev_flags |= PHY_BCM_FLAGS_MODE_1000BX;
> +	}
> +
> +	return 0;
> +}
> +
>  static int bcm54616s_config_aneg(struct phy_device *phydev)
>  {
>  	int ret;
>  
>  	/* Aneg firsly. */
> -	ret = genphy_config_aneg(phydev);
> +	if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
> +		ret = genphy_c37_config_aneg(phydev);
> +	else
> +		ret = genphy_config_aneg(phydev);
>  

I'm just wondering whether it needs to be considered that 100base-FX
doesn't support auto-negotiation. I suppose BMSR reports aneg as
supported, therefore phylib will use aneg per default.
Not sure who could set 100Base-FX mode when, but maybe at that place
also phydev->autoneg needs to be cleared. Did you test 100Base-FX mode?

Heiner

^ permalink raw reply

* [PATCH 05/16] net: remove ks8695 driver
From: Arnd Bergmann @ 2019-08-09 20:27 UTC (permalink / raw)
  To: soc; +Cc: Arnd Bergmann, David S. Miller, linux-kernel, netdev
In-Reply-To: <20190809202749.742267-1-arnd@arndb.de>

The platform is getting removed, so there are no remaining
users of this driver.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 drivers/net/ethernet/micrel/Kconfig     |   11 +-
 drivers/net/ethernet/micrel/Makefile    |    1 -
 drivers/net/ethernet/micrel/ks8695net.c | 1632 -----------------------
 drivers/net/ethernet/micrel/ks8695net.h |  108 --
 4 files changed, 1 insertion(+), 1751 deletions(-)
 delete mode 100644 drivers/net/ethernet/micrel/ks8695net.c
 delete mode 100644 drivers/net/ethernet/micrel/ks8695net.h

diff --git a/drivers/net/ethernet/micrel/Kconfig b/drivers/net/ethernet/micrel/Kconfig
index 90a8c6bead56..b9c4d48e28e4 100644
--- a/drivers/net/ethernet/micrel/Kconfig
+++ b/drivers/net/ethernet/micrel/Kconfig
@@ -6,8 +6,7 @@
 config NET_VENDOR_MICREL
 	bool "Micrel devices"
 	default y
-	depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM || \
-		   (ARM && ARCH_KS8695)
+	depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y.
 
@@ -18,14 +17,6 @@ config NET_VENDOR_MICREL
 
 if NET_VENDOR_MICREL
 
-config ARM_KS8695_ETHER
-	tristate "KS8695 Ethernet support"
-	depends on ARM && ARCH_KS8695
-	select MII
-	---help---
-	  If you wish to compile a kernel for the KS8695 and want to
-	  use the internal ethernet then you should answer Y to this.
-
 config KS8842
 	tristate "Micrel KSZ8841/42 with generic bus interface"
 	depends on HAS_IOMEM && DMA_ENGINE
diff --git a/drivers/net/ethernet/micrel/Makefile b/drivers/net/ethernet/micrel/Makefile
index 848fc1c5a5dc..6d8ac5527aef 100644
--- a/drivers/net/ethernet/micrel/Makefile
+++ b/drivers/net/ethernet/micrel/Makefile
@@ -3,7 +3,6 @@
 # Makefile for the Micrel network device drivers.
 #
 
-obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o
 obj-$(CONFIG_KS8842) += ks8842.o
 obj-$(CONFIG_KS8851) += ks8851.o
 obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c
deleted file mode 100644
index 1390ef5323a2..000000000000
--- a/drivers/net/ethernet/micrel/ks8695net.c
+++ /dev/null
@@ -1,1632 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Micrel KS8695 (Centaur) Ethernet.
- *
- * Copyright 2008 Simtec Electronics
- *		  Daniel Silverstone <dsilvers@simtec.co.uk>
- *		  Vincent Sanders <vince@simtec.co.uk>
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/interrupt.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <asm/irq.h>
-
-#include <mach/regs-switch.h>
-#include <mach/regs-misc.h>
-#include <asm/mach/irq.h>
-#include <mach/regs-irq.h>
-
-#include "ks8695net.h"
-
-#define MODULENAME	"ks8695_ether"
-#define MODULEVERSION	"1.02"
-
-/*
- * Transmit and device reset timeout, default 5 seconds.
- */
-static int watchdog = 5000;
-
-/* Hardware structures */
-
-/**
- *	struct rx_ring_desc - Receive descriptor ring element
- *	@status: The status of the descriptor element (E.g. who owns it)
- *	@length: The number of bytes in the block pointed to by data_ptr
- *	@data_ptr: The physical address of the data block to receive into
- *	@next_desc: The physical address of the next descriptor element.
- */
-struct rx_ring_desc {
-	__le32	status;
-	__le32	length;
-	__le32	data_ptr;
-	__le32	next_desc;
-};
-
-/**
- *	struct tx_ring_desc - Transmit descriptor ring element
- *	@owner: Who owns the descriptor
- *	@status: The number of bytes in the block pointed to by data_ptr
- *	@data_ptr: The physical address of the data block to receive into
- *	@next_desc: The physical address of the next descriptor element.
- */
-struct tx_ring_desc {
-	__le32	owner;
-	__le32	status;
-	__le32	data_ptr;
-	__le32	next_desc;
-};
-
-/**
- *	struct ks8695_skbuff - sk_buff wrapper for rx/tx rings.
- *	@skb: The buffer in the ring
- *	@dma_ptr: The mapped DMA pointer of the buffer
- *	@length: The number of bytes mapped to dma_ptr
- */
-struct ks8695_skbuff {
-	struct sk_buff	*skb;
-	dma_addr_t	dma_ptr;
-	u32		length;
-};
-
-/* Private device structure */
-
-#define MAX_TX_DESC 8
-#define MAX_TX_DESC_MASK 0x7
-#define MAX_RX_DESC 16
-#define MAX_RX_DESC_MASK 0xf
-
-/*napi_weight have better more than rx DMA buffers*/
-#define NAPI_WEIGHT   64
-
-#define MAX_RXBUF_SIZE 0x700
-
-#define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC)
-#define RX_RING_DMA_SIZE (sizeof(struct rx_ring_desc) * MAX_RX_DESC)
-#define RING_DMA_SIZE (TX_RING_DMA_SIZE + RX_RING_DMA_SIZE)
-
-/**
- *	enum ks8695_dtype - Device type
- *	@KS8695_DTYPE_WAN: This device is a WAN interface
- *	@KS8695_DTYPE_LAN: This device is a LAN interface
- *	@KS8695_DTYPE_HPNA: This device is an HPNA interface
- */
-enum ks8695_dtype {
-	KS8695_DTYPE_WAN,
-	KS8695_DTYPE_LAN,
-	KS8695_DTYPE_HPNA,
-};
-
-/**
- *	struct ks8695_priv - Private data for the KS8695 Ethernet
- *	@in_suspend: Flag to indicate if we're suspending/resuming
- *	@ndev: The net_device for this interface
- *	@dev: The platform device object for this interface
- *	@dtype: The type of this device
- *	@io_regs: The ioremapped registers for this interface
- *      @napi : Add support NAPI for Rx
- *	@rx_irq_name: The textual name of the RX IRQ from the platform data
- *	@tx_irq_name: The textual name of the TX IRQ from the platform data
- *	@link_irq_name: The textual name of the link IRQ from the
- *			platform data if available
- *	@rx_irq: The IRQ number for the RX IRQ
- *	@tx_irq: The IRQ number for the TX IRQ
- *	@link_irq: The IRQ number for the link IRQ if available
- *	@regs_req: The resource request for the registers region
- *	@phyiface_req: The resource request for the phy/switch region
- *		       if available
- *	@phyiface_regs: The ioremapped registers for the phy/switch if available
- *	@ring_base: The base pointer of the dma coherent memory for the rings
- *	@ring_base_dma: The DMA mapped equivalent of ring_base
- *	@tx_ring: The pointer in ring_base of the TX ring
- *	@tx_ring_used: The number of slots in the TX ring which are occupied
- *	@tx_ring_next_slot: The next slot to fill in the TX ring
- *	@tx_ring_dma: The DMA mapped equivalent of tx_ring
- *	@tx_buffers: The sk_buff mappings for the TX ring
- *	@txq_lock: A lock to protect the tx_buffers tx_ring_used etc variables
- *	@rx_ring: The pointer in ring_base of the RX ring
- *	@rx_ring_dma: The DMA mapped equivalent of rx_ring
- *	@rx_buffers: The sk_buff mappings for the RX ring
- *	@next_rx_desc_read: The next RX descriptor to read from on IRQ
- *      @rx_lock: A lock to protect Rx irq function
- *	@msg_enable: The flags for which messages to emit
- */
-struct ks8695_priv {
-	int in_suspend;
-	struct net_device *ndev;
-	struct device *dev;
-	enum ks8695_dtype dtype;
-	void __iomem *io_regs;
-
-	struct napi_struct	napi;
-
-	const char *rx_irq_name, *tx_irq_name, *link_irq_name;
-	int rx_irq, tx_irq, link_irq;
-
-	struct resource *regs_req, *phyiface_req;
-	void __iomem *phyiface_regs;
-
-	void *ring_base;
-	dma_addr_t ring_base_dma;
-
-	struct tx_ring_desc *tx_ring;
-	int tx_ring_used;
-	int tx_ring_next_slot;
-	dma_addr_t tx_ring_dma;
-	struct ks8695_skbuff tx_buffers[MAX_TX_DESC];
-	spinlock_t txq_lock;
-
-	struct rx_ring_desc *rx_ring;
-	dma_addr_t rx_ring_dma;
-	struct ks8695_skbuff rx_buffers[MAX_RX_DESC];
-	int next_rx_desc_read;
-	spinlock_t rx_lock;
-
-	int msg_enable;
-};
-
-/* Register access */
-
-/**
- *	ks8695_readreg - Read from a KS8695 ethernet register
- *	@ksp: The device to read from
- *	@reg: The register to read
- */
-static inline u32
-ks8695_readreg(struct ks8695_priv *ksp, int reg)
-{
-	return readl(ksp->io_regs + reg);
-}
-
-/**
- *	ks8695_writereg - Write to a KS8695 ethernet register
- *	@ksp: The device to write to
- *	@reg: The register to write
- *	@value: The value to write to the register
- */
-static inline void
-ks8695_writereg(struct ks8695_priv *ksp, int reg, u32 value)
-{
-	writel(value, ksp->io_regs + reg);
-}
-
-/* Utility functions */
-
-/**
- *	ks8695_port_type - Retrieve port-type as user-friendly string
- *	@ksp: The device to return the type for
- *
- *	Returns a string indicating which of the WAN, LAN or HPNA
- *	ports this device is likely to represent.
- */
-static const char *
-ks8695_port_type(struct ks8695_priv *ksp)
-{
-	switch (ksp->dtype) {
-	case KS8695_DTYPE_LAN:
-		return "LAN";
-	case KS8695_DTYPE_WAN:
-		return "WAN";
-	case KS8695_DTYPE_HPNA:
-		return "HPNA";
-	}
-
-	return "UNKNOWN";
-}
-
-/**
- *	ks8695_update_mac - Update the MAC registers in the device
- *	@ksp: The device to update
- *
- *	Updates the MAC registers in the KS8695 device from the address in the
- *	net_device structure associated with this interface.
- */
-static void
-ks8695_update_mac(struct ks8695_priv *ksp)
-{
-	/* Update the HW with the MAC from the net_device */
-	struct net_device *ndev = ksp->ndev;
-	u32 machigh, maclow;
-
-	maclow	= ((ndev->dev_addr[2] << 24) | (ndev->dev_addr[3] << 16) |
-		   (ndev->dev_addr[4] <<  8) | (ndev->dev_addr[5] <<  0));
-	machigh = ((ndev->dev_addr[0] <<  8) | (ndev->dev_addr[1] <<  0));
-
-	ks8695_writereg(ksp, KS8695_MAL, maclow);
-	ks8695_writereg(ksp, KS8695_MAH, machigh);
-
-}
-
-/**
- *	ks8695_refill_rxbuffers - Re-fill the RX buffer ring
- *	@ksp: The device to refill
- *
- *	Iterates the RX ring of the device looking for empty slots.
- *	For each empty slot, we allocate and map a new SKB and give it
- *	to the hardware.
- *	This can be called from interrupt context safely.
- */
-static void
-ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
-{
-	/* Run around the RX ring, filling in any missing sk_buff's */
-	int buff_n;
-
-	for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
-		if (!ksp->rx_buffers[buff_n].skb) {
-			struct sk_buff *skb =
-				netdev_alloc_skb(ksp->ndev, MAX_RXBUF_SIZE);
-			dma_addr_t mapping;
-
-			ksp->rx_buffers[buff_n].skb = skb;
-			if (skb == NULL) {
-				/* Failed to allocate one, perhaps
-				 * we'll try again later.
-				 */
-				break;
-			}
-
-			mapping = dma_map_single(ksp->dev, skb->data,
-						 MAX_RXBUF_SIZE,
-						 DMA_FROM_DEVICE);
-			if (unlikely(dma_mapping_error(ksp->dev, mapping))) {
-				/* Failed to DMA map this SKB, try later */
-				dev_kfree_skb_irq(skb);
-				ksp->rx_buffers[buff_n].skb = NULL;
-				break;
-			}
-			ksp->rx_buffers[buff_n].dma_ptr = mapping;
-			ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE;
-
-			/* Record this into the DMA ring */
-			ksp->rx_ring[buff_n].data_ptr = cpu_to_le32(mapping);
-			ksp->rx_ring[buff_n].length =
-				cpu_to_le32(MAX_RXBUF_SIZE);
-
-			wmb();
-
-			/* And give ownership over to the hardware */
-			ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
-		}
-	}
-}
-
-/* Maximum number of multicast addresses which the KS8695 HW supports */
-#define KS8695_NR_ADDRESSES	16
-
-/**
- *	ks8695_init_partial_multicast - Init the mcast addr registers
- *	@ksp: The device to initialise
- *	@addr: The multicast address list to use
- *	@nr_addr: The number of addresses in the list
- *
- *	This routine is a helper for ks8695_set_multicast - it writes
- *	the additional-address registers in the KS8695 ethernet device
- *	and cleans up any others left behind.
- */
-static void
-ks8695_init_partial_multicast(struct ks8695_priv *ksp,
-			      struct net_device *ndev)
-{
-	u32 low, high;
-	int i;
-	struct netdev_hw_addr *ha;
-
-	i = 0;
-	netdev_for_each_mc_addr(ha, ndev) {
-		/* Ran out of space in chip? */
-		BUG_ON(i == KS8695_NR_ADDRESSES);
-
-		low = (ha->addr[2] << 24) | (ha->addr[3] << 16) |
-		      (ha->addr[4] << 8) | (ha->addr[5]);
-		high = (ha->addr[0] << 8) | (ha->addr[1]);
-
-		ks8695_writereg(ksp, KS8695_AAL_(i), low);
-		ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high);
-		i++;
-	}
-
-	/* Clear the remaining Additional Station Addresses */
-	for (; i < KS8695_NR_ADDRESSES; i++) {
-		ks8695_writereg(ksp, KS8695_AAL_(i), 0);
-		ks8695_writereg(ksp, KS8695_AAH_(i), 0);
-	}
-}
-
-/* Interrupt handling */
-
-/**
- *	ks8695_tx_irq - Transmit IRQ handler
- *	@irq: The IRQ which went off (ignored)
- *	@dev_id: The net_device for the interrupt
- *
- *	Process the TX ring, clearing out any transmitted slots.
- *	Allows the net_device to pass us new packets once slots are
- *	freed.
- */
-static irqreturn_t
-ks8695_tx_irq(int irq, void *dev_id)
-{
-	struct net_device *ndev = (struct net_device *)dev_id;
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	int buff_n;
-
-	for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
-		if (ksp->tx_buffers[buff_n].skb &&
-		    !(ksp->tx_ring[buff_n].owner & cpu_to_le32(TDES_OWN))) {
-			rmb();
-			/* An SKB which is not owned by HW is present */
-			/* Update the stats for the net_device */
-			ndev->stats.tx_packets++;
-			ndev->stats.tx_bytes += ksp->tx_buffers[buff_n].length;
-
-			/* Free the packet from the ring */
-			ksp->tx_ring[buff_n].data_ptr = 0;
-
-			/* Free the sk_buff */
-			dma_unmap_single(ksp->dev,
-					 ksp->tx_buffers[buff_n].dma_ptr,
-					 ksp->tx_buffers[buff_n].length,
-					 DMA_TO_DEVICE);
-			dev_consume_skb_irq(ksp->tx_buffers[buff_n].skb);
-			ksp->tx_buffers[buff_n].skb = NULL;
-			ksp->tx_ring_used--;
-		}
-	}
-
-	netif_wake_queue(ndev);
-
-	return IRQ_HANDLED;
-}
-
-/**
- *	ks8695_get_rx_enable_bit - Get rx interrupt enable/status bit
- *	@ksp: Private data for the KS8695 Ethernet
- *
- *    For KS8695 document:
- *    Interrupt Enable Register (offset 0xE204)
- *        Bit29 : WAN MAC Receive Interrupt Enable
- *        Bit16 : LAN MAC Receive Interrupt Enable
- *    Interrupt Status Register (Offset 0xF208)
- *        Bit29: WAN MAC Receive Status
- *        Bit16: LAN MAC Receive Status
- *    So, this Rx interrupt enable/status bit number is equal
- *    as Rx IRQ number.
- */
-static inline u32 ks8695_get_rx_enable_bit(struct ks8695_priv *ksp)
-{
-	return ksp->rx_irq;
-}
-
-/**
- *	ks8695_rx_irq - Receive IRQ handler
- *	@irq: The IRQ which went off (ignored)
- *	@dev_id: The net_device for the interrupt
- *
- *	Inform NAPI that packet reception needs to be scheduled
- */
-
-static irqreturn_t
-ks8695_rx_irq(int irq, void *dev_id)
-{
-	struct net_device *ndev = (struct net_device *)dev_id;
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	spin_lock(&ksp->rx_lock);
-
-	if (napi_schedule_prep(&ksp->napi)) {
-		unsigned long status = readl(KS8695_IRQ_VA + KS8695_INTEN);
-		unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
-		/*disable rx interrupt*/
-		status &= ~mask_bit;
-		writel(status , KS8695_IRQ_VA + KS8695_INTEN);
-		__napi_schedule(&ksp->napi);
-	}
-
-	spin_unlock(&ksp->rx_lock);
-	return IRQ_HANDLED;
-}
-
-/**
- *	ks8695_rx - Receive packets called by NAPI poll method
- *	@ksp: Private data for the KS8695 Ethernet
- *	@budget: Number of packets allowed to process
- */
-static int ks8695_rx(struct ks8695_priv *ksp, int budget)
-{
-	struct net_device *ndev = ksp->ndev;
-	struct sk_buff *skb;
-	int buff_n;
-	u32 flags;
-	int pktlen;
-	int received = 0;
-
-	buff_n = ksp->next_rx_desc_read;
-	while (received < budget
-			&& ksp->rx_buffers[buff_n].skb
-			&& (!(ksp->rx_ring[buff_n].status &
-					cpu_to_le32(RDES_OWN)))) {
-			rmb();
-			flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
-
-			/* Found an SKB which we own, this means we
-			 * received a packet
-			 */
-			if ((flags & (RDES_FS | RDES_LS)) !=
-			    (RDES_FS | RDES_LS)) {
-				/* This packet is not the first and
-				 * the last segment.  Therefore it is
-				 * a "spanning" packet and we can't
-				 * handle it
-				 */
-				goto rx_failure;
-			}
-
-			if (flags & (RDES_ES | RDES_RE)) {
-				/* It's an error packet */
-				ndev->stats.rx_errors++;
-				if (flags & RDES_TL)
-					ndev->stats.rx_length_errors++;
-				if (flags & RDES_RF)
-					ndev->stats.rx_length_errors++;
-				if (flags & RDES_CE)
-					ndev->stats.rx_crc_errors++;
-				if (flags & RDES_RE)
-					ndev->stats.rx_missed_errors++;
-
-				goto rx_failure;
-			}
-
-			pktlen = flags & RDES_FLEN;
-			pktlen -= 4; /* Drop the CRC */
-
-			/* Retrieve the sk_buff */
-			skb = ksp->rx_buffers[buff_n].skb;
-
-			/* Clear it from the ring */
-			ksp->rx_buffers[buff_n].skb = NULL;
-			ksp->rx_ring[buff_n].data_ptr = 0;
-
-			/* Unmap the SKB */
-			dma_unmap_single(ksp->dev,
-					 ksp->rx_buffers[buff_n].dma_ptr,
-					 ksp->rx_buffers[buff_n].length,
-					 DMA_FROM_DEVICE);
-
-			/* Relinquish the SKB to the network layer */
-			skb_put(skb, pktlen);
-			skb->protocol = eth_type_trans(skb, ndev);
-			napi_gro_receive(&ksp->napi, skb);
-
-			/* Record stats */
-			ndev->stats.rx_packets++;
-			ndev->stats.rx_bytes += pktlen;
-			goto rx_finished;
-
-rx_failure:
-			/* This ring entry is an error, but we can
-			 * re-use the skb
-			 */
-			/* Give the ring entry back to the hardware */
-			ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
-rx_finished:
-			received++;
-			buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
-	}
-
-	/* And note which RX descriptor we last did */
-	ksp->next_rx_desc_read = buff_n;
-
-	/* And refill the buffers */
-	ks8695_refill_rxbuffers(ksp);
-
-	/* Kick the RX DMA engine, in case it became suspended */
-	ks8695_writereg(ksp, KS8695_DRSC, 0);
-
-	return received;
-}
-
-
-/**
- *	ks8695_poll - Receive packet by NAPI poll method
- *	@ksp: Private data for the KS8695 Ethernet
- *	@budget: The remaining number packets for network subsystem
- *
- *     Invoked by the network core when it requests for new
- *     packets from the driver
- */
-static int ks8695_poll(struct napi_struct *napi, int budget)
-{
-	struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi);
-	unsigned long isr = readl(KS8695_IRQ_VA + KS8695_INTEN);
-	unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
-	int work_done;
-
-	work_done = ks8695_rx(ksp, budget);
-
-	if (work_done < budget && napi_complete_done(napi, work_done)) {
-		unsigned long flags;
-
-		spin_lock_irqsave(&ksp->rx_lock, flags);
-		/* enable rx interrupt */
-		writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
-		spin_unlock_irqrestore(&ksp->rx_lock, flags);
-	}
-	return work_done;
-}
-
-/**
- *	ks8695_link_irq - Link change IRQ handler
- *	@irq: The IRQ which went off (ignored)
- *	@dev_id: The net_device for the interrupt
- *
- *	The WAN interface can generate an IRQ when the link changes,
- *	report this to the net layer and the user.
- */
-static irqreturn_t
-ks8695_link_irq(int irq, void *dev_id)
-{
-	struct net_device *ndev = (struct net_device *)dev_id;
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	u32 ctrl;
-
-	ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-	if (ctrl & WMC_WLS) {
-		netif_carrier_on(ndev);
-		if (netif_msg_link(ksp))
-			dev_info(ksp->dev,
-				 "%s: Link is now up (10%sMbps/%s-duplex)\n",
-				 ndev->name,
-				 (ctrl & WMC_WSS) ? "0" : "",
-				 (ctrl & WMC_WDS) ? "Full" : "Half");
-	} else {
-		netif_carrier_off(ndev);
-		if (netif_msg_link(ksp))
-			dev_info(ksp->dev, "%s: Link is now down.\n",
-				 ndev->name);
-	}
-
-	return IRQ_HANDLED;
-}
-
-
-/* KS8695 Device functions */
-
-/**
- *	ks8695_reset - Reset a KS8695 ethernet interface
- *	@ksp: The interface to reset
- *
- *	Perform an engine reset of the interface and re-program it
- *	with sensible defaults.
- */
-static void
-ks8695_reset(struct ks8695_priv *ksp)
-{
-	int reset_timeout = watchdog;
-	/* Issue the reset via the TX DMA control register */
-	ks8695_writereg(ksp, KS8695_DTXC, DTXC_TRST);
-	while (reset_timeout--) {
-		if (!(ks8695_readreg(ksp, KS8695_DTXC) & DTXC_TRST))
-			break;
-		msleep(1);
-	}
-
-	if (reset_timeout < 0) {
-		dev_crit(ksp->dev,
-			 "Timeout waiting for DMA engines to reset\n");
-		/* And blithely carry on */
-	}
-
-	/* Definitely wait long enough before attempting to program
-	 * the engines
-	 */
-	msleep(10);
-
-	/* RX: unicast and broadcast */
-	ks8695_writereg(ksp, KS8695_DRXC, DRXC_RU | DRXC_RB);
-	/* TX: pad and add CRC */
-	ks8695_writereg(ksp, KS8695_DTXC, DTXC_TEP | DTXC_TAC);
-}
-
-/**
- *	ks8695_shutdown - Shut down a KS8695 ethernet interface
- *	@ksp: The interface to shut down
- *
- *	This disables packet RX/TX, cleans up IRQs, drains the rings,
- *	and basically places the interface into a clean shutdown
- *	state.
- */
-static void
-ks8695_shutdown(struct ks8695_priv *ksp)
-{
-	u32 ctrl;
-	int buff_n;
-
-	/* Disable packet transmission */
-	ctrl = ks8695_readreg(ksp, KS8695_DTXC);
-	ks8695_writereg(ksp, KS8695_DTXC, ctrl & ~DTXC_TE);
-
-	/* Disable packet reception */
-	ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-	ks8695_writereg(ksp, KS8695_DRXC, ctrl & ~DRXC_RE);
-
-	/* Release the IRQs */
-	free_irq(ksp->rx_irq, ksp->ndev);
-	free_irq(ksp->tx_irq, ksp->ndev);
-	if (ksp->link_irq != -1)
-		free_irq(ksp->link_irq, ksp->ndev);
-
-	/* Throw away any pending TX packets */
-	for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
-		if (ksp->tx_buffers[buff_n].skb) {
-			/* Remove this SKB from the TX ring */
-			ksp->tx_ring[buff_n].owner = 0;
-			ksp->tx_ring[buff_n].status = 0;
-			ksp->tx_ring[buff_n].data_ptr = 0;
-
-			/* Unmap and bin this SKB */
-			dma_unmap_single(ksp->dev,
-					 ksp->tx_buffers[buff_n].dma_ptr,
-					 ksp->tx_buffers[buff_n].length,
-					 DMA_TO_DEVICE);
-			dev_kfree_skb_irq(ksp->tx_buffers[buff_n].skb);
-			ksp->tx_buffers[buff_n].skb = NULL;
-		}
-	}
-
-	/* Purge the RX buffers */
-	for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
-		if (ksp->rx_buffers[buff_n].skb) {
-			/* Remove the SKB from the RX ring */
-			ksp->rx_ring[buff_n].status = 0;
-			ksp->rx_ring[buff_n].data_ptr = 0;
-
-			/* Unmap and bin the SKB */
-			dma_unmap_single(ksp->dev,
-					 ksp->rx_buffers[buff_n].dma_ptr,
-					 ksp->rx_buffers[buff_n].length,
-					 DMA_FROM_DEVICE);
-			dev_kfree_skb_irq(ksp->rx_buffers[buff_n].skb);
-			ksp->rx_buffers[buff_n].skb = NULL;
-		}
-	}
-}
-
-
-/**
- *	ks8695_setup_irq - IRQ setup helper function
- *	@irq: The IRQ number to claim
- *	@irq_name: The name to give the IRQ claimant
- *	@handler: The function to call to handle the IRQ
- *	@ndev: The net_device to pass in as the dev_id argument to the handler
- *
- *	Return 0 on success.
- */
-static int
-ks8695_setup_irq(int irq, const char *irq_name,
-		 irq_handler_t handler, struct net_device *ndev)
-{
-	int ret;
-
-	ret = request_irq(irq, handler, IRQF_SHARED, irq_name, ndev);
-
-	if (ret) {
-		dev_err(&ndev->dev, "failure to request IRQ %d\n", irq);
-		return ret;
-	}
-
-	return 0;
-}
-
-/**
- *	ks8695_init_net - Initialise a KS8695 ethernet interface
- *	@ksp: The interface to initialise
- *
- *	This routine fills the RX ring, initialises the DMA engines,
- *	allocates the IRQs and then starts the packet TX and RX
- *	engines.
- */
-static int
-ks8695_init_net(struct ks8695_priv *ksp)
-{
-	int ret;
-	u32 ctrl;
-
-	ks8695_refill_rxbuffers(ksp);
-
-	/* Initialise the DMA engines */
-	ks8695_writereg(ksp, KS8695_RDLB, (u32) ksp->rx_ring_dma);
-	ks8695_writereg(ksp, KS8695_TDLB, (u32) ksp->tx_ring_dma);
-
-	/* Request the IRQs */
-	ret = ks8695_setup_irq(ksp->rx_irq, ksp->rx_irq_name,
-			       ks8695_rx_irq, ksp->ndev);
-	if (ret)
-		return ret;
-	ret = ks8695_setup_irq(ksp->tx_irq, ksp->tx_irq_name,
-			       ks8695_tx_irq, ksp->ndev);
-	if (ret)
-		return ret;
-	if (ksp->link_irq != -1) {
-		ret = ks8695_setup_irq(ksp->link_irq, ksp->link_irq_name,
-				       ks8695_link_irq, ksp->ndev);
-		if (ret)
-			return ret;
-	}
-
-	/* Set up the ring indices */
-	ksp->next_rx_desc_read = 0;
-	ksp->tx_ring_next_slot = 0;
-	ksp->tx_ring_used = 0;
-
-	/* Bring up transmission */
-	ctrl = ks8695_readreg(ksp, KS8695_DTXC);
-	/* Enable packet transmission */
-	ks8695_writereg(ksp, KS8695_DTXC, ctrl | DTXC_TE);
-
-	/* Bring up the reception */
-	ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-	/* Enable packet reception */
-	ks8695_writereg(ksp, KS8695_DRXC, ctrl | DRXC_RE);
-	/* And start the DMA engine */
-	ks8695_writereg(ksp, KS8695_DRSC, 0);
-
-	/* All done */
-	return 0;
-}
-
-/**
- *	ks8695_release_device - HW resource release for KS8695 e-net
- *	@ksp: The device to be freed
- *
- *	This unallocates io memory regions, dma-coherent regions etc
- *	which were allocated in ks8695_probe.
- */
-static void
-ks8695_release_device(struct ks8695_priv *ksp)
-{
-	/* Unmap the registers */
-	iounmap(ksp->io_regs);
-	if (ksp->phyiface_regs)
-		iounmap(ksp->phyiface_regs);
-
-	/* And release the request */
-	release_resource(ksp->regs_req);
-	kfree(ksp->regs_req);
-	if (ksp->phyiface_req) {
-		release_resource(ksp->phyiface_req);
-		kfree(ksp->phyiface_req);
-	}
-
-	/* Free the ring buffers */
-	dma_free_coherent(ksp->dev, RING_DMA_SIZE,
-			  ksp->ring_base, ksp->ring_base_dma);
-}
-
-/* Ethtool support */
-
-/**
- *	ks8695_get_msglevel - Get the messages enabled for emission
- *	@ndev: The network device to read from
- */
-static u32
-ks8695_get_msglevel(struct net_device *ndev)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	return ksp->msg_enable;
-}
-
-/**
- *	ks8695_set_msglevel - Set the messages enabled for emission
- *	@ndev: The network device to configure
- *	@value: The messages to set for emission
- */
-static void
-ks8695_set_msglevel(struct net_device *ndev, u32 value)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	ksp->msg_enable = value;
-}
-
-/**
- *	ks8695_wan_get_link_ksettings - Get device-specific settings.
- *	@ndev: The network device to read settings from
- *	@cmd: The ethtool structure to read into
- */
-static int
-ks8695_wan_get_link_ksettings(struct net_device *ndev,
-			      struct ethtool_link_ksettings *cmd)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	u32 ctrl;
-	u32 supported, advertising;
-
-	/* All ports on the KS8695 support these... */
-	supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
-			  SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
-			  SUPPORTED_TP | SUPPORTED_MII);
-
-	advertising = ADVERTISED_TP | ADVERTISED_MII;
-	cmd->base.port = PORT_MII;
-	supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
-	cmd->base.phy_address = 0;
-
-	ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-	if ((ctrl & WMC_WAND) == 0) {
-		/* auto-negotiation is enabled */
-		advertising |= ADVERTISED_Autoneg;
-		if (ctrl & WMC_WANA100F)
-			advertising |= ADVERTISED_100baseT_Full;
-		if (ctrl & WMC_WANA100H)
-			advertising |= ADVERTISED_100baseT_Half;
-		if (ctrl & WMC_WANA10F)
-			advertising |= ADVERTISED_10baseT_Full;
-		if (ctrl & WMC_WANA10H)
-			advertising |= ADVERTISED_10baseT_Half;
-		if (ctrl & WMC_WANAP)
-			advertising |= ADVERTISED_Pause;
-		cmd->base.autoneg = AUTONEG_ENABLE;
-
-		cmd->base.speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
-		cmd->base.duplex = (ctrl & WMC_WDS) ?
-			DUPLEX_FULL : DUPLEX_HALF;
-	} else {
-		/* auto-negotiation is disabled */
-		cmd->base.autoneg = AUTONEG_DISABLE;
-
-		cmd->base.speed = (ctrl & WMC_WANF100) ?
-					    SPEED_100 : SPEED_10;
-		cmd->base.duplex = (ctrl & WMC_WANFF) ?
-			DUPLEX_FULL : DUPLEX_HALF;
-	}
-
-	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
-						supported);
-	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
-						advertising);
-
-	return 0;
-}
-
-/**
- *	ks8695_wan_set_link_ksettings - Set device-specific settings.
- *	@ndev: The network device to configure
- *	@cmd: The settings to configure
- */
-static int
-ks8695_wan_set_link_ksettings(struct net_device *ndev,
-			      const struct ethtool_link_ksettings *cmd)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	u32 ctrl;
-	u32 advertising;
-
-	ethtool_convert_link_mode_to_legacy_u32(&advertising,
-						cmd->link_modes.advertising);
-
-	if ((cmd->base.speed != SPEED_10) && (cmd->base.speed != SPEED_100))
-		return -EINVAL;
-	if ((cmd->base.duplex != DUPLEX_HALF) &&
-	    (cmd->base.duplex != DUPLEX_FULL))
-		return -EINVAL;
-	if (cmd->base.port != PORT_MII)
-		return -EINVAL;
-	if ((cmd->base.autoneg != AUTONEG_DISABLE) &&
-	    (cmd->base.autoneg != AUTONEG_ENABLE))
-		return -EINVAL;
-
-	if (cmd->base.autoneg == AUTONEG_ENABLE) {
-		if ((advertising & (ADVERTISED_10baseT_Half |
-				ADVERTISED_10baseT_Full |
-				ADVERTISED_100baseT_Half |
-				ADVERTISED_100baseT_Full)) == 0)
-			return -EINVAL;
-
-		ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-		ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
-			  WMC_WANA10F | WMC_WANA10H);
-		if (advertising & ADVERTISED_100baseT_Full)
-			ctrl |= WMC_WANA100F;
-		if (advertising & ADVERTISED_100baseT_Half)
-			ctrl |= WMC_WANA100H;
-		if (advertising & ADVERTISED_10baseT_Full)
-			ctrl |= WMC_WANA10F;
-		if (advertising & ADVERTISED_10baseT_Half)
-			ctrl |= WMC_WANA10H;
-
-		/* force a re-negotiation */
-		ctrl |= WMC_WANR;
-		writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-	} else {
-		ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-		/* disable auto-negotiation */
-		ctrl |= WMC_WAND;
-		ctrl &= ~(WMC_WANF100 | WMC_WANFF);
-
-		if (cmd->base.speed == SPEED_100)
-			ctrl |= WMC_WANF100;
-		if (cmd->base.duplex == DUPLEX_FULL)
-			ctrl |= WMC_WANFF;
-
-		writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-	}
-
-	return 0;
-}
-
-/**
- *	ks8695_wan_nwayreset - Restart the autonegotiation on the port.
- *	@ndev: The network device to restart autoneotiation on
- */
-static int
-ks8695_wan_nwayreset(struct net_device *ndev)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	u32 ctrl;
-
-	ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-	if ((ctrl & WMC_WAND) == 0)
-		writel(ctrl | WMC_WANR,
-		       ksp->phyiface_regs + KS8695_WMC);
-	else
-		/* auto-negotiation not enabled */
-		return -EINVAL;
-
-	return 0;
-}
-
-/**
- *	ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
- *	@ndev: The device to retrieve settings from
- *	@param: The structure to fill out with the information
- */
-static void
-ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	u32 ctrl;
-
-	ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-	/* advertise Pause */
-	param->autoneg = (ctrl & WMC_WANAP);
-
-	/* current Rx Flow-control */
-	ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-	param->rx_pause = (ctrl & DRXC_RFCE);
-
-	/* current Tx Flow-control */
-	ctrl = ks8695_readreg(ksp, KS8695_DTXC);
-	param->tx_pause = (ctrl & DTXC_TFCE);
-}
-
-/**
- *	ks8695_get_drvinfo - Retrieve driver information
- *	@ndev: The network device to retrieve info about
- *	@info: The info structure to fill out.
- */
-static void
-ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
-{
-	strlcpy(info->driver, MODULENAME, sizeof(info->driver));
-	strlcpy(info->version, MODULEVERSION, sizeof(info->version));
-	strlcpy(info->bus_info, dev_name(ndev->dev.parent),
-		sizeof(info->bus_info));
-}
-
-static const struct ethtool_ops ks8695_ethtool_ops = {
-	.get_msglevel	= ks8695_get_msglevel,
-	.set_msglevel	= ks8695_set_msglevel,
-	.get_drvinfo	= ks8695_get_drvinfo,
-};
-
-static const struct ethtool_ops ks8695_wan_ethtool_ops = {
-	.get_msglevel	= ks8695_get_msglevel,
-	.set_msglevel	= ks8695_set_msglevel,
-	.nway_reset	= ks8695_wan_nwayreset,
-	.get_link	= ethtool_op_get_link,
-	.get_pauseparam = ks8695_wan_get_pause,
-	.get_drvinfo	= ks8695_get_drvinfo,
-	.get_link_ksettings = ks8695_wan_get_link_ksettings,
-	.set_link_ksettings = ks8695_wan_set_link_ksettings,
-};
-
-/* Network device interface functions */
-
-/**
- *	ks8695_set_mac - Update MAC in net dev and HW
- *	@ndev: The network device to update
- *	@addr: The new MAC address to set
- */
-static int
-ks8695_set_mac(struct net_device *ndev, void *addr)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	struct sockaddr *address = addr;
-
-	if (!is_valid_ether_addr(address->sa_data))
-		return -EADDRNOTAVAIL;
-
-	memcpy(ndev->dev_addr, address->sa_data, ndev->addr_len);
-
-	ks8695_update_mac(ksp);
-
-	dev_dbg(ksp->dev, "%s: Updated MAC address to %pM\n",
-		ndev->name, ndev->dev_addr);
-
-	return 0;
-}
-
-/**
- *	ks8695_set_multicast - Set up the multicast behaviour of the interface
- *	@ndev: The net_device to configure
- *
- *	This routine, called by the net layer, configures promiscuity
- *	and multicast reception behaviour for the interface.
- */
-static void
-ks8695_set_multicast(struct net_device *ndev)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	u32 ctrl;
-
-	ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-
-	if (ndev->flags & IFF_PROMISC) {
-		/* enable promiscuous mode */
-		ctrl |= DRXC_RA;
-	} else if (ndev->flags & ~IFF_PROMISC) {
-		/* disable promiscuous mode */
-		ctrl &= ~DRXC_RA;
-	}
-
-	if (ndev->flags & IFF_ALLMULTI) {
-		/* enable all multicast mode */
-		ctrl |= DRXC_RM;
-	} else if (netdev_mc_count(ndev) > KS8695_NR_ADDRESSES) {
-		/* more specific multicast addresses than can be
-		 * handled in hardware
-		 */
-		ctrl |= DRXC_RM;
-	} else {
-		/* enable specific multicasts */
-		ctrl &= ~DRXC_RM;
-		ks8695_init_partial_multicast(ksp, ndev);
-	}
-
-	ks8695_writereg(ksp, KS8695_DRXC, ctrl);
-}
-
-/**
- *	ks8695_timeout - Handle a network tx/rx timeout.
- *	@ndev: The net_device which timed out.
- *
- *	A network transaction timed out, reset the device.
- */
-static void
-ks8695_timeout(struct net_device *ndev)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	netif_stop_queue(ndev);
-	ks8695_shutdown(ksp);
-
-	ks8695_reset(ksp);
-
-	ks8695_update_mac(ksp);
-
-	/* We ignore the return from this since it managed to init
-	 * before it probably will be okay to init again.
-	 */
-	ks8695_init_net(ksp);
-
-	/* Reconfigure promiscuity etc */
-	ks8695_set_multicast(ndev);
-
-	/* And start the TX queue once more */
-	netif_start_queue(ndev);
-}
-
-/**
- *	ks8695_start_xmit - Start a packet transmission
- *	@skb: The packet to transmit
- *	@ndev: The network device to send the packet on
- *
- *	This routine, called by the net layer, takes ownership of the
- *	sk_buff and adds it to the TX ring. It then kicks the TX DMA
- *	engine to ensure transmission begins.
- */
-static netdev_tx_t
-ks8695_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	int buff_n;
-	dma_addr_t dmap;
-
-	spin_lock_irq(&ksp->txq_lock);
-
-	if (ksp->tx_ring_used == MAX_TX_DESC) {
-		/* Somehow we got entered when we have no room */
-		spin_unlock_irq(&ksp->txq_lock);
-		return NETDEV_TX_BUSY;
-	}
-
-	buff_n = ksp->tx_ring_next_slot;
-
-	BUG_ON(ksp->tx_buffers[buff_n].skb);
-
-	dmap = dma_map_single(ksp->dev, skb->data, skb->len, DMA_TO_DEVICE);
-	if (unlikely(dma_mapping_error(ksp->dev, dmap))) {
-		/* Failed to DMA map this SKB, give it back for now */
-		spin_unlock_irq(&ksp->txq_lock);
-		dev_dbg(ksp->dev, "%s: Could not map DMA memory for "\
-			"transmission, trying later\n", ndev->name);
-		return NETDEV_TX_BUSY;
-	}
-
-	ksp->tx_buffers[buff_n].dma_ptr = dmap;
-	/* Mapped okay, store the buffer pointer and length for later */
-	ksp->tx_buffers[buff_n].skb = skb;
-	ksp->tx_buffers[buff_n].length = skb->len;
-
-	/* Fill out the TX descriptor */
-	ksp->tx_ring[buff_n].data_ptr =
-		cpu_to_le32(ksp->tx_buffers[buff_n].dma_ptr);
-	ksp->tx_ring[buff_n].status =
-		cpu_to_le32(TDES_IC | TDES_FS | TDES_LS |
-			    (skb->len & TDES_TBS));
-
-	wmb();
-
-	/* Hand it over to the hardware */
-	ksp->tx_ring[buff_n].owner = cpu_to_le32(TDES_OWN);
-
-	if (++ksp->tx_ring_used == MAX_TX_DESC)
-		netif_stop_queue(ndev);
-
-	/* Kick the TX DMA in case it decided to go IDLE */
-	ks8695_writereg(ksp, KS8695_DTSC, 0);
-
-	/* And update the next ring slot */
-	ksp->tx_ring_next_slot = (buff_n + 1) & MAX_TX_DESC_MASK;
-
-	spin_unlock_irq(&ksp->txq_lock);
-	return NETDEV_TX_OK;
-}
-
-/**
- *	ks8695_stop - Stop (shutdown) a KS8695 ethernet interface
- *	@ndev: The net_device to stop
- *
- *	This disables the TX queue and cleans up a KS8695 ethernet
- *	device.
- */
-static int
-ks8695_stop(struct net_device *ndev)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	netif_stop_queue(ndev);
-	napi_disable(&ksp->napi);
-
-	ks8695_shutdown(ksp);
-
-	return 0;
-}
-
-/**
- *	ks8695_open - Open (bring up) a KS8695 ethernet interface
- *	@ndev: The net_device to open
- *
- *	This resets, configures the MAC, initialises the RX ring and
- *	DMA engines and starts the TX queue for a KS8695 ethernet
- *	device.
- */
-static int
-ks8695_open(struct net_device *ndev)
-{
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-	int ret;
-
-	ks8695_reset(ksp);
-
-	ks8695_update_mac(ksp);
-
-	ret = ks8695_init_net(ksp);
-	if (ret) {
-		ks8695_shutdown(ksp);
-		return ret;
-	}
-
-	napi_enable(&ksp->napi);
-	netif_start_queue(ndev);
-
-	return 0;
-}
-
-/* Platform device driver */
-
-/**
- *	ks8695_init_switch - Init LAN switch to known good defaults.
- *	@ksp: The device to initialise
- *
- *	This initialises the LAN switch in the KS8695 to a known-good
- *	set of defaults.
- */
-static void
-ks8695_init_switch(struct ks8695_priv *ksp)
-{
-	u32 ctrl;
-
-	/* Default value for SEC0 according to datasheet */
-	ctrl = 0x40819e00;
-
-	/* LED0 = Speed	 LED1 = Link/Activity */
-	ctrl &= ~(SEC0_LLED1S | SEC0_LLED0S);
-	ctrl |= (LLED0S_LINK | LLED1S_LINK_ACTIVITY);
-
-	/* Enable Switch */
-	ctrl |= SEC0_ENABLE;
-
-	writel(ctrl, ksp->phyiface_regs + KS8695_SEC0);
-
-	/* Defaults for SEC1 */
-	writel(0x9400100, ksp->phyiface_regs + KS8695_SEC1);
-}
-
-/**
- *	ks8695_init_wan_phy - Initialise the WAN PHY to sensible defaults
- *	@ksp: The device to initialise
- *
- *	This initialises a KS8695's WAN phy to sensible values for
- *	autonegotiation etc.
- */
-static void
-ks8695_init_wan_phy(struct ks8695_priv *ksp)
-{
-	u32 ctrl;
-
-	/* Support auto-negotiation */
-	ctrl = (WMC_WANAP | WMC_WANA100F | WMC_WANA100H |
-		WMC_WANA10F | WMC_WANA10H);
-
-	/* LED0 = Activity , LED1 = Link */
-	ctrl |= (WLED0S_ACTIVITY | WLED1S_LINK);
-
-	/* Restart Auto-negotiation */
-	ctrl |= WMC_WANR;
-
-	writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-
-	writel(0, ksp->phyiface_regs + KS8695_WPPM);
-	writel(0, ksp->phyiface_regs + KS8695_PPS);
-}
-
-static const struct net_device_ops ks8695_netdev_ops = {
-	.ndo_open		= ks8695_open,
-	.ndo_stop		= ks8695_stop,
-	.ndo_start_xmit		= ks8695_start_xmit,
-	.ndo_tx_timeout		= ks8695_timeout,
-	.ndo_set_mac_address	= ks8695_set_mac,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_rx_mode	= ks8695_set_multicast,
-};
-
-/**
- *	ks8695_probe - Probe and initialise a KS8695 ethernet interface
- *	@pdev: The platform device to probe
- *
- *	Initialise a KS8695 ethernet device from platform data.
- *
- *	This driver requires at least one IORESOURCE_MEM for the
- *	registers and two IORESOURCE_IRQ for the RX and TX IRQs
- *	respectively. It can optionally take an additional
- *	IORESOURCE_MEM for the switch or phy in the case of the lan or
- *	wan ports, and an IORESOURCE_IRQ for the link IRQ for the wan
- *	port.
- */
-static int
-ks8695_probe(struct platform_device *pdev)
-{
-	struct ks8695_priv *ksp;
-	struct net_device *ndev;
-	struct resource *regs_res, *phyiface_res;
-	struct resource *rxirq_res, *txirq_res, *linkirq_res;
-	int ret = 0;
-	int buff_n;
-	bool inv_mac_addr = false;
-	u32 machigh, maclow;
-
-	/* Initialise a net_device */
-	ndev = alloc_etherdev(sizeof(struct ks8695_priv));
-	if (!ndev)
-		return -ENOMEM;
-
-	SET_NETDEV_DEV(ndev, &pdev->dev);
-
-	dev_dbg(&pdev->dev, "ks8695_probe() called\n");
-
-	/* Configure our private structure a little */
-	ksp = netdev_priv(ndev);
-
-	ksp->dev = &pdev->dev;
-	ksp->ndev = ndev;
-	ksp->msg_enable = NETIF_MSG_LINK;
-
-	/* Retrieve resources */
-	regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	phyiface_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-
-	rxirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	txirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-	linkirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
-
-	if (!(regs_res && rxirq_res && txirq_res)) {
-		dev_err(ksp->dev, "insufficient resources\n");
-		ret = -ENOENT;
-		goto failure;
-	}
-
-	ksp->regs_req = request_mem_region(regs_res->start,
-					   resource_size(regs_res),
-					   pdev->name);
-
-	if (!ksp->regs_req) {
-		dev_err(ksp->dev, "cannot claim register space\n");
-		ret = -EIO;
-		goto failure;
-	}
-
-	ksp->io_regs = ioremap(regs_res->start, resource_size(regs_res));
-
-	if (!ksp->io_regs) {
-		dev_err(ksp->dev, "failed to ioremap registers\n");
-		ret = -EINVAL;
-		goto failure;
-	}
-
-	if (phyiface_res) {
-		ksp->phyiface_req =
-			request_mem_region(phyiface_res->start,
-					   resource_size(phyiface_res),
-					   phyiface_res->name);
-
-		if (!ksp->phyiface_req) {
-			dev_err(ksp->dev,
-				"cannot claim switch register space\n");
-			ret = -EIO;
-			goto failure;
-		}
-
-		ksp->phyiface_regs = ioremap(phyiface_res->start,
-					     resource_size(phyiface_res));
-
-		if (!ksp->phyiface_regs) {
-			dev_err(ksp->dev,
-				"failed to ioremap switch registers\n");
-			ret = -EINVAL;
-			goto failure;
-		}
-	}
-
-	ksp->rx_irq = rxirq_res->start;
-	ksp->rx_irq_name = rxirq_res->name ? rxirq_res->name : "Ethernet RX";
-	ksp->tx_irq = txirq_res->start;
-	ksp->tx_irq_name = txirq_res->name ? txirq_res->name : "Ethernet TX";
-	ksp->link_irq = (linkirq_res ? linkirq_res->start : -1);
-	ksp->link_irq_name = (linkirq_res && linkirq_res->name) ?
-		linkirq_res->name : "Ethernet Link";
-
-	/* driver system setup */
-	ndev->netdev_ops = &ks8695_netdev_ops;
-	ndev->watchdog_timeo	 = msecs_to_jiffies(watchdog);
-
-	netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
-
-	/* Retrieve the default MAC addr from the chip. */
-	/* The bootloader should have left it in there for us. */
-
-	machigh = ks8695_readreg(ksp, KS8695_MAH);
-	maclow = ks8695_readreg(ksp, KS8695_MAL);
-
-	ndev->dev_addr[0] = (machigh >> 8) & 0xFF;
-	ndev->dev_addr[1] = machigh & 0xFF;
-	ndev->dev_addr[2] = (maclow >> 24) & 0xFF;
-	ndev->dev_addr[3] = (maclow >> 16) & 0xFF;
-	ndev->dev_addr[4] = (maclow >> 8) & 0xFF;
-	ndev->dev_addr[5] = maclow & 0xFF;
-
-	if (!is_valid_ether_addr(ndev->dev_addr))
-		inv_mac_addr = true;
-
-	/* In order to be efficient memory-wise, we allocate both
-	 * rings in one go.
-	 */
-	ksp->ring_base = dma_alloc_coherent(&pdev->dev, RING_DMA_SIZE,
-					    &ksp->ring_base_dma, GFP_KERNEL);
-	if (!ksp->ring_base) {
-		ret = -ENOMEM;
-		goto failure;
-	}
-
-	/* Specify the TX DMA ring buffer */
-	ksp->tx_ring = ksp->ring_base;
-	ksp->tx_ring_dma = ksp->ring_base_dma;
-
-	/* And initialise the queue's lock */
-	spin_lock_init(&ksp->txq_lock);
-	spin_lock_init(&ksp->rx_lock);
-
-	/* Specify the RX DMA ring buffer */
-	ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE;
-	ksp->rx_ring_dma = ksp->ring_base_dma + TX_RING_DMA_SIZE;
-
-	/* Zero the descriptor rings */
-	memset(ksp->tx_ring, 0, TX_RING_DMA_SIZE);
-	memset(ksp->rx_ring, 0, RX_RING_DMA_SIZE);
-
-	/* Build the rings */
-	for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
-		ksp->tx_ring[buff_n].next_desc =
-			cpu_to_le32(ksp->tx_ring_dma +
-				    (sizeof(struct tx_ring_desc) *
-				     ((buff_n + 1) & MAX_TX_DESC_MASK)));
-	}
-
-	for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
-		ksp->rx_ring[buff_n].next_desc =
-			cpu_to_le32(ksp->rx_ring_dma +
-				    (sizeof(struct rx_ring_desc) *
-				     ((buff_n + 1) & MAX_RX_DESC_MASK)));
-	}
-
-	/* Initialise the port (physically) */
-	if (ksp->phyiface_regs && ksp->link_irq == -1) {
-		ks8695_init_switch(ksp);
-		ksp->dtype = KS8695_DTYPE_LAN;
-		ndev->ethtool_ops = &ks8695_ethtool_ops;
-	} else if (ksp->phyiface_regs && ksp->link_irq != -1) {
-		ks8695_init_wan_phy(ksp);
-		ksp->dtype = KS8695_DTYPE_WAN;
-		ndev->ethtool_ops = &ks8695_wan_ethtool_ops;
-	} else {
-		/* No initialisation since HPNA does not have a PHY */
-		ksp->dtype = KS8695_DTYPE_HPNA;
-		ndev->ethtool_ops = &ks8695_ethtool_ops;
-	}
-
-	/* And bring up the net_device with the net core */
-	platform_set_drvdata(pdev, ndev);
-	ret = register_netdev(ndev);
-
-	if (ret == 0) {
-		if (inv_mac_addr)
-			dev_warn(ksp->dev, "%s: Invalid ethernet MAC address. Please set using ip\n",
-				 ndev->name);
-		dev_info(ksp->dev, "ks8695 ethernet (%s) MAC: %pM\n",
-			 ks8695_port_type(ksp), ndev->dev_addr);
-	} else {
-		/* Report the failure to register the net_device */
-		dev_err(ksp->dev, "ks8695net: failed to register netdev.\n");
-		goto failure;
-	}
-
-	/* All is well */
-	return 0;
-
-	/* Error exit path */
-failure:
-	ks8695_release_device(ksp);
-	free_netdev(ndev);
-
-	return ret;
-}
-
-/**
- *	ks8695_drv_suspend - Suspend a KS8695 ethernet platform device.
- *	@pdev: The device to suspend
- *	@state: The suspend state
- *
- *	This routine detaches and shuts down a KS8695 ethernet device.
- */
-static int
-ks8695_drv_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	struct net_device *ndev = platform_get_drvdata(pdev);
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	ksp->in_suspend = 1;
-
-	if (netif_running(ndev)) {
-		netif_device_detach(ndev);
-		ks8695_shutdown(ksp);
-	}
-
-	return 0;
-}
-
-/**
- *	ks8695_drv_resume - Resume a KS8695 ethernet platform device.
- *	@pdev: The device to resume
- *
- *	This routine re-initialises and re-attaches a KS8695 ethernet
- *	device.
- */
-static int
-ks8695_drv_resume(struct platform_device *pdev)
-{
-	struct net_device *ndev = platform_get_drvdata(pdev);
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	if (netif_running(ndev)) {
-		ks8695_reset(ksp);
-		ks8695_init_net(ksp);
-		ks8695_set_multicast(ndev);
-		netif_device_attach(ndev);
-	}
-
-	ksp->in_suspend = 0;
-
-	return 0;
-}
-
-/**
- *	ks8695_drv_remove - Remove a KS8695 net device on driver unload.
- *	@pdev: The platform device to remove
- *
- *	This unregisters and releases a KS8695 ethernet device.
- */
-static int
-ks8695_drv_remove(struct platform_device *pdev)
-{
-	struct net_device *ndev = platform_get_drvdata(pdev);
-	struct ks8695_priv *ksp = netdev_priv(ndev);
-
-	netif_napi_del(&ksp->napi);
-
-	unregister_netdev(ndev);
-	ks8695_release_device(ksp);
-	free_netdev(ndev);
-
-	dev_dbg(&pdev->dev, "released and freed device\n");
-	return 0;
-}
-
-static struct platform_driver ks8695_driver = {
-	.driver = {
-		.name	= MODULENAME,
-	},
-	.probe		= ks8695_probe,
-	.remove		= ks8695_drv_remove,
-	.suspend	= ks8695_drv_suspend,
-	.resume		= ks8695_drv_resume,
-};
-
-module_platform_driver(ks8695_driver);
-
-MODULE_AUTHOR("Simtec Electronics");
-MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" MODULENAME);
-
-module_param(watchdog, int, 0400);
-MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
diff --git a/drivers/net/ethernet/micrel/ks8695net.h b/drivers/net/ethernet/micrel/ks8695net.h
deleted file mode 100644
index b18fad4ad5fd..000000000000
--- a/drivers/net/ethernet/micrel/ks8695net.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Micrel KS8695 (Centaur) Ethernet.
- *
- * Copyright 2008 Simtec Electronics
- *		  Daniel Silverstone <dsilvers@simtec.co.uk>
- *		  Vincent Sanders <vince@simtec.co.uk>
- */
-
-#ifndef KS8695NET_H
-#define KS8695NET_H
-
-/* Receive descriptor flags */
-#define RDES_OWN	(1 << 31)	/* Ownership */
-#define RDES_FS		(1 << 30)	/* First Descriptor */
-#define RDES_LS		(1 << 29)	/* Last Descriptor */
-#define RDES_IPE	(1 << 28)	/* IP Checksum error */
-#define RDES_TCPE	(1 << 27)	/* TCP Checksum error */
-#define RDES_UDPE	(1 << 26)	/* UDP Checksum error */
-#define RDES_ES		(1 << 25)	/* Error summary */
-#define RDES_MF		(1 << 24)	/* Multicast Frame */
-#define RDES_RE		(1 << 19)	/* MII Error reported */
-#define RDES_TL		(1 << 18)	/* Frame too Long */
-#define RDES_RF		(1 << 17)	/* Runt Frame */
-#define RDES_CE		(1 << 16)	/* CRC error */
-#define RDES_FT		(1 << 15)	/* Frame Type */
-#define RDES_FLEN	(0x7ff)		/* Frame Length */
-
-#define RDES_RER	(1 << 25)	/* Receive End of Ring */
-#define RDES_RBS	(0x7ff)		/* Receive Buffer Size */
-
-/* Transmit descriptor flags */
-
-#define TDES_OWN	(1 << 31)	/* Ownership */
-
-#define TDES_IC		(1 << 31)	/* Interrupt on Completion */
-#define TDES_FS		(1 << 30)	/* First Segment */
-#define TDES_LS		(1 << 29)	/* Last Segment */
-#define TDES_IPCKG	(1 << 28)	/* IP Checksum generate */
-#define TDES_TCPCKG	(1 << 27)	/* TCP Checksum generate */
-#define TDES_UDPCKG	(1 << 26)	/* UDP Checksum generate */
-#define TDES_TER	(1 << 25)	/* Transmit End of Ring */
-#define TDES_TBS	(0x7ff)		/* Transmit Buffer Size */
-
-/*
- * Network controller register offsets
- */
-#define KS8695_DTXC		(0x00)		/* DMA Transmit Control */
-#define KS8695_DRXC		(0x04)		/* DMA Receive Control */
-#define KS8695_DTSC		(0x08)		/* DMA Transmit Start Command */
-#define KS8695_DRSC		(0x0c)		/* DMA Receive Start Command */
-#define KS8695_TDLB		(0x10)		/* Transmit Descriptor List
-						 * Base Address
-						 */
-#define KS8695_RDLB		(0x14)		/* Receive Descriptor List
-						 * Base Address
-						 */
-#define KS8695_MAL		(0x18)		/* MAC Station Address Low */
-#define KS8695_MAH		(0x1c)		/* MAC Station Address High */
-#define KS8695_AAL_(n)		(0x80 + ((n)*8))	/* MAC Additional
-							 * Station Address
-							 * (0..15) Low
-							 */
-#define KS8695_AAH_(n)		(0x84 + ((n)*8))	/* MAC Additional
-							 * Station Address
-							 * (0..15) High
-							 */
-
-
-/* DMA Transmit Control Register */
-#define DTXC_TRST		(1    << 31)	/* Soft Reset */
-#define DTXC_TBS		(0x3f << 24)	/* Transmit Burst Size */
-#define DTXC_TUCG		(1    << 18)	/* Transmit UDP
-						 * Checksum Generate
-						 */
-#define DTXC_TTCG		(1    << 17)	/* Transmit TCP
-						 * Checksum Generate
-						 */
-#define DTXC_TICG		(1    << 16)	/* Transmit IP
-						 * Checksum Generate
-						 */
-#define DTXC_TFCE		(1    <<  9)	/* Transmit Flow
-						 * Control Enable
-						 */
-#define DTXC_TLB		(1    <<  8)	/* Loopback mode */
-#define DTXC_TEP		(1    <<  2)	/* Transmit Enable Padding */
-#define DTXC_TAC		(1    <<  1)	/* Transmit Add CRC */
-#define DTXC_TE			(1    <<  0)	/* TX Enable */
-
-/* DMA Receive Control Register */
-#define DRXC_RBS		(0x3f << 24)	/* Receive Burst Size */
-#define DRXC_RUCC		(1    << 18)	/* Receive UDP Checksum check */
-#define DRXC_RTCG		(1    << 17)	/* Receive TCP Checksum check */
-#define DRXC_RICG		(1    << 16)	/* Receive IP Checksum check */
-#define DRXC_RFCE		(1    <<  9)	/* Receive Flow Control
-						 * Enable
-						 */
-#define DRXC_RB			(1    <<  6)	/* Receive Broadcast */
-#define DRXC_RM			(1    <<  5)	/* Receive Multicast */
-#define DRXC_RU			(1    <<  4)	/* Receive Unicast */
-#define DRXC_RERR		(1    <<  3)	/* Receive Error Frame */
-#define DRXC_RA			(1    <<  2)	/* Receive All */
-#define DRXC_RE			(1    <<  0)	/* RX Enable */
-
-/* Additional Station Address High */
-#define AAH_E			(1    << 31)	/* Address Enabled */
-
-#endif /* KS8695NET_H */
-- 
2.20.0


^ permalink raw reply related


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