* Re: [PATCH v1 2/3] net/fsl: acpize xgmac_mdio
From: Russell King - ARM Linux admin @ 2020-06-17 18:56 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Calvin Johnson, Jeremy Linton, Jon, Cristi Sovaiala,
Ioana Ciornei, Andrew Lunn, Florian Fainelli, Madalin Bucur,
netdev, linux.cj
In-Reply-To: <CAHp75VeP_+2wJUyMThNs6_AbbbVa8qV6KrLDbXD5BYiOkp13qg@mail.gmail.com>
On Wed, Jun 17, 2020 at 08:54:23PM +0300, Andy Shevchenko wrote:
> On Wed, Jun 17, 2020 at 8:49 PM Russell King - ARM Linux admin
> <linux@armlinux.org.uk> wrote:
> > On Wed, Jun 17, 2020 at 10:45:34PM +0530, Calvin Johnson wrote:
>
> ...
>
> > > - ret = of_address_to_resource(np, 0, &res);
> > > - if (ret) {
> > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > > + if (!res) {
> > > dev_err(&pdev->dev, "could not obtain address\n");
> > > - return ret;
> > > + return -EINVAL;
> > > }
> >
> > I think, as you're completely rewriting the resource handling, it would
> > be a good idea to switch over to using devm_* stuff here.
> >
> > void __iomem *regs;
> >
> > regs = devm_platform_ioremap_resource(pdev, 0);
> > if (IS_ERR(regs))
> {
> > dev_err(&pdev->dev, "could not map resource: %pe\n",
> > regs);
>
> And just in case, this message is dup. The API has few of them
> depending on the error conditions.
I did try to check for that, but it seems it was rather buried. This
seems to have been a common mistake, as I've seen patches removing
such things from various drivers, but I'm never sure which require that
treatment.
Maybe adding such details to the kerneldoc for the functions (maybe
actually _writing_ some kernel doc to describe what the functions are
doing) would be a good start to prevent this kind of thing...
There's a difference between the lazy kerneldoc style of:
/**
* devm_platform_ioremap_resource - call devm_ioremap_resource() for a platform
* device
*
* @pdev: platform device to use both for memory resource lookup as well as
* resource management
* @index: resource index
*/
and the "lets try to be informative" style:
/**
* phy_lookup_setting - lookup a PHY setting
* @speed: speed to match
* @duplex: duplex to match
* @mask: allowed link modes
* @exact: an exact match is required
*
* Search the settings array for a setting that matches the speed and
* duplex, and which is supported.
*
* If @exact is unset, either an exact match or %NULL for no match will
* be returned.
*
* If @exact is set, an exact match, the fastest supported setting at
* or below the specified speed, the slowest supported setting, or if
* they all fail, %NULL will be returned.
*/
;)
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply
* Re: [PATCH net v2] net: phy: smsc: fix printing too many logs
From: Andrew Lunn @ 2020-06-17 18:53 UTC (permalink / raw)
To: Dejin Zheng
Cc: f.fainelli, hkallweit1, linux, davem, kuba, netdev, linux-kernel,
Kevin Groeneveld
In-Reply-To: <20200617183400.19386-1-zhengdejin5@gmail.com>
> v1 -> v2:
> - add more commit message spell out why has this commit
> and how to modify it.
Just to re-iterate what i said for v1, this does not explain why -110
is not an error and so should not cause a message to be printed.
Andrew
^ permalink raw reply
* [PATCH v2] tg3: driver sleeps indefinitely when EEH errors exceed eeh_max_freezes
From: David Christensen @ 2020-06-17 18:51 UTC (permalink / raw)
To: netdev, Siva Reddy Kallam, Prashant Sreedharan, Michael Chan
Cc: linux-kernel, David Christensen
In-Reply-To: <20200615190119.382589-1-drc@linux.vnet.ibm.com>
The driver function tg3_io_error_detected() calls napi_disable twice,
without an intervening napi_enable, when the number of EEH errors exceeds
eeh_max_freezes, resulting in an indefinite sleep while holding rtnl_lock.
Add check for pcierr_recovery which skips code already executed for the
"Frozen" state.
Signed-off-by: David Christensen <drc@linux.vnet.ibm.com>
---
drivers/net/ethernet/broadcom/tg3.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 7a3b22b35238..ebff1fc0d8ce 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -18168,8 +18168,8 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
rtnl_lock();
- /* We probably don't have netdev yet */
- if (!netdev || !netif_running(netdev))
+ /* Could be second call or maybe we don't have netdev yet */
+ if (!netdev || tp->pcierr_recovery || !netif_running(netdev))
goto done;
/* We needn't recover from permanent error */
--
2.18.2
^ permalink raw reply related
* Re: [PATCH v1 1/3] net: phy: Allow mdio buses to auto-probe c45 devices
From: Andrew Lunn @ 2020-06-17 18:51 UTC (permalink / raw)
To: Russell King - ARM Linux admin
Cc: Calvin Johnson, Jeremy Linton, Jon, Cristi Sovaiala,
Ioana Ciornei, Andy Shevchenko, Florian Fainelli, Madalin Bucur,
netdev, linux.cj
In-Reply-To: <20200617174451.GT1551@shell.armlinux.org.uk>
> > + /* bus capabilities, used for probing */
> > + enum {
> > + MDIOBUS_C22 = 0,
> > + MDIOBUS_C45,
> > + MDIOBUS_C22_C45,
> > + } probe_capabilities;
>
> I think it would be better to reserve "0" to mean that no capabilities
> have been declared. We hae the situation where we have mii_bus that
> exist which do support C45, but as they stand, probe_capabilities will
> be zero, and with your definitions above, that means MDIOBUS_C22.
>
> It seems this could lock in some potential issues later down the line
> if we want to use this elsewhere.
Hi Russell
Actually, this patch already causes issues, i think.
drivers/net/ethernet/marvell/mvmdio.c contains two MDIO bus master
drivers. "marvell,orion-mdio" is C22 only. "marvell,xmdio" is C45
only. Because the capabilites is not initialized, it will default to
0, aka MDIOBUS_C22, for the C45 only bus master, and i expect bad
things will happen.
We need the value of 0 to cause existing behaviour. Or all MDIO bus
drivers need reviewing, and the correct capabilities set.
Andrew
^ permalink raw reply
* [PATCH net-next 5/5] net: tso: add UDP segmentation support
From: Eric Dumazet @ 2020-06-17 18:48 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Willem de Bruijn,
Antoine Tenart
In-Reply-To: <20200617184819.49986-1-edumazet@google.com>
Note that like TCP, we do not support additional encapsulations,
and that checksums must be offloaded to the NIC.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/core/tso.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/net/core/tso.c b/net/core/tso.c
index 9f35518815bda275106d27bc5cc34b019429d254..4148f6d48953e1e1ebd878c3953f3e41d47832d9 100644
--- a/net/core/tso.c
+++ b/net/core/tso.c
@@ -16,7 +16,6 @@ EXPORT_SYMBOL(tso_count_descs);
void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
int size, bool is_last)
{
- struct tcphdr *tcph;
int hdr_len = skb_transport_offset(skb) + tso->tlen;
int mac_hdr_len = skb_network_offset(skb);
@@ -32,21 +31,29 @@ void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
iph->payload_len = htons(size + tso->tlen);
}
- tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
- put_unaligned_be32(tso->tcp_seq, &tcph->seq);
+ hdr += skb_transport_offset(skb);
+ if (tso->tlen != sizeof(struct udphdr)) {
+ struct tcphdr *tcph = (struct tcphdr *)hdr;
- if (!is_last) {
- /* Clear all special flags for not last packet */
- tcph->psh = 0;
- tcph->fin = 0;
- tcph->rst = 0;
+ put_unaligned_be32(tso->tcp_seq, &tcph->seq);
+
+ if (!is_last) {
+ /* Clear all special flags for not last packet */
+ tcph->psh = 0;
+ tcph->fin = 0;
+ tcph->rst = 0;
+ }
+ } else {
+ struct udphdr *uh = (struct udphdr *)hdr;
+
+ uh->len = htons(sizeof(*uh) + size);
}
}
EXPORT_SYMBOL(tso_build_hdr);
void tso_build_data(const struct sk_buff *skb, struct tso_t *tso, int size)
{
- tso->tcp_seq += size;
+ tso->tcp_seq += size; /* not worth avoiding this operation for UDP */
tso->size -= size;
tso->data += size;
@@ -64,12 +71,12 @@ EXPORT_SYMBOL(tso_build_data);
int tso_start(struct sk_buff *skb, struct tso_t *tso)
{
- int tlen = tcp_hdrlen(skb);
+ int tlen = skb_is_gso_tcp(skb) ? tcp_hdrlen(skb) : sizeof(struct udphdr);
int hdr_len = skb_transport_offset(skb) + tlen;
tso->tlen = tlen;
tso->ip_id = ntohs(ip_hdr(skb)->id);
- tso->tcp_seq = ntohl(tcp_hdr(skb)->seq);
+ tso->tcp_seq = (tlen != sizeof(struct udphdr)) ? ntohl(tcp_hdr(skb)->seq) : 0;
tso->next_frag_idx = 0;
tso->ipv6 = vlan_get_protocol(skb) == htons(ETH_P_IPV6);
--
2.27.0.290.gba653c62da-goog
^ permalink raw reply related
* [PATCH net-next 4/5] net: tso: cache transport header length
From: Eric Dumazet @ 2020-06-17 18:48 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Willem de Bruijn,
Antoine Tenart
In-Reply-To: <20200617184819.49986-1-edumazet@google.com>
Add tlen field into struct tso_t, and change tso_start()
to return skb_transport_offset(skb) + tso->tlen
This removes from callers the need to use tcp_hdrlen(skb) and
will ease UDP segmentation offload addition.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 5 +++--
drivers/net/ethernet/freescale/fec_main.c | 5 ++---
drivers/net/ethernet/marvell/mv643xx_eth.c | 5 ++---
drivers/net/ethernet/marvell/mvneta.c | 5 ++---
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 6 +++---
.../net/ethernet/marvell/octeontx2/nic/otx2_txrx.c | 6 +++---
include/net/tso.h | 3 ++-
net/core/tso.c | 11 +++++++----
8 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index 069e7413f1ef57ef401adfa6c7efdaad8005aba0..a45223f0cca5813324dd6543095f5375ffe5f27e 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -1489,9 +1489,10 @@ static int nicvf_sq_append_tso(struct nicvf *nic, struct snd_queue *sq,
int seg_subdescs = 0, desc_cnt = 0;
int seg_len, total_len, data_left;
int hdr_qentry = qentry;
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ int hdr_len;
+
+ hdr_len = tso_start(skb, &tso);
- tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
char *hdr;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 2d0d313ee7c5a193a805f858b9fcd83f98a4ebea..9f80a33c5b16b07b30aa8ebfbc4dc8338a6ae056 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -710,8 +710,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- int total_len, data_left;
+ int hdr_len, total_len, data_left;
struct bufdesc *bdp = txq->bd.cur;
struct tso_t tso;
unsigned int index = 0;
@@ -731,7 +730,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
}
/* Initialize the TSO handler, and prepare the first payload */
- tso_start(skb, &tso);
+ hdr_len = tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 4d4b6243318a59ac01190446766d2864f016564e..90e6111ce534dba7f16de983549ade748890124c 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -816,10 +816,9 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
struct net_device *dev)
{
struct mv643xx_eth_private *mp = txq_to_mp(txq);
- int total_len, data_left, ret;
+ int hdr_len, total_len, data_left, ret;
int desc_count = 0;
struct tso_t tso;
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
struct tx_desc *first_tx_desc;
u32 first_cmd_sts = 0;
@@ -832,7 +831,7 @@ static int txq_submit_tso(struct tx_queue *txq, struct sk_buff *skb,
first_tx_desc = &txq->tx_desc_area[txq->tx_curr_desc];
/* Initialize the TSO handler, and prepare the first payload */
- tso_start(skb, &tso);
+ hdr_len = tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 946925bbcb2de93629f45c3b9eecbfaf7338e8d1..95b447c14411479a026cf5a0375e79b345152d7c 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -2604,11 +2604,10 @@ mvneta_tso_put_data(struct net_device *dev, struct mvneta_tx_queue *txq,
static int mvneta_tx_tso(struct sk_buff *skb, struct net_device *dev,
struct mvneta_tx_queue *txq)
{
- int total_len, data_left;
+ int hdr_len, total_len, data_left;
int desc_count = 0;
struct mvneta_port *pp = netdev_priv(dev);
struct tso_t tso;
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
int i;
/* Count needed descriptors */
@@ -2621,7 +2620,7 @@ static int mvneta_tx_tso(struct sk_buff *skb, struct net_device *dev,
}
/* Initialize the TSO handler, and prepare the first payload */
- tso_start(skb, &tso);
+ hdr_len = tso_start(skb, &tso);
total_len = skb->len - hdr_len;
while (total_len > 0) {
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 24f4d8e0da989daaca10333ec9c5a3a22ec66c48..e9f28756802628cc0a77dd80451a36ffe4b7f19c 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -3160,9 +3160,8 @@ static int mvpp2_tx_tso(struct sk_buff *skb, struct net_device *dev,
struct mvpp2_txq_pcpu *txq_pcpu)
{
struct mvpp2_port *port = netdev_priv(dev);
+ int hdr_sz, i, len, descs = 0;
struct tso_t tso;
- int hdr_sz = skb_transport_offset(skb) + tcp_hdrlen(skb);
- int i, len, descs = 0;
/* Check number of available descriptors */
if (mvpp2_aggr_desc_num_check(port, aggr_txq, tso_count_descs(skb)) ||
@@ -3170,7 +3169,8 @@ static int mvpp2_tx_tso(struct sk_buff *skb, struct net_device *dev,
tso_count_descs(skb)))
return 0;
- tso_start(skb, &tso);
+ hdr_sz = tso_start(skb, &tso);
+
len = skb->len - hdr_sz;
while (len > 0) {
int left = min_t(int, skb_shinfo(skb)->gso_size, len);
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
index b04f5429d72d911da145ee13b99506d84a9d7925..e54df6ed6daaa8ba90798904942e0155a90ea889 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
@@ -619,8 +619,7 @@ static void otx2_sq_append_tso(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
struct sk_buff *skb, u16 qidx)
{
struct netdev_queue *txq = netdev_get_tx_queue(pfvf->netdev, qidx);
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
- int tcp_data, seg_len, pkt_len, offset;
+ int hdr_len, tcp_data, seg_len, pkt_len, offset;
struct nix_sqe_hdr_s *sqe_hdr;
int first_sqe = sq->head;
struct sg_list list;
@@ -636,7 +635,8 @@ static void otx2_sq_append_tso(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
netdev_tx_sent_queue(txq, skb->len);
- tso_start(skb, &tso);
+ hdr_len = tso_start(skb, &tso);
+
tcp_data = skb->len - hdr_len;
while (tcp_data > 0) {
char *hdr;
diff --git a/include/net/tso.h b/include/net/tso.h
index 32d9272ade6af0e3dd1272ecafa948f1535ea61f..62c98a9c60f15d7b4869f1ab523dfeb83fb18ba6 100644
--- a/include/net/tso.h
+++ b/include/net/tso.h
@@ -11,6 +11,7 @@ struct tso_t {
int size;
void *data;
u16 ip_id;
+ u8 tlen; /* transport header len */
bool ipv6;
u32 tcp_seq;
};
@@ -19,6 +20,6 @@ int tso_count_descs(const struct sk_buff *skb);
void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
int size, bool is_last);
void tso_build_data(const struct sk_buff *skb, struct tso_t *tso, int size);
-void tso_start(struct sk_buff *skb, struct tso_t *tso);
+int tso_start(struct sk_buff *skb, struct tso_t *tso);
#endif /* _TSO_H */
diff --git a/net/core/tso.c b/net/core/tso.c
index 56487e3bb26dc01b65f73f96fd0157bec73ea0d0..9f35518815bda275106d27bc5cc34b019429d254 100644
--- a/net/core/tso.c
+++ b/net/core/tso.c
@@ -17,7 +17,7 @@ void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
int size, bool is_last)
{
struct tcphdr *tcph;
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ int hdr_len = skb_transport_offset(skb) + tso->tlen;
int mac_hdr_len = skb_network_offset(skb);
memcpy(hdr, skb->data, hdr_len);
@@ -30,7 +30,7 @@ void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
} else {
struct ipv6hdr *iph = (void *)(hdr + mac_hdr_len);
- iph->payload_len = htons(size + tcp_hdrlen(skb));
+ iph->payload_len = htons(size + tso->tlen);
}
tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
put_unaligned_be32(tso->tcp_seq, &tcph->seq);
@@ -62,10 +62,12 @@ void tso_build_data(const struct sk_buff *skb, struct tso_t *tso, int size)
}
EXPORT_SYMBOL(tso_build_data);
-void tso_start(struct sk_buff *skb, struct tso_t *tso)
+int tso_start(struct sk_buff *skb, struct tso_t *tso)
{
- int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+ int tlen = tcp_hdrlen(skb);
+ int hdr_len = skb_transport_offset(skb) + tlen;
+ tso->tlen = tlen;
tso->ip_id = ntohs(ip_hdr(skb)->id);
tso->tcp_seq = ntohl(tcp_hdr(skb)->seq);
tso->next_frag_idx = 0;
@@ -83,5 +85,6 @@ void tso_start(struct sk_buff *skb, struct tso_t *tso)
tso->data = skb_frag_address(frag);
tso->next_frag_idx++;
}
+ return hdr_len;
}
EXPORT_SYMBOL(tso_start);
--
2.27.0.290.gba653c62da-goog
^ permalink raw reply related
* [PATCH net-next 3/5] net: tso: constify tso_count_descs() and friends
From: Eric Dumazet @ 2020-06-17 18:48 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Willem de Bruijn,
Antoine Tenart
In-Reply-To: <20200617184819.49986-1-edumazet@google.com>
skb argument of tso_count_descs(), tso_build_hdr() and tso_build_data() can be const.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/tso.h | 6 +++---
net/core/tso.c | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/net/tso.h b/include/net/tso.h
index d9b0a14b2a57b388ae4518fc63497ffd600b8887..32d9272ade6af0e3dd1272ecafa948f1535ea61f 100644
--- a/include/net/tso.h
+++ b/include/net/tso.h
@@ -15,10 +15,10 @@ struct tso_t {
u32 tcp_seq;
};
-int tso_count_descs(struct sk_buff *skb);
-void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
+int tso_count_descs(const struct sk_buff *skb);
+void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
int size, bool is_last);
-void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size);
+void tso_build_data(const struct sk_buff *skb, struct tso_t *tso, int size);
void tso_start(struct sk_buff *skb, struct tso_t *tso);
#endif /* _TSO_H */
diff --git a/net/core/tso.c b/net/core/tso.c
index d4d5c077ad7293aa71c3a64f67629e1079060227..56487e3bb26dc01b65f73f96fd0157bec73ea0d0 100644
--- a/net/core/tso.c
+++ b/net/core/tso.c
@@ -6,14 +6,14 @@
#include <asm/unaligned.h>
/* Calculate expected number of TX descriptors */
-int tso_count_descs(struct sk_buff *skb)
+int tso_count_descs(const struct sk_buff *skb)
{
/* The Marvell Way */
return skb_shinfo(skb)->gso_segs * 2 + skb_shinfo(skb)->nr_frags;
}
EXPORT_SYMBOL(tso_count_descs);
-void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
+void tso_build_hdr(const struct sk_buff *skb, char *hdr, struct tso_t *tso,
int size, bool is_last)
{
struct tcphdr *tcph;
@@ -44,7 +44,7 @@ void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
}
EXPORT_SYMBOL(tso_build_hdr);
-void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size)
+void tso_build_data(const struct sk_buff *skb, struct tso_t *tso, int size)
{
tso->tcp_seq += size;
tso->size -= size;
--
2.27.0.290.gba653c62da-goog
^ permalink raw reply related
* [PATCH net-next 2/5] net: tso: shrink struct tso_t
From: Eric Dumazet @ 2020-06-17 18:48 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Willem de Bruijn,
Antoine Tenart
In-Reply-To: <20200617184819.49986-1-edumazet@google.com>
size field can be an int, no need for size_t
Removes a 32bit hole on 64bit kernels.
And align fields for better readability.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/tso.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/include/net/tso.h b/include/net/tso.h
index c33dd00c161f7a6aa65f586b0ceede46af2e8730..d9b0a14b2a57b388ae4518fc63497ffd600b8887 100644
--- a/include/net/tso.h
+++ b/include/net/tso.h
@@ -7,12 +7,12 @@
#define TSO_HEADER_SIZE 256
struct tso_t {
- int next_frag_idx;
- void *data;
- size_t size;
- u16 ip_id;
- bool ipv6;
- u32 tcp_seq;
+ int next_frag_idx;
+ int size;
+ void *data;
+ u16 ip_id;
+ bool ipv6;
+ u32 tcp_seq;
};
int tso_count_descs(struct sk_buff *skb);
--
2.27.0.290.gba653c62da-goog
^ permalink raw reply related
* [PATCH net-next 1/5] net: tso: double TSO_HEADER_SIZE value
From: Eric Dumazet @ 2020-06-17 18:48 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Willem de Bruijn,
Antoine Tenart
In-Reply-To: <20200617184819.49986-1-edumazet@google.com>
Transport header size could be 60 bytes, and network header
size can also be 60 bytes. Add the Ethernet header and we
are above 128 bytes.
Since drivers using net/core/tso.c usually allocates
one DMA coherent piece of memory per TX queue, this patch
might cause issues if a driver was using too many slots.
For 1024 slots, we would need 256 KB of physically
contiguous memory instead of 128 KB.
Alternative fix would be to add checks in the fast path,
but this involves more work in all drivers using net/core/tso.c.
Fixes: f9cbe9a556af ("net: define the TSO header size in net/tso.h")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Antoine Tenart <antoine.tenart@bootlin.com>
---
Note : please wait at least one cycle before backporting to stable versions.
include/net/tso.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/tso.h b/include/net/tso.h
index 7e166a5703497fadf4662acc474f827b2754da78..c33dd00c161f7a6aa65f586b0ceede46af2e8730 100644
--- a/include/net/tso.h
+++ b/include/net/tso.h
@@ -4,7 +4,7 @@
#include <net/ip.h>
-#define TSO_HEADER_SIZE 128
+#define TSO_HEADER_SIZE 256
struct tso_t {
int next_frag_idx;
--
2.27.0.290.gba653c62da-goog
^ permalink raw reply related
* [PATCH net-next 0/5] net: tso: expand to UDP support
From: Eric Dumazet @ 2020-06-17 18:48 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Willem de Bruijn,
Antoine Tenart
With QUIC getting more attention these days, it is worth
implementing UDP direct segmentation, the same we did for TCP.
Drivers will need to advertize NETIF_F_GSO_UDP_L4 so that
GSO stack does not do the (more expensive) segmentation.
Eric Dumazet (5):
net: tso: double TSO_HEADER_SIZE value
net: tso: shrink struct tso_t
net: tso: constify tso_count_descs() and friends
net: tso: cache transport header length
net: tso: add UDP segmentation support
.../ethernet/cavium/thunder/nicvf_queues.c | 5 ++-
drivers/net/ethernet/freescale/fec_main.c | 5 +--
drivers/net/ethernet/marvell/mv643xx_eth.c | 5 +--
drivers/net/ethernet/marvell/mvneta.c | 5 +--
.../net/ethernet/marvell/mvpp2/mvpp2_main.c | 6 +--
.../marvell/octeontx2/nic/otx2_txrx.c | 6 +--
include/net/tso.h | 23 +++++-----
net/core/tso.c | 44 ++++++++++++-------
8 files changed, 54 insertions(+), 45 deletions(-)
--
2.27.0.290.gba653c62da-goog
^ permalink raw reply
* [PATCH][next] enetc: Use struct_size() helper in kzalloc()
From: Gustavo A. R. Silva @ 2020-06-17 18:53 UTC (permalink / raw)
To: Claudiu Manoil, David S. Miller, Jakub Kicinski
Cc: netdev, linux-kernel, Gustavo A. R. Silva
Make use of the struct_size() helper instead of an open-coded version
in order to avoid any potential type mistakes.
This code was detected with the help of Coccinelle and, audited and
fixed manually.
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
drivers/net/ethernet/freescale/enetc/enetc.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c
index 298c55786fd9..61dbf19075fb 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -1687,7 +1687,7 @@ int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
int enetc_alloc_msix(struct enetc_ndev_priv *priv)
{
struct pci_dev *pdev = priv->si->pdev;
- int size, v_tx_rings;
+ int v_tx_rings;
int i, n, err, nvec;
nvec = ENETC_BDR_INT_BASE_IDX + priv->bdr_int_num;
@@ -1702,15 +1702,13 @@ int enetc_alloc_msix(struct enetc_ndev_priv *priv)
/* # of tx rings per int vector */
v_tx_rings = priv->num_tx_rings / priv->bdr_int_num;
- size = sizeof(struct enetc_int_vector) +
- sizeof(struct enetc_bdr) * v_tx_rings;
for (i = 0; i < priv->bdr_int_num; i++) {
struct enetc_int_vector *v;
struct enetc_bdr *bdr;
int j;
- v = kzalloc(size, GFP_KERNEL);
+ v = kzalloc(struct_size(v, tx_ring, v_tx_rings), GFP_KERNEL);
if (!v) {
err = -ENOMEM;
goto fail;
--
2.27.0
^ permalink raw reply related
* Re: [PATCH net-next 1/5] net: tso: double TSO_HEADER_SIZE value
From: Eric Dumazet @ 2020-06-17 18:45 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, Eric Dumazet, Willem de Bruijn, Antoine Tenart
In-Reply-To: <20200617184403.48837-1-edumazet@google.com>
On Wed, Jun 17, 2020 at 11:44 AM Eric Dumazet <edumazet@google.com> wrote:
>
> Transport header size could be 60 bytes, and network header
> size can also be 60 bytes. Add the Ethernet header and we
> are above 128 bytes.
>
> Since drivers using net/core/tso.c usually allocates
> one DMA coherent piece of memory per TX queue, this patch
> might cause issues if a driver was using too many slots.
>
> For 1024 slots, we would need 256 KB of physically
> contiguous memory instead of 128 KB.
>
> Alternative fix would be to add checks in the fast path,
> but this involves more work in all drivers using net/core/tso.c.
>
> Fixes: f9cbe9a556af ("net: define the TSO header size in net/tso.h")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Antoine Tenart <antoine.tenart@bootlin.com>
>
Please disregard this patch, I will send a patch series, sorry for the noise.
^ permalink raw reply
* [PATCH net-next 1/5] net: tso: double TSO_HEADER_SIZE value
From: Eric Dumazet @ 2020-06-17 18:44 UTC (permalink / raw)
To: David S . Miller
Cc: netdev, Eric Dumazet, Eric Dumazet, Willem de Bruijn,
Antoine Tenart
Transport header size could be 60 bytes, and network header
size can also be 60 bytes. Add the Ethernet header and we
are above 128 bytes.
Since drivers using net/core/tso.c usually allocates
one DMA coherent piece of memory per TX queue, this patch
might cause issues if a driver was using too many slots.
For 1024 slots, we would need 256 KB of physically
contiguous memory instead of 128 KB.
Alternative fix would be to add checks in the fast path,
but this involves more work in all drivers using net/core/tso.c.
Fixes: f9cbe9a556af ("net: define the TSO header size in net/tso.h")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Antoine Tenart <antoine.tenart@bootlin.com>
---
include/net/tso.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/net/tso.h b/include/net/tso.h
index 7e166a5703497fadf4662acc474f827b2754da78..c33dd00c161f7a6aa65f586b0ceede46af2e8730 100644
--- a/include/net/tso.h
+++ b/include/net/tso.h
@@ -4,7 +4,7 @@
#include <net/ip.h>
-#define TSO_HEADER_SIZE 128
+#define TSO_HEADER_SIZE 256
struct tso_t {
int next_frag_idx;
--
2.27.0.290.gba653c62da-goog
^ permalink raw reply related
* Re: [PATCH net v1] net: phy: smsc: fix printing too many logs
From: Andrew Lunn @ 2020-06-17 18:43 UTC (permalink / raw)
To: Dejin Zheng
Cc: f.fainelli, hkallweit1, linux, davem, kuba, netdev, linux-kernel,
Kevin Groeneveld
In-Reply-To: <20200617175039.GA18631@nuc8i5>
On Thu, Jun 18, 2020 at 01:50:39AM +0800, Dejin Zheng wrote:
> On Wed, Jun 17, 2020 at 06:19:25PM +0200, Andrew Lunn wrote:
> > On Wed, Jun 17, 2020 at 11:33:40PM +0800, Dejin Zheng wrote:
> > > Commit 7ae7ad2f11ef47 ("net: phy: smsc: use phy_read_poll_timeout()
> > > to simplify the code") will print a lot of logs as follows when Ethernet
> > > cable is not connected:
> > >
> > > [ 4.473105] SMSC LAN8710/LAN8720 2188000.ethernet-1:00: lan87xx_read_status failed: -110
> > >
> > > So fix it by read_poll_timeout().
> >
> > Do you have a more detailed explanation of what is going on here?
> >
> > After a lot of thought, i think i can see how this happens. But the
> > commit message should really spell out why this is the correct fix.
> >
> Hi Andrew:
>
> Kevin report a bug for me in link[1], I check the Commit 7ae7ad2f11ef47
> ("net: phy: smsc: use phy_read_poll_timeout() to simplify the code") and
> found it change the original behavior in smsc driver. It does not has
> any error message whether it is timeout or phy_read fails, but this Commit
> will changed it and will print some error messages by
> phy_read_poll_timeout() when it is timeout or phy_read fails. so use the
> read_poll_timeout() to replace phy_read_poll_timeout() to fix this
> issue. the read_poll_timeout() does not print any log when it goes
> wrong.
>
> the original codes is that:
>
> /* Wait max 640 ms to detect energy */
> for (i = 0; i < 64; i++) {
> /* Sleep to allow link test pulses to be sent */
> msleep(10);
> rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
> if (rc < 0)
> return rc;
> if (rc & MII_LAN83C185_ENERGYON)
> break;
> }
>
> Commit 7ae7ad2f11ef47 modify it as this:
>
> phy_read_poll_timeout(phydev, MII_LAN83C185_CTRL_STATUS,
> rc & MII_LAN83C185_ENERGYON, 10000,
> 640000, true);
> if (rc < 0)
> return rc;
>
> the phy_read_poll_timeout() will print a error log by phydev_err()
> when timeout or rc < 0. read_poll_timeout() just return timeout
> error and does not print any error log.
>
> #define phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \
> timeout_us, sleep_before_read) \
> ({ \
> int __ret = read_poll_timeout(phy_read, val, (cond) || val < 0, \
> sleep_us, timeout_us, sleep_before_read, phydev, regnum); \
> if (val < 0) \
> __ret = val; \
> if (__ret) \
> phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
> __ret; \
> })
>
> So use read_poll_timeout Use read_poll_timeout() to be consistent with the
> original code.
You have explained what the change does. But not why it is
needed. What exactly is happening. To me, the key thing is
understanding why we get -110, and why it is not an actual error we
should be reporting as an error. That is what needs explaining.
And once that is understood, i think we might be looking at a
different solution.
Andrew
^ permalink raw reply
* Re: [PATCH net] ionic: export features for vlans to use
From: Jonathan Toppins @ 2020-06-17 18:42 UTC (permalink / raw)
To: Shannon Nelson, netdev, davem
In-Reply-To: <20200616150626.42738-1-snelson@pensando.io>
On 6/16/20 11:06 AM, Shannon Nelson wrote:
> Set up vlan_features for use by any vlans above us.
>
> Fixes: beead698b173 ("ionic: Add the basic NDO callbacks for netdev support")
> Signed-off-by: Shannon Nelson <snelson@pensando.io>
Acked-by: Jonathan Toppins <jtoppins@redhat.com>
^ permalink raw reply
* Re: [PATCH v4 02/11] fs: Move __scm_install_fd() to __fd_install_received()
From: Kees Cook @ 2020-06-17 18:40 UTC (permalink / raw)
To: David Laight
Cc: linux-kernel@vger.kernel.org, Sargun Dhillon, Christian Brauner,
David S. Miller, Christoph Hellwig, Tycho Andersen,
Jakub Kicinski, Alexander Viro, Aleksa Sarai, Matt Denton,
Jann Horn, Chris Palmer, Robert Sesek, Giuseppe Scrivano,
Greg Kroah-Hartman, Andy Lutomirski, Will Drewry, Shuah Khan,
netdev@vger.kernel.org, containers@lists.linux-foundation.org,
linux-api@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-kselftest@vger.kernel.org
In-Reply-To: <b58ef9a368214b69a86c7a78b67f84d5@AcuMS.aculab.com>
On Wed, Jun 17, 2020 at 03:25:41PM +0000, David Laight wrote:
> From: Kees Cook
> > Sent: 16 June 2020 04:25
>
> > In preparation for users of the "install a received file" logic outside
> > of net/ (pidfd and seccomp), relocate and rename __scm_install_fd() from
> > net/core/scm.c to __fd_install_received() in fs/file.c, and provide a
> > wrapper named fd_install_received_user(), as future patches will change
> > the interface to __fd_install_received().
>
> Any reason for the leading __ ??
Mainly because of the code pattern of only using the inline helpers to
call it.
--
Kees Cook
^ permalink raw reply
* [PATCH net v2] net: phy: smsc: fix printing too many logs
From: Dejin Zheng @ 2020-06-17 18:34 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, linux, davem, kuba, netdev
Cc: linux-kernel, Dejin Zheng, Kevin Groeneveld
Commit 7ae7ad2f11ef47 ("net: phy: smsc: use phy_read_poll_timeout()
to simplify the code") will print a lot of logs as follows when Ethernet
cable is not connected:
[ 4.473105] SMSC LAN8710/LAN8720 2188000.ethernet-1:00: lan87xx_read_status failed: -110
The commit will change the original behavior in smsc driver.
It does not has any error message whether it is timeout or
phy_read() fails, but this commit will changed it and print some
error messages by phy_read_poll_timeout() when it is timeout or
phy_read() fails. so use the read_poll_timeout() function to replace
phy_read_poll_timeout() for fix this issue. the read_poll_timeout()
function does not print any log when it goes wrong.
the original codes is that:
/* Wait max 640 ms to detect energy */
for (i = 0; i < 64; i++) {
/* Sleep to allow link test pulses to be sent */
msleep(10);
rc = phy_read(phydev, MII_LAN83C185_CTRL_STATUS);
if (rc < 0)
return rc;
if (rc & MII_LAN83C185_ENERGYON)
break;
}
the commit 7ae7ad2f11ef47 ("net: phy: smsc: use phy_read_poll_timeout()
to simplify the code") modify it as this:
phy_read_poll_timeout(phydev, MII_LAN83C185_CTRL_STATUS,
rc & MII_LAN83C185_ENERGYON, 10000,
640000, true);
if (rc < 0)
return rc;
the phy_read_poll_timeout() will print a error log by phydev_err()
when timeout or rc < 0. read_poll_timeout() just return timeout
error and does not print any error log.
#define phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \
timeout_us, sleep_before_read) \
({ \
int __ret = read_poll_timeout(phy_read, val, (cond) || val < 0, \
sleep_us, timeout_us, sleep_before_read, phydev, regnum); \
if (val < 0) \
__ret = val; \
if (__ret) \
phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
__ret; \
})
So use read_poll_timeout() to replace phy_read_poll_timeout() for
be consistent with the original code and fix this issue.
Fixes: 7ae7ad2f11ef47 ("net: phy: smsc: use phy_read_poll_timeout() to simplify the code")
Reported-by: Kevin Groeneveld <kgroeneveld@gmail.com>
Signed-off-by: Dejin Zheng <zhengdejin5@gmail.com>
---
v1 -> v2:
- add more commit message spell out why has this commit
and how to modify it.
drivers/net/phy/smsc.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 93da7d3d0954..36c5a57917b8 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -123,9 +123,10 @@ static int lan87xx_read_status(struct phy_device *phydev)
return rc;
/* Wait max 640 ms to detect energy */
- phy_read_poll_timeout(phydev, MII_LAN83C185_CTRL_STATUS, rc,
- rc & MII_LAN83C185_ENERGYON, 10000,
- 640000, true);
+ read_poll_timeout(phy_read, rc,
+ rc & MII_LAN83C185_ENERGYON || rc < 0,
+ 10000, 640000, true, phydev,
+ MII_LAN83C185_CTRL_STATUS);
if (rc < 0)
return rc;
--
2.25.0
^ permalink raw reply related
* Re: WARNING: locking bug in __queue_work
From: syzbot @ 2020-06-17 18:34 UTC (permalink / raw)
To: agruenba, bp, cluster-devel, davem, hpa, jon.maloy, keescook,
konrad.wilk, kuznet, len.brown, linux-kernel, luto, mingo, netdev,
nstange, puwen, rpeterso, syzkaller-bugs, tglx, tipc-discussion,
wad, wang.yi59, x86, ying.xue, yoshfuji
In-Reply-To: <0000000000000655c0057cd141f1@google.com>
syzbot suspects this bug was fixed by commit:
commit ea22eee4e6027d8927099de344f7fff43c507ef9
Author: Bob Peterson <rpeterso@redhat.com>
Date: Wed Apr 29 13:45:54 2020 +0000
gfs2: Allow lock_nolock mount to specify jid=X
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=16fcf249100000
start commit: fe5cdef2 Merge tag 'for-linus-5.1-2' of git://github.com/c..
git tree: upstream
kernel config: https://syzkaller.appspot.com/x/.config?x=856fc6d0fbbeede9
dashboard link: https://syzkaller.appspot.com/bug?extid=6174a6c5eba4b3cdd606
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=17f6c7e3200000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=101507fd200000
If the result looks correct, please mark the bug fixed by replying with:
#syz fix: gfs2: Allow lock_nolock mount to specify jid=X
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
^ permalink raw reply
* [PATCH v2 bpf-next] libbpf: bump version to 0.1.0
From: Andrii Nakryiko @ 2020-06-17 18:31 UTC (permalink / raw)
To: bpf, netdev, ast, daniel; +Cc: andrii.nakryiko, kernel-team, Andrii Nakryiko
Bump libbpf version to 0.1.0, as new development cycle starts.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
---
tools/lib/bpf/libbpf.map | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index f732c77b7ed0..c914347f5065 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -270,3 +270,6 @@ LIBBPF_0.0.9 {
ring_buffer__new;
ring_buffer__poll;
} LIBBPF_0.0.8;
+
+LIBBPF_0.1.0 {
+} LIBBPF_0.0.9;
--
2.24.1
^ permalink raw reply related
* Re: [PATCH net-next v7 6/6] net: phy: DP83822: Add ability to advertise Fiber connection
From: Dan Murphy @ 2020-06-17 18:27 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem, robh
Cc: netdev, linux-kernel, devicetree
In-Reply-To: <20200617182019.6790-7-dmurphy@ti.com>
All
On 6/17/20 1:20 PM, Dan Murphy wrote:
> The DP83822 can be configured to use the RGMII interface. There are
> independent fixed 3.5ns clock shift (aka internal delay) for the TX and RX
> paths. This allow either one to be set if the MII interface is RGMII and
> the value is set in the firmware node.
$subject is wrong. I used the 83822 fiber patch as my base as it had
90% of the work done that I needed for the
internal delay. I will fix it in v8 after review comments.
Dan
^ permalink raw reply
* [PATCH net-next v7 2/6] net: phy: Add a helper to return the index for of the internal delay
From: Dan Murphy @ 2020-06-17 18:20 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem, robh
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200617182019.6790-1-dmurphy@ti.com>
Add a helper function that will return the index in the array for the
passed in internal delay value. The helper requires the array, size and
delay value.
The helper will then return the index for the exact match or return the
index for the index to the closest smaller value.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
drivers/net/phy/phy_device.c | 68 ++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 4 +++
2 files changed, 72 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 04946de74fa0..611d4e68e3c6 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -31,6 +31,7 @@
#include <linux/mdio.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/property.h>
MODULE_DESCRIPTION("PHY library");
MODULE_AUTHOR("Andy Fleming");
@@ -2657,6 +2658,73 @@ void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause)
}
EXPORT_SYMBOL(phy_get_pause);
+/**
+ * phy_get_delay_index - returns the index of the internal delay
+ * @phydev: phy_device struct
+ * @dev: pointer to the devices device struct
+ * @delay_values: array of delays the PHY supports
+ * @size: the size of the delay array
+ * @is_rx: boolean to indicate to get the rx internal delay
+ *
+ * Returns the index within the array of internal delay passed in.
+ * Or if size == 0 then the delay read from the firmware is returned.
+ * The array must be in ascending order.
+ * Return errno if the delay is invalid or cannot be found.
+ */
+s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
+ const int *delay_values, int size, bool is_rx)
+{
+ int ret;
+ int i;
+ s32 delay;
+
+ if (is_rx)
+ ret = device_property_read_u32(dev, "rx-internal-delay-ps",
+ &delay);
+ else
+ ret = device_property_read_u32(dev, "tx-internal-delay-ps",
+ &delay);
+ if (ret) {
+ phydev_err(phydev, "internal delay not defined\n");
+ return -EINVAL;
+ }
+
+ if (delay < 0)
+ return -EINVAL;
+
+ if (size <= 0)
+ return delay;
+
+ if (delay < delay_values[0] || delay > delay_values[size - 1]) {
+ phydev_err(phydev, "Delay %d is out of range\n", delay);
+ return -EINVAL;
+ }
+
+ if (delay == delay_values[0])
+ return 0;
+
+ for (i = 1; i < size; i++) {
+ if (delay == delay_values[i])
+ return i;
+
+ /* Find an approximate index by looking up the table */
+ if (delay > delay_values[i - 1] &&
+ delay < delay_values[i]) {
+ if (delay - delay_values[i - 1] <
+ delay_values[i] - delay)
+ return i - 1;
+ else
+ return i;
+ }
+ }
+
+ phydev_err(phydev, "error finding internal delay index for %d\n",
+ delay);
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(phy_get_internal_delay);
+
static bool phy_drv_supports_irq(struct phy_driver *phydrv)
{
return phydrv->config_intr && phydrv->ack_interrupt;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 8c05d0fb5c00..917bfd422e06 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1430,6 +1430,10 @@ void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx);
bool phy_validate_pause(struct phy_device *phydev,
struct ethtool_pauseparam *pp);
void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause);
+
+s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
+ const int *delay_values, int size, bool is_rx);
+
void phy_resolve_pause(unsigned long *local_adv, unsigned long *partner_adv,
bool *tx_pause, bool *rx_pause);
--
2.26.2
^ permalink raw reply related
* [PATCH net-next v7 1/6] dt-bindings: net: Add tx and rx internal delays
From: Dan Murphy @ 2020-06-17 18:20 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem, robh
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200617182019.6790-1-dmurphy@ti.com>
tx-internal-delays and rx-internal-delays are a common setting for RGMII
capable devices.
These properties are used when the phy-mode or phy-controller is set to
rgmii-id, rgmii-rxid or rgmii-txid. These modes indicate to the
controller that the PHY will add the internal delay for the connection.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
.../devicetree/bindings/net/ethernet-phy.yaml | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/ethernet-phy.yaml b/Documentation/devicetree/bindings/net/ethernet-phy.yaml
index 9b1f1147ca36..b2887476fe6a 100644
--- a/Documentation/devicetree/bindings/net/ethernet-phy.yaml
+++ b/Documentation/devicetree/bindings/net/ethernet-phy.yaml
@@ -162,6 +162,17 @@ properties:
description:
Specifies a reference to a node representing a SFP cage.
+
+ rx-internal-delay-ps:
+ description: |
+ RGMII Receive PHY Clock Delay defined in pico seconds. This is used for
+ PHY's that have configurable RX internal delays.
+
+ tx-internal-delay-ps:
+ description: |
+ RGMII Transmit PHY Clock Delay defined in pico seconds. This is used for
+ PHY's that have configurable TX internal delays.
+
required:
- reg
--
2.26.2
^ permalink raw reply related
* [PATCH net-next v7 6/6] net: phy: DP83822: Add ability to advertise Fiber connection
From: Dan Murphy @ 2020-06-17 18:20 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem, robh
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200617182019.6790-1-dmurphy@ti.com>
The DP83822 can be configured to use the RGMII interface. There are
independent fixed 3.5ns clock shift (aka internal delay) for the TX and RX
paths. This allow either one to be set if the MII interface is RGMII and
the value is set in the firmware node.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
drivers/net/phy/dp83822.c | 108 +++++++++++++++++++++++++++++++++++---
1 file changed, 100 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
index 1dd19d0cb269..49574c3df9ca 100644
--- a/drivers/net/phy/dp83822.c
+++ b/drivers/net/phy/dp83822.c
@@ -26,7 +26,9 @@
#define MII_DP83822_PHYSCR 0x11
#define MII_DP83822_MISR1 0x12
#define MII_DP83822_MISR2 0x13
+#define MII_DP83822_RCSR 0x17
#define MII_DP83822_RESET_CTRL 0x1f
+#define MII_DP83822_GENCFG 0x465
#define DP83822_HW_RESET BIT(15)
#define DP83822_SW_RESET BIT(14)
@@ -77,6 +79,15 @@
#define DP83822_WOL_INDICATION_SEL BIT(8)
#define DP83822_WOL_CLR_INDICATION BIT(11)
+/* RSCR bits */
+#define DP83822_RX_CLK_SHIFT BIT(12)
+#define DP83822_TX_CLK_SHIFT BIT(11)
+
+struct dp83822_private {
+ int rx_int_delay;
+ int tx_int_delay;
+};
+
static int dp83822_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -255,7 +266,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
}
-static int dp83822_config_init(struct phy_device *phydev)
+static int dp8382x_disable_wol(struct phy_device *phydev)
{
int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
DP83822_WOL_SECURE_ON;
@@ -264,6 +275,32 @@ static int dp83822_config_init(struct phy_device *phydev)
MII_DP83822_WOL_CFG, value);
}
+static int dp83822_config_init(struct phy_device *phydev)
+{
+ struct dp83822_private *dp83822 = phydev->priv;
+ int rgmii_delay;
+ int err = 0;
+
+ if (phy_interface_is_rgmii(phydev)) {
+ if (dp83822->rx_int_delay)
+ rgmii_delay = DP83822_RX_CLK_SHIFT;
+
+ if (dp83822->tx_int_delay)
+ rgmii_delay |= DP83822_TX_CLK_SHIFT;
+
+ if (rgmii_delay)
+ err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
+ MII_DP83822_RCSR, rgmii_delay);
+ }
+
+ return dp8382x_disable_wol(phydev);
+}
+
+static int dp8382x_config_init(struct phy_device *phydev)
+{
+ return dp8382x_disable_wol(phydev);
+}
+
static int dp83822_phy_reset(struct phy_device *phydev)
{
int err;
@@ -272,7 +309,46 @@ static int dp83822_phy_reset(struct phy_device *phydev)
if (err < 0)
return err;
- dp83822_config_init(phydev);
+ return phydev->drv->config_init(phydev);
+}
+
+#ifdef CONFIG_OF_MDIO
+static int dp83822_of_init(struct phy_device *phydev)
+{
+ struct dp83822_private *dp83822 = phydev->priv;
+ struct device *dev = &phydev->mdio.dev;
+
+ dp83822->rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
+ true);
+ if (dp83822->rx_int_delay < 0)
+ dp83822->rx_int_delay = 0;
+
+ dp83822->tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
+ false);
+ if (dp83822->tx_int_delay < 0)
+ dp83822->tx_int_delay = 0;
+
+ return 0;
+}
+#else
+static int dp83822_of_init(struct phy_device *phydev)
+{
+ return 0;
+}
+#endif /* CONFIG_OF_MDIO */
+
+static int dp83822_probe(struct phy_device *phydev)
+{
+ struct dp83822_private *dp83822;
+
+ dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822),
+ GFP_KERNEL);
+ if (!dp83822)
+ return -ENOMEM;
+
+ phydev->priv = dp83822;
+
+ dp83822_of_init(phydev);
return 0;
}
@@ -308,6 +384,7 @@ static int dp83822_resume(struct phy_device *phydev)
PHY_ID_MATCH_MODEL(_id), \
.name = (_name), \
/* PHY_BASIC_FEATURES */ \
+ .probe = dp83822_probe, \
.soft_reset = dp83822_phy_reset, \
.config_init = dp83822_config_init, \
.get_wol = dp83822_get_wol, \
@@ -318,14 +395,29 @@ static int dp83822_resume(struct phy_device *phydev)
.resume = dp83822_resume, \
}
+#define DP8382X_PHY_DRIVER(_id, _name) \
+ { \
+ PHY_ID_MATCH_MODEL(_id), \
+ .name = (_name), \
+ /* PHY_BASIC_FEATURES */ \
+ .soft_reset = dp83822_phy_reset, \
+ .config_init = dp8382x_config_init, \
+ .get_wol = dp83822_get_wol, \
+ .set_wol = dp83822_set_wol, \
+ .ack_interrupt = dp83822_ack_interrupt, \
+ .config_intr = dp83822_config_intr, \
+ .suspend = dp83822_suspend, \
+ .resume = dp83822_resume, \
+ }
+
static struct phy_driver dp83822_driver[] = {
DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
- DP83822_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
- DP83822_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
- DP83822_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
- DP83822_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
- DP83822_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
- DP83822_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
+ DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
+ DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
+ DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
+ DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
+ DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
+ DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
};
module_phy_driver(dp83822_driver);
--
2.26.2
^ permalink raw reply related
* [PATCH net-next v7 5/6] dt-bindings: net: dp83822: Add TI dp83822 phy
From: Dan Murphy @ 2020-06-17 18:20 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem, robh
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200617182019.6790-1-dmurphy@ti.com>
Add a dt binding for the TI dp83822 ethernet phy device.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
.../devicetree/bindings/net/ti,dp83822.yaml | 51 +++++++++++++++++++
1 file changed, 51 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/ti,dp83822.yaml
diff --git a/Documentation/devicetree/bindings/net/ti,dp83822.yaml b/Documentation/devicetree/bindings/net/ti,dp83822.yaml
new file mode 100644
index 000000000000..09e0e5fd88e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ti,dp83822.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause)
+# Copyright (C) 2020 Texas Instruments Incorporated
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/net/ti,dp83822.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: TI DP83822 ethernet PHY
+
+allOf:
+ - $ref: "ethernet-phy.yaml#"
+
+maintainers:
+ - Dan Murphy <dmurphy@ti.com>
+
+description: |
+ The DP83822 is a low-power, single-port, 10/100 Mbps Ethernet PHY. It
+ provides all of the physical layer functions needed to transmit and receive
+ data over standard, twisted-pair cables or to connect to an external,
+ fiber-optic transceiver. Additionally, the DP83822 provides flexibility to
+ connect to a MAC through a standard MII, RMII, or RGMII interface
+
+ Specifications about the charger can be found at:
+ http://www.ti.com/lit/ds/symlink/dp83822i.pdf
+
+properties:
+ reg:
+ maxItems: 1
+
+ rx-internal-delay-ps:
+ description: Enables the RX fixed internal delay of 3.5ns.
+ default: 3500
+
+ tx-internal-delay-ps:
+ description: Enables the TX fixed internal delay of 3.5ns.
+ default: 3500
+
+required:
+ - reg
+
+examples:
+ - |
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ rx-internal-delay-ps = <3500>;
+ tx-internal-delay-ps = <3500>;
+ };
+ };
--
2.26.2
^ permalink raw reply related
* [PATCH net-next v7 4/6] net: dp83869: Add RGMII internal delay configuration
From: Dan Murphy @ 2020-06-17 18:20 UTC (permalink / raw)
To: andrew, f.fainelli, hkallweit1, davem, robh
Cc: netdev, linux-kernel, devicetree, Dan Murphy
In-Reply-To: <20200617182019.6790-1-dmurphy@ti.com>
Add RGMII internal delay configuration for Rx and Tx.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
drivers/net/phy/dp83869.c | 53 ++++++++++++++++++++++++++++++++++++---
1 file changed, 50 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/dp83869.c b/drivers/net/phy/dp83869.c
index 53ed3abc26c9..2c651bcc440d 100644
--- a/drivers/net/phy/dp83869.c
+++ b/drivers/net/phy/dp83869.c
@@ -64,6 +64,10 @@
#define DP83869_RGMII_TX_CLK_DELAY_EN BIT(1)
#define DP83869_RGMII_RX_CLK_DELAY_EN BIT(0)
+/* RGMIIDCTL */
+#define DP83869_RGMII_CLK_DELAY_SHIFT 4
+#define DP83869_CLK_DELAY_DEF 7
+
/* STRAP_STS1 bits */
#define DP83869_STRAP_OP_MODE_MASK GENMASK(2, 0)
#define DP83869_STRAP_STS1_RESERVED BIT(11)
@@ -78,9 +82,6 @@
#define DP83869_PHYCR_FIFO_DEPTH_MASK GENMASK(15, 12)
#define DP83869_PHYCR_RESERVED_MASK BIT(11)
-/* RGMIIDCTL bits */
-#define DP83869_RGMII_TX_CLK_DELAY_SHIFT 4
-
/* IO_MUX_CFG bits */
#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f
@@ -99,6 +100,10 @@
#define DP83869_OP_MODE_MII BIT(5)
#define DP83869_SGMII_RGMII_BRIDGE BIT(6)
+static const int dp83869_internal_delay[] = {250, 500, 750, 1000, 1250, 1500,
+ 1750, 2000, 2250, 2500, 2750, 3000,
+ 3250, 3500, 3750, 4000};
+
enum {
DP83869_PORT_MIRRORING_KEEP,
DP83869_PORT_MIRRORING_EN,
@@ -108,6 +113,8 @@ enum {
struct dp83869_private {
int tx_fifo_depth;
int rx_fifo_depth;
+ s32 rx_int_delay;
+ s32 tx_int_delay;
int io_impedance;
int port_mirroring;
bool rxctrl_strap_quirk;
@@ -182,6 +189,7 @@ static int dp83869_of_init(struct phy_device *phydev)
struct dp83869_private *dp83869 = phydev->priv;
struct device *dev = &phydev->mdio.dev;
struct device_node *of_node = dev->of_node;
+ int delay_size = ARRAY_SIZE(dp83869_internal_delay);
int ret;
if (!of_node)
@@ -235,6 +243,20 @@ static int dp83869_of_init(struct phy_device *phydev)
&dp83869->tx_fifo_depth))
dp83869->tx_fifo_depth = DP83869_PHYCR_FIFO_DEPTH_4_B_NIB;
+ dp83869->rx_int_delay = phy_get_internal_delay(phydev, dev,
+ &dp83869_internal_delay[0],
+ delay_size, true);
+ if (dp83869->rx_int_delay < 0)
+ dp83869->rx_int_delay =
+ dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+
+ dp83869->tx_int_delay = phy_get_internal_delay(phydev, dev,
+ &dp83869_internal_delay[0],
+ delay_size, false);
+ if (dp83869->tx_int_delay < 0)
+ dp83869->tx_int_delay =
+ dp83869_internal_delay[DP83869_CLK_DELAY_DEF];
+
return ret;
}
#else
@@ -397,6 +419,31 @@ static int dp83869_config_init(struct phy_device *phydev)
dp83869->clk_output_sel <<
DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT);
+ if (phy_interface_is_rgmii(phydev)) {
+ ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL,
+ dp83869->rx_int_delay |
+ dp83869->tx_int_delay << DP83869_RGMII_CLK_DELAY_SHIFT);
+ if (ret)
+ return ret;
+
+ val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL);
+ val &= ~(DP83869_RGMII_TX_CLK_DELAY_EN |
+ DP83869_RGMII_RX_CLK_DELAY_EN);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+ val |= (DP83869_RGMII_TX_CLK_DELAY_EN |
+ DP83869_RGMII_RX_CLK_DELAY_EN);
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ val |= DP83869_RGMII_TX_CLK_DELAY_EN;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ val |= DP83869_RGMII_RX_CLK_DELAY_EN;
+
+ ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL,
+ val);
+ }
+
return ret;
}
--
2.26.2
^ permalink raw reply related
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