* Re: [RFC PATCH net v2 2/3] dt: bindings: add ethernet phy eee-disable-advert option documentation
From: Florian Fainelli @ 2016-11-22 5:35 UTC (permalink / raw)
To: Andrew Lunn, Jerome Brunet
Cc: netdev, devicetree, Alexandre TORGUE, Neil Armstrong,
Martin Blumenstingl, Kevin Hilman, linux-kernel, Andre Roth,
linux-amlogic, Carlo Caione, Giuseppe Cavallaro, linux-arm-kernel
In-Reply-To: <20161121164733.GG1922@lunn.ch>
Le 21/11/2016 à 08:47, Andrew Lunn a écrit :
>> What I did not realize when doing this patch for the realtek driver is
>> that there is already 6 valid modes defined in the kernel
>>
>> #define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /*
>> 100TX EEE cap */
>> #define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /*
>> 1000T EEE cap */
>> #define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */
>> #define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap
>> */
>> #define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap
>> */
>> #define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap
>> */
>>
>> I took care of only 2 in the case of realtek.c since it only support
>> MDIO_EEE_100TX and MDIO_EEE_1000T.
>>
>> Defining a property for each is certainly doable but it does not look
>> very nice either. If it extends in the future, it will get even more
>> messier, especially if you want to disable everything.
>
> Yes, agreed.
One risk with the definition a group of advertisement capabilities
(under the form of a bitmask for instance) to enable/disable is that we
end up with Device Tree contain some kind of configuration policy as
opposed to just flagging particular hardware features as broken.
Fortunately, there does not seem to be a ton of PHYs out there which
require EEE to be disabled to function properly so having individual
properties vs. bitmasks/groups is kind of speculative here.
Another approach to solving this problem could be to register a PHY
fixup which disables EEE at the PHY level, and which is only called for
specific boards affected by this problem (of_machine_is_compatible()).
This code can leave in arch/*/* when that is possible, or it can just be
somewhere where it is relevant, e.g; in the PHY driver for instance
(similarly to how PCI fixups are done).
--
Florian
^ permalink raw reply
* Re: [PATCH net 1/1] net: l2tp: Treat NET_XMIT_CN as success in l2tp_eth_dev_xmit
From: Cong Wang @ 2016-11-22 5:29 UTC (permalink / raw)
To: fgao
Cc: Eric Dumazet, David Miller, javier,
Linux Kernel Network Developers, Feng Gao
In-Reply-To: <1479689781-2125-1-git-send-email-fgao@ikuai8.com>
On Sun, Nov 20, 2016 at 4:56 PM, <fgao@ikuai8.com> wrote:
> From: Gao Feng <gfree.wind@gmail.com>
>
> The tc could return NET_XMIT_CN as one congestion notification, but
> it does not mean the packe is lost. Other modules like ipvlan,
> macvlan, and others treat NET_XMIT_CN as success too.
> So l2tp_eth_dev_xmit should add the NET_XMIT_CN check.
>
> Signed-off-by: Gao Feng <gfree.wind@gmail.com>
> ---
> net/l2tp/l2tp_eth.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
> index 965f7e3..3dc97b4 100644
> --- a/net/l2tp/l2tp_eth.c
> +++ b/net/l2tp/l2tp_eth.c
> @@ -97,7 +97,7 @@ static int l2tp_eth_dev_xmit(struct sk_buff *skb, struct net_device *dev)
> unsigned int len = skb->len;
> int ret = l2tp_xmit_skb(session, skb, session->hdr_len);
>
> - if (likely(ret == NET_XMIT_SUCCESS)) {
> + if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
How could l2tp_xmit_skb() possibly return NET_XMIT_CN?
Note It ignores the return value of l2tp_xmit_core().
^ permalink raw reply
* Re: [PATCH net 1/1] net sched filters: pass netlink message flags in event notification
From: Cong Wang @ 2016-11-22 5:23 UTC (permalink / raw)
To: Roman Mashak
Cc: David Miller, Linux Kernel Network Developers, Jamal Hadi Salim
In-Reply-To: <CAM_iQpU_ivg4eBV=88DH6qEcomrq0+G5M=c9rafLszf09PAP_w@mail.gmail.com>
On Thu, Nov 17, 2016 at 1:02 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Wed, Nov 16, 2016 at 2:16 PM, Roman Mashak <mrv@mojatatu.com> wrote:
>> Userland client should be able to read an event, and reflect it back to
>> the kernel, therefore it needs to extract complete set of netlink flags.
>>
>> For example, this will allow "tc monitor" to distinguish Add and Replace
>> operations.
>>
>> Signed-off-by: Roman Mashak <mrv@mojatatu.com>
>> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
>> ---
>> net/sched/cls_api.c | 5 +++--
>> 1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>> index 2b2a797..8e93d4a 100644
>> --- a/net/sched/cls_api.c
>> +++ b/net/sched/cls_api.c
>> @@ -112,7 +112,7 @@ static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb,
>>
>> for (it_chain = chain; (tp = rtnl_dereference(*it_chain)) != NULL;
>> it_chain = &tp->next)
>> - tfilter_notify(net, oskb, n, tp, 0, event, false);
>> + tfilter_notify(net, oskb, n, tp, n->nlmsg_flags, event, false);
>
>
> I must miss something, why does it make sense to pass n->nlmsg_flags
> as 'fh' to tfilter_notify()??
Ping... Any response?
It still doesn't look correct to me. I will send a fix unless someone could
explain this.
^ permalink raw reply
* [PATCH] bnxt_en: Fix a VXLAN vs GENEVE issue
From: Christophe JAILLET @ 2016-11-22 5:14 UTC (permalink / raw)
To: davem, michael.chan, prashant.sreedharan
Cc: netdev, kernel-janitors, Christophe JAILLET
Knowing that:
#define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN (0x1UL << 0)
#define TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE (0x5UL << 0)
and that 'bnxt_hwrm_tunnel_dst_port_alloc()' is only called with one of
these 2 constants, the TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE can not
trigger.
Replace the bit test that overlap by an equality test, just as in
'bnxt_hwrm_tunnel_dst_port_free()' above.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
Compile-tested only
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index d313b02485a1..25d9ffe51825 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -3210,11 +3210,17 @@ static int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, __be16 port,
goto err_out;
}
- if (tunnel_type & TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN)
+ switch (tunnel_type) {
+ case TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN:
bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id;
-
- else if (tunnel_type & TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE)
+ break;
+ case TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE:
bp->nge_fw_dst_port_id = resp->tunnel_dst_port_id;
+ break;
+ default:
+ break;
+ }
+
err_out:
mutex_unlock(&bp->hwrm_cmd_lock);
return rc;
--
2.9.3
^ permalink raw reply related
* Re: [RFC PATCH net v2 1/3] net: phy: add an option to disable EEE advertisement
From: Anand Moon @ 2016-11-22 5:04 UTC (permalink / raw)
To: Jerome Brunet
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree, Florian Fainelli,
Alexandre TORGUE, Neil Armstrong, Martin Blumenstingl,
Kevin Hilman, Linux Kernel, Andre Roth,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Carlo Caione,
Giuseppe Cavallaro, linux-arm-kernel
In-Reply-To: <1479742524-30222-2-git-send-email-jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
Hi Jerome,
On 21 November 2016 at 21:05, Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org> wrote:
> This patch adds an option to disable EEE advertisement in the generic PHY
> by providing a mask of prohibited modes corresponding to the value found in
> the MDIO_AN_EEE_ADV register.
>
> On some platforms, PHY Low power idle seems to be causing issues, even
> breaking the link some cases. The patch provides a convenient way for these
> platforms to disable EEE advertisement and work around the issue.
>
> Signed-off-by: Jerome Brunet <jbrunet-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> drivers/net/phy/phy.c | 3 ++
> drivers/net/phy/phy_device.c | 80 +++++++++++++++++++++++++++++++++++++++-----
> include/linux/phy.h | 3 ++
> 3 files changed, 77 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index f424b867f73e..a44ee14bd953 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -1348,6 +1348,9 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data)
> {
> int val = ethtool_adv_to_mmd_eee_adv_t(data->advertised);
>
> + /* Mask prohibited EEE modes */
> + val &= ~phydev->eee_advert_disabled;
> +
> phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN, val);
>
> return 0;
> diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
> index 1a4bf8acad78..74c628e046cb 100644
> --- a/drivers/net/phy/phy_device.c
> +++ b/drivers/net/phy/phy_device.c
> @@ -1116,6 +1116,43 @@ static int genphy_config_advert(struct phy_device *phydev)
> }
>
> /**
> + * genphy_config_eee_advert - disable unwanted eee mode advertisement
> + * @phydev: target phy_device struct
> + *
> + * Description: Writes MDIO_AN_EEE_ADV after disabling unsupported energy
> + * efficent ethernet modes. Returns 0 if the PHY's advertisement hasn't
> + * changed, and 1 if it has changed.
> + */
> +static int genphy_config_eee_advert(struct phy_device *phydev)
> +{
> + u32 disabled = phydev->eee_advert_disabled;
> + u32 old_adv, adv;
> +
> + /* Nothing to disable */
> + if (!disabled)
> + return 0;
> +
> + /* If the following call fails, we assume that EEE is not
> + * supported by the phy. If we read 0, EEE is not advertised
> + * In both case, we don't need to continue
> + */
> + adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN);
> + if (adv <= 0)
> + return 0;
> +
> + old_adv = adv;
> + adv &= ~disabled;
> +
> + /* Advertising remains unchanged with the ban */
> + if (old_adv == adv)
> + return 0;
> +
> + phy_write_mmd_indirect(phydev, MDIO_AN_EEE_ADV, MDIO_MMD_AN, adv);
> +
> + return 1;
> +}
> +
> +/**
> * genphy_setup_forced - configures/forces speed/duplex from @phydev
> * @phydev: target phy_device struct
> *
> @@ -1173,15 +1210,20 @@ EXPORT_SYMBOL(genphy_restart_aneg);
> */
> int genphy_config_aneg(struct phy_device *phydev)
> {
> - int result;
> + int err, changed;
> +
> + changed = genphy_config_eee_advert(phydev);
>
> if (AUTONEG_ENABLE != phydev->autoneg)
> return genphy_setup_forced(phydev);
>
> - result = genphy_config_advert(phydev);
> - if (result < 0) /* error */
> - return result;
> - if (result == 0) {
> + err = genphy_config_advert(phydev);
> + if (err < 0) /* error */
> + return err;
> +
> + changed |= err;
> +
> + if (changed == 0) {
> /* Advertisement hasn't changed, but maybe aneg was never on to
> * begin with? Or maybe phy was isolated?
> */
> @@ -1191,16 +1233,16 @@ int genphy_config_aneg(struct phy_device *phydev)
> return ctl;
>
> if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
> - result = 1; /* do restart aneg */
> + changed = 1; /* do restart aneg */
> }
>
> /* Only restart aneg if we are advertising something different
> * than we were before.
> */
> - if (result > 0)
> - result = genphy_restart_aneg(phydev);
> + if (changed > 0)
> + return genphy_restart_aneg(phydev);
>
> - return result;
> + return 0;
> }
> EXPORT_SYMBOL(genphy_config_aneg);
>
> @@ -1558,6 +1600,21 @@ static void of_set_phy_supported(struct phy_device *phydev)
> __set_phy_supported(phydev, max_speed);
> }
>
> +static void of_set_phy_eee_disable(struct phy_device *phydev)
> +{
> + struct device_node *node = phydev->mdio.dev.of_node;
> + u32 disabled;
> +
> + if (!IS_ENABLED(CONFIG_OF_MDIO))
> + return;
> +
> + if (!node)
> + return;
> +
> + if (!of_property_read_u32(node, "eee-advert-disable", &disabled))
> + phydev->eee_advert_disabled = disabled;
> +}
> +
> /**
> * phy_probe - probe and init a PHY device
> * @dev: device to probe and init
> @@ -1595,6 +1652,11 @@ static int phy_probe(struct device *dev)
> of_set_phy_supported(phydev);
> phydev->advertising = phydev->supported;
>
> + /* Get the EEE modes we want to prohibit. We will ask
> + * the PHY stop advertising these mode later on
> + */
> + of_set_phy_eee_disable(phydev);
> +
> /* Set the state to READY by default */
> phydev->state = PHY_READY;
>
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index e25f1830fbcf..7f2ea0af16d1 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -401,6 +401,9 @@ struct phy_device {
> u32 advertising;
> u32 lp_advertising;
>
> + /* Energy efficient ethernet modes which should be prohibited */
> + u32 eee_advert_disabled;
> +
> int autoneg;
>
> int link_timeout;
> --
> 2.7.4
>
iperf3 tcp test summary at my end
Test Complete. Summary Results:
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-100.00 sec 10.9 GBytes 936 Mbits/sec 0 sender
[ 4] 0.00-100.00 sec 10.9 GBytes 936 Mbits/sec receiver
CPU Utilization: local/sender 5.7% (0.2%u/5.5%s), remote/receiver
11.9% (0.9%u/11.0%s)
iperf3 udp test summary at my end.
Test Complete. Summary Results:
[ ID] Interval Transfer Bandwidth Jitter
Lost/Total Datagrams
[ 4] 0.00-100.00 sec 12.5 MBytes 1.05 Mbits/sec 0.025 ms 0/1599 (0%)
[ 4] Sent 1599 datagrams
CPU Utilization: local/sender 0.1% (0.0%u/0.1%s), remote/receiver 0.0%
(0.0%u/0.0%s)
Best Regards
-Anand Moon
>
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [PATCH] net: ioctl SIOCSIFADDR minor cleanup
From: YUAN Linyu @ 2016-11-22 4:30 UTC (permalink / raw)
To: Cong Wang; +Cc: David Miller, cugyly@163.com, netdev@vger.kernel.org
In-Reply-To: <CAM_iQpW0SnpXfN-DjBm-72_23KxtzH8kXbbc3FiQn=VChdX3Ww@mail.gmail.com>
I think there are newbie include me still use ifconfig utility.
So when I check this code, it can be optimized.
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
> On Behalf Of Cong Wang
> Sent: Tuesday, November 22, 2016 12:20 PM
> To: YUAN Linyu
> Cc: David Miller; cugyly@163.com; netdev@vger.kernel.org
> Subject: Re: [PATCH] net: ioctl SIOCSIFADDR minor cleanup
>
> On Tue, Nov 15, 2016 at 7:57 PM, YUAN Linyu
> <Linyu.Yuan@alcatel-sbell.com.cn> wrote:
> > No, this patch will not change dev->name,
> > It's care about ifa->ifa_label.
> >> - if (colon)
> >> - memcpy(ifa->ifa_label, ifr.ifr_name,
> IFNAMSIZ);
> >> - else
> >> - memcpy(ifa->ifa_label, dev->name,
> IFNAMSIZ);
> > When ifr.ifr_name have no colon, dev->name must equal to ifr.ifr_name.
> > So we change to
> >> - else
> >> - memcpy(ifa->ifa_label, ifr.ifr_name,
> IFNAMSIZ);
> > Then if and else do same thing. Just one line is enough,
> > memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
> >
>
> I don't understand why you try to optimize a slow path and some kind of
> obsolete code.
^ permalink raw reply
* Re: [PATCH] net: ioctl SIOCSIFADDR minor cleanup
From: Cong Wang @ 2016-11-22 4:20 UTC (permalink / raw)
To: YUAN Linyu; +Cc: David Miller, cugyly@163.com, netdev@vger.kernel.org
In-Reply-To: <8729016553E3654398EA69218DA29EEF0E42F7ED@cnshjmbx02>
On Tue, Nov 15, 2016 at 7:57 PM, YUAN Linyu
<Linyu.Yuan@alcatel-sbell.com.cn> wrote:
> No, this patch will not change dev->name,
> It's care about ifa->ifa_label.
>> - if (colon)
>> - memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
>> - else
>> - memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
> When ifr.ifr_name have no colon, dev->name must equal to ifr.ifr_name.
> So we change to
>> - else
>> - memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
> Then if and else do same thing. Just one line is enough,
> memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
>
I don't understand why you try to optimize a slow path and some kind of
obsolete code.
^ permalink raw reply
* [PATCH] netdevice.h: fix kernel-doc warning
From: Randy Dunlap @ 2016-11-22 2:28 UTC (permalink / raw)
To: netdev@vger.kernel.org, David Miller
From: Randy Dunlap <rdunlap@infradead.org>
Fix kernel-doc warning in <linux/netdevice.h> (missing ':'):
..//include/linux/netdevice.h:1904: warning: No description found for parameter 'prio_tc_map[TC_BITMASK + 1]'
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
---
include/linux/netdevice.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- lnx-49-rc6.orig/include/linux/netdevice.h
+++ lnx-49-rc6/include/linux/netdevice.h
@@ -1619,7 +1619,7 @@ enum netdev_priv_flags {
* @dcbnl_ops: Data Center Bridging netlink ops
* @num_tc: Number of traffic classes in the net device
* @tc_to_txq: XXX: need comments on this one
- * @prio_tc_map XXX: need comments on this one
+ * @prio_tc_map: XXX: need comments on this one
*
* @fcoe_ddp_xid: Max exchange id for FCoE LRO by ddp
*
^ permalink raw reply
* [PATCH net 1/1] driver: macvlan: Check if need rollback multicast setting in macvlan_open
From: fgao @ 2016-11-22 1:54 UTC (permalink / raw)
To: davem, kaber, netdev, gfree.wind; +Cc: Gao Feng
From: Gao Feng <fgao@ikuai8.com>
When dev_set_promiscuity failed in macvlan_open, it always invokes
dev_set_allmulti without checking if necessary.
Now check the IFF_ALLMULTI flag firstly before rollback the multicast
setting in the error handler.
Signed-off-by: Gao Feng <fgao@ikuai8.com>
---
drivers/net/macvlan.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d2d6f12..26d6f0b 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -623,7 +623,8 @@ static int macvlan_open(struct net_device *dev)
return 0;
clear_multi:
- dev_set_allmulti(lowerdev, -1);
+ if (dev->flags & IFF_ALLMULTI)
+ dev_set_allmulti(lowerdev, -1);
del_unicast:
dev_uc_del(lowerdev, dev->dev_addr);
out:
--
1.9.1
^ permalink raw reply related
* Re: [RFC 02/10] IB/hfi-vnic: Virtual Network Interface Controller (VNIC) Bus driver
From: Vishwanathapura, Niranjana @ 2016-11-22 1:53 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Doug Ledford, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Dennis Dalessandro
In-Reply-To: <20161121233118.GA31132-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
On Mon, Nov 21, 2016 at 04:31:18PM -0700, Jason Gunthorpe wrote:
>> >>>>+ ida_init(&hfi_vnic_ctrl_ida);
>> >>>>+ idr_init(&hfi_vnic_idr);
>> >>>>+
>> >>>>+ rc = bus_register(&hfi_vnic_bus);
>> >>>
>> >>>Why on earth do we need this? Didn't I give you enough grief for the
>> >>>psm stuff and now you want to create an entire subystem hidden away!?
>> >>>
>> >>>Use some netlink scheme to control your vnic like the rest of the net
>> >>>stack..
>> >>>
>> >>
>> >>The hfi_vnic_bus is only abstracting the HW independent functionality (like
>> >>Ethernet interface, encapsulation, IB MAD interface etc) with the HW
>> >>dependent functionality (sending/receiving packets on the wire).
>> >>Thus providing a cleaner interface between HW independent hfi_vnic Ethernet
>> >>and Control drivers and the HW dependent HFI1 driver.
>> >
>> >That doesn't explain anything, sound like you don't need it so get rid
>> >of it.
>
>> >>There is no other User interface here other than the standard Ethernet
>> >>interface through network stack.
>> >
>> >Good, then this isn't needed, because it doesn't provide a user interface.
>> >
>>
>> Can you explain what exactly you are asking to get rid of here and why?
>
>Get rid of the bus_register/etc as drivers do not get to call this.
>
There are many example drivers in kernel which are using bus_register() in
an initcall.
We could add a custom Interface between HFI1 driver and hfi_vnic drivers
without involving a bus.
But using the existing bus model gave a lot of in-built flexibility in
decoupling devices from the drivers.
Niranjana
>Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH ethtool v3 2/2] Ethtool: Implements ETHTOOL_PHY_GTUNABLE/ETHTOOL_PHY_STUNABLE and PHY downshift
From: Florian Fainelli @ 2016-11-22 1:51 UTC (permalink / raw)
To: Allan W. Nielsen, netdev; +Cc: andrew, raju.lakkaraju
In-Reply-To: <1479384480-31201-3-git-send-email-allan.nielsen@microsemi.com>
On 11/17/2016 04:08 AM, Allan W. Nielsen wrote:
> From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
>
> Add ethtool get and set tunable to access PHY drivers.
>
> Ethtool Help: ethtool -h for PHY tunables
> ethtool --set-phy-tunable DEVNAME Set PHY tunable
> [ downshift on|off [count N] ]
> ethtool --get-phy-tunable DEVNAME Get PHY tunable
> [ downshift ]
>
> Ethtool ex:
> ethtool --set-phy-tuanble eth0 downshift on
> ethtool --set-phy-tuanble eth0 downshift off
> ethtool --set-phy-tuanble eth0 downshift on count 2
s/tunable/tunable/
Since this will be used as examples for people testing this feature,
this is kind of important to get the example right ;)
Other than that:
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
>
> ethtool --get-phy-tunable eth0 downshift
>
> Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
> Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
> ---
> +.B downshift
> +For operation in cabling environments that are incompatible with 1000BASE-T,
> +PHY device provides an automatic link speed downshift operation.
Might be worth mentioning that this is particularly useful if you are
using a cable which does not have the 4 pairs for instance.
--
Florian
^ permalink raw reply
* Re: linux-next: build warnings after merge of the net-next tree
From: Florian Fainelli @ 2016-11-22 1:28 UTC (permalink / raw)
To: Stephen Rothwell, David Miller, Networking
Cc: linux-next, linux-kernel, Thomas Petazzoni, Gregory Clement
In-Reply-To: <20161122122216.575b1793@canb.auug.org.au>
+Thomas, Gregory,
On 11/21/2016 05:22 PM, Stephen Rothwell wrote:
[snip]
>
> Introduced by commit
>
> a0627f776a45 ("net: marvell: Allow drivers to be built with COMPILE_TEST")
>
> "a few warnings" is a matter of perception. :-(
Thomas, based on our IRC conversation, do you already have patches for
mvneta and mvpp2 to build without warning on 64-bit or should I prepare
patches for these?
--
Florian
^ permalink raw reply
* linux-next: build warnings after merge of the net-next tree
From: Stephen Rothwell @ 2016-11-22 1:22 UTC (permalink / raw)
To: David Miller, Networking; +Cc: Florian Fainelli, linux-next, linux-kernel
Hi all,
After merging the net-next tree, today's linux-next build (x86_64
allmodconfig) produced these warnings:
drivers/net/ethernet/marvell/mvneta_bm.c: In function 'mvneta_bm_construct':
drivers/net/ethernet/marvell/mvneta_bm.c:103:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
*(u32 *)buf = (u32)buf;
^
In file included from include/linux/clk.h:16:0,
from drivers/net/ethernet/marvell/mvneta_bm.c:13:
drivers/net/ethernet/marvell/mvneta_bm.c: In function 'mvneta_bm_pool_create':
drivers/net/ethernet/marvell/mvneta_bm.c:128:18: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVNETA_BM_POOL_PTR_ALIGN)) {
^
include/linux/kernel.h:51:30: note: in definition of macro 'IS_ALIGNED'
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
^
drivers/net/ethernet/marvell/mvneta_bm.c:128:18: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVNETA_BM_POOL_PTR_ALIGN)) {
^
include/linux/kernel.h:51:44: note: in definition of macro 'IS_ALIGNED'
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
^
drivers/net/ethernet/marvell/mvneta.c: In function 'mvneta_rx_refill':
drivers/net/ethernet/marvell/mvneta.c:1802:42: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)data);
^
drivers/net/ethernet/marvell/mvneta.c: In function 'mvneta_rxq_drop_pkts':
drivers/net/ethernet/marvell/mvneta.c:1864:16: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
void *data = (void *)rx_desc->buf_cookie;
^
drivers/net/ethernet/marvell/mvneta.c: In function 'mvneta_rx_swbm':
drivers/net/ethernet/marvell/mvneta.c:1902:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
data = (unsigned char *)rx_desc->buf_cookie;
^
drivers/net/ethernet/marvell/mvneta.c: In function 'mvneta_rx_hwbm':
drivers/net/ethernet/marvell/mvneta.c:2023:10: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
data = (unsigned char *)rx_desc->buf_cookie;
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_mac_promisc_set':
drivers/net/ethernet/marvell/mvpp2.c:524:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L2_UCAST ~(BIT(9) | BIT(10))
^
drivers/net/ethernet/marvell/mvpp2.c:1459:33: note: in expansion of macro 'MVPP2_PRS_RI_L2_UCAST'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L2_UCAST,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_dsa_tag_set':
drivers/net/ethernet/marvell/mvpp2.c:517:34: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_VLAN_NONE ~(BIT(2) | BIT(3))
^
drivers/net/ethernet/marvell/mvpp2.c:1572:34: note: in expansion of macro 'MVPP2_PRS_RI_VLAN_NONE'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_dsa_tag_ethertype_set':
drivers/net/ethernet/marvell/mvpp2.c:517:34: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_VLAN_NONE ~(BIT(2) | BIT(3))
^
drivers/net/ethernet/marvell/mvpp2.c:1642:34: note: in expansion of macro 'MVPP2_PRS_RI_VLAN_NONE'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_etype_init':
drivers/net/ethernet/marvell/mvpp2.c:529:30: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14))
^
drivers/net/ethernet/marvell/mvpp2.c:2477:32: note: in expansion of macro 'MVPP2_PRS_RI_L3_UN'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,
^
drivers/net/ethernet/marvell/mvpp2.c:529:30: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14))
^
drivers/net/ethernet/marvell/mvpp2.c:2488:42: note: in expansion of macro 'MVPP2_PRS_RI_L3_UN'
mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_UN,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_vlan_init':
drivers/net/ethernet/marvell/mvpp2.c:517:34: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_VLAN_NONE ~(BIT(2) | BIT(3))
^
drivers/net/ethernet/marvell/mvpp2.c:2563:32: note: in expansion of macro 'MVPP2_PRS_RI_VLAN_NONE'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_pppoe_init':
drivers/net/ethernet/marvell/mvpp2.c:529:30: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14))
^
drivers/net/ethernet/marvell/mvpp2.c:2669:32: note: in expansion of macro 'MVPP2_PRS_RI_L3_UN'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_ip4_init':
drivers/net/ethernet/marvell/mvpp2.c:537:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L3_UCAST ~(BIT(15) | BIT(16))
^
drivers/net/ethernet/marvell/mvpp2.c:2755:32: note: in expansion of macro 'MVPP2_PRS_RI_L3_UCAST'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_ip6_init':
drivers/net/ethernet/marvell/mvpp2.c:529:30: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L3_UN ~(BIT(12) | BIT(13) | BIT(14))
^
drivers/net/ethernet/marvell/mvpp2.c:2823:32: note: in expansion of macro 'MVPP2_PRS_RI_L3_UN'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN |
^
drivers/net/ethernet/marvell/mvpp2.c:537:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L3_UCAST ~(BIT(15) | BIT(16))
^
drivers/net/ethernet/marvell/mvpp2.c:2887:32: note: in expansion of macro 'MVPP2_PRS_RI_L3_UCAST'
mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_prs_mac_da_accept':
drivers/net/ethernet/marvell/mvpp2.c:524:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
#define MVPP2_PRS_RI_L2_UCAST ~(BIT(9) | BIT(10))
^
drivers/net/ethernet/marvell/mvpp2.c:3100:8: note: in expansion of macro 'MVPP2_PRS_RI_L2_UCAST'
ri = MVPP2_PRS_RI_L2_UCAST | MVPP2_PRS_RI_MAC_ME_MASK;
^
In file included from drivers/net/ethernet/marvell/mvpp2.c:13:0:
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_bm_pool_create':
drivers/net/ethernet/marvell/mvpp2.c:3375:18: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVPP2_BM_POOL_PTR_ALIGN)) {
^
include/linux/kernel.h:51:30: note: in definition of macro 'IS_ALIGNED'
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
^
drivers/net/ethernet/marvell/mvpp2.c:3375:18: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
if (!IS_ALIGNED((u32)bm_pool->virt_addr, MVPP2_BM_POOL_PTR_ALIGN)) {
^
include/linux/kernel.h:51:44: note: in definition of macro 'IS_ALIGNED'
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0)
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_bm_bufs_free':
drivers/net/ethernet/marvell/mvpp2.c:3433:21: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
dev_kfree_skb_any((struct sk_buff *)vaddr);
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_bm_bufs_add':
drivers/net/ethernet/marvell/mvpp2.c:3647:47: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
mvpp2_pool_refill(port, bm, (u32)phys_addr, (u32)skb);
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_rx_refill':
drivers/net/ethernet/marvell/mvpp2.c:5011:46: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
mvpp2_pool_refill(port, bm, (u32)phys_addr, (u32)skb);
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_buff_hdr_rx':
drivers/net/ethernet/marvell/mvpp2.c:5066:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
skb = (struct sk_buff *)buff_virt_addr;
^
drivers/net/ethernet/marvell/mvpp2.c: In function 'mvpp2_rx':
drivers/net/ethernet/marvell/mvpp2.c:5136:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
skb = (struct sk_buff *)rx_desc->buf_cookie;
^
Introduced by commit
a0627f776a45 ("net: marvell: Allow drivers to be built with COMPILE_TEST")
"a few warnings" is a matter of perception. :-(
Please fix these up.
--
Cheers,
Stephen Rothwell
^ permalink raw reply
* Re: [PATCH ethtool v3 1/2] ethtool-copy.h:sync with net
From: Florian Fainelli @ 2016-11-22 1:03 UTC (permalink / raw)
To: Allan W. Nielsen, netdev; +Cc: andrew, raju.lakkaraju
In-Reply-To: <1479384480-31201-2-git-send-email-allan.nielsen@microsemi.com>
On 11/17/2016 04:07 AM, Allan W. Nielsen wrote:
> From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
>
> This covers kernel changes upto:
>
> commit f5a4732f85613b3fb43f8bc33a017e3db3b3605a
> Author: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
> Date: Wed Nov 9 16:33:09 2016 +0530
>
> ethtool: (uapi) Add ETHTOOL_PHY_DOWNSHIFT to PHY tunables
>
> For operation in cabling environments that are incompatible with
> 1000BASE-T, PHY device may provide an automatic link speed downshift
> operation. When enabled, the device automatically changes its 1000BASE-T
> auto-negotiation to the next slower speed after a configured number of
> failed attempts at 1000BASE-T. This feature is useful in setting up in
> networks using older cable installations that include only pairs A and B,
> and not pairs C and D.
>
> Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
> Signed-off-by: Allan W. Nielsen <allan.nielsen@microsemi.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* linux-next: manual merge of the net-next tree with the net tree
From: Stephen Rothwell @ 2016-11-22 0:58 UTC (permalink / raw)
To: David Miller, Networking
Cc: linux-next, linux-kernel, Giuseppe CAVALLARO, LABBE Corentin
Hi all,
Today's linux-next merge of the net-next tree got a conflict in:
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
between commit:
ba1ffd74df74 ("stmmac: fix PTP support for GMAC4")
from the net tree and commit:
38ddc59d65b6 ("net: stmmac: replace all pr_xxx by their netdev_xxx counterpart")
from the net-next tree.
I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging. You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.
--
Cheers,
Stephen Rothwell
diff --cc drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1f9ec02fa7f8,fbd1cd79233d..000000000000
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@@ -2484,7 -2493,7 +2493,7 @@@ static int stmmac_rx(struct stmmac_pri
if (netif_msg_rx_status(priv)) {
void *rx_head;
- pr_info(">>>>>> %s: descriptor ring:\n", __func__);
- netdev_dbg(priv->dev, "%s: descriptor ring:\n", __func__);
++ netdev_info(priv->dev, ">>>>>> %s: descriptor ring:\n", __func__);
if (priv->extend_desc)
rx_head = (void *)priv->dma_erx;
else
@@@ -2571,11 -2577,11 +2580,11 @@@
frame_len -= ETH_FCS_LEN;
if (netif_msg_rx_status(priv)) {
- pr_info("\tdesc: %p [entry %d] buff=0x%x\n",
- p, entry, des);
- netdev_dbg(priv->dev, "\tdesc: %p [entry %d] buff=0x%x\n",
- p, entry, des);
++ netdev_info(priv->dev, "\tdesc: %p [entry %d] buff=0x%x\n",
++ p, entry, des);
if (frame_len > ETH_FRAME_LEN)
- pr_debug("\tframe size %d, COE: %d\n",
- frame_len, status);
+ netdev_dbg(priv->dev, "frame size %d, COE: %d\n",
+ frame_len, status);
}
/* The zero-copy is always used for all the sizes
@@@ -2628,8 -2635,11 +2638,9 @@@
DMA_FROM_DEVICE);
}
- stmmac_get_rx_hwtstamp(priv, entry, skb);
-
if (netif_msg_pktdata(priv)) {
- pr_debug("frame received (%dbytes)", frame_len);
+ netdev_dbg(priv->dev, "frame received (%dbytes)",
+ frame_len);
print_pkt(skb->data, frame_len);
}
^ permalink raw reply
* RE: [PATCH iproute2 2/2] tc/act_tunnel: Introduce ip tunnel action
From: Rosen, Rami @ 2016-11-21 23:50 UTC (permalink / raw)
To: Amir Vadai, Stephen Hemminger
Cc: David S. Miller, netdev@vger.kernel.org, Or Gerlitz,
Hadar Har-Zion, Roi Dayan
In-Reply-To: <20161121102056.13468-3-amir@vadai.me>
Hi, Amir,
Following are three minor comments:
Seems that TCA_TUNNEL_KEY_PAD used anywhere:
+ TCA_TUNNEL_KEY_PAD,
+ __TCA_TUNNEL_KEY_MAX,
+};
Should be "and destination IP 11.11.0.2" instead of "and destination IP 11.11.0.1":
+Tunnel ID (for example VNI in VXLAN tunnel) .TP .B src_ip Outer header
+source IP address (IPv4 or IPv6) .TP .B dst_ip Outer header destination
+IP address (IPv4 or IPv6) .RE .SH EXAMPLES The following example
+encapsulates incoming ICMP packets on eth0 into a vxlan tunnel by
+setting metadata to VNI 11, source IP 11.11.0.1 and destination IP
+11.11.0.1 by forwarding the skb with the metadata to device vxlan0,
+which will prepare the VXLAN headers:
+
+.RS
+.EX
+#tc qdisc add dev eth0 handle ffff: ingress #tc filter add dev eth0
+protocol ip parent ffff: \\
+ flower \\
+ ip_proto icmp \\
+ action tunnel_key set \\
+ src_ip 11.11.0.1 \\
+ dst_ip 11.11.0.2 \\
+ id 11 \\
Typo: should be "ip tunnel" instead of "ip tunel":
+ * m_tunnel_key.c ip tunel manipulation module
+ *
+ * This program is free software; you can redistribute it and/or
Keep on the good work!
Regards,
Rami Rosen
Intel Corporation
^ permalink raw reply
* Re: [RFC 02/10] IB/hfi-vnic: Virtual Network Interface Controller (VNIC) Bus driver
From: Jason Gunthorpe @ 2016-11-21 23:31 UTC (permalink / raw)
To: Vishwanathapura, Niranjana
Cc: Doug Ledford, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Dennis Dalessandro
In-Reply-To: <20161121232629.GA67988-wPcXA7LoDC+1XWohqUldA0EOCMrvLtNR@public.gmane.org>
On Mon, Nov 21, 2016 at 03:26:29PM -0800, Vishwanathapura, Niranjana wrote:
> I did not see any example IB mad agent outside drivers/inifiniband
> folder.
You can be the first.
> I did see some netdev drivers outside the net/ folder (like ipoib and
> drivers/infiniband/hw/nes/).
It is very rare, and arguably ipoib was a mistake..
> The hfi_vnic Ethernet driver is entirely a soft driver without any HW access.
> Also, any interface changes between hfi_vnic and the HFI driver makes it
> difficult to manage if they are under two subsystems/maintainers.
We manage this already for all the rocee drivers that are based on
netdev drivers, you will be fine.
> We have 'rdmavt' and 'soft-roce' drivers under drivers/infiniband/sw/ folder
> which are soft drivers similar to hfi_vnic. So we decided to put
> 'hif_vnic'
As I said those are HCA drivers & support, not just random 'software'.
> >>>>+ ida_init(&hfi_vnic_ctrl_ida);
> >>>>+ idr_init(&hfi_vnic_idr);
> >>>>+
> >>>>+ rc = bus_register(&hfi_vnic_bus);
> >>>
> >>>Why on earth do we need this? Didn't I give you enough grief for the
> >>>psm stuff and now you want to create an entire subystem hidden away!?
> >>>
> >>>Use some netlink scheme to control your vnic like the rest of the net
> >>>stack..
> >>>
> >>
> >>The hfi_vnic_bus is only abstracting the HW independent functionality (like
> >>Ethernet interface, encapsulation, IB MAD interface etc) with the HW
> >>dependent functionality (sending/receiving packets on the wire).
> >>Thus providing a cleaner interface between HW independent hfi_vnic Ethernet
> >>and Control drivers and the HW dependent HFI1 driver.
> >
> >That doesn't explain anything, sound like you don't need it so get rid
> >of it.
> >>There is no other User interface here other than the standard Ethernet
> >>interface through network stack.
> >
> >Good, then this isn't needed, because it doesn't provide a user interface.
> >
>
> Can you explain what exactly you are asking to get rid of here and why?
Get rid of the bus_register/etc as drivers do not get to call this.
Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC 02/10] IB/hfi-vnic: Virtual Network Interface Controller (VNIC) Bus driver
From: Vishwanathapura, Niranjana @ 2016-11-21 23:26 UTC (permalink / raw)
To: Jason Gunthorpe; +Cc: Doug Ledford, linux-rdma, netdev, Dennis Dalessandro
In-Reply-To: <20161121213930.GA30111@obsidianresearch.com>
On Mon, Nov 21, 2016 at 02:39:30PM -0700, Jason Gunthorpe wrote:
>On Mon, Nov 21, 2016 at 01:30:17PM -0800, Vishwanathapura, Niranjana wrote:
>> On Sat, Nov 19, 2016 at 12:04:45PM -0700, Jason Gunthorpe wrote:
>> >On Fri, Nov 18, 2016 at 02:42:10PM -0800, Vishwanathapura, Niranjana wrote:
>> >>+HFI-VNIC DRIVER
>> >>+M: Dennis Dalessandro <dennis.dalessandro@intel.com>
>> >>+M: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
>> >>+L: linux-rdma@vger.kernel.org
>> >>+S: Supported
>> >>+F: drivers/infiniband/sw/intel/vnic
>> >
>> >This is either a net driver or a ULP, no idea why it should go in this
>> >directory!?
>> >
>> >It sounds like an ethernet driver, so you should probably put it
>> >there...
>> >
>>
>> The hfi_vnic is an Ethernet driver. It is similar to ULP like ipoib, but
>> instead it is Ethernet over Omni-path here.
>> The VNIC Ethernet (hfi_vnic) driver encapsulates Ethernet packets in an
>> Omni-path header.
>> The hfi_vnic Ethernet driver do not access the HW. It interfaces with HFI1
>> driver which sends/receives Omni-Path encapsulated Ethernet frames from HW.
>> Also, the VNIC control path driver (VEMA) is an IB MAD agent which should be
>> under drivers/infiniband/.. .
>> Putting the VNIC Ethernet driver and the VNIC control driver together under
>> a single module (hfi_vnic.ko) provided a simpler interface between them.
>>
>> So, we have put the driver under drivers/infiniband/sw/intel for two reasons:
>> a) We have VNIC control driver (VEMA) which is an IB mad agent.
>> b) hfi_vnic Ethernet driver is dependent on HFI1 driver for sending/receving
>> Omni-path encapsulated Ethernet packets from HW.
>
>Sounds like this driver belongs under net/ someplace to me.
>
>NAK on drivers/infiniband/sw/ at least - that dir is only for HCA
>drivers.
>
I did not see any example IB mad agent outside drivers/inifiniband folder.
I did see some netdev drivers outside the net/ folder (like ipoib and
drivers/infiniband/hw/nes/).
The hfi_vnic Ethernet driver is entirely a soft driver without any HW access.
Also, any interface changes between hfi_vnic and the HFI driver makes it
difficult to manage if they are under two subsystems/maintainers.
So drivers/infiniband is probably more approriate for this driver.
We have 'rdmavt' and 'soft-roce' drivers under drivers/infiniband/sw/ folder
which are soft drivers similar to hfi_vnic. So we decided to put 'hif_vnic'
under there.
Other places under drivers/infiniband where we can put this driver are,
drivers/infiniband/ulp/hfi_vnic
drivers/infiniband/hw/hfi_vnic
>> >>+/* hfi_vnic_bus_init - initialize the hfi vnic bus drvier */
>> >>+static int hfi_vnic_bus_init(void)
>> >>+{
>> >>+ int rc;
>> >>+
>> >>+ ida_init(&hfi_vnic_ctrl_ida);
>> >>+ idr_init(&hfi_vnic_idr);
>> >>+
>> >>+ rc = bus_register(&hfi_vnic_bus);
>> >
>> >Why on earth do we need this? Didn't I give you enough grief for the
>> >psm stuff and now you want to create an entire subystem hidden away!?
>> >
>> >Use some netlink scheme to control your vnic like the rest of the net
>> >stack..
>> >
>>
>> The hfi_vnic_bus is only abstracting the HW independent functionality (like
>> Ethernet interface, encapsulation, IB MAD interface etc) with the HW
>> dependent functionality (sending/receiving packets on the wire).
>> Thus providing a cleaner interface between HW independent hfi_vnic Ethernet
>> and Control drivers and the HW dependent HFI1 driver.
>
>That doesn't explain anything, sound like you don't need it so get rid
>of it.
>
>> There is no other User interface here other than the standard Ethernet
>> interface through network stack.
>
>Good, then this isn't needed, because it doesn't provide a user interface.
>
Can you explain what exactly you are asking to get rid of here and why?
>> #ls /sys/bus/hfi_vnic_bus/devices/
>> hfi_vnic_ctrl_00 /* control device for HFI instance 0 */
>> hfi_vnic_00.01.00 /* first VNIC port on HFI instance 0, port 1 */
>
>Jason
^ permalink raw reply
* Re: [net-next PATCH v2 1/5] net: virtio dynamically disable/enable LRO
From: Michael S. Tsirkin @ 2016-11-21 23:23 UTC (permalink / raw)
To: John Fastabend
Cc: daniel, eric.dumazet, kubakici, shm, davem, alexei.starovoitov,
netdev, bblanco, john.r.fastabend, brouer, tgraf
In-Reply-To: <20161120024934.19187.8294.stgit@john-Precision-Tower-5810>
On Sat, Nov 19, 2016 at 06:49:34PM -0800, John Fastabend wrote:
> This adds support for dynamically setting the LRO feature flag. The
> message to control guest features in the backend uses the
> CTRL_GUEST_OFFLOADS msg type.
>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
> drivers/net/virtio_net.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 44 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index ca5239a..8189e5b 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1419,6 +1419,41 @@ static void virtnet_init_settings(struct net_device *dev)
> .set_settings = virtnet_set_settings,
> };
>
> +static int virtnet_set_features(struct net_device *netdev,
> + netdev_features_t features)
> +{
> + struct virtnet_info *vi = netdev_priv(netdev);
> + struct virtio_device *vdev = vi->vdev;
> + struct scatterlist sg;
> + u64 offloads = 0;
> +
> + if (features & NETIF_F_LRO)
> + offloads |= (1 << VIRTIO_NET_F_GUEST_TSO4) |
> + (1 << VIRTIO_NET_F_GUEST_TSO6);
> +
> + if (features & NETIF_F_RXCSUM)
> + offloads |= (1 << VIRTIO_NET_F_GUEST_CSUM);
> +
> + if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
> + sg_init_one(&sg, &offloads, sizeof(uint64_t));
> + if (!virtnet_send_command(vi,
> + VIRTIO_NET_CTRL_GUEST_OFFLOADS,
> + VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET,
> + &sg)) {
> + dev_warn(&netdev->dev,
> + "Failed to set guest offloads by virtnet command.\n");
> + return -EINVAL;
> + }
> + } else if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) &&
> + !virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) {
> + dev_warn(&netdev->dev,
> + "No support for setting offloads pre version_1.\n");
> + return -EINVAL;
> + }
I don't get this last warning. VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
was exposes by legacy devices, I don't think it's related to
VIRTIO_F_VERSION_1.
> +
> + return 0;
> +}
> +
> static const struct net_device_ops virtnet_netdev = {
> .ndo_open = virtnet_open,
> .ndo_stop = virtnet_close,
> @@ -1435,6 +1470,7 @@ static void virtnet_init_settings(struct net_device *dev)
> #ifdef CONFIG_NET_RX_BUSY_POLL
> .ndo_busy_poll = virtnet_busy_poll,
> #endif
> + .ndo_set_features = virtnet_set_features,
> };
>
> static void virtnet_config_changed_work(struct work_struct *work)
> @@ -1810,6 +1846,12 @@ static int virtnet_probe(struct virtio_device *vdev)
> if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
> dev->features |= NETIF_F_RXCSUM;
>
> + if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) &&
> + virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) {
> + dev->features |= NETIF_F_LRO;
> + dev->hw_features |= NETIF_F_LRO;
> + }
> +
> dev->vlan_features = dev->features;
>
> /* MTU range: 68 - 65535 */
> @@ -2047,7 +2089,8 @@ static int virtnet_restore(struct virtio_device *vdev)
> VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
> VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
> VIRTIO_NET_F_CTRL_MAC_ADDR, \
> - VIRTIO_NET_F_MTU
> + VIRTIO_NET_F_MTU, \
> + VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
>
> static unsigned int features[] = {
> VIRTNET_FEATURES,
^ permalink raw reply
* Re: [net-next PATCH v2 3/5] virtio_net: Add XDP support
From: Michael S. Tsirkin @ 2016-11-21 23:20 UTC (permalink / raw)
To: John Fastabend
Cc: daniel, eric.dumazet, kubakici, shm, davem, alexei.starovoitov,
netdev, bblanco, john.r.fastabend, brouer, tgraf
In-Reply-To: <20161120025033.19187.11082.stgit@john-Precision-Tower-5810>
On Sat, Nov 19, 2016 at 06:50:33PM -0800, John Fastabend wrote:
> From: Shrijeet Mukherjee <shrijeet@gmail.com>
>
> This adds XDP support to virtio_net. Some requirements must be
> met for XDP to be enabled depending on the mode. First it will
> only be supported with LRO disabled so that data is not pushed
> across multiple buffers. The MTU must be less than a page size
> to avoid having to handle XDP across multiple pages.
>
> If mergeable receive is enabled this first series only supports
> the case where header and data are in the same buf which we can
> check when a packet is received by looking at num_buf. If the
> num_buf is greater than 1 and a XDP program is loaded the packet
> is dropped and a warning is thrown. When any_header_sg is set this
> does not happen and both header and data is put in a single buffer
> as expected so we check this when XDP programs are loaded. Note I
> have only tested this with Linux vhost backend.
>
> If big packets mode is enabled and MTU/LRO conditions above are
> met then XDP is allowed.
>
> A follow on patch can be generated to solve the mergeable receive
> case with num_bufs equal to 2. Buffers greater than two may not
> be handled has easily.
I would very much prefer support for other layouts without drops
before merging this.
header by itself can certainly be handled by skipping it.
People wanted to use that e.g. for zero copy.
Anything else can be handled by copying the packet.
> Suggested-by: Shrijeet Mukherjee <shrijeet@gmail.com>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
> drivers/net/virtio_net.c | 146 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 142 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 8189e5b..8f99a53 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -22,6 +22,7 @@
> #include <linux/module.h>
> #include <linux/virtio.h>
> #include <linux/virtio_net.h>
> +#include <linux/bpf.h>
> #include <linux/scatterlist.h>
> #include <linux/if_vlan.h>
> #include <linux/slab.h>
> @@ -81,6 +82,8 @@ struct receive_queue {
>
> struct napi_struct napi;
>
> + struct bpf_prog __rcu *xdp_prog;
> +
> /* Chain pages by the private ptr. */
> struct page *pages;
>
> @@ -324,6 +327,38 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
> return skb;
> }
>
> +static u32 do_xdp_prog(struct virtnet_info *vi,
> + struct bpf_prog *xdp_prog,
> + struct page *page, int offset, int len)
> +{
> + int hdr_padded_len;
> + struct xdp_buff xdp;
> + u32 act;
> + u8 *buf;
> +
> + buf = page_address(page) + offset;
> +
> + if (vi->mergeable_rx_bufs)
> + hdr_padded_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
> + else
> + hdr_padded_len = sizeof(struct padded_vnet_hdr);
> +
> + xdp.data = buf + hdr_padded_len;
> + xdp.data_end = xdp.data + (len - vi->hdr_len);
> +
> + act = bpf_prog_run_xdp(xdp_prog, &xdp);
> + switch (act) {
> + case XDP_PASS:
> + return XDP_PASS;
> + default:
> + bpf_warn_invalid_xdp_action(act);
> + case XDP_TX:
> + case XDP_ABORTED:
> + case XDP_DROP:
> + return XDP_DROP;
> + }
> +}
> +
> static struct sk_buff *receive_small(struct virtnet_info *vi, void *buf, unsigned int len)
> {
> struct sk_buff * skb = buf;
> @@ -340,9 +375,19 @@ static struct sk_buff *receive_big(struct net_device *dev,
> void *buf,
> unsigned int len)
> {
> + struct bpf_prog *xdp_prog;
> struct page *page = buf;
> - struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
> + struct sk_buff *skb;
>
> + xdp_prog = rcu_dereference_bh(rq->xdp_prog);
> + if (xdp_prog) {
> + u32 act = do_xdp_prog(vi, xdp_prog, page, 0, len);
> +
> + if (act == XDP_DROP)
> + goto err;
> + }
> +
> + skb = page_to_skb(vi, rq, page, 0, len, PAGE_SIZE);
> if (unlikely(!skb))
> goto err;
>
> @@ -366,10 +411,25 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
> struct page *page = virt_to_head_page(buf);
> int offset = buf - page_address(page);
> unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
> + struct sk_buff *head_skb, *curr_skb;
> + struct bpf_prog *xdp_prog;
>
> - struct sk_buff *head_skb = page_to_skb(vi, rq, page, offset, len,
> - truesize);
> - struct sk_buff *curr_skb = head_skb;
> + xdp_prog = rcu_dereference_bh(rq->xdp_prog);
> + if (xdp_prog) {
> + u32 act;
> +
> + if (num_buf > 1) {
> + bpf_warn_invalid_xdp_buffer();
> + goto err_skb;
> + }
> +
> + act = do_xdp_prog(vi, xdp_prog, page, offset, len);
> + if (act == XDP_DROP)
> + goto err_skb;
> + }
> +
> + head_skb = page_to_skb(vi, rq, page, offset, len, truesize);
> + curr_skb = head_skb;
>
> if (unlikely(!curr_skb))
> goto err_skb;
> @@ -1328,6 +1388,13 @@ static int virtnet_set_channels(struct net_device *dev,
> if (queue_pairs > vi->max_queue_pairs || queue_pairs == 0)
> return -EINVAL;
>
> + /* For now we don't support modifying channels while XDP is loaded
> + * also when XDP is loaded all RX queues have XDP programs so we only
> + * need to check a single RX queue.
> + */
> + if (vi->rq[0].xdp_prog)
> + return -EINVAL;
> +
> get_online_cpus();
> err = virtnet_set_queues(vi, queue_pairs);
> if (!err) {
> @@ -1454,6 +1521,68 @@ static int virtnet_set_features(struct net_device *netdev,
> return 0;
> }
>
> +static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
> +{
> + struct virtnet_info *vi = netdev_priv(dev);
> + struct bpf_prog *old_prog;
> + int i;
> +
> + if ((dev->features & NETIF_F_LRO) && prog) {
> + netdev_warn(dev, "can't set XDP while LRO is on, disable LRO first\n");
> + return -EINVAL;
> + }
> +
> + if (vi->mergeable_rx_bufs && !vi->any_header_sg) {
> + netdev_warn(dev, "XDP expects header/data in single page\n");
> + return -EINVAL;
> + }
> +
> + if (dev->mtu > PAGE_SIZE) {
> + netdev_warn(dev, "XDP requires MTU less than %lu\n", PAGE_SIZE);
> + return -EINVAL;
> + }
> +
> + if (prog) {
> + prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
> + if (IS_ERR(prog))
> + return PTR_ERR(prog);
> + }
> +
> + for (i = 0; i < vi->max_queue_pairs; i++) {
> + old_prog = rtnl_dereference(vi->rq[i].xdp_prog);
> + rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
> + if (old_prog)
> + bpf_prog_put(old_prog);
> + }
> +
> + return 0;
> +}
> +
> +static bool virtnet_xdp_query(struct net_device *dev)
> +{
> + struct virtnet_info *vi = netdev_priv(dev);
> + int i;
> +
> + for (i = 0; i < vi->max_queue_pairs; i++) {
> + if (vi->rq[i].xdp_prog)
> + return true;
> + }
> + return false;
> +}
> +
> +static int virtnet_xdp(struct net_device *dev, struct netdev_xdp *xdp)
> +{
> + switch (xdp->command) {
> + case XDP_SETUP_PROG:
> + return virtnet_xdp_set(dev, xdp->prog);
> + case XDP_QUERY_PROG:
> + xdp->prog_attached = virtnet_xdp_query(dev);
> + return 0;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> static const struct net_device_ops virtnet_netdev = {
> .ndo_open = virtnet_open,
> .ndo_stop = virtnet_close,
> @@ -1471,6 +1600,7 @@ static int virtnet_set_features(struct net_device *netdev,
> .ndo_busy_poll = virtnet_busy_poll,
> #endif
> .ndo_set_features = virtnet_set_features,
> + .ndo_xdp = virtnet_xdp,
> };
>
> static void virtnet_config_changed_work(struct work_struct *work)
> @@ -1527,12 +1657,20 @@ static void virtnet_free_queues(struct virtnet_info *vi)
>
> static void free_receive_bufs(struct virtnet_info *vi)
> {
> + struct bpf_prog *old_prog;
> int i;
>
> + rtnl_lock();
> for (i = 0; i < vi->max_queue_pairs; i++) {
> while (vi->rq[i].pages)
> __free_pages(get_a_page(&vi->rq[i], GFP_KERNEL), 0);
> +
> + old_prog = rtnl_dereference(vi->rq[i].xdp_prog);
> + RCU_INIT_POINTER(vi->rq[i].xdp_prog, NULL);
> + if (old_prog)
> + bpf_prog_put(old_prog);
> }
> + rtnl_unlock();
> }
>
> static void free_receive_page_frags(struct virtnet_info *vi)
^ permalink raw reply
* Re: [net-next PATCH v2 4/5] virtio_net: add dedicated XDP transmit queues
From: Michael S. Tsirkin @ 2016-11-21 23:13 UTC (permalink / raw)
To: John Fastabend
Cc: daniel, eric.dumazet, kubakici, shm, davem, alexei.starovoitov,
netdev, bblanco, john.r.fastabend, brouer, tgraf
In-Reply-To: <20161120025104.19187.54400.stgit@john-Precision-Tower-5810>
On Sat, Nov 19, 2016 at 06:51:04PM -0800, John Fastabend wrote:
> XDP requires using isolated transmit queues to avoid interference
> with normal networking stack (BQL, NETDEV_TX_BUSY, etc). This patch
> adds a XDP queue per cpu when a XDP program is loaded and does not
> expose the queues to the OS via the normal API call to
> netif_set_real_num_tx_queues(). This way the stack will never push
> an skb to these queues.
>
> However virtio/vhost/qemu implementation only allows for creating
> TX/RX queue pairs at this time so creating only TX queues was not
> possible. And because the associated RX queues are being created I
> went ahead and exposed these to the stack and let the backend use
> them. This creates more RX queues visible to the network stack than
> TX queues which is worth mentioning but does not cause any issues as
> far as I can tell.
>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
FYI what's supposed to happen is packets from the same
flow going in the reverse direction will go on the
same queue.
This might come in handy when implementing RX XDP.
> ---
> drivers/net/virtio_net.c | 32 +++++++++++++++++++++++++++++---
> 1 file changed, 29 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 8f99a53..80a426c 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -114,6 +114,9 @@ struct virtnet_info {
> /* # of queue pairs currently used by the driver */
> u16 curr_queue_pairs;
>
> + /* # of XDP queue pairs currently used by the driver */
> + u16 xdp_queue_pairs;
> +
> /* I like... big packets and I cannot lie! */
> bool big_packets;
>
> @@ -1525,7 +1528,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
> {
> struct virtnet_info *vi = netdev_priv(dev);
> struct bpf_prog *old_prog;
> - int i;
> + u16 xdp_qp = 0, curr_qp;
> + int err, i;
>
> if ((dev->features & NETIF_F_LRO) && prog) {
> netdev_warn(dev, "can't set XDP while LRO is on, disable LRO first\n");
> @@ -1542,12 +1546,34 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog)
> return -EINVAL;
> }
>
> + curr_qp = vi->curr_queue_pairs - vi->xdp_queue_pairs;
> + if (prog)
> + xdp_qp = nr_cpu_ids;
> +
> + /* XDP requires extra queues for XDP_TX */
> + if (curr_qp + xdp_qp > vi->max_queue_pairs) {
> + netdev_warn(dev, "request %i queues but max is %i\n",
> + curr_qp + xdp_qp, vi->max_queue_pairs);
> + return -ENOMEM;
> + }
> +
> + err = virtnet_set_queues(vi, curr_qp + xdp_qp);
> + if (err) {
> + dev_warn(&dev->dev, "XDP Device queue allocation failure.\n");
> + return err;
> + }
> +
> if (prog) {
> - prog = bpf_prog_add(prog, vi->max_queue_pairs - 1);
> - if (IS_ERR(prog))
> + prog = bpf_prog_add(prog, vi->max_queue_pairs);
> + if (IS_ERR(prog)) {
> + virtnet_set_queues(vi, curr_qp);
> return PTR_ERR(prog);
> + }
> }
>
> + vi->xdp_queue_pairs = xdp_qp;
> + netif_set_real_num_rx_queues(dev, curr_qp + xdp_qp);
> +
> for (i = 0; i < vi->max_queue_pairs; i++) {
> old_prog = rtnl_dereference(vi->rq[i].xdp_prog);
> rcu_assign_pointer(vi->rq[i].xdp_prog, prog);
^ permalink raw reply
* [PATCH 2/2] net: qcom/emac: add support for the Qualcomm Technologies QDF2400
From: Timur Tabi @ 2016-11-21 22:58 UTC (permalink / raw)
To: David Miller, alokc, netdev
In-Reply-To: <1479769102-27909-1-git-send-email-timur@codeaurora.org>
The QDF2432 and the QDF2400 have slightly different internal PHYs,
so there are some programming differences. Some of the registers in
the QDF2400 have moved, and some registers require different values
during initialization.
Because of the differences, the internal PHY on the QDF2400 has a new
ACPI HID, QCOM8072.
Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
drivers/net/ethernet/qualcomm/emac/Makefile | 3 +-
.../ethernet/qualcomm/emac/emac-sgmii-qdf2400.c | 217 +++++++++++++++++++++
drivers/net/ethernet/qualcomm/emac/emac-sgmii.c | 4 +
drivers/net/ethernet/qualcomm/emac/emac-sgmii.h | 1 +
4 files changed, 224 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2400.c
diff --git a/drivers/net/ethernet/qualcomm/emac/Makefile b/drivers/net/ethernet/qualcomm/emac/Makefile
index 204b787..7a66879 100644
--- a/drivers/net/ethernet/qualcomm/emac/Makefile
+++ b/drivers/net/ethernet/qualcomm/emac/Makefile
@@ -5,4 +5,5 @@
obj-$(CONFIG_QCOM_EMAC) += qcom-emac.o
qcom-emac-objs := emac.o emac-mac.o emac-phy.o emac-sgmii.o \
- emac-sgmii-fsm9900.o emac-sgmii-qdf2432.o
+ emac-sgmii-fsm9900.o emac-sgmii-qdf2432.o \
+ emac-sgmii-qdf2400.o
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2400.c b/drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2400.c
new file mode 100644
index 0000000..efaaa96
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2400.c
@@ -0,0 +1,217 @@
+/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Qualcomm Technologies, Inc. QDF2400 EMAC SGMII Controller driver.
+ */
+
+#include <linux/iopoll.h>
+#include "emac.h"
+
+/* EMAC_SGMII register offsets */
+#define EMAC_SGMII_PHY_TX_PWR_CTRL 0x000C
+#define EMAC_SGMII_PHY_LANE_CTRL1 0x0018
+#define EMAC_SGMII_PHY_CDR_CTRL0 0x0058
+#define EMAC_SGMII_PHY_POW_DWN_CTRL0 0x0080
+#define EMAC_SGMII_PHY_RESET_CTRL 0x00a8
+#define EMAC_SGMII_PHY_INTERRUPT_MASK 0x00b4
+
+/* SGMII digital lane registers */
+#define EMAC_SGMII_LN_DRVR_CTRL0 0x000C
+#define EMAC_SGMII_LN_DRVR_TAP_EN 0x0018
+#define EMAC_SGMII_LN_TX_MARGINING 0x001C
+#define EMAC_SGMII_LN_TX_PRE 0x0020
+#define EMAC_SGMII_LN_TX_POST 0x0024
+#define EMAC_SGMII_LN_TX_BAND_MODE 0x0060
+#define EMAC_SGMII_LN_LANE_MODE 0x0064
+#define EMAC_SGMII_LN_PARALLEL_RATE 0x007C
+#define EMAC_SGMII_LN_CML_CTRL_MODE0 0x00C0
+#define EMAC_SGMII_LN_MIXER_CTRL_MODE0 0x00D8
+#define EMAC_SGMII_LN_VGA_INITVAL 0x013C
+#define EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0 0x0184
+#define EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0 0x0190
+#define EMAC_SGMII_LN_UCDR_SO_CONFIG 0x019C
+#define EMAC_SGMII_LN_RX_BAND 0x01A4
+#define EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0 0x01C0
+#define EMAC_SGMII_LN_RSM_CONFIG 0x01F8
+#define EMAC_SGMII_LN_SIGDET_ENABLES 0x0230
+#define EMAC_SGMII_LN_SIGDET_CNTRL 0x0234
+#define EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL 0x0238
+#define EMAC_SGMII_LN_RX_EN_SIGNAL 0x02AC
+#define EMAC_SGMII_LN_RX_MISC_CNTRL0 0x02B8
+#define EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV 0x02C8
+
+/* SGMII digital lane register values */
+#define UCDR_STEP_BY_TWO_MODE0 BIT(7)
+#define UCDR_xO_GAIN_MODE(x) ((x) & 0x7f)
+#define UCDR_ENABLE BIT(6)
+#define UCDR_SO_SATURATION(x) ((x) & 0x3f)
+
+#define SIGDET_LP_BYP_PS4 BIT(7)
+#define SIGDET_EN_PS0_TO_PS2 BIT(6)
+
+#define TXVAL_VALID_INIT BIT(4)
+#define KR_PCIGEN3_MODE BIT(0)
+
+#define MAIN_EN BIT(0)
+
+#define TX_MARGINING_MUX BIT(6)
+#define TX_MARGINING(x) ((x) & 0x3f)
+
+#define TX_PRE_MUX BIT(6)
+
+#define TX_POST_MUX BIT(6)
+
+#define CML_GEAR_MODE(x) (((x) & 7) << 3)
+#define CML2CMOS_IBOOST_MODE(x) ((x) & 7)
+
+#define MIXER_LOADB_MODE(x) (((x) & 0xf) << 2)
+#define MIXER_DATARATE_MODE(x) ((x) & 3)
+
+#define VGA_THRESH_DFE(x) ((x) & 0x3f)
+
+#define SIGDET_LP_BYP_PS0_TO_PS2 BIT(5)
+#define SIGDET_FLT_BYP BIT(0)
+
+#define SIGDET_LVL(x) (((x) & 0xf) << 4)
+
+#define SIGDET_DEGLITCH_CTRL(x) (((x) & 0xf) << 1)
+
+#define INVERT_PCS_RX_CLK BIT(7)
+
+#define DRVR_LOGIC_CLK_EN BIT(4)
+#define DRVR_LOGIC_CLK_DIV(x) ((x) & 0xf)
+
+#define PARALLEL_RATE_MODE0(x) ((x) & 0x3)
+
+#define BAND_MODE0(x) ((x) & 0x3)
+
+#define LANE_MODE(x) ((x) & 0x1f)
+
+#define CDR_PD_SEL_MODE0(x) (((x) & 0x3) << 5)
+#define EN_DLL_MODE0 BIT(4)
+#define EN_IQ_DCC_MODE0 BIT(3)
+#define EN_IQCAL_MODE0 BIT(2)
+
+#define BYPASS_RSM_SAMP_CAL BIT(1)
+#define BYPASS_RSM_DLL_CAL BIT(0)
+
+#define L0_RX_EQUALIZE_ENABLE BIT(6)
+
+#define PWRDN_B BIT(0)
+
+#define CDR_MAX_CNT(x) ((x) & 0xff)
+
+#define SERDES_START_WAIT_TIMES 100
+
+struct emac_reg_write {
+ unsigned int offset;
+ u32 val;
+};
+
+static void emac_reg_write_all(void __iomem *base,
+ const struct emac_reg_write *itr, size_t size)
+{
+ size_t i;
+
+ for (i = 0; i < size; ++itr, ++i)
+ writel(itr->val, base + itr->offset);
+}
+
+static const struct emac_reg_write sgmii_laned[] = {
+ /* CDR Settings */
+ {EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0,
+ UCDR_STEP_BY_TWO_MODE0 | UCDR_xO_GAIN_MODE(10)},
+ {EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(0)},
+ {EMAC_SGMII_LN_UCDR_SO_CONFIG, UCDR_ENABLE | UCDR_SO_SATURATION(12)},
+
+ /* TX/RX Settings */
+ {EMAC_SGMII_LN_RX_EN_SIGNAL, SIGDET_LP_BYP_PS4 | SIGDET_EN_PS0_TO_PS2},
+
+ {EMAC_SGMII_LN_DRVR_CTRL0, TXVAL_VALID_INIT | KR_PCIGEN3_MODE},
+ {EMAC_SGMII_LN_DRVR_TAP_EN, MAIN_EN},
+ {EMAC_SGMII_LN_TX_MARGINING, TX_MARGINING_MUX | TX_MARGINING(25)},
+ {EMAC_SGMII_LN_TX_PRE, TX_PRE_MUX},
+ {EMAC_SGMII_LN_TX_POST, TX_POST_MUX},
+
+ {EMAC_SGMII_LN_CML_CTRL_MODE0,
+ CML_GEAR_MODE(1) | CML2CMOS_IBOOST_MODE(1)},
+ {EMAC_SGMII_LN_MIXER_CTRL_MODE0,
+ MIXER_LOADB_MODE(12) | MIXER_DATARATE_MODE(1)},
+ {EMAC_SGMII_LN_VGA_INITVAL, VGA_THRESH_DFE(31)},
+ {EMAC_SGMII_LN_SIGDET_ENABLES,
+ SIGDET_LP_BYP_PS0_TO_PS2 | SIGDET_FLT_BYP},
+ {EMAC_SGMII_LN_SIGDET_CNTRL, SIGDET_LVL(8)},
+
+ {EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL, SIGDET_DEGLITCH_CTRL(4)},
+ {EMAC_SGMII_LN_RX_MISC_CNTRL0, INVERT_PCS_RX_CLK},
+ {EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV,
+ DRVR_LOGIC_CLK_EN | DRVR_LOGIC_CLK_DIV(4)},
+
+ {EMAC_SGMII_LN_PARALLEL_RATE, PARALLEL_RATE_MODE0(1)},
+ {EMAC_SGMII_LN_TX_BAND_MODE, BAND_MODE0(1)},
+ {EMAC_SGMII_LN_RX_BAND, BAND_MODE0(2)},
+ {EMAC_SGMII_LN_LANE_MODE, LANE_MODE(26)},
+ {EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0, CDR_PD_SEL_MODE0(2) |
+ EN_DLL_MODE0 | EN_IQ_DCC_MODE0| EN_IQCAL_MODE0},
+ {EMAC_SGMII_LN_RSM_CONFIG, BYPASS_RSM_SAMP_CAL | BYPASS_RSM_DLL_CAL},
+};
+
+static const struct emac_reg_write physical_coding_sublayer_programming[] = {
+ {EMAC_SGMII_PHY_POW_DWN_CTRL0, PWRDN_B},
+ {EMAC_SGMII_PHY_CDR_CTRL0, CDR_MAX_CNT(15)},
+ {EMAC_SGMII_PHY_TX_PWR_CTRL, 0},
+ {EMAC_SGMII_PHY_LANE_CTRL1, L0_RX_EQUALIZE_ENABLE},
+};
+
+int emac_sgmii_init_qdf2400(struct emac_adapter *adpt)
+{
+ struct emac_phy *phy = &adpt->phy;
+ void __iomem *phy_regs = phy->base;
+ void __iomem *laned = phy->digital;
+ unsigned int i;
+ u32 lnstatus;
+
+ /* PCS lane-x init */
+ emac_reg_write_all(phy->base, physical_coding_sublayer_programming,
+ ARRAY_SIZE(physical_coding_sublayer_programming));
+
+ /* SGMII lane-x init */
+ emac_reg_write_all(phy->digital, sgmii_laned, ARRAY_SIZE(sgmii_laned));
+
+ /* Power up PCS and start reset lane state machine */
+
+ writel(0, phy_regs + EMAC_SGMII_PHY_RESET_CTRL);
+ writel(1, laned + SGMII_LN_RSM_START);
+
+ /* Wait for c_ready assertion */
+ for (i = 0; i < SERDES_START_WAIT_TIMES; i++) {
+ lnstatus = readl(phy_regs + SGMII_PHY_LN_LANE_STATUS);
+ if (lnstatus & BIT(1))
+ break;
+ usleep_range(100, 200);
+ }
+
+ if (i == SERDES_START_WAIT_TIMES) {
+ netdev_err(adpt->netdev, "SGMII failed to start\n");
+ return -EIO;
+ }
+
+ /* Disable digital and SERDES loopback */
+ writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN0);
+ writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN2);
+ writel(0, phy_regs + SGMII_PHY_LN_CDR_CTRL1);
+
+ /* Mask out all the SGMII Interrupt */
+ writel(0, phy_regs + EMAC_SGMII_PHY_INTERRUPT_MASK);
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
index 07c872a..c5dc9ef 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
@@ -166,6 +166,10 @@ static int emac_sgmii_acpi_match(struct device *dev, void *data)
.id = "QCOM8071",
.driver_data = (kernel_ulong_t)emac_sgmii_init_qdf2432,
},
+ {
+ .id = "QCOM8072",
+ .driver_data = (kernel_ulong_t)emac_sgmii_init_qdf2400,
+ },
{}
};
const struct acpi_device_id *id = acpi_match_device(match_table, dev);
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h
index e2bef14..80ed3dc 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h
+++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h
@@ -21,5 +21,6 @@ void emac_sgmii_reset(struct emac_adapter *adpt);
int emac_sgmii_init_fsm9900(struct emac_adapter *adpt);
int emac_sgmii_init_qdf2432(struct emac_adapter *adpt);
+int emac_sgmii_init_qdf2400(struct emac_adapter *adpt);
#endif
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH 1/2] net: qcom/emac: move phy init code to separate files
From: Timur Tabi @ 2016-11-21 22:58 UTC (permalink / raw)
To: David Miller, alokc, netdev
In-Reply-To: <1479769102-27909-1-git-send-email-timur@codeaurora.org>
The internal PHY of the EMAC differs on each SOC, and the list will
only continue to grow. By separating the code into individual files,
we can add support for more SOCs more cleanly.
Note: The internal PHY is also sometimes called the SGMII device.
We also stop referring to the various PHY variations by version number,
so no more "v2", "v3", etc. Instead, the devices are named after the
SOC they are, which is in sync with the device tree property names.
Future patches will probably rearrange more code among the files.
Signed-off-by: Timur Tabi <timur@codeaurora.org>
---
drivers/net/ethernet/qualcomm/emac/Makefile | 3 +-
.../ethernet/qualcomm/emac/emac-sgmii-fsm9900.c | 246 ++++++++++
.../ethernet/qualcomm/emac/emac-sgmii-qdf2432.c | 210 ++++++++
drivers/net/ethernet/qualcomm/emac/emac-sgmii.c | 538 +--------------------
drivers/net/ethernet/qualcomm/emac/emac-sgmii.h | 5 +-
5 files changed, 479 insertions(+), 523 deletions(-)
create mode 100644 drivers/net/ethernet/qualcomm/emac/emac-sgmii-fsm9900.c
create mode 100644 drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2432.c
diff --git a/drivers/net/ethernet/qualcomm/emac/Makefile b/drivers/net/ethernet/qualcomm/emac/Makefile
index 01ee144..204b787 100644
--- a/drivers/net/ethernet/qualcomm/emac/Makefile
+++ b/drivers/net/ethernet/qualcomm/emac/Makefile
@@ -4,4 +4,5 @@
obj-$(CONFIG_QCOM_EMAC) += qcom-emac.o
-qcom-emac-objs := emac.o emac-mac.o emac-phy.o emac-sgmii.o
+qcom-emac-objs := emac.o emac-mac.o emac-phy.o emac-sgmii.o \
+ emac-sgmii-fsm9900.o emac-sgmii-qdf2432.o
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii-fsm9900.c b/drivers/net/ethernet/qualcomm/emac/emac-sgmii-fsm9900.c
new file mode 100644
index 0000000..46f01b3
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii-fsm9900.c
@@ -0,0 +1,246 @@
+/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Qualcomm Technologies, Inc. FSM9900 EMAC SGMII Controller driver.
+ */
+
+#include <linux/iopoll.h>
+#include "emac.h"
+
+/* EMAC_QSERDES register offsets */
+#define EMAC_QSERDES_COM_SYS_CLK_CTRL 0x0000
+#define EMAC_QSERDES_COM_PLL_CNTRL 0x0014
+#define EMAC_QSERDES_COM_PLL_IP_SETI 0x0018
+#define EMAC_QSERDES_COM_PLL_CP_SETI 0x0024
+#define EMAC_QSERDES_COM_PLL_IP_SETP 0x0028
+#define EMAC_QSERDES_COM_PLL_CP_SETP 0x002c
+#define EMAC_QSERDES_COM_SYSCLK_EN_SEL 0x0038
+#define EMAC_QSERDES_COM_RESETSM_CNTRL 0x0040
+#define EMAC_QSERDES_COM_PLLLOCK_CMP1 0x0044
+#define EMAC_QSERDES_COM_PLLLOCK_CMP2 0x0048
+#define EMAC_QSERDES_COM_PLLLOCK_CMP3 0x004c
+#define EMAC_QSERDES_COM_PLLLOCK_CMP_EN 0x0050
+#define EMAC_QSERDES_COM_DEC_START1 0x0064
+#define EMAC_QSERDES_COM_DIV_FRAC_START1 0x0098
+#define EMAC_QSERDES_COM_DIV_FRAC_START2 0x009c
+#define EMAC_QSERDES_COM_DIV_FRAC_START3 0x00a0
+#define EMAC_QSERDES_COM_DEC_START2 0x00a4
+#define EMAC_QSERDES_COM_PLL_CRCTRL 0x00ac
+#define EMAC_QSERDES_COM_RESET_SM 0x00bc
+#define EMAC_QSERDES_TX_BIST_MODE_LANENO 0x0100
+#define EMAC_QSERDES_TX_TX_EMP_POST1_LVL 0x0108
+#define EMAC_QSERDES_TX_TX_DRV_LVL 0x010c
+#define EMAC_QSERDES_TX_LANE_MODE 0x0150
+#define EMAC_QSERDES_TX_TRAN_DRVR_EMP_EN 0x0170
+#define EMAC_QSERDES_RX_CDR_CONTROL 0x0200
+#define EMAC_QSERDES_RX_CDR_CONTROL2 0x0210
+#define EMAC_QSERDES_RX_RX_EQ_GAIN12 0x0230
+
+/* EMAC_SGMII register offsets */
+#define EMAC_SGMII_PHY_SERDES_START 0x0000
+#define EMAC_SGMII_PHY_CMN_PWR_CTRL 0x0004
+#define EMAC_SGMII_PHY_RX_PWR_CTRL 0x0008
+#define EMAC_SGMII_PHY_TX_PWR_CTRL 0x000C
+#define EMAC_SGMII_PHY_LANE_CTRL1 0x0018
+#define EMAC_SGMII_PHY_CDR_CTRL0 0x0058
+#define EMAC_SGMII_PHY_POW_DWN_CTRL0 0x0080
+#define EMAC_SGMII_PHY_INTERRUPT_MASK 0x00b4
+
+#define PLL_IPSETI(x) ((x) & 0x3f)
+
+#define PLL_CPSETI(x) ((x) & 0xff)
+
+#define PLL_IPSETP(x) ((x) & 0x3f)
+
+#define PLL_CPSETP(x) ((x) & 0x1f)
+
+#define PLL_RCTRL(x) (((x) & 0xf) << 4)
+#define PLL_CCTRL(x) ((x) & 0xf)
+
+#define LANE_MODE(x) ((x) & 0x1f)
+
+#define SYSCLK_CM BIT(4)
+#define SYSCLK_AC_COUPLE BIT(3)
+
+#define OCP_EN BIT(5)
+#define PLL_DIV_FFEN BIT(2)
+#define PLL_DIV_ORD BIT(1)
+
+#define SYSCLK_SEL_CMOS BIT(3)
+
+#define FRQ_TUNE_MODE BIT(4)
+
+#define PLLLOCK_CMP_EN BIT(0)
+
+#define DEC_START1_MUX BIT(7)
+#define DEC_START1(x) ((x) & 0x7f)
+
+#define DIV_FRAC_START_MUX BIT(7)
+#define DIV_FRAC_START(x) ((x) & 0x7f)
+
+#define DIV_FRAC_START3_MUX BIT(4)
+#define DIV_FRAC_START3(x) ((x) & 0xf)
+
+#define DEC_START2_MUX BIT(1)
+#define DEC_START2 BIT(0)
+
+#define READY BIT(5)
+
+#define TX_EMP_POST1_LVL_MUX BIT(5)
+#define TX_EMP_POST1_LVL(x) ((x) & 0x1f)
+
+#define TX_DRV_LVL_MUX BIT(4)
+#define TX_DRV_LVL(x) ((x) & 0xf)
+
+#define EMP_EN_MUX BIT(1)
+#define EMP_EN BIT(0)
+
+#define SECONDORDERENABLE BIT(6)
+#define FIRSTORDER_THRESH(x) (((x) & 0x7) << 3)
+#define SECONDORDERGAIN(x) ((x) & 0x7)
+
+#define RX_EQ_GAIN2(x) (((x) & 0xf) << 4)
+#define RX_EQ_GAIN1(x) ((x) & 0xf)
+
+#define SERDES_START BIT(0)
+
+#define BIAS_EN BIT(6)
+#define PLL_EN BIT(5)
+#define SYSCLK_EN BIT(4)
+#define CLKBUF_L_EN BIT(3)
+#define PLL_TXCLK_EN BIT(1)
+#define PLL_RXCLK_EN BIT(0)
+
+#define L0_RX_SIGDET_EN BIT(7)
+#define L0_RX_TERM_MODE(x) (((x) & 3) << 4)
+#define L0_RX_I_EN BIT(1)
+
+#define L0_TX_EN BIT(5)
+#define L0_CLKBUF_EN BIT(4)
+#define L0_TRAN_BIAS_EN BIT(1)
+
+#define L0_RX_EQUALIZE_ENABLE BIT(6)
+#define L0_RESET_TSYNC_EN BIT(4)
+#define L0_DRV_LVL(x) ((x) & 0xf)
+
+#define PWRDN_B BIT(0)
+#define CDR_MAX_CNT(x) ((x) & 0xff)
+
+#define PLLLOCK_CMP(x) ((x) & 0xff)
+
+#define SERDES_START_WAIT_TIMES 100
+
+struct emac_reg_write {
+ unsigned int offset;
+ u32 val;
+};
+
+static void emac_reg_write_all(void __iomem *base,
+ const struct emac_reg_write *itr, size_t size)
+{
+ size_t i;
+
+ for (i = 0; i < size; ++itr, ++i)
+ writel(itr->val, base + itr->offset);
+}
+
+static const struct emac_reg_write physical_coding_sublayer_programming_v1[] = {
+ {EMAC_SGMII_PHY_CDR_CTRL0, CDR_MAX_CNT(15)},
+ {EMAC_SGMII_PHY_POW_DWN_CTRL0, PWRDN_B},
+ {EMAC_SGMII_PHY_CMN_PWR_CTRL,
+ BIAS_EN | SYSCLK_EN | CLKBUF_L_EN | PLL_TXCLK_EN | PLL_RXCLK_EN},
+ {EMAC_SGMII_PHY_TX_PWR_CTRL, L0_TX_EN | L0_CLKBUF_EN | L0_TRAN_BIAS_EN},
+ {EMAC_SGMII_PHY_RX_PWR_CTRL,
+ L0_RX_SIGDET_EN | L0_RX_TERM_MODE(1) | L0_RX_I_EN},
+ {EMAC_SGMII_PHY_CMN_PWR_CTRL,
+ BIAS_EN | PLL_EN | SYSCLK_EN | CLKBUF_L_EN | PLL_TXCLK_EN |
+ PLL_RXCLK_EN},
+ {EMAC_SGMII_PHY_LANE_CTRL1,
+ L0_RX_EQUALIZE_ENABLE | L0_RESET_TSYNC_EN | L0_DRV_LVL(15)},
+};
+
+static const struct emac_reg_write sysclk_refclk_setting[] = {
+ {EMAC_QSERDES_COM_SYSCLK_EN_SEL, SYSCLK_SEL_CMOS},
+ {EMAC_QSERDES_COM_SYS_CLK_CTRL, SYSCLK_CM | SYSCLK_AC_COUPLE},
+};
+
+static const struct emac_reg_write pll_setting[] = {
+ {EMAC_QSERDES_COM_PLL_IP_SETI, PLL_IPSETI(1)},
+ {EMAC_QSERDES_COM_PLL_CP_SETI, PLL_CPSETI(59)},
+ {EMAC_QSERDES_COM_PLL_IP_SETP, PLL_IPSETP(10)},
+ {EMAC_QSERDES_COM_PLL_CP_SETP, PLL_CPSETP(9)},
+ {EMAC_QSERDES_COM_PLL_CRCTRL, PLL_RCTRL(15) | PLL_CCTRL(11)},
+ {EMAC_QSERDES_COM_PLL_CNTRL, OCP_EN | PLL_DIV_FFEN | PLL_DIV_ORD},
+ {EMAC_QSERDES_COM_DEC_START1, DEC_START1_MUX | DEC_START1(2)},
+ {EMAC_QSERDES_COM_DEC_START2, DEC_START2_MUX | DEC_START2},
+ {EMAC_QSERDES_COM_DIV_FRAC_START1,
+ DIV_FRAC_START_MUX | DIV_FRAC_START(85)},
+ {EMAC_QSERDES_COM_DIV_FRAC_START2,
+ DIV_FRAC_START_MUX | DIV_FRAC_START(42)},
+ {EMAC_QSERDES_COM_DIV_FRAC_START3,
+ DIV_FRAC_START3_MUX | DIV_FRAC_START3(3)},
+ {EMAC_QSERDES_COM_PLLLOCK_CMP1, PLLLOCK_CMP(43)},
+ {EMAC_QSERDES_COM_PLLLOCK_CMP2, PLLLOCK_CMP(104)},
+ {EMAC_QSERDES_COM_PLLLOCK_CMP3, PLLLOCK_CMP(0)},
+ {EMAC_QSERDES_COM_PLLLOCK_CMP_EN, PLLLOCK_CMP_EN},
+ {EMAC_QSERDES_COM_RESETSM_CNTRL, FRQ_TUNE_MODE},
+};
+
+static const struct emac_reg_write cdr_setting[] = {
+ {EMAC_QSERDES_RX_CDR_CONTROL,
+ SECONDORDERENABLE | FIRSTORDER_THRESH(3) | SECONDORDERGAIN(2)},
+ {EMAC_QSERDES_RX_CDR_CONTROL2,
+ SECONDORDERENABLE | FIRSTORDER_THRESH(3) | SECONDORDERGAIN(4)},
+};
+
+static const struct emac_reg_write tx_rx_setting[] = {
+ {EMAC_QSERDES_TX_BIST_MODE_LANENO, 0},
+ {EMAC_QSERDES_TX_TX_DRV_LVL, TX_DRV_LVL_MUX | TX_DRV_LVL(15)},
+ {EMAC_QSERDES_TX_TRAN_DRVR_EMP_EN, EMP_EN_MUX | EMP_EN},
+ {EMAC_QSERDES_TX_TX_EMP_POST1_LVL,
+ TX_EMP_POST1_LVL_MUX | TX_EMP_POST1_LVL(1)},
+ {EMAC_QSERDES_RX_RX_EQ_GAIN12, RX_EQ_GAIN2(15) | RX_EQ_GAIN1(15)},
+ {EMAC_QSERDES_TX_LANE_MODE, LANE_MODE(8)},
+};
+
+int emac_sgmii_init_fsm9900(struct emac_adapter *adpt)
+{
+ struct emac_phy *phy = &adpt->phy;
+ unsigned int i;
+
+ emac_reg_write_all(phy->base, physical_coding_sublayer_programming_v1,
+ ARRAY_SIZE(physical_coding_sublayer_programming_v1));
+ emac_reg_write_all(phy->base, sysclk_refclk_setting,
+ ARRAY_SIZE(sysclk_refclk_setting));
+ emac_reg_write_all(phy->base, pll_setting, ARRAY_SIZE(pll_setting));
+ emac_reg_write_all(phy->base, cdr_setting, ARRAY_SIZE(cdr_setting));
+ emac_reg_write_all(phy->base, tx_rx_setting, ARRAY_SIZE(tx_rx_setting));
+
+ /* Power up the Ser/Des engine */
+ writel(SERDES_START, phy->base + EMAC_SGMII_PHY_SERDES_START);
+
+ for (i = 0; i < SERDES_START_WAIT_TIMES; i++) {
+ if (readl(phy->base + EMAC_QSERDES_COM_RESET_SM) & READY)
+ break;
+ usleep_range(100, 200);
+ }
+
+ if (i == SERDES_START_WAIT_TIMES) {
+ netdev_err(adpt->netdev, "error: ser/des failed to start\n");
+ return -EIO;
+ }
+ /* Mask out all the SGMII Interrupt */
+ writel(0, phy->base + EMAC_SGMII_PHY_INTERRUPT_MASK);
+
+ return 0;
+}
+
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2432.c b/drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2432.c
new file mode 100644
index 0000000..6170200
--- /dev/null
+++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2432.c
@@ -0,0 +1,210 @@
+/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* Qualcomm Technologies, Inc. QDF2432 EMAC SGMII Controller driver.
+ */
+
+#include <linux/iopoll.h>
+#include "emac.h"
+
+/* EMAC_SGMII register offsets */
+#define EMAC_SGMII_PHY_TX_PWR_CTRL 0x000C
+#define EMAC_SGMII_PHY_LANE_CTRL1 0x0018
+#define EMAC_SGMII_PHY_CDR_CTRL0 0x0058
+#define EMAC_SGMII_PHY_POW_DWN_CTRL0 0x0080
+#define EMAC_SGMII_PHY_RESET_CTRL 0x00a8
+#define EMAC_SGMII_PHY_INTERRUPT_MASK 0x00b4
+
+/* SGMII digital lane registers */
+#define EMAC_SGMII_LN_DRVR_CTRL0 0x000C
+#define EMAC_SGMII_LN_DRVR_TAP_EN 0x0018
+#define EMAC_SGMII_LN_TX_MARGINING 0x001C
+#define EMAC_SGMII_LN_TX_PRE 0x0020
+#define EMAC_SGMII_LN_TX_POST 0x0024
+#define EMAC_SGMII_LN_TX_BAND_MODE 0x0060
+#define EMAC_SGMII_LN_LANE_MODE 0x0064
+#define EMAC_SGMII_LN_PARALLEL_RATE 0x0078
+#define EMAC_SGMII_LN_CML_CTRL_MODE0 0x00B8
+#define EMAC_SGMII_LN_MIXER_CTRL_MODE0 0x00D0
+#define EMAC_SGMII_LN_VGA_INITVAL 0x0134
+#define EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0 0x017C
+#define EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0 0x0188
+#define EMAC_SGMII_LN_UCDR_SO_CONFIG 0x0194
+#define EMAC_SGMII_LN_RX_BAND 0x019C
+#define EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0 0x01B8
+#define EMAC_SGMII_LN_RSM_CONFIG 0x01F0
+#define EMAC_SGMII_LN_SIGDET_ENABLES 0x0224
+#define EMAC_SGMII_LN_SIGDET_CNTRL 0x0228
+#define EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL 0x022C
+#define EMAC_SGMII_LN_RX_EN_SIGNAL 0x02A0
+#define EMAC_SGMII_LN_RX_MISC_CNTRL0 0x02AC
+#define EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV 0x02BC
+
+/* SGMII digital lane register values */
+#define UCDR_STEP_BY_TWO_MODE0 BIT(7)
+#define UCDR_xO_GAIN_MODE(x) ((x) & 0x7f)
+#define UCDR_ENABLE BIT(6)
+#define UCDR_SO_SATURATION(x) ((x) & 0x3f)
+
+#define SIGDET_LP_BYP_PS4 BIT(7)
+#define SIGDET_EN_PS0_TO_PS2 BIT(6)
+
+#define TXVAL_VALID_INIT BIT(4)
+#define KR_PCIGEN3_MODE BIT(0)
+
+#define MAIN_EN BIT(0)
+
+#define TX_MARGINING_MUX BIT(6)
+#define TX_MARGINING(x) ((x) & 0x3f)
+
+#define TX_PRE_MUX BIT(6)
+
+#define TX_POST_MUX BIT(6)
+
+#define CML_GEAR_MODE(x) (((x) & 7) << 3)
+#define CML2CMOS_IBOOST_MODE(x) ((x) & 7)
+
+#define MIXER_LOADB_MODE(x) (((x) & 0xf) << 2)
+#define MIXER_DATARATE_MODE(x) ((x) & 3)
+
+#define VGA_THRESH_DFE(x) ((x) & 0x3f)
+
+#define SIGDET_LP_BYP_PS0_TO_PS2 BIT(5)
+#define SIGDET_FLT_BYP BIT(0)
+
+#define SIGDET_LVL(x) (((x) & 0xf) << 4)
+
+#define SIGDET_DEGLITCH_CTRL(x) (((x) & 0xf) << 1)
+
+#define DRVR_LOGIC_CLK_EN BIT(4)
+#define DRVR_LOGIC_CLK_DIV(x) ((x) & 0xf)
+
+#define PARALLEL_RATE_MODE0(x) ((x) & 0x3)
+
+#define BAND_MODE0(x) ((x) & 0x3)
+
+#define LANE_MODE(x) ((x) & 0x1f)
+
+#define CDR_PD_SEL_MODE0(x) (((x) & 0x3) << 5)
+#define BYPASS_RSM_SAMP_CAL BIT(1)
+#define BYPASS_RSM_DLL_CAL BIT(0)
+
+#define L0_RX_EQUALIZE_ENABLE BIT(6)
+
+#define PWRDN_B BIT(0)
+
+#define CDR_MAX_CNT(x) ((x) & 0xff)
+
+#define SERDES_START_WAIT_TIMES 100
+
+struct emac_reg_write {
+ unsigned int offset;
+ u32 val;
+};
+
+static void emac_reg_write_all(void __iomem *base,
+ const struct emac_reg_write *itr, size_t size)
+{
+ size_t i;
+
+ for (i = 0; i < size; ++itr, ++i)
+ writel(itr->val, base + itr->offset);
+}
+
+static const struct emac_reg_write sgmii_laned[] = {
+ /* CDR Settings */
+ {EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0,
+ UCDR_STEP_BY_TWO_MODE0 | UCDR_xO_GAIN_MODE(10)},
+ {EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(0)},
+ {EMAC_SGMII_LN_UCDR_SO_CONFIG, UCDR_ENABLE | UCDR_SO_SATURATION(12)},
+
+ /* TX/RX Settings */
+ {EMAC_SGMII_LN_RX_EN_SIGNAL, SIGDET_LP_BYP_PS4 | SIGDET_EN_PS0_TO_PS2},
+
+ {EMAC_SGMII_LN_DRVR_CTRL0, TXVAL_VALID_INIT | KR_PCIGEN3_MODE},
+ {EMAC_SGMII_LN_DRVR_TAP_EN, MAIN_EN},
+ {EMAC_SGMII_LN_TX_MARGINING, TX_MARGINING_MUX | TX_MARGINING(25)},
+ {EMAC_SGMII_LN_TX_PRE, TX_PRE_MUX},
+ {EMAC_SGMII_LN_TX_POST, TX_POST_MUX},
+
+ {EMAC_SGMII_LN_CML_CTRL_MODE0,
+ CML_GEAR_MODE(1) | CML2CMOS_IBOOST_MODE(1)},
+ {EMAC_SGMII_LN_MIXER_CTRL_MODE0,
+ MIXER_LOADB_MODE(12) | MIXER_DATARATE_MODE(1)},
+ {EMAC_SGMII_LN_VGA_INITVAL, VGA_THRESH_DFE(31)},
+ {EMAC_SGMII_LN_SIGDET_ENABLES,
+ SIGDET_LP_BYP_PS0_TO_PS2 | SIGDET_FLT_BYP},
+ {EMAC_SGMII_LN_SIGDET_CNTRL, SIGDET_LVL(8)},
+
+ {EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL, SIGDET_DEGLITCH_CTRL(4)},
+ {EMAC_SGMII_LN_RX_MISC_CNTRL0, 0},
+ {EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV,
+ DRVR_LOGIC_CLK_EN | DRVR_LOGIC_CLK_DIV(4)},
+
+ {EMAC_SGMII_LN_PARALLEL_RATE, PARALLEL_RATE_MODE0(1)},
+ {EMAC_SGMII_LN_TX_BAND_MODE, BAND_MODE0(2)},
+ {EMAC_SGMII_LN_RX_BAND, BAND_MODE0(3)},
+ {EMAC_SGMII_LN_LANE_MODE, LANE_MODE(26)},
+ {EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0, CDR_PD_SEL_MODE0(3)},
+ {EMAC_SGMII_LN_RSM_CONFIG, BYPASS_RSM_SAMP_CAL | BYPASS_RSM_DLL_CAL},
+};
+
+static const struct emac_reg_write physical_coding_sublayer_programming[] = {
+ {EMAC_SGMII_PHY_POW_DWN_CTRL0, PWRDN_B},
+ {EMAC_SGMII_PHY_CDR_CTRL0, CDR_MAX_CNT(15)},
+ {EMAC_SGMII_PHY_TX_PWR_CTRL, 0},
+ {EMAC_SGMII_PHY_LANE_CTRL1, L0_RX_EQUALIZE_ENABLE},
+};
+
+int emac_sgmii_init_qdf2432(struct emac_adapter *adpt)
+{
+ struct emac_phy *phy = &adpt->phy;
+ void __iomem *phy_regs = phy->base;
+ void __iomem *laned = phy->digital;
+ unsigned int i;
+ u32 lnstatus;
+
+ /* PCS lane-x init */
+ emac_reg_write_all(phy->base, physical_coding_sublayer_programming,
+ ARRAY_SIZE(physical_coding_sublayer_programming));
+
+ /* SGMII lane-x init */
+ emac_reg_write_all(phy->digital, sgmii_laned, ARRAY_SIZE(sgmii_laned));
+
+ /* Power up PCS and start reset lane state machine */
+
+ writel(0, phy_regs + EMAC_SGMII_PHY_RESET_CTRL);
+ writel(1, laned + SGMII_LN_RSM_START);
+
+ /* Wait for c_ready assertion */
+ for (i = 0; i < SERDES_START_WAIT_TIMES; i++) {
+ lnstatus = readl(phy_regs + SGMII_PHY_LN_LANE_STATUS);
+ if (lnstatus & BIT(1))
+ break;
+ usleep_range(100, 200);
+ }
+
+ if (i == SERDES_START_WAIT_TIMES) {
+ netdev_err(adpt->netdev, "SGMII failed to start\n");
+ return -EIO;
+ }
+
+ /* Disable digital and SERDES loopback */
+ writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN0);
+ writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN2);
+ writel(0, phy_regs + SGMII_PHY_LN_CDR_CTRL1);
+
+ /* Mask out all the SGMII Interrupt */
+ writel(0, phy_regs + EMAC_SGMII_PHY_INTERRUPT_MASK);
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
index 3edb5a5..07c872a 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
+++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.c
@@ -20,448 +20,33 @@
#include "emac-mac.h"
#include "emac-sgmii.h"
-/* EMAC_QSERDES register offsets */
-#define EMAC_QSERDES_COM_SYS_CLK_CTRL 0x000000
-#define EMAC_QSERDES_COM_PLL_CNTRL 0x000014
-#define EMAC_QSERDES_COM_PLL_IP_SETI 0x000018
-#define EMAC_QSERDES_COM_PLL_CP_SETI 0x000024
-#define EMAC_QSERDES_COM_PLL_IP_SETP 0x000028
-#define EMAC_QSERDES_COM_PLL_CP_SETP 0x00002c
-#define EMAC_QSERDES_COM_SYSCLK_EN_SEL 0x000038
-#define EMAC_QSERDES_COM_RESETSM_CNTRL 0x000040
-#define EMAC_QSERDES_COM_PLLLOCK_CMP1 0x000044
-#define EMAC_QSERDES_COM_PLLLOCK_CMP2 0x000048
-#define EMAC_QSERDES_COM_PLLLOCK_CMP3 0x00004c
-#define EMAC_QSERDES_COM_PLLLOCK_CMP_EN 0x000050
-#define EMAC_QSERDES_COM_DEC_START1 0x000064
-#define EMAC_QSERDES_COM_DIV_FRAC_START1 0x000098
-#define EMAC_QSERDES_COM_DIV_FRAC_START2 0x00009c
-#define EMAC_QSERDES_COM_DIV_FRAC_START3 0x0000a0
-#define EMAC_QSERDES_COM_DEC_START2 0x0000a4
-#define EMAC_QSERDES_COM_PLL_CRCTRL 0x0000ac
-#define EMAC_QSERDES_COM_RESET_SM 0x0000bc
-#define EMAC_QSERDES_TX_BIST_MODE_LANENO 0x000100
-#define EMAC_QSERDES_TX_TX_EMP_POST1_LVL 0x000108
-#define EMAC_QSERDES_TX_TX_DRV_LVL 0x00010c
-#define EMAC_QSERDES_TX_LANE_MODE 0x000150
-#define EMAC_QSERDES_TX_TRAN_DRVR_EMP_EN 0x000170
-#define EMAC_QSERDES_RX_CDR_CONTROL 0x000200
-#define EMAC_QSERDES_RX_CDR_CONTROL2 0x000210
-#define EMAC_QSERDES_RX_RX_EQ_GAIN12 0x000230
-
/* EMAC_SGMII register offsets */
-#define EMAC_SGMII_PHY_SERDES_START 0x000000
-#define EMAC_SGMII_PHY_CMN_PWR_CTRL 0x000004
-#define EMAC_SGMII_PHY_RX_PWR_CTRL 0x000008
-#define EMAC_SGMII_PHY_TX_PWR_CTRL 0x00000C
-#define EMAC_SGMII_PHY_LANE_CTRL1 0x000018
-#define EMAC_SGMII_PHY_AUTONEG_CFG2 0x000048
-#define EMAC_SGMII_PHY_CDR_CTRL0 0x000058
-#define EMAC_SGMII_PHY_SPEED_CFG1 0x000074
-#define EMAC_SGMII_PHY_POW_DWN_CTRL0 0x000080
-#define EMAC_SGMII_PHY_RESET_CTRL 0x0000a8
-#define EMAC_SGMII_PHY_IRQ_CMD 0x0000ac
-#define EMAC_SGMII_PHY_INTERRUPT_CLEAR 0x0000b0
-#define EMAC_SGMII_PHY_INTERRUPT_MASK 0x0000b4
-#define EMAC_SGMII_PHY_INTERRUPT_STATUS 0x0000b8
-#define EMAC_SGMII_PHY_RX_CHK_STATUS 0x0000d4
-#define EMAC_SGMII_PHY_AUTONEG0_STATUS 0x0000e0
-#define EMAC_SGMII_PHY_AUTONEG1_STATUS 0x0000e4
-
-/* EMAC_QSERDES_COM_PLL_IP_SETI */
-#define PLL_IPSETI(x) ((x) & 0x3f)
-
-/* EMAC_QSERDES_COM_PLL_CP_SETI */
-#define PLL_CPSETI(x) ((x) & 0xff)
-
-/* EMAC_QSERDES_COM_PLL_IP_SETP */
-#define PLL_IPSETP(x) ((x) & 0x3f)
-
-/* EMAC_QSERDES_COM_PLL_CP_SETP */
-#define PLL_CPSETP(x) ((x) & 0x1f)
-
-/* EMAC_QSERDES_COM_PLL_CRCTRL */
-#define PLL_RCTRL(x) (((x) & 0xf) << 4)
-#define PLL_CCTRL(x) ((x) & 0xf)
-
-/* SGMII v2 PHY registers per lane */
-#define EMAC_SGMII_PHY_LN_OFFSET 0x0400
-
-/* SGMII v2 digital lane registers */
-#define EMAC_SGMII_LN_DRVR_CTRL0 0x00C
-#define EMAC_SGMII_LN_DRVR_TAP_EN 0x018
-#define EMAC_SGMII_LN_TX_MARGINING 0x01C
-#define EMAC_SGMII_LN_TX_PRE 0x020
-#define EMAC_SGMII_LN_TX_POST 0x024
-#define EMAC_SGMII_LN_TX_BAND_MODE 0x060
-#define EMAC_SGMII_LN_LANE_MODE 0x064
-#define EMAC_SGMII_LN_PARALLEL_RATE 0x078
-#define EMAC_SGMII_LN_CML_CTRL_MODE0 0x0B8
-#define EMAC_SGMII_LN_MIXER_CTRL_MODE0 0x0D0
-#define EMAC_SGMII_LN_VGA_INITVAL 0x134
-#define EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0 0x17C
-#define EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0 0x188
-#define EMAC_SGMII_LN_UCDR_SO_CONFIG 0x194
-#define EMAC_SGMII_LN_RX_BAND 0x19C
-#define EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0 0x1B8
-#define EMAC_SGMII_LN_RSM_CONFIG 0x1F0
-#define EMAC_SGMII_LN_SIGDET_ENABLES 0x224
-#define EMAC_SGMII_LN_SIGDET_CNTRL 0x228
-#define EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL 0x22C
-#define EMAC_SGMII_LN_RX_EN_SIGNAL 0x2A0
-#define EMAC_SGMII_LN_RX_MISC_CNTRL0 0x2AC
-#define EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV 0x2BC
-
-/* SGMII v2 digital lane register values */
-#define UCDR_STEP_BY_TWO_MODE0 BIT(7)
-#define UCDR_xO_GAIN_MODE(x) ((x) & 0x7f)
-#define UCDR_ENABLE BIT(6)
-#define UCDR_SO_SATURATION(x) ((x) & 0x3f)
-#define SIGDET_LP_BYP_PS4 BIT(7)
-#define SIGDET_EN_PS0_TO_PS2 BIT(6)
-#define EN_ACCOUPLEVCM_SW_MUX BIT(5)
-#define EN_ACCOUPLEVCM_SW BIT(4)
-#define RX_SYNC_EN BIT(3)
-#define RXTERM_HIGHZ_PS5 BIT(2)
-#define SIGDET_EN_PS3 BIT(1)
-#define EN_ACCOUPLE_VCM_PS3 BIT(0)
-#define UFS_MODE BIT(5)
-#define TXVAL_VALID_INIT BIT(4)
-#define TXVAL_VALID_MUX BIT(3)
-#define TXVAL_VALID BIT(2)
-#define USB3P1_MODE BIT(1)
-#define KR_PCIGEN3_MODE BIT(0)
-#define PRE_EN BIT(3)
-#define POST_EN BIT(2)
-#define MAIN_EN_MUX BIT(1)
-#define MAIN_EN BIT(0)
-#define TX_MARGINING_MUX BIT(6)
-#define TX_MARGINING(x) ((x) & 0x3f)
-#define TX_PRE_MUX BIT(6)
-#define TX_PRE(x) ((x) & 0x3f)
-#define TX_POST_MUX BIT(6)
-#define TX_POST(x) ((x) & 0x3f)
-#define CML_GEAR_MODE(x) (((x) & 7) << 3)
-#define CML2CMOS_IBOOST_MODE(x) ((x) & 7)
-#define MIXER_LOADB_MODE(x) (((x) & 0xf) << 2)
-#define MIXER_DATARATE_MODE(x) ((x) & 3)
-#define VGA_THRESH_DFE(x) ((x) & 0x3f)
-#define SIGDET_LP_BYP_PS0_TO_PS2 BIT(5)
-#define SIGDET_LP_BYP_MUX BIT(4)
-#define SIGDET_LP_BYP BIT(3)
-#define SIGDET_EN_MUX BIT(2)
-#define SIGDET_EN BIT(1)
-#define SIGDET_FLT_BYP BIT(0)
-#define SIGDET_LVL(x) (((x) & 0xf) << 4)
-#define SIGDET_BW_CTRL(x) ((x) & 0xf)
-#define SIGDET_DEGLITCH_CTRL(x) (((x) & 0xf) << 1)
-#define SIGDET_DEGLITCH_BYP BIT(0)
-#define INVERT_PCS_RX_CLK BIT(7)
-#define PWM_EN BIT(6)
-#define RXBIAS_SEL(x) (((x) & 0x3) << 4)
-#define EBDAC_SIGN BIT(3)
-#define EDAC_SIGN BIT(2)
-#define EN_AUXTAP1SIGN_INVERT BIT(1)
-#define EN_DAC_CHOPPING BIT(0)
-#define DRVR_LOGIC_CLK_EN BIT(4)
-#define DRVR_LOGIC_CLK_DIV(x) ((x) & 0xf)
-#define PARALLEL_RATE_MODE2(x) (((x) & 0x3) << 4)
-#define PARALLEL_RATE_MODE1(x) (((x) & 0x3) << 2)
-#define PARALLEL_RATE_MODE0(x) ((x) & 0x3)
-#define BAND_MODE2(x) (((x) & 0x3) << 4)
-#define BAND_MODE1(x) (((x) & 0x3) << 2)
-#define BAND_MODE0(x) ((x) & 0x3)
-#define LANE_SYNC_MODE BIT(5)
-#define LANE_MODE(x) ((x) & 0x1f)
-#define CDR_PD_SEL_MODE0(x) (((x) & 0x3) << 5)
-#define EN_DLL_MODE0 BIT(4)
-#define EN_IQ_DCC_MODE0 BIT(3)
-#define EN_IQCAL_MODE0 BIT(2)
-#define EN_QPATH_MODE0 BIT(1)
-#define EN_EPATH_MODE0 BIT(0)
-#define FORCE_TSYNC_ACK BIT(7)
-#define FORCE_CMN_ACK BIT(6)
-#define FORCE_CMN_READY BIT(5)
-#define EN_RCLK_DEGLITCH BIT(4)
-#define BYPASS_RSM_CDR_RESET BIT(3)
-#define BYPASS_RSM_TSYNC BIT(2)
-#define BYPASS_RSM_SAMP_CAL BIT(1)
-#define BYPASS_RSM_DLL_CAL BIT(0)
-
-/* EMAC_QSERDES_COM_SYS_CLK_CTRL */
-#define SYSCLK_CM BIT(4)
-#define SYSCLK_AC_COUPLE BIT(3)
-
-/* EMAC_QSERDES_COM_PLL_CNTRL */
-#define OCP_EN BIT(5)
-#define PLL_DIV_FFEN BIT(2)
-#define PLL_DIV_ORD BIT(1)
-
-/* EMAC_QSERDES_COM_SYSCLK_EN_SEL */
-#define SYSCLK_SEL_CMOS BIT(3)
-
-/* EMAC_QSERDES_COM_RESETSM_CNTRL */
-#define FRQ_TUNE_MODE BIT(4)
-
-/* EMAC_QSERDES_COM_PLLLOCK_CMP_EN */
-#define PLLLOCK_CMP_EN BIT(0)
-
-/* EMAC_QSERDES_COM_DEC_START1 */
-#define DEC_START1_MUX BIT(7)
-#define DEC_START1(x) ((x) & 0x7f)
-
-/* EMAC_QSERDES_COM_DIV_FRAC_START1 * EMAC_QSERDES_COM_DIV_FRAC_START2 */
-#define DIV_FRAC_START_MUX BIT(7)
-#define DIV_FRAC_START(x) ((x) & 0x7f)
-
-/* EMAC_QSERDES_COM_DIV_FRAC_START3 */
-#define DIV_FRAC_START3_MUX BIT(4)
-#define DIV_FRAC_START3(x) ((x) & 0xf)
-
-/* EMAC_QSERDES_COM_DEC_START2 */
-#define DEC_START2_MUX BIT(1)
-#define DEC_START2 BIT(0)
-
-/* EMAC_QSERDES_COM_RESET_SM */
-#define READY BIT(5)
-
-/* EMAC_QSERDES_TX_TX_EMP_POST1_LVL */
-#define TX_EMP_POST1_LVL_MUX BIT(5)
-#define TX_EMP_POST1_LVL(x) ((x) & 0x1f)
-#define TX_EMP_POST1_LVL_BMSK 0x1f
-#define TX_EMP_POST1_LVL_SHFT 0
-
-/* EMAC_QSERDES_TX_TX_DRV_LVL */
-#define TX_DRV_LVL_MUX BIT(4)
-#define TX_DRV_LVL(x) ((x) & 0xf)
-
-/* EMAC_QSERDES_TX_TRAN_DRVR_EMP_EN */
-#define EMP_EN_MUX BIT(1)
-#define EMP_EN BIT(0)
-
-/* EMAC_QSERDES_RX_CDR_CONTROL & EMAC_QSERDES_RX_CDR_CONTROL2 */
-#define HBW_PD_EN BIT(7)
-#define SECONDORDERENABLE BIT(6)
-#define FIRSTORDER_THRESH(x) (((x) & 0x7) << 3)
-#define SECONDORDERGAIN(x) ((x) & 0x7)
-
-/* EMAC_QSERDES_RX_RX_EQ_GAIN12 */
-#define RX_EQ_GAIN2(x) (((x) & 0xf) << 4)
-#define RX_EQ_GAIN1(x) ((x) & 0xf)
-
-/* EMAC_SGMII_PHY_SERDES_START */
-#define SERDES_START BIT(0)
-
-/* EMAC_SGMII_PHY_CMN_PWR_CTRL */
-#define BIAS_EN BIT(6)
-#define PLL_EN BIT(5)
-#define SYSCLK_EN BIT(4)
-#define CLKBUF_L_EN BIT(3)
-#define PLL_TXCLK_EN BIT(1)
-#define PLL_RXCLK_EN BIT(0)
-
-/* EMAC_SGMII_PHY_RX_PWR_CTRL */
-#define L0_RX_SIGDET_EN BIT(7)
-#define L0_RX_TERM_MODE(x) (((x) & 3) << 4)
-#define L0_RX_I_EN BIT(1)
-
-/* EMAC_SGMII_PHY_TX_PWR_CTRL */
-#define L0_TX_EN BIT(5)
-#define L0_CLKBUF_EN BIT(4)
-#define L0_TRAN_BIAS_EN BIT(1)
-
-/* EMAC_SGMII_PHY_LANE_CTRL1 */
-#define L0_RX_EQUALIZE_ENABLE BIT(6)
-#define L0_RESET_TSYNC_EN BIT(4)
-#define L0_DRV_LVL(x) ((x) & 0xf)
-
-/* EMAC_SGMII_PHY_AUTONEG_CFG2 */
+#define EMAC_SGMII_PHY_AUTONEG_CFG2 0x0048
+#define EMAC_SGMII_PHY_SPEED_CFG1 0x0074
+#define EMAC_SGMII_PHY_IRQ_CMD 0x00ac
+#define EMAC_SGMII_PHY_INTERRUPT_CLEAR 0x00b0
+#define EMAC_SGMII_PHY_INTERRUPT_STATUS 0x00b8
+
#define FORCE_AN_TX_CFG BIT(5)
#define FORCE_AN_RX_CFG BIT(4)
#define AN_ENABLE BIT(0)
-/* EMAC_SGMII_PHY_SPEED_CFG1 */
#define DUPLEX_MODE BIT(4)
#define SPDMODE_1000 BIT(1)
#define SPDMODE_100 BIT(0)
#define SPDMODE_10 0
-#define SPDMODE_BMSK 3
-#define SPDMODE_SHFT 0
-
-/* EMAC_SGMII_PHY_POW_DWN_CTRL0 */
-#define PWRDN_B BIT(0)
-#define CDR_MAX_CNT(x) ((x) & 0xff)
-
-/* EMAC_QSERDES_TX_BIST_MODE_LANENO */
-#define BIST_LANE_NUMBER(x) (((x) & 3) << 5)
-#define BISTMODE(x) ((x) & 0x1f)
-
-/* EMAC_QSERDES_COM_PLLLOCK_CMPx */
-#define PLLLOCK_CMP(x) ((x) & 0xff)
-/* EMAC_SGMII_PHY_RESET_CTRL */
-#define PHY_SW_RESET BIT(0)
-
-/* EMAC_SGMII_PHY_IRQ_CMD */
#define IRQ_GLOBAL_CLEAR BIT(0)
-/* EMAC_SGMII_PHY_INTERRUPT_MASK */
#define DECODE_CODE_ERR BIT(7)
#define DECODE_DISP_ERR BIT(6)
-#define PLL_UNLOCK BIT(5)
-#define AN_ILLEGAL_TERM BIT(4)
-#define SYNC_FAIL BIT(3)
-#define AN_START BIT(2)
-#define AN_END BIT(1)
-#define AN_REQUEST BIT(0)
#define SGMII_PHY_IRQ_CLR_WAIT_TIME 10
-#define SGMII_PHY_INTERRUPT_ERR (\
- DECODE_CODE_ERR |\
- DECODE_DISP_ERR)
-
-#define SGMII_ISR_AN_MASK (\
- AN_REQUEST |\
- AN_START |\
- AN_END |\
- AN_ILLEGAL_TERM |\
- PLL_UNLOCK |\
- SYNC_FAIL)
-
-#define SGMII_ISR_MASK (\
- SGMII_PHY_INTERRUPT_ERR |\
- SGMII_ISR_AN_MASK)
-
-/* SGMII TX_CONFIG */
-#define TXCFG_LINK 0x8000
-#define TXCFG_MODE_BMSK 0x1c00
-#define TXCFG_1000_FULL 0x1800
-#define TXCFG_100_FULL 0x1400
-#define TXCFG_100_HALF 0x0400
-#define TXCFG_10_FULL 0x1000
-#define TXCFG_10_HALF 0x0000
+#define SGMII_PHY_INTERRUPT_ERR (DECODE_CODE_ERR | DECODE_DISP_ERR)
#define SERDES_START_WAIT_TIMES 100
-struct emac_reg_write {
- unsigned int offset;
- u32 val;
-};
-
-static void emac_reg_write_all(void __iomem *base,
- const struct emac_reg_write *itr, size_t size)
-{
- size_t i;
-
- for (i = 0; i < size; ++itr, ++i)
- writel(itr->val, base + itr->offset);
-}
-
-static const struct emac_reg_write physical_coding_sublayer_programming_v1[] = {
- {EMAC_SGMII_PHY_CDR_CTRL0, CDR_MAX_CNT(15)},
- {EMAC_SGMII_PHY_POW_DWN_CTRL0, PWRDN_B},
- {EMAC_SGMII_PHY_CMN_PWR_CTRL,
- BIAS_EN | SYSCLK_EN | CLKBUF_L_EN | PLL_TXCLK_EN | PLL_RXCLK_EN},
- {EMAC_SGMII_PHY_TX_PWR_CTRL, L0_TX_EN | L0_CLKBUF_EN | L0_TRAN_BIAS_EN},
- {EMAC_SGMII_PHY_RX_PWR_CTRL,
- L0_RX_SIGDET_EN | L0_RX_TERM_MODE(1) | L0_RX_I_EN},
- {EMAC_SGMII_PHY_CMN_PWR_CTRL,
- BIAS_EN | PLL_EN | SYSCLK_EN | CLKBUF_L_EN | PLL_TXCLK_EN |
- PLL_RXCLK_EN},
- {EMAC_SGMII_PHY_LANE_CTRL1,
- L0_RX_EQUALIZE_ENABLE | L0_RESET_TSYNC_EN | L0_DRV_LVL(15)},
-};
-
-static const struct emac_reg_write sysclk_refclk_setting[] = {
- {EMAC_QSERDES_COM_SYSCLK_EN_SEL, SYSCLK_SEL_CMOS},
- {EMAC_QSERDES_COM_SYS_CLK_CTRL, SYSCLK_CM | SYSCLK_AC_COUPLE},
-};
-
-static const struct emac_reg_write pll_setting[] = {
- {EMAC_QSERDES_COM_PLL_IP_SETI, PLL_IPSETI(1)},
- {EMAC_QSERDES_COM_PLL_CP_SETI, PLL_CPSETI(59)},
- {EMAC_QSERDES_COM_PLL_IP_SETP, PLL_IPSETP(10)},
- {EMAC_QSERDES_COM_PLL_CP_SETP, PLL_CPSETP(9)},
- {EMAC_QSERDES_COM_PLL_CRCTRL, PLL_RCTRL(15) | PLL_CCTRL(11)},
- {EMAC_QSERDES_COM_PLL_CNTRL, OCP_EN | PLL_DIV_FFEN | PLL_DIV_ORD},
- {EMAC_QSERDES_COM_DEC_START1, DEC_START1_MUX | DEC_START1(2)},
- {EMAC_QSERDES_COM_DEC_START2, DEC_START2_MUX | DEC_START2},
- {EMAC_QSERDES_COM_DIV_FRAC_START1,
- DIV_FRAC_START_MUX | DIV_FRAC_START(85)},
- {EMAC_QSERDES_COM_DIV_FRAC_START2,
- DIV_FRAC_START_MUX | DIV_FRAC_START(42)},
- {EMAC_QSERDES_COM_DIV_FRAC_START3,
- DIV_FRAC_START3_MUX | DIV_FRAC_START3(3)},
- {EMAC_QSERDES_COM_PLLLOCK_CMP1, PLLLOCK_CMP(43)},
- {EMAC_QSERDES_COM_PLLLOCK_CMP2, PLLLOCK_CMP(104)},
- {EMAC_QSERDES_COM_PLLLOCK_CMP3, PLLLOCK_CMP(0)},
- {EMAC_QSERDES_COM_PLLLOCK_CMP_EN, PLLLOCK_CMP_EN},
- {EMAC_QSERDES_COM_RESETSM_CNTRL, FRQ_TUNE_MODE},
-};
-
-static const struct emac_reg_write cdr_setting[] = {
- {EMAC_QSERDES_RX_CDR_CONTROL,
- SECONDORDERENABLE | FIRSTORDER_THRESH(3) | SECONDORDERGAIN(2)},
- {EMAC_QSERDES_RX_CDR_CONTROL2,
- SECONDORDERENABLE | FIRSTORDER_THRESH(3) | SECONDORDERGAIN(4)},
-};
-
-static const struct emac_reg_write tx_rx_setting[] = {
- {EMAC_QSERDES_TX_BIST_MODE_LANENO, 0},
- {EMAC_QSERDES_TX_TX_DRV_LVL, TX_DRV_LVL_MUX | TX_DRV_LVL(15)},
- {EMAC_QSERDES_TX_TRAN_DRVR_EMP_EN, EMP_EN_MUX | EMP_EN},
- {EMAC_QSERDES_TX_TX_EMP_POST1_LVL,
- TX_EMP_POST1_LVL_MUX | TX_EMP_POST1_LVL(1)},
- {EMAC_QSERDES_RX_RX_EQ_GAIN12, RX_EQ_GAIN2(15) | RX_EQ_GAIN1(15)},
- {EMAC_QSERDES_TX_LANE_MODE, LANE_MODE(8)},
-};
-
-static const struct emac_reg_write sgmii_v2_laned[] = {
- /* CDR Settings */
- {EMAC_SGMII_LN_UCDR_FO_GAIN_MODE0,
- UCDR_STEP_BY_TWO_MODE0 | UCDR_xO_GAIN_MODE(10)},
- {EMAC_SGMII_LN_UCDR_SO_GAIN_MODE0, UCDR_xO_GAIN_MODE(0)},
- {EMAC_SGMII_LN_UCDR_SO_CONFIG, UCDR_ENABLE | UCDR_SO_SATURATION(12)},
-
- /* TX/RX Settings */
- {EMAC_SGMII_LN_RX_EN_SIGNAL, SIGDET_LP_BYP_PS4 | SIGDET_EN_PS0_TO_PS2},
-
- {EMAC_SGMII_LN_DRVR_CTRL0, TXVAL_VALID_INIT | KR_PCIGEN3_MODE},
- {EMAC_SGMII_LN_DRVR_TAP_EN, MAIN_EN},
- {EMAC_SGMII_LN_TX_MARGINING, TX_MARGINING_MUX | TX_MARGINING(25)},
- {EMAC_SGMII_LN_TX_PRE, TX_PRE_MUX},
- {EMAC_SGMII_LN_TX_POST, TX_POST_MUX},
-
- {EMAC_SGMII_LN_CML_CTRL_MODE0,
- CML_GEAR_MODE(1) | CML2CMOS_IBOOST_MODE(1)},
- {EMAC_SGMII_LN_MIXER_CTRL_MODE0,
- MIXER_LOADB_MODE(12) | MIXER_DATARATE_MODE(1)},
- {EMAC_SGMII_LN_VGA_INITVAL, VGA_THRESH_DFE(31)},
- {EMAC_SGMII_LN_SIGDET_ENABLES,
- SIGDET_LP_BYP_PS0_TO_PS2 | SIGDET_FLT_BYP},
- {EMAC_SGMII_LN_SIGDET_CNTRL, SIGDET_LVL(8)},
-
- {EMAC_SGMII_LN_SIGDET_DEGLITCH_CNTRL, SIGDET_DEGLITCH_CTRL(4)},
- {EMAC_SGMII_LN_RX_MISC_CNTRL0, 0},
- {EMAC_SGMII_LN_DRVR_LOGIC_CLKDIV,
- DRVR_LOGIC_CLK_EN | DRVR_LOGIC_CLK_DIV(4)},
-
- {EMAC_SGMII_LN_PARALLEL_RATE, PARALLEL_RATE_MODE0(1)},
- {EMAC_SGMII_LN_TX_BAND_MODE, BAND_MODE0(2)},
- {EMAC_SGMII_LN_RX_BAND, BAND_MODE0(3)},
- {EMAC_SGMII_LN_LANE_MODE, LANE_MODE(26)},
- {EMAC_SGMII_LN_RX_RCVR_PATH1_MODE0, CDR_PD_SEL_MODE0(3)},
- {EMAC_SGMII_LN_RSM_CONFIG, BYPASS_RSM_SAMP_CAL | BYPASS_RSM_DLL_CAL},
-};
-
-static const struct emac_reg_write physical_coding_sublayer_programming_v2[] = {
- {EMAC_SGMII_PHY_POW_DWN_CTRL0, PWRDN_B},
- {EMAC_SGMII_PHY_CDR_CTRL0, CDR_MAX_CNT(15)},
- {EMAC_SGMII_PHY_TX_PWR_CTRL, 0},
- {EMAC_SGMII_PHY_LANE_CTRL1, L0_RX_EQUALIZE_ENABLE},
-};
-
static int emac_sgmii_link_init(struct emac_adapter *adpt)
{
struct phy_device *phydev = adpt->phydev;
@@ -536,98 +121,6 @@ static int emac_sgmii_irq_clear(struct emac_adapter *adpt, u32 irq_bits)
return 0;
}
-int emac_sgmii_init_v1(struct emac_adapter *adpt)
-{
- struct emac_phy *phy = &adpt->phy;
- unsigned int i;
- int ret;
-
- ret = emac_sgmii_link_init(adpt);
- if (ret)
- return ret;
-
- emac_reg_write_all(phy->base, physical_coding_sublayer_programming_v1,
- ARRAY_SIZE(physical_coding_sublayer_programming_v1));
- emac_reg_write_all(phy->base, sysclk_refclk_setting,
- ARRAY_SIZE(sysclk_refclk_setting));
- emac_reg_write_all(phy->base, pll_setting, ARRAY_SIZE(pll_setting));
- emac_reg_write_all(phy->base, cdr_setting, ARRAY_SIZE(cdr_setting));
- emac_reg_write_all(phy->base, tx_rx_setting,
- ARRAY_SIZE(tx_rx_setting));
-
- /* Power up the Ser/Des engine */
- writel(SERDES_START, phy->base + EMAC_SGMII_PHY_SERDES_START);
-
- for (i = 0; i < SERDES_START_WAIT_TIMES; i++) {
- if (readl(phy->base + EMAC_QSERDES_COM_RESET_SM) & READY)
- break;
- usleep_range(100, 200);
- }
-
- if (i == SERDES_START_WAIT_TIMES) {
- netdev_err(adpt->netdev, "error: ser/des failed to start\n");
- return -EIO;
- }
- /* Mask out all the SGMII Interrupt */
- writel(0, phy->base + EMAC_SGMII_PHY_INTERRUPT_MASK);
-
- emac_sgmii_irq_clear(adpt, SGMII_PHY_INTERRUPT_ERR);
-
- return 0;
-}
-
-int emac_sgmii_init_v2(struct emac_adapter *adpt)
-{
- struct emac_phy *phy = &adpt->phy;
- void __iomem *phy_regs = phy->base;
- void __iomem *laned = phy->digital;
- unsigned int i;
- u32 lnstatus;
- int ret;
-
- ret = emac_sgmii_link_init(adpt);
- if (ret)
- return ret;
-
- /* PCS lane-x init */
- emac_reg_write_all(phy->base, physical_coding_sublayer_programming_v2,
- ARRAY_SIZE(physical_coding_sublayer_programming_v2));
-
- /* SGMII lane-x init */
- emac_reg_write_all(phy->digital,
- sgmii_v2_laned, ARRAY_SIZE(sgmii_v2_laned));
-
- /* Power up PCS and start reset lane state machine */
-
- writel(0, phy_regs + EMAC_SGMII_PHY_RESET_CTRL);
- writel(1, laned + SGMII_LN_RSM_START);
-
- /* Wait for c_ready assertion */
- for (i = 0; i < SERDES_START_WAIT_TIMES; i++) {
- lnstatus = readl(phy_regs + SGMII_PHY_LN_LANE_STATUS);
- if (lnstatus & BIT(1))
- break;
- usleep_range(100, 200);
- }
-
- if (i == SERDES_START_WAIT_TIMES) {
- netdev_err(adpt->netdev, "SGMII failed to start\n");
- return -EIO;
- }
-
- /* Disable digital and SERDES loopback */
- writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN0);
- writel(0, phy_regs + SGMII_PHY_LN_BIST_GEN2);
- writel(0, phy_regs + SGMII_PHY_LN_CDR_CTRL1);
-
- /* Mask out all the SGMII Interrupt */
- writel(0, phy_regs + EMAC_SGMII_PHY_INTERRUPT_MASK);
-
- emac_sgmii_irq_clear(adpt, SGMII_PHY_INTERRUPT_ERR);
-
- return 0;
-}
-
static void emac_sgmii_reset_prepare(struct emac_adapter *adpt)
{
struct emac_phy *phy = &adpt->phy;
@@ -651,16 +144,19 @@ void emac_sgmii_reset(struct emac_adapter *adpt)
{
int ret;
- clk_set_rate(adpt->clk[EMAC_CLK_HIGH_SPEED], 19200000);
emac_sgmii_reset_prepare(adpt);
+ ret = emac_sgmii_link_init(adpt);
+ if (ret) {
+ netdev_err(adpt->netdev, "unsupported link speed\n");
+ return;
+ }
+
ret = adpt->phy.initialize(adpt);
if (ret)
netdev_err(adpt->netdev,
"could not reinitialize internal PHY (error=%i)\n",
ret);
-
- clk_set_rate(adpt->clk[EMAC_CLK_HIGH_SPEED], 125000000);
}
static int emac_sgmii_acpi_match(struct device *dev, void *data)
@@ -668,7 +164,7 @@ static int emac_sgmii_acpi_match(struct device *dev, void *data)
static const struct acpi_device_id match_table[] = {
{
.id = "QCOM8071",
- .driver_data = (kernel_ulong_t)emac_sgmii_init_v2,
+ .driver_data = (kernel_ulong_t)emac_sgmii_init_qdf2432,
},
{}
};
@@ -684,11 +180,11 @@ static int emac_sgmii_acpi_match(struct device *dev, void *data)
static const struct of_device_id emac_sgmii_dt_match[] = {
{
.compatible = "qcom,fsm9900-emac-sgmii",
- .data = emac_sgmii_init_v1,
+ .data = emac_sgmii_init_fsm9900,
},
{
.compatible = "qcom,qdf2432-emac-sgmii",
- .data = emac_sgmii_init_v2,
+ .data = emac_sgmii_init_qdf2432,
},
{}
};
@@ -760,6 +256,8 @@ int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt)
if (ret)
goto error;
+ emac_sgmii_irq_clear(adpt, SGMII_PHY_INTERRUPT_ERR);
+
/* We've remapped the addresses, so we don't need the device any
* more. of_find_device_by_node() says we should release it.
*/
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h
index ce79212..e2bef14 100644
--- a/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h
+++ b/drivers/net/ethernet/qualcomm/emac/emac-sgmii.h
@@ -16,9 +16,10 @@
struct emac_adapter;
struct platform_device;
-int emac_sgmii_init_v1(struct emac_adapter *adpt);
-int emac_sgmii_init_v2(struct emac_adapter *adpt);
int emac_sgmii_config(struct platform_device *pdev, struct emac_adapter *adpt);
void emac_sgmii_reset(struct emac_adapter *adpt);
+int emac_sgmii_init_fsm9900(struct emac_adapter *adpt);
+int emac_sgmii_init_qdf2432(struct emac_adapter *adpt);
+
#endif
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply related
* [PATCH 0/2] net: qcom/emac: simplify support for different SOCs
From: Timur Tabi @ 2016-11-21 22:58 UTC (permalink / raw)
To: David Miller, alokc, netdev
On SOCs that have the Qualcomm EMAC network controller, the internal
PHY block is always different. Sometimes the differences are small,
sometimes it might be a completely different IP. Either way, using version
numbers to differentiate them and putting all of the init code in one
file does not scale.
This patchset does two things: The first breaks up the current code into
different files, and the second patch adds support for a third SOC, the
Qualcomm Technologies QDF2400 ARM Server SOC.
Timur Tabi (2):
net: qcom/emac: move phy init code to separate files
net: qcom/emac: add support for the Qualcomm Technologies QDF2400
drivers/net/ethernet/qualcomm/emac/Makefile | 4 +-
.../ethernet/qualcomm/emac/emac-sgmii-fsm9900.c | 246 ++++++++++
.../ethernet/qualcomm/emac/emac-sgmii-qdf2400.c | 217 +++++++++
.../ethernet/qualcomm/emac/emac-sgmii-qdf2432.c | 210 ++++++++
drivers/net/ethernet/qualcomm/emac/emac-sgmii.c | 542 +--------------------
drivers/net/ethernet/qualcomm/emac/emac-sgmii.h | 6 +-
6 files changed, 702 insertions(+), 523 deletions(-)
create mode 100644 drivers/net/ethernet/qualcomm/emac/emac-sgmii-fsm9900.c
create mode 100644 drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2400.c
create mode 100644 drivers/net/ethernet/qualcomm/emac/emac-sgmii-qdf2432.c
--
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm
Technologies, Inc. Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* Re: [PATCH net] ipv6 addrconf: Implemented enhanced DAD (RFC7527)
From: Hannes Frederic Sowa @ 2016-11-21 22:46 UTC (permalink / raw)
To: Erik Nordmark, netdev
In-Reply-To: <ff28e755-be89-c5de-8e1b-3f6adfb1225a@sonic.net>
Hi,
On 21.11.2016 18:10, Erik Nordmark wrote:
> On 11/16/16 10:49 PM, Hannes Frederic Sowa wrote:
>> I thought about even removing the sysctl altogether and enable enhanced
>> DAD by default. ;)
>>
>> I am in favor of enabling it by default.
>>
>> But given that there could be broken implementations out there, we
>> should give users a choice and provide.
> OK, I'll make it the default and send out a new version of the patch. I
> was told I should base the patch on net-next instead of linux-stable so
> I'll move it there.
Correct.
>>
>> Could you always generate a nonce in the interface structure? You could
>> check the sysctl in the send and receive path to attach and check the
>> nonce. This has the advantage that you don't need to delete the
>> interface and recreate it to enable/disable enhanced dad on an interface
>> (also you can get away with the loop around get_random_bytes to make
>> sure its value is not zero as we don't depend on a non-zero nonce
>> variable to signal enaling of the feature, see below).
> The nonce is per interface address and not per interface. Furthermore,
> the RFC says that on a retry of DAD the nodes will end up using a
> different nonce implying that even for the same interface address it
> should pick a different nonce for each DAD attempt.
> Note that since there is no automatic retry of DAD (per RFC4862) and
> each try would check the current sysctl setting so I don't think
> pre-generating the nonce would change the behavior.
Sorry for misreading the code then. ;) Indeed, I don't see a problem
with your proposal.
Thanks,
Hannes
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox