Netdev List
 help / color / mirror / Atom feed
* [PATCH v4 00/12] PCI: Remove '*val = 0' from pcie_capability_read_*()
From: Saheed O. Bolarinwa @ 2020-07-31 11:02 UTC (permalink / raw)
  To: helgaas, Mike Marciniszyn, Dennis Dalessandro, Doug Ledford,
	Jason Gunthorpe, Arnd Bergmann, Greg Kroah-Hartman,
	David S. Miller, Kalle Valo, Jakub Kicinski, Rafael J. Wysocki,
	Len Brown, Russell Currey, Sam Bobroff, Oliver O'Halloran
  Cc: Saheed O. Bolarinwa, bjorn, skhan, linux-kernel-mentees,
	linux-pci, linux-kernel, linux-rdma, QCA ath9k Development,
	linux-wireless, netdev, linux-acpi, linuxppc-dev

v4 CHANGES:
- Drop uses of pcie_capability_read_*() return value. This related to
  [1] which is pointing towards making the accessors return void.
- Remove patches found to be unnecessary
- Reword some commit messages

v3 CHANGES:
- Split previous PATCH 6/13 into two : PATCH 6/14 and PATCH 7/14
- Fix commit message of PATCH 5/14
- Update Patch numbering and Commit messages
- Add 'Acked by Greg KH' to PATCH 2/14
- Add PATCH version

v2 CHANGES:
- Fix missing comma, causing the email cc error
- Fix typos and numbering errors in commit messages
- Add commit message to 13/13
- Add two more patches: PATCH 3/13 and PATCH 4/13

MERGING:
- Patch 6/12 depends on Patch 5/12. However Patch 5/12 has no dependency.
  Please, merge PATCH 6/12 only after Patch 5/12.
- Patch 12/12 depends on all preceding patches. Please merge Patch 12/12
  only after other patches in this series have been merged.
- All other patches have no dependencies besides those mentioned above and
  can be merge individually.

PATCH 5/12:
Set the default case in the switch-statement to set status
to "Power On".

PATCH 1/12 to 11/12:
Use the value read by pcie_capability_read_*() to determine success or
failure. This is done by checking if it is ~0, while maintaining the
functions' behaviour. This ensures that the changes in PATCH 12/12 does
not introduce any bug.

PATCH 12/12:
There are several reasons why a PCI capability read may fail whether the
device is present or not. If this happens, pcie_capability_read_*() will
return -EINVAL/PCIBIOS_BAD_REGISTER_NUMBER or PCIBIOS_DEVICE_NOT_FOUND
and *val is set to 0.

This behaviour if further ensured by this code inside
pcie_capability_read_*()

 ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val);
 /*
  * Reset *val to 0 if pci_read_config_dword() fails, it may
  * have been written as 0xFFFFFFFF if hardware error happens
  * during pci_read_config_dword().
  */
 if (ret)
	 *val = 0;
 return ret;

a) Since all pci_generic_config_read() does is read a register value,
it may return success after reading a ~0 which *may* have been fabricated
by the PCI host bridge due to a read timeout. Hence pci_read_config_*() 
will return success with a fabricated ~0 in *val, indicating a problem.
In this case, the assumed behaviour of  pcie_capability_read_*() will be
wrong. To avoid error slipping through, more checks are necessary.

b) pci_read_config_*() will return PCIBIOS_DEVICE_NOT_FOUND only if 
dev->error_state = pci_channel_io_perm_failure (i.e. 
pci_dev_is_disconnected()) or if pci_generic_config_read() can't find the
device. In both cases *val is initially set to ~0 but as shown in the code
above pcie_capability_read_*() resets it back to 0. Even with this effort,
drivers still have to perform validation checks more so if 0 is a valid
value.

Most drivers only consider the case (b) and in some cases, there is the 
expectation that on timeout *val has a fabricated value of ~0, which *may*
not always be true as explained in (a).

In any case, checks need to be done to validate the value read and maybe
confirm which error has occurred. It is better left to the drivers to do.

Check the return value of pcie_capability_read_dword() to ensure success
and avoid bug as a result of Patch 14/14.
Remove the reset of *val to 0 when pci_read_config_*() fails.

[1] https://lore.kernel.org/linux-pci/20200714234625.GA428442@bjorn-Precision-5520/


Saheed O. Bolarinwa (12):
  IB/hfi1: Check if pcie_capability_read_*() reads ~0
  misc: rtsx: Check if pcie_capability_read_*() reads ~0
  ath9k: Check if pcie_capability_read_*() reads ~0
  iwlegacy: Check if pcie_capability_read_*() reads ~0
  PCI: pciehp: Set "Power On" as the default get_power_status
  PCI: pciehp: Check if pcie_capability_read_*() reads ~0
  PCI/ACPI: Check if pcie_capability_read_*() reads ~0
  PCI: Check if pcie_capability_read_*() reads ~0
  PCI/PM: Check if pcie_capability_read_*() reads ~0
  PCI/AER: Check if pcie_capability_read_*() reads ~0
  PCI/ASPM: Check if pcie_capability_read_*() reads ~0
  PCI: Remove '*val = 0' from pcie_capability_read_*()

 drivers/infiniband/hw/hfi1/aspm.c            |  6 ++--
 drivers/misc/cardreader/rts5227.c            |  2 +-
 drivers/misc/cardreader/rts5249.c            |  2 +-
 drivers/misc/cardreader/rts5260.c            |  2 +-
 drivers/misc/cardreader/rts5261.c            |  2 +-
 drivers/net/wireless/ath/ath9k/pci.c         |  3 +-
 drivers/net/wireless/intel/iwlegacy/common.c |  2 +-
 drivers/pci/access.c                         | 14 --------
 drivers/pci/hotplug/pciehp_hpc.c             | 13 +++++---
 drivers/pci/pci-acpi.c                       |  4 +--
 drivers/pci/pci.c                            | 34 ++++++++++++++------
 drivers/pci/pcie/aer.c                       |  2 +-
 drivers/pci/pcie/aspm.c                      | 10 +++---
 drivers/pci/probe.c                          | 12 +++----
 14 files changed, 56 insertions(+), 52 deletions(-)

-- 
2.18.4


^ permalink raw reply

* Re: [Linux-kernel-mentees] [PATCH net] rds: Prevent kernel-infoleak in rds_notify_queue_get()
From: Greg Kroah-Hartman @ 2020-07-31 11:59 UTC (permalink / raw)
  To: Håkon Bugge
  Cc: Dan Carpenter, Leon Romanovsky, Peilin Ye, Santosh Shilimkar,
	David S. Miller, Jakub Kicinski, Arnd Bergmann,
	linux-kernel-mentees, netdev, OFED mailing list, rds-devel,
	linux-kernel
In-Reply-To: <81B40AF5-EBCA-4628-8CF6-687C12134552@oracle.com>

On Fri, Jul 31, 2020 at 01:14:09PM +0200, Håkon Bugge wrote:
> 
> 
> > On 31 Jul 2020, at 11:59, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> > 
> > On Fri, Jul 31, 2020 at 07:53:01AM +0300, Leon Romanovsky wrote:
> >> On Thu, Jul 30, 2020 at 03:20:26PM -0400, Peilin Ye wrote:
> >>> rds_notify_queue_get() is potentially copying uninitialized kernel stack
> >>> memory to userspace since the compiler may leave a 4-byte hole at the end
> >>> of `cmsg`.
> >>> 
> >>> In 2016 we tried to fix this issue by doing `= { 0 };` on `cmsg`, which
> >>> unfortunately does not always initialize that 4-byte hole. Fix it by using
> >>> memset() instead.
> >> 
> >> Of course, this is the difference between "{ 0 }" and "{}" initializations.
> >> 
> > 
> > No, there is no difference.  Even struct assignments like:
> > 
> > 	foo = *bar;
> > 
> > can leave struct holes uninitialized.  Depending on the compiler the
> > assignment can be implemented as a memset() or as a series of struct
> > member assignments.
> 
> What about:
> 
> struct rds_rdma_notify {
> 	__u64                      user_token;
> 	__s32                      status;
> } __attribute__((packed));

Why is this still a discussion at all?

Try it and see, run pahole and see if there are holes in this structure
(odds are no), you don't need us to say what is happening here...

thanks,

greg k-h

^ permalink raw reply

* Re: [RFC PATCH bpf-next 2/3] bpf: Add helper to do forwarding lookups in kernel FDB table
From: Maciej Fijalkowski @ 2020-07-31 11:52 UTC (permalink / raw)
  To: Yoshiki Komachi
  Cc: David S. Miller, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, Jakub Kicinski,
	Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko,
	KP Singh, Roopa Prabhu, Nikolay Aleksandrov, David Ahern, netdev,
	bridge, bpf
In-Reply-To: <1596170660-5582-3-git-send-email-komachi.yoshiki@gmail.com>

On Fri, Jul 31, 2020 at 01:44:19PM +0900, Yoshiki Komachi wrote:
> This patch adds a new bpf helper to access FDB in the kernel tables
> from XDP programs. The helper enables us to find the destination port
> of master bridge in XDP layer with high speed. If an entry in the
> tables is successfully found, egress device index will be returned.
> 
> In cases of failure, packets will be dropped or forwarded to upper
> networking stack in the kernel by XDP programs. Multicast and broadcast
> packets are currently not supported. Thus, these will need to be
> passed to upper layer on the basis of XDP_PASS action.
> 
> The API uses destination MAC and VLAN ID as keys, so XDP programs
> need to extract these from forwarded packets.
> 
> Signed-off-by: Yoshiki Komachi <komachi.yoshiki@gmail.com>
> ---
>  include/uapi/linux/bpf.h       | 28 +++++++++++++++++++++
>  net/core/filter.c              | 45 ++++++++++++++++++++++++++++++++++
>  scripts/bpf_helpers_doc.py     |  1 +
>  tools/include/uapi/linux/bpf.h | 28 +++++++++++++++++++++
>  4 files changed, 102 insertions(+)
> 

[...]

> diff --git a/net/core/filter.c b/net/core/filter.c
> index 654c346b7d91..68800d1b8cd5 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -45,6 +45,7 @@
>  #include <linux/filter.h>
>  #include <linux/ratelimit.h>
>  #include <linux/seccomp.h>
> +#include <linux/if_bridge.h>
>  #include <linux/if_vlan.h>
>  #include <linux/bpf.h>
>  #include <linux/btf.h>
> @@ -5084,6 +5085,46 @@ static const struct bpf_func_proto bpf_skb_fib_lookup_proto = {
>  	.arg4_type	= ARG_ANYTHING,
>  };
>  
> +#if IS_ENABLED(CONFIG_BRIDGE)
> +BPF_CALL_4(bpf_xdp_fdb_lookup, struct xdp_buff *, ctx,
> +	   struct bpf_fdb_lookup *, params, int, plen, u32, flags)
> +{
> +	struct net_device *src, *dst;
> +	struct net *net;
> +
> +	if (plen < sizeof(*params))
> +		return -EINVAL;
> +
> +	net = dev_net(ctx->rxq->dev);
> +
> +	if (is_multicast_ether_addr(params->addr) ||
> +	    is_broadcast_ether_addr(params->addr))
> +		return BPF_FDB_LKUP_RET_NOENT;

small nit: you could move that validation before dev_net() call.

> +
> +	src = dev_get_by_index_rcu(net, params->ifindex);
> +	if (unlikely(!src))
> +		return -ENODEV;
> +
> +	dst = br_fdb_find_port_xdp(src, params->addr, params->vlan_id);
> +	if (dst) {
> +		params->ifindex = dst->ifindex;
> +		return BPF_FDB_LKUP_RET_SUCCESS;
> +	}
> +
> +	return BPF_FDB_LKUP_RET_NOENT;
> +}

^ permalink raw reply

* Re: [PATCH v3 5/9] ethernet: ti: am65-cpts: Use generic helper function
From: Kurt Kanzenbach @ 2020-07-31 11:48 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Grygorii Strashko, Richard Cochran, Andrew Lunn, Vivien Didelot,
	Florian Fainelli, David S. Miller, Jakub Kicinski, Jiri Pirko,
	Ido Schimmel, Heiner Kallweit, Russell King, Ivan Khoronzhuk,
	Samuel Zou, Networking, Petr Machata
In-Reply-To: <CAK8P3a2G7YJqzwrLDnDDO3ZUtNvyBSyun=6NjY3M2KS0Wr1ubg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1004 bytes --]

On Thu Jul 30 2020, Arnd Bergmann wrote:
> On Thu, Jul 30, 2020 at 11:41 AM Kurt Kanzenbach <kurt@linutronix.de> wrote:
>> On Thu Jul 30 2020, Grygorii Strashko wrote:
>> > On 30/07/2020 11:00, Kurt Kanzenbach wrote:
>> >> +    msgtype = ptp_get_msgtype(hdr, ptp_class);
>> >> +    seqid   = be16_to_cpu(hdr->sequence_id);
>> >
>> > Is there any reason to not use "ntohs()"?
>>
>> This is just my personal preference, because I think it's more
>> readable. Internally ntohs() uses be16_to_cpu(). There's no technical
>> reason for it.
>
> I think for traditional reasons, code in net/* tends to use ntohs()
> while code in drivers/*  tends to use be16_to_cpu().
>
> In drivers/net/* the two are used roughly the same, though I guess
> one could make the argument that be16_to_cpu() would be
> more appropriate for data structures exchanged with hardware
> while ntohs() makes sense on data structures sent over the
> network.

I see, makes sense. I could simply keep it the way it was, or?

Thanks,
Kurt

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: [Linux-kernel-mentees] [PATCH net] rds: Prevent kernel-infoleak in rds_notify_queue_get()
From: Håkon Bugge @ 2020-07-31 11:14 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Leon Romanovsky, Peilin Ye, Santosh Shilimkar, David S. Miller,
	Jakub Kicinski, Arnd Bergmann, Greg Kroah-Hartman,
	linux-kernel-mentees, netdev, OFED mailing list, rds-devel,
	linux-kernel
In-Reply-To: <20200731095943.GI5493@kadam>



> On 31 Jul 2020, at 11:59, Dan Carpenter <dan.carpenter@oracle.com> wrote:
> 
> On Fri, Jul 31, 2020 at 07:53:01AM +0300, Leon Romanovsky wrote:
>> On Thu, Jul 30, 2020 at 03:20:26PM -0400, Peilin Ye wrote:
>>> rds_notify_queue_get() is potentially copying uninitialized kernel stack
>>> memory to userspace since the compiler may leave a 4-byte hole at the end
>>> of `cmsg`.
>>> 
>>> In 2016 we tried to fix this issue by doing `= { 0 };` on `cmsg`, which
>>> unfortunately does not always initialize that 4-byte hole. Fix it by using
>>> memset() instead.
>> 
>> Of course, this is the difference between "{ 0 }" and "{}" initializations.
>> 
> 
> No, there is no difference.  Even struct assignments like:
> 
> 	foo = *bar;
> 
> can leave struct holes uninitialized.  Depending on the compiler the
> assignment can be implemented as a memset() or as a series of struct
> member assignments.

What about:

struct rds_rdma_notify {
	__u64                      user_token;
	__s32                      status;
} __attribute__((packed));


Thxs, Håkon


> regards,
> dan carpenter
> 


^ permalink raw reply

* Re: [PATCH net-next] cxgb4: Add support to flash firmware config image
From: Ganji Aravind @ 2020-07-31 11:09 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, davem, vishal, rahul.lakkireddy
In-Reply-To: <20200730162335.6a6aa4cf@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Thursday, July 07/30/20, 2020 at 16:23:35 -0700, Jakub Kicinski wrote:
> On Thu, 30 Jul 2020 20:41:38 +0530 Ganji Aravind wrote:
> > Update set_flash to flash firmware configuration image
> > to flash region.
> 
> And the reason why you need to flash some .ini files separately is?

Hi Jakub,

The firmware config file contains information on how the firmware
should distribute the hardware resources among NIC and
Upper Layer Drivers(ULD), like iWARP, crypto, filtering, etc.

The firmware image comes with an in-built default config file that
distributes resources among the NIC and all the ULDs. However, in
some cases, where we don't want to run a particular ULD, or if we
want to redistribute the resources, then we'd modify the firmware
config file and then firmware will redistribute those resources
according to the new configuration. So, if firmware finds this
custom config file in flash, it reads this first. Otherwise, it'll
continue initializing the adapter with its own in-built default
config file.

Thanks
-Ganji Aravind.

^ permalink raw reply

* [PATCH net v2 5/5] fsl/fman: fix eth hash table allocation
From: Florinel Iordache @ 2020-07-31 10:49 UTC (permalink / raw)
  To: madalin.bucur, davem, kuba, netdev, Markus.Elfring
  Cc: linux-kernel, Florinel Iordache
In-Reply-To: <1596192562-7629-1-git-send-email-florinel.iordache@nxp.com>

Fix memory allocation for ethernet address hash table.
The code was wrongly allocating an array for eth hash table which
is incorrect because this is the main structure for eth hash table
(struct eth_hash_t) that contains inside a number of elements.

Fixes: 57ba4c9b56d8 ("fsl/fman: Add FMan MAC support")

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman_mac.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_mac.h b/drivers/net/ethernet/freescale/fman/fman_mac.h
index dd6d052..19f327e 100644
--- a/drivers/net/ethernet/freescale/fman/fman_mac.h
+++ b/drivers/net/ethernet/freescale/fman/fman_mac.h
@@ -252,7 +252,7 @@ static inline struct eth_hash_t *alloc_hash_table(u16 size)
 	struct eth_hash_t *hash;
 
 	/* Allocate address hash table */
-	hash = kmalloc_array(size, sizeof(struct eth_hash_t *), GFP_KERNEL);
+	hash = kmalloc(sizeof(*hash), GFP_KERNEL);
 	if (!hash)
 		return NULL;
 
-- 
1.9.1


^ permalink raw reply related

* [PATCH net v2 4/5] fsl/fman: check dereferencing null pointer
From: Florinel Iordache @ 2020-07-31 10:49 UTC (permalink / raw)
  To: madalin.bucur, davem, kuba, netdev, Markus.Elfring
  Cc: linux-kernel, Florinel Iordache
In-Reply-To: <1596192562-7629-1-git-send-email-florinel.iordache@nxp.com>

Add a safe check to avoid dereferencing null pointer

Fixes: 57ba4c9b56d8 ("fsl/fman: Add FMan MAC support")

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman_dtsec.c | 4 ++--
 drivers/net/ethernet/freescale/fman/fman_memac.c | 2 +-
 drivers/net/ethernet/freescale/fman/fman_tgec.c  | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
index 004c266..bce3c93 100644
--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
@@ -1200,7 +1200,7 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
 		list_for_each(pos,
 			      &dtsec->multicast_addr_hash->lsts[bucket]) {
 			hash_entry = ETH_HASH_ENTRY_OBJ(pos);
-			if (hash_entry->addr == addr) {
+			if (hash_entry && hash_entry->addr == addr) {
 				list_del_init(&hash_entry->node);
 				kfree(hash_entry);
 				break;
@@ -1213,7 +1213,7 @@ int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
 		list_for_each(pos,
 			      &dtsec->unicast_addr_hash->lsts[bucket]) {
 			hash_entry = ETH_HASH_ENTRY_OBJ(pos);
-			if (hash_entry->addr == addr) {
+			if (hash_entry && hash_entry->addr == addr) {
 				list_del_init(&hash_entry->node);
 				kfree(hash_entry);
 				break;
diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index bb02b37..645764a 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -981,7 +981,7 @@ int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
 
 	list_for_each(pos, &memac->multicast_addr_hash->lsts[hash]) {
 		hash_entry = ETH_HASH_ENTRY_OBJ(pos);
-		if (hash_entry->addr == addr) {
+		if (hash_entry && hash_entry->addr == addr) {
 			list_del_init(&hash_entry->node);
 			kfree(hash_entry);
 			break;
diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
index 8c7eb87..41946b1 100644
--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
+++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
@@ -626,7 +626,7 @@ int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
 
 	list_for_each(pos, &tgec->multicast_addr_hash->lsts[hash]) {
 		hash_entry = ETH_HASH_ENTRY_OBJ(pos);
-		if (hash_entry->addr == addr) {
+		if (hash_entry && hash_entry->addr == addr) {
 			list_del_init(&hash_entry->node);
 			kfree(hash_entry);
 			break;
-- 
1.9.1


^ permalink raw reply related

* [PATCH net v2 3/5] fsl/fman: fix unreachable code
From: Florinel Iordache @ 2020-07-31 10:49 UTC (permalink / raw)
  To: madalin.bucur, davem, kuba, netdev, Markus.Elfring
  Cc: linux-kernel, Florinel Iordache
In-Reply-To: <1596192562-7629-1-git-send-email-florinel.iordache@nxp.com>

The parameter 'priority' is incorrectly forced to zero which ultimately
induces logically dead code in the subsequent lines.

Fixes: 57ba4c9b56d8 ("fsl/fman: Add FMan MAC support")

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman_memac.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
index a5500ed..bb02b37 100644
--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
+++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
@@ -852,7 +852,6 @@ int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
 
 	tmp = ioread32be(&regs->command_config);
 	tmp &= ~CMD_CFG_PFC_MODE;
-	priority = 0;
 
 	iowrite32be(tmp, &regs->command_config);
 
-- 
1.9.1


^ permalink raw reply related

* [PATCH net v2 2/5] fsl/fman: fix dereference null return value
From: Florinel Iordache @ 2020-07-31 10:49 UTC (permalink / raw)
  To: madalin.bucur, davem, kuba, netdev, Markus.Elfring
  Cc: linux-kernel, Florinel Iordache
In-Reply-To: <1596192562-7629-1-git-send-email-florinel.iordache@nxp.com>

Check before using returned value to avoid dereferencing null pointer.

Fixes: 18a6c85fcc78 ("fsl/fman: Add FMan Port Support")

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman_port.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c
index 87b26f0..c27df15 100644
--- a/drivers/net/ethernet/freescale/fman/fman_port.c
+++ b/drivers/net/ethernet/freescale/fman/fman_port.c
@@ -1767,6 +1767,7 @@ static int fman_port_probe(struct platform_device *of_dev)
 	struct fman_port *port;
 	struct fman *fman;
 	struct device_node *fm_node, *port_node;
+	struct platform_device *fm_pdev;
 	struct resource res;
 	struct resource *dev_res;
 	u32 val;
@@ -1791,8 +1792,14 @@ static int fman_port_probe(struct platform_device *of_dev)
 		goto return_err;
 	}
 
-	fman = dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
+	fm_pdev = of_find_device_by_node(fm_node);
 	of_node_put(fm_node);
+	if (!fm_pdev) {
+		err = -EINVAL;
+		goto return_err;
+	}
+
+	fman = dev_get_drvdata(&fm_pdev->dev);
 	if (!fman) {
 		err = -EINVAL;
 		goto return_err;
-- 
1.9.1


^ permalink raw reply related

* [PATCH net v2 1/5] fsl/fman: use 32-bit unsigned integer
From: Florinel Iordache @ 2020-07-31 10:49 UTC (permalink / raw)
  To: madalin.bucur, davem, kuba, netdev, Markus.Elfring
  Cc: linux-kernel, Florinel Iordache
In-Reply-To: <1596192562-7629-1-git-send-email-florinel.iordache@nxp.com>

Potentially overflowing expression (ts_freq << 16 and intgr << 16)
declared as type u32 (32-bit unsigned) is evaluated using 32-bit
arithmetic and then used in a context that expects an expression of
type u64 (64-bit unsigned) which ultimately is used as 16-bit
unsigned by typecasting to u16. Fixed by using an unsigned 32-bit
integer since the value is truncated anyway in the end.

Fixes: 414fd46e7762 ("fsl/fman: Add FMan support")

Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
---
 drivers/net/ethernet/freescale/fman/fman.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
index f151d6e..ef67e85 100644
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -1398,8 +1398,7 @@ static void enable_time_stamp(struct fman *fman)
 {
 	struct fman_fpm_regs __iomem *fpm_rg = fman->fpm_regs;
 	u16 fm_clk_freq = fman->state->fm_clk_freq;
-	u32 tmp, intgr, ts_freq;
-	u64 frac;
+	u32 tmp, intgr, ts_freq, frac;
 
 	ts_freq = (u32)(1 << fman->state->count1_micro_bit);
 	/* configure timestamp so that bit 8 will count 1 microsecond
-- 
1.9.1


^ permalink raw reply related

* [PATCH net v2 0/5] DPAA FMan driver fixes
From: Florinel Iordache @ 2020-07-31 10:49 UTC (permalink / raw)
  To: madalin.bucur, davem, kuba, netdev, Markus.Elfring
  Cc: linux-kernel, Florinel Iordache

Here are several fixes for the DPAA FMan driver.

v2 changes:
* corrected patch 4 by removing the line added by mistake
* used longer fixes tags with the first 12 characters of the SHA-1 ID

Florinel Iordache (5):
  fsl/fman: use 32-bit unsigned integer
  fsl/fman: fix dereference null return value
  fsl/fman: fix unreachable code
  fsl/fman: check dereferencing null pointer
  fsl/fman: fix eth hash table allocation

 drivers/net/ethernet/freescale/fman/fman.c       | 3 +--
 drivers/net/ethernet/freescale/fman/fman_dtsec.c | 4 ++--
 drivers/net/ethernet/freescale/fman/fman_mac.h   | 2 +-
 drivers/net/ethernet/freescale/fman/fman_memac.c | 3 +--
 drivers/net/ethernet/freescale/fman/fman_port.c  | 9 ++++++++-
 drivers/net/ethernet/freescale/fman/fman_tgec.c  | 2 +-
 6 files changed, 14 insertions(+), 9 deletions(-)

-- 
1.9.1


^ permalink raw reply

* [PATCH] ethtool: Add QSFP-DD support
From: Adrian Pop @ 2020-07-31  8:47 UTC (permalink / raw)
  Cc: netdev, linville, davem, kuba, jiri, vadimp, popadrian1996, mlxsw,
	idosch, andrew

The Common Management Interface Specification (CMIS) for QSFP-DD shares
some similarities with other form factors such as QSFP or SFP, but due to
the fact that the module memory map is different, the current ethtool
version is not able to provide relevant information about an interface.

This patch adds QSFP-DD support to ethtool. The changes are similar to
the ones already existing in qsfp.c, but customized to use the memory
addresses and logic as defined in the specifications document.

Page 0x00 (lower and higher memory) are always implemented, so the ethtool
expects at least 256 bytes if the identifier matches the one for QSFP-DD.
For optical connected cables, additional pages are usually available (the
contain module defined  thresholds or lane diagnostic information). In
this case, ethtool expects to receive 768 bytes in the following format:

    +----------+----------+----------+----------+----------+----------+
    |   Page   |   Page   |   Page   |   Page   |   Page   |   Page   |
    |   0x00   |   0x00   |   0x01   |   0x02   |   0x10   |   0x11   |
    |  (lower) | (higher) | (higher) | (higher) | (higher) | (higher) |
    |   128B   |   128B   |   128B   |   128B   |   128B   |   128B   |
    +----------+----------+----------+----------+----------+----------

Several functions from qsfp.c could be reused, so an additional parameter
was added to each and the functions were moved to sff-common.c.

Signed-off-by: Adrian Pop <popadrian1996@gmail.com>
Tested-by: Ido Schimmel <idosch@mellanox.com>
---
 Makefile.am  |   7 +-
 qsfp-dd.c    | 561 +++++++++++++++++++++++++++++++++++++++++++++++++++
 qsfp-dd.h    | 236 ++++++++++++++++++++++
 qsfp.c       |  60 ++----
 qsfp.h       |   8 -
 sff-common.c |  52 +++++
 sff-common.h |  26 ++-
 7 files changed, 894 insertions(+), 56 deletions(-)
 create mode 100644 qsfp-dd.c
 create mode 100644 qsfp-dd.h

diff --git a/Makefile.am b/Makefile.am
index 2abb274..9fd8024 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,7 +17,8 @@ ethtool_SOURCES += \
 		  smsc911x.c at76c50x-usb.c sfc.c stmmac.c	\
 		  sff-common.c sff-common.h sfpid.c sfpdiag.c	\
 		  ixgbevf.c tse.c vmxnet3.c qsfp.c qsfp.h fjes.c lan78xx.c \
-		  igc.c
+		  igc.c \
+		  qsfp-dd.c qsfp-dd.h
 endif
 
 if ENABLE_BASH_COMPLETION
@@ -47,12 +48,12 @@ endif
 
 TESTS = test-cmdline
 check_PROGRAMS = test-cmdline
-test_cmdline_SOURCES = test-cmdline.c test-common.c $(ethtool_SOURCES) 
+test_cmdline_SOURCES = test-cmdline.c test-common.c $(ethtool_SOURCES)
 test_cmdline_CFLAGS = -DTEST_ETHTOOL
 if !ETHTOOL_ENABLE_NETLINK
 TESTS += test-features
 check_PROGRAMS += test-features
-test_features_SOURCES = test-features.c test-common.c $(ethtool_SOURCES) 
+test_features_SOURCES = test-features.c test-common.c $(ethtool_SOURCES)
 test_features_CFLAGS = -DTEST_ETHTOOL
 endif
 
diff --git a/qsfp-dd.c b/qsfp-dd.c
new file mode 100644
index 0000000..4d533f8
--- /dev/null
+++ b/qsfp-dd.c
@@ -0,0 +1,561 @@
+/**
+ * Description:
+ *
+ * This module adds QSFP-DD support to ethtool. The changes are similar to
+ * the ones already existing in qsfp.c, but customized to use the memory
+ * addresses and logic as defined in the specification's document.
+ *
+ * Page 0x00 (lower and higher memory) are always implemented, so the ethtool
+ * expects at least 256 bytes if the identifier matches the one for QSFP-DD.
+ * For optical connected cables, additional pages are usually available (they
+ * contain module defined thresholds or lane diagnostic information). In
+ * this case, ethtool expects to receive 768 bytes in the following format:
+ *
+ *     +----------+----------+----------+----------+----------+----------+
+ *     |   Page   |   Page   |   Page   |   Page   |   Page   |   Page   |
+ *     |   0x00   |   0x00   |   0x01   |   0x02   |   0x10   |   0x11   |
+ *     |  (lower) | (higher) | (higher) | (higher) | (higher) | (higher) |
+ *     |   128b   |   128b   |   128b   |   128b   |   128b   |   128b   |
+ *     +----------+----------+----------+----------+----------+----------+
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "internal.h"
+#include "sff-common.h"
+#include "qsfp-dd.h"
+
+static void qsfp_dd_show_identifier(const __u8 *id)
+{
+	sff8024_show_identifier(id, QSFP_DD_ID_OFFSET);
+}
+
+static void qsfp_dd_show_connector(const __u8 *id)
+{
+	sff8024_show_connector(id, QSFP_DD_CTOR_OFFSET);
+}
+
+static void qsfp_dd_show_oui(const __u8 *id)
+{
+	sff8024_show_oui(id, QSFP_DD_VENDOR_OUI_OFFSET);
+}
+
+/**
+ * Print the revision compliance. Relevant documents:
+ * [1] CMIS Rev. 3, pag. 45, section 1.7.2.1, Table 18
+ * [2] CMIS Rev. 4, pag. 81, section 8.2.1, Table 8-2
+ */
+static void qsfp_dd_show_rev_compliance(const __u8 *id)
+{
+	__u8 rev = id[QSFP_DD_REV_COMPLIANCE_OFFSET];
+	int major = (rev >> 4) & 0x0F;
+	int minor = rev & 0x0F;
+
+	printf("\t%-41s : Rev. %d.%d\n", "Revision compliance", major, minor);
+}
+
+/**
+ * Print information about the device's power consumption.
+ * Relevant documents:
+ * [1] CMIS Rev. 3, pag. 59, section 1.7.3.9, Table 30
+ * [2] CMIS Rev. 4, pag. 94, section 8.3.9, Table 8-18
+ * [3] QSFP-DD Hardware Rev 5.0, pag. 22, section 4.2.1
+ */
+static void qsfp_dd_show_power_info(const __u8 *id)
+{
+	float max_power = 0.0f;
+	__u8 base_power = 0;
+	__u8 power_class;
+
+	/* Get the power class (first 3 most significat bytes) */
+	power_class = (id[QSFP_DD_PWR_CLASS_OFFSET] >> 5) & 0x07;
+
+	/* Get the base power in multiples of 0.25W */
+	base_power = id[QSFP_DD_PWR_MAX_POWER_OFFSET];
+	max_power = base_power * 0.25f;
+
+	printf("\t%-41s : %d\n", "Power class", power_class + 1);
+	printf("\t%-41s : %.02fW\n", "Max power", max_power);
+}
+
+/**
+ * Print the cable assembly length, for both passive copper and active
+ * optical or electrical cables. The base length (bits 5-0) must be
+ * multiplied with the SMF length multiplier (bits 7-6) to obtain the
+ * correct value. Relevant documents:
+ * [1] CMIS Rev. 3, pag. 59, section 1.7.3.10, Table 31
+ * [2] CMIS Rev. 4, pag. 94, section 8.3.10, Table 8-19
+ */
+static void qsfp_dd_show_cbl_asm_len(const __u8 *id)
+{
+	static const char *fn = "Cable assembly length";
+	float mul = 1.0f;
+	float val = 0.0f;
+
+	/* Check if max length */
+	if (id[QSFP_DD_CBL_ASM_LEN_OFFSET] == QSFP_DD_6300M_MAX_LEN) {
+		printf("\t%-41s : > 6.3km\n", fn);
+		return;
+	}
+
+	/* Get the multiplier from the first two bits */
+	switch (id[QSFP_DD_CBL_ASM_LEN_OFFSET] & QSFP_DD_LEN_MUL_MASK) {
+	case QSFP_DD_MULTIPLIER_00:
+		mul = 0.1f;
+		break;
+	case QSFP_DD_MULTIPLIER_01:
+		mul = 1.0f;
+		break;
+	case QSFP_DD_MULTIPLIER_10:
+		mul = 10.0f;
+		break;
+	case QSFP_DD_MULTIPLIER_11:
+		mul = 100.0f;
+		break;
+	default:
+		break;
+	}
+
+	/* Get base value from first 6 bits and multiply by mul */
+	val = (id[QSFP_DD_CBL_ASM_LEN_OFFSET] & QSFP_DD_LEN_VAL_MASK);
+	val = (float)val * mul;
+	printf("\t%-41s : %0.2fkm\n", fn, val);
+}
+
+/**
+ * Print the length for SMF fiber. The base length (bits 5-0) must be
+ * multiplied with the SMF length multiplier (bits 7-6) to obtain the
+ * correct value. Relevant documents:
+ * [1] CMIS Rev. 3, pag. 63, section 1.7.4.2, Table 39
+ * [2] CMIS Rev. 4, pag. 99, section 8.4.2, Table 8-27
+ */
+static void qsfp_dd_print_smf_cbl_len(const __u8 *id)
+{
+	static const char *fn = "Length (SMF)";
+	float mul = 1.0f;
+	float val = 0.0f;
+
+	/* Get the multiplier from the first two bits */
+	switch (id[QSFP_DD_SMF_LEN_OFFSET] & QSFP_DD_LEN_MUL_MASK) {
+	case QSFP_DD_MULTIPLIER_00:
+		mul = 0.1f;
+		break;
+	case QSFP_DD_MULTIPLIER_01:
+		mul = 1.0f;
+		break;
+	default:
+		break;
+	}
+
+	/* Get base value from first 6 bits and multiply by mul */
+	val = (id[QSFP_DD_SMF_LEN_OFFSET] & QSFP_DD_LEN_VAL_MASK);
+	val = (float)val * mul;
+	printf("\t%-41s : %0.2fkm\n", fn, val);
+}
+
+/**
+ * Print relevant signal integrity control properties. Relevant documents:
+ * [1] CMIS Rev. 3, pag. 71, section 1.7.4.10, Table 46
+ * [2] CMIS Rev. 4, pag. 105, section 8.4.10, Table 8-34
+ */
+static void qsfp_dd_show_sig_integrity(const __u8 *id)
+{
+	/* CDR Bypass control: 2nd bit from each byte */
+	printf("\t%-41s : ", "Tx CDR bypass control");
+	printf("%s\n", YESNO(id[QSFP_DD_SIG_INTEG_TX_OFFSET] & 0x02));
+
+	printf("\t%-41s : ", "Rx CDR bypass control");
+	printf("%s\n", YESNO(id[QSFP_DD_SIG_INTEG_RX_OFFSET] & 0x02));
+
+	/* CDR Implementation: 1st bit from each byte */
+	printf("\t%-41s : ", "Tx CDR");
+	printf("%s\n", YESNO(id[QSFP_DD_SIG_INTEG_TX_OFFSET] & 0x01));
+
+	printf("\t%-41s : ", "Rx CDR");
+	printf("%s\n", YESNO(id[QSFP_DD_SIG_INTEG_RX_OFFSET] & 0x01));
+}
+
+/**
+ * Print relevant media interface technology info. Relevant documents:
+ * [1] CMIS Rev. 3
+ * --> pag. 61, section 1.7.3.14, Table 36
+ * --> pag. 64, section 1.7.4.3, 1.7.4.4
+ * [2] CMIS Rev. 4
+ * --> pag. 97, section 8.3.14, Table 8-24
+ * --> pag. 98, section 8.4, Table 8-25
+ * --> page 100, section 8.4.3, 8.4.4
+ */
+static void qsfp_dd_show_mit_compliance(const __u8 *id)
+{
+	static const char *cc = " (Copper cable,";
+
+	printf("\t%-41s : 0x%02x", "Transmitter technology",
+	       id[QSFP_DD_MEDIA_INTF_TECH_OFFSET]);
+
+	switch (id[QSFP_DD_MEDIA_INTF_TECH_OFFSET]) {
+	case QSFP_DD_850_VCSEL:
+		printf(" (850 nm VCSEL)\n");
+		break;
+	case QSFP_DD_1310_VCSEL:
+		printf(" (1310 nm VCSEL)\n");
+		break;
+	case QSFP_DD_1550_VCSEL:
+		printf(" (1550 nm VCSEL)\n");
+		break;
+	case QSFP_DD_1310_FP:
+		printf(" (1310 nm FP)\n");
+		break;
+	case QSFP_DD_1310_DFB:
+		printf(" (1310 nm DFB)\n");
+		break;
+	case QSFP_DD_1550_DFB:
+		printf(" (1550 nm DFB)\n");
+		break;
+	case QSFP_DD_1310_EML:
+		printf(" (1310 nm EML)\n");
+		break;
+	case QSFP_DD_1550_EML:
+		printf(" (1550 nm EML)\n");
+		break;
+	case QSFP_DD_OTHERS:
+		printf(" (Others/Undefined)\n");
+		break;
+	case QSFP_DD_1490_DFB:
+		printf(" (1490 nm DFB)\n");
+		break;
+	case QSFP_DD_COPPER_UNEQUAL:
+		printf("%s unequalized)\n", cc);
+		break;
+	case QSFP_DD_COPPER_PASS_EQUAL:
+		printf("%s passive equalized)\n", cc);
+		break;
+	case QSFP_DD_COPPER_NF_EQUAL:
+		printf("%s near and far end limiting active equalizers)\n", cc);
+		break;
+	case QSFP_DD_COPPER_F_EQUAL:
+		printf("%s far end limiting active equalizers)\n", cc);
+		break;
+	case QSFP_DD_COPPER_N_EQUAL:
+		printf("%s near end limiting active equalizers)\n", cc);
+		break;
+	case QSFP_DD_COPPER_LINEAR_EQUAL:
+		printf("%s linear active equalizers)\n", cc);
+		break;
+	}
+
+	if (id[QSFP_DD_MEDIA_INTF_TECH_OFFSET] >= QSFP_DD_COPPER_UNEQUAL) {
+		printf("\t%-41s : %udb\n", "Attenuation at 5GHz",
+		       id[QSFP_DD_COPPER_ATT_5GHZ]);
+		printf("\t%-41s : %udb\n", "Attenuation at 7GHz",
+		       id[QSFP_DD_COPPER_ATT_7GHZ]);
+		printf("\t%-41s : %udb\n", "Attenuation at 12.9GHz",
+		       id[QSFP_DD_COPPER_ATT_12P9GHZ]);
+		printf("\t%-41s : %udb\n", "Attenuation at 25.8GHz",
+		       id[QSFP_DD_COPPER_ATT_25P8GHZ]);
+	} else {
+		printf("\t%-41s : %.3lfnm\n", "Laser wavelength",
+		       (((id[QSFP_DD_NOM_WAVELENGTH_MSB] << 8) |
+				id[QSFP_DD_NOM_WAVELENGTH_LSB]) * 0.05));
+		printf("\t%-41s : %.3lfnm\n", "Laser wavelength tolerance",
+		       (((id[QSFP_DD_WAVELENGTH_TOL_MSB] << 8) |
+		       id[QSFP_DD_WAVELENGTH_TOL_LSB]) * 0.005));
+	}
+}
+
+/**
+ * Read the high/low alarms or warnings for a specific channel. This
+ * information is found in the i'th bit of each byte associated with
+ * one of the aforementioned properties. A value greater than zero
+ * means the alarm/warning is turned on.
+ * The values are stored in the qsfp_dd_diags structure, in the rxaw
+ * or txaw array (each element corresponds to an alarm/warning).
+ */
+static void qsfp_dd_read_aw_for_channel(const __u8 *id, int ch, int mode,
+					struct qsfp_dd_diags * const sd)
+{
+	__u8 cmsk = (1 << ch);
+
+	if (mode == QSFP_DD_READ_TX) {
+		sd->txaw[ch][HA] = id[QSFP_DD_TX_HA_OFFSET] & cmsk;
+		sd->txaw[ch][LA] = id[QSFP_DD_TX_LA_OFFSET] & cmsk;
+		sd->txaw[ch][HW] = id[QSFP_DD_TX_HW_OFFSET] & cmsk;
+		sd->txaw[ch][LW] = id[QSFP_DD_TX_LW_OFFSET] & cmsk;
+	} else {
+		sd->rxaw[ch][HA] = id[QSFP_DD_RX_HA_OFFSET] & cmsk;
+		sd->rxaw[ch][LA] = id[QSFP_DD_RX_LA_OFFSET] & cmsk;
+		sd->rxaw[ch][HW] = id[QSFP_DD_RX_HW_OFFSET] & cmsk;
+		sd->rxaw[ch][LW] = id[QSFP_DD_RX_LW_OFFSET] & cmsk;
+	}
+}
+
+/*
+ * 2-byte internal temperature conversions:
+ * First byte is a signed 8-bit integer, which is the temp decimal part
+ * Second byte is a multiple of 1/256th of a degree, which is added to
+ * the dec part.
+ */
+#define OFFSET_TO_TEMP(offset) ((__s16)OFFSET_TO_U16(offset))
+
+/**
+ * Get and parse relevant diagnostic information for the current module.
+ * These are stored for every channel in a qsfp_dd_diags structure.
+ */
+static void
+qsfp_dd_parse_diagnostics(const __u8 *id, struct qsfp_dd_diags *const sd)
+{
+	__u16 rx_power_offset;
+	__u16 tx_power_offset;
+	__u16 tx_bias_offset;
+	__u16 temp_offset;
+	__u16 volt_offset;
+	int i;
+
+	for (i = 0; i < QSFP_DD_MAX_CHANNELS; ++i) {
+		/*
+		 * Add Tx/Rx output/input optical power relevant information.
+		 * To access the info for the ith lane, we have to skip i * 2
+		 * bytes starting from the offset of the first lane for that
+		 * specific channel property.
+		 */
+		tx_bias_offset = QSFP_DD_TX_BIAS_START_OFFSET + (i << 1);
+		rx_power_offset = QSFP_DD_RX_PWR_START_OFFSET + (i << 1);
+		tx_power_offset = QSFP_DD_TX_PWR_START_OFFSET + (i << 1);
+
+		sd->scd[i].bias_cur = OFFSET_TO_U16(tx_bias_offset);
+		sd->scd[i].rx_power = OFFSET_TO_U16(rx_power_offset);
+		sd->scd[i].tx_power = OFFSET_TO_U16(tx_power_offset);
+
+		/* Add alarms/warnings related info */
+		qsfp_dd_read_aw_for_channel(id, i, QSFP_DD_READ_TX, sd);
+		qsfp_dd_read_aw_for_channel(id, i, QSFP_DD_READ_RX, sd);
+	}
+
+	/**
+	 * Gather Module-Level Monitor Thresholds and Lane-specific Monitor
+	 * Thresholds. These values are stored in two bytes (MSB, LSB) in
+	 * the following order: HA, LA, HW, LW, thus we only need the start
+	 * offset for each property.
+	 */
+	for (i = 0; i < 4; ++i) {
+		tx_power_offset = QSFP_DD_TXPW_THRS_START_OFFSET + (i << 1);
+		sd->tx_power[i] = OFFSET_TO_U16(tx_power_offset);
+
+		rx_power_offset = QSFP_DD_RXPW_THRS_START_OFFSET + (i << 1);
+		sd->rx_power[i] = OFFSET_TO_U16(rx_power_offset);
+
+		tx_bias_offset = QSFP_DD_TXBI_THRS_START_OFFSET + (i << 1);
+		sd->bias_cur[i] = OFFSET_TO_U16(tx_bias_offset);
+
+		temp_offset = QSFP_DD_TEMP_THRS_START_OFFSET + (i << 1);
+		sd->sfp_temp[i] = OFFSET_TO_TEMP(temp_offset);
+
+		volt_offset = QSFP_DD_VOLT_THRS_START_OFFSET + (i << 1);
+		sd->sfp_voltage[i] = OFFSET_TO_U16(volt_offset);
+	}
+}
+
+/**
+ * Print the Module-Level Monitor Thresholds and the Lane-specific
+ * Monitor Thresholds. This is the same function as the one in the
+ * sff-common.c file, but is using a struct qsfp_dd_diags as a pa-
+ * rameter.
+ */
+static void qsfp_dd_show_thresholds(const struct qsfp_dd_diags sd)
+{
+	PRINT_BIAS("Laser bias current high alarm threshold",
+		   sd.bias_cur[HA]);
+	PRINT_BIAS("Laser bias current low alarm threshold",
+		   sd.bias_cur[LA]);
+	PRINT_BIAS("Laser bias current high warning threshold",
+		   sd.bias_cur[HW]);
+	PRINT_BIAS("Laser bias current low warning threshold",
+		   sd.bias_cur[LW]);
+
+	PRINT_xX_PWR("Laser output power high alarm threshold",
+		     sd.tx_power[HA]);
+	PRINT_xX_PWR("Laser output power low alarm threshold",
+		     sd.tx_power[LA]);
+	PRINT_xX_PWR("Laser output power high warning threshold",
+		     sd.tx_power[HW]);
+	PRINT_xX_PWR("Laser output power low warning threshold",
+		     sd.tx_power[LW]);
+
+	PRINT_TEMP("Module temperature high alarm threshold",
+		   sd.sfp_temp[HA]);
+	PRINT_TEMP("Module temperature low alarm threshold",
+		   sd.sfp_temp[LA]);
+	PRINT_TEMP("Module temperature high warning threshold",
+		   sd.sfp_temp[HW]);
+	PRINT_TEMP("Module temperature low warning threshold",
+		   sd.sfp_temp[LW]);
+
+	PRINT_VCC("Module voltage high alarm threshold",
+		  sd.sfp_voltage[HA]);
+	PRINT_VCC("Module voltage low alarm threshold",
+		  sd.sfp_voltage[LA]);
+	PRINT_VCC("Module voltage high warning threshold",
+		  sd.sfp_voltage[HW]);
+	PRINT_VCC("Module voltage low warning threshold",
+		  sd.sfp_voltage[LW]);
+
+	PRINT_xX_PWR("Laser rx power high alarm threshold",
+		     sd.rx_power[HA]);
+	PRINT_xX_PWR("Laser rx power low alarm threshold",
+		     sd.rx_power[LA]);
+	PRINT_xX_PWR("Laser rx power high warning threshold",
+		     sd.rx_power[HW]);
+	PRINT_xX_PWR("Laser rx power low warning threshold",
+		     sd.rx_power[LW]);
+}
+
+/**
+ * Print relevant lane specific monitor information for each of
+ * the 8 available channels. Relevant documents:
+ * [1] CMIS Rev. 3:
+ * --> pag. 50, section 1.7.2.4, Table 22
+ * --> pag. 53, section 1.7.2.7, Table 26
+ * --> pag. 76, section 1.7.5.1, Table 50
+ * --> pag. 78, section 1.7.5.2, Table 51
+ * --> pag. 98, section 1.7.7.2, Table 67
+ *
+ * [2] CMIS Rev. 4:
+ * --> pag. 84, section 8.2.4, Table 8-6
+ * --> pag. 89, section 8.2.9, Table 8-12
+ * --> pag. 112, section 8.5.1/2, Table 8-41/42
+ * --> pag. 137, section 8.8.2, Table 8-60/61
+ * --> pag. 140, section 8.8.3, Table 8-62
+ */
+static void qsfp_dd_show_sig_optical_pwr(const __u8 *id, __u32 eeprom_len)
+{
+	static const char * const aw_strings[] = {
+		"%s power high alarm   (Channel %d)",
+		"%s power low alarm    (Channel %d)",
+		"%s power high warning (Channel %d)",
+		"%s power low warning  (Channel %d)"
+	};
+	__u8 module_type = id[QSFP_DD_MODULE_TYPE_OFFSET];
+	char field_desc[QSFP_DD_MAX_DESC_SIZE];
+	struct qsfp_dd_diags sd = { { 0 } };
+	const char *cs = "%s (Channel %d)";
+	int i, j;
+
+	/* Print current temperature & voltage */
+	PRINT_TEMP("Module temperature",
+		   OFFSET_TO_TEMP(QSFP_DD_CURR_TEMP_OFFSET));
+	PRINT_VCC("Module voltage",
+		  OFFSET_TO_U16(QSFP_DD_CURR_CURR_OFFSET));
+
+	/**
+	 * The thresholds and the high/low alarms/warnings are available
+	 * only if an optical interface (MMF/SMF) is present (if this is
+	 * the case, it means that 5 pages are available).
+	 */
+	if (module_type != QSFP_DD_MT_MMF &&
+	    module_type != QSFP_DD_MT_SMF &&
+	    eeprom_len != QSFP_DD_EEPROM_5PAG)
+		return;
+
+	/* Extract the diagnostic variables */
+	qsfp_dd_parse_diagnostics(id, &sd);
+
+	/* Print Tx bias current monitor values */
+	for (i = 0; i < QSFP_DD_MAX_CHANNELS; ++i) {
+		snprintf(field_desc, QSFP_DD_MAX_DESC_SIZE, cs,
+			 "Tx bias current monitor", i + 1);
+		PRINT_BIAS(field_desc, sd.scd[i].bias_cur);
+	}
+
+	/* Print Tx output optical power values */
+	for (i = 0; i < QSFP_DD_MAX_CHANNELS; ++i) {
+		snprintf(field_desc, QSFP_DD_MAX_DESC_SIZE, cs,
+			 "Tx output optical power", i + 1);
+		PRINT_xX_PWR(field_desc, sd.scd[i].tx_power);
+	}
+
+	/* Print Rx output optical power values */
+	for (i = 0; i < QSFP_DD_MAX_CHANNELS; ++i) {
+		snprintf(field_desc, QSFP_DD_MAX_DESC_SIZE, cs,
+			 "Rx input optical power", i + 1);
+		PRINT_xX_PWR(field_desc, sd.scd[i].rx_power);
+	}
+
+	/* Print the Rx alarms/warnings for each channel */
+	for (i = 0; i < QSFP_DD_MAX_CHANNELS; ++i) {
+		for (j = 0; j < 4; ++j) {
+			snprintf(field_desc, QSFP_DD_MAX_DESC_SIZE,
+				 aw_strings[j], "Rx", i + 1);
+			printf("\t%-41s : %s\n", field_desc,
+			       ONOFF(sd.rxaw[i][j]));
+		}
+	}
+
+	/* Print the Tx alarms/warnings for each channel */
+	for (i = 0; i < QSFP_DD_MAX_CHANNELS; ++i) {
+		for (j = 0; j < 4; ++j) {
+			snprintf(field_desc, QSFP_DD_MAX_DESC_SIZE,
+				 aw_strings[j], "Tx", i + 1);
+			printf("\t%-41s : %s\n", field_desc,
+			       ONOFF(sd.rxaw[i][j]));
+		}
+	}
+
+	qsfp_dd_show_thresholds(sd);
+}
+
+/**
+ * Print relevant info about the maximum supported fiber media length
+ * for each type of fiber media at the maximum module-supported bit rate.
+ * Relevant documents:
+ * [1] CMIS Rev. 3, page 64, section 1.7.4.2, Table 39
+ * [2] CMIS Rev. 4, page 99, section 8.4.2, Table 8-27
+ */
+static void qsfp_dd_show_link_len(const __u8 *id)
+{
+	qsfp_dd_print_smf_cbl_len(id);
+	sff_show_value_with_unit(id, QSFP_DD_OM5_LEN_OFFSET,
+				 "Length (OM5)", 2, "m");
+	sff_show_value_with_unit(id, QSFP_DD_OM4_LEN_OFFSET,
+				 "Length (OM4)", 2, "m");
+	sff_show_value_with_unit(id, QSFP_DD_OM3_LEN_OFFSET,
+				 "Length (OM3 50/125um)", 2, "m");
+	sff_show_value_with_unit(id, QSFP_DD_OM2_LEN_OFFSET,
+				 "Length (OM2 50/125um)", 1, "m");
+}
+
+/**
+ * Show relevant information about the vendor. Relevant documents:
+ * [1] CMIS Rev. 3, page 56, section 1.7.3, Table 27
+ * [2] CMIS Rev. 4, page 91, section 8.2, Table 8-15
+ */
+static void qsfp_dd_show_vendor_info(const __u8 *id)
+{
+	sff_show_ascii(id, QSFP_DD_VENDOR_NAME_START_OFFSET,
+		       QSFP_DD_VENDOR_NAME_END_OFFSET, "Vendor name");
+	qsfp_dd_show_oui(id);
+	sff_show_ascii(id, QSFP_DD_VENDOR_PN_START_OFFSET,
+		       QSFP_DD_VENDOR_PN_END_OFFSET, "Vendor PN");
+	sff_show_ascii(id, QSFP_DD_VENDOR_REV_START_OFFSET,
+		       QSFP_DD_VENDOR_REV_END_OFFSET, "Vendor rev");
+	sff_show_ascii(id, QSFP_DD_VENDOR_SN_START_OFFSET,
+		       QSFP_DD_VENDOR_SN_END_OFFSET, "Vendor SN");
+	sff_show_ascii(id, QSFP_DD_DATE_YEAR_OFFSET,
+		       QSFP_DD_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
+
+	if (id[QSFP_DD_CLEI_PRESENT_BYTE] & QSFP_DD_CLEI_PRESENT_MASK)
+		sff_show_ascii(id, QSFP_DD_CLEI_START_OFFSET,
+			       QSFP_DD_CLEI_END_OFFSET, "CLEI code");
+}
+
+void qsfp_dd_show_all(const __u8 *id, __u32 eeprom_len)
+{
+	qsfp_dd_show_identifier(id);
+	qsfp_dd_show_power_info(id);
+	qsfp_dd_show_connector(id);
+	qsfp_dd_show_cbl_asm_len(id);
+	qsfp_dd_show_sig_integrity(id);
+	qsfp_dd_show_mit_compliance(id);
+	qsfp_dd_show_sig_optical_pwr(id, eeprom_len);
+	qsfp_dd_show_link_len(id);
+	qsfp_dd_show_vendor_info(id);
+	qsfp_dd_show_rev_compliance(id);
+}
diff --git a/qsfp-dd.h b/qsfp-dd.h
new file mode 100644
index 0000000..a7a7051
--- /dev/null
+++ b/qsfp-dd.h
@@ -0,0 +1,236 @@
+#ifndef QSFP_DD_H__
+#define QSFP_DD_H__
+
+#define QSFP_DD_PAG_SIZE			0x80
+#define QSFP_DD_EEPROM_5PAG			(0x80 * 6)
+#define QSFP_DD_MAX_CHANNELS			0x08
+#define QSFP_DD_MAX_DESC_SIZE			0x2A
+#define QSFP_DD_READ_TX				0x00
+#define QSFP_DD_READ_RX				0x01
+
+/* Struct for the current/power of a channel */
+struct qsfp_dd_channel_diags {
+	__u16 bias_cur;
+	__u16 rx_power;
+	__u16 tx_power;
+};
+
+struct qsfp_dd_diags {
+	/* Voltage in 0.1mV units; the first 4 elements represent
+	 * the high/low alarm, high/low warning and the last one
+	 * represent the current voltage of the module.
+	 */
+	__u16 sfp_voltage[4];
+
+	/**
+	 * Temperature in 16-bit signed 1/256 Celsius; the first 4
+	 * elements represent the high/low alarm, high/low warning
+	 * and the last one represent the current temp of the module.
+	 */
+	__s16 sfp_temp[4];
+
+	/* Tx bias current in 2uA units */
+	__u16 bias_cur[4];
+
+	/* Measured TX Power */
+	__u16 tx_power[4];
+
+	/* Measured RX Power */
+	__u16 rx_power[4];
+
+	/* Rx alarms and warnings */
+	bool rxaw[QSFP_DD_MAX_CHANNELS][4];
+
+	/* Tx alarms and warnings */
+	bool txaw[QSFP_DD_MAX_CHANNELS][4];
+
+	struct qsfp_dd_channel_diags scd[QSFP_DD_MAX_CHANNELS];
+};
+
+#define HA					0
+#define LA					1
+#define HW					2
+#define LW					3
+
+/* Identifier and revision compliance (Page 0) */
+#define	QSFP_DD_ID_OFFSET			0x00
+#define QSFP_DD_REV_COMPLIANCE_OFFSET		0x01
+
+#define QSFP_DD_MODULE_TYPE_OFFSET		0x55
+#define QSFP_DD_MT_MMF				0x01
+#define QSFP_DD_MT_SMF				0x02
+
+/* Module-Level Monitors (Page 0) */
+#define QSFP_DD_CURR_TEMP_OFFSET		0x0E
+#define QSFP_DD_CURR_CURR_OFFSET		0x10
+
+#define QSFP_DD_CTOR_OFFSET			0xCB
+
+/* Vendor related information (Page 0) */
+#define QSFP_DD_VENDOR_NAME_START_OFFSET	0x81
+#define QSFP_DD_VENDOR_NAME_END_OFFSET		0x90
+
+#define QSFP_DD_VENDOR_OUI_OFFSET		0x91
+
+#define QSFP_DD_VENDOR_PN_START_OFFSET		0x94
+#define QSFP_DD_VENDOR_PN_END_OFFSET		0xA3
+
+#define QSFP_DD_VENDOR_REV_START_OFFSET		0xA4
+#define QSFP_DD_VENDOR_REV_END_OFFSET		0xA5
+
+#define QSFP_DD_VENDOR_SN_START_OFFSET		0xA6
+#define QSFP_DD_VENDOR_SN_END_OFFSET		0xB5
+
+#define QSFP_DD_DATE_YEAR_OFFSET		0xB6
+#define QSFP_DD_DATE_VENDOR_LOT_OFFSET		0xBD
+
+/* CLEI Code (Page 0) */
+#define QSFP_DD_CLEI_PRESENT_BYTE		0x02
+#define QSFP_DD_CLEI_PRESENT_MASK		0x20
+#define QSFP_DD_CLEI_START_OFFSET		0xBE
+#define QSFP_DD_CLEI_END_OFFSET			0xC7
+
+/* Cable assembly length */
+#define QSFP_DD_CBL_ASM_LEN_OFFSET		0xCA
+#define QSFP_DD_6300M_MAX_LEN			0xFF
+
+/* Cable length with multiplier */
+#define QSFP_DD_MULTIPLIER_00			0x00
+#define QSFP_DD_MULTIPLIER_01			0x40
+#define QSFP_DD_MULTIPLIER_10			0x80
+#define QSFP_DD_MULTIPLIER_11			0xC0
+#define QSFP_DD_LEN_MUL_MASK			0xC0
+#define QSFP_DD_LEN_VAL_MASK			0x3F
+
+/* Module power characteristics */
+#define QSFP_DD_PWR_CLASS_OFFSET		0xC8
+#define QSFP_DD_PWR_MAX_POWER_OFFSET		0xC9
+#define QSFP_DD_PWR_CLASS_MASK			0xE0
+#define QSFP_DD_PWR_CLASS_1			0x00
+#define QSFP_DD_PWR_CLASS_2			0x01
+#define QSFP_DD_PWR_CLASS_3			0x02
+#define QSFP_DD_PWR_CLASS_4			0x03
+#define QSFP_DD_PWR_CLASS_5			0x04
+#define QSFP_DD_PWR_CLASS_6			0x05
+#define QSFP_DD_PWR_CLASS_7			0x06
+#define QSFP_DD_PWR_CLASS_8			0x07
+
+/* Copper cable attenuation */
+#define QSFP_DD_COPPER_ATT_5GHZ			0xCC
+#define QSFP_DD_COPPER_ATT_7GHZ			0xCD
+#define QSFP_DD_COPPER_ATT_12P9GHZ		0xCE
+#define QSFP_DD_COPPER_ATT_25P8GHZ		0xCF
+
+/* Cable assembly lane */
+#define QSFP_DD_CABLE_ASM_NEAR_END_OFFSET	0xD2
+#define QSFP_DD_CABLE_ASM_FAR_END_OFFSET	0xD3
+
+/* Media interface technology */
+#define QSFP_DD_MEDIA_INTF_TECH_OFFSET		0xD4
+#define QSFP_DD_850_VCSEL			0x00
+#define QSFP_DD_1310_VCSEL			0x01
+#define QSFP_DD_1550_VCSEL			0x02
+#define QSFP_DD_1310_FP				0x03
+#define QSFP_DD_1310_DFB			0x04
+#define QSFP_DD_1550_DFB			0x05
+#define QSFP_DD_1310_EML			0x06
+#define QSFP_DD_1550_EML			0x07
+#define QSFP_DD_OTHERS				0x08
+#define QSFP_DD_1490_DFB			0x09
+#define QSFP_DD_COPPER_UNEQUAL			0x0A
+#define QSFP_DD_COPPER_PASS_EQUAL		0x0B
+#define QSFP_DD_COPPER_NF_EQUAL			0x0C
+#define QSFP_DD_COPPER_F_EQUAL			0x0D
+#define QSFP_DD_COPPER_N_EQUAL			0x0E
+#define QSFP_DD_COPPER_LINEAR_EQUAL		0x0F
+
+/*-----------------------------------------------------------------------
+ * For optical connected cables (the eeprom length is equal to  640 bytes
+ * = QSFP_DD_EEPROM_WITH_OPTICAL), the memory has the following format:
+ * Bytes   0-127: page  0 (lower)
+ * Bytes 128-255: page  0 (higher)
+ * Bytes 256-383: page  1 (higher)
+ * Bytes 384-511: page  2 (higher)
+ * Bytes 512-639: page 16 (higher)
+ * Bytes 640-768: page 17 (higher)
+ *
+ * Since for pages with an index > 0 the lower part is missing from the memory,
+ * but the offset values are still in the [128, 255) range, the real offset in
+ * the eeprom memory must be calculated as following:
+ * RealOffset = PageIndex * 0x80 + LocalOffset
+
+ * The page index is the index of the page, starting from 0: page 0 has index
+ * 1, page 1 has index 1, page 2 has index 2, page 16 has index 3 and page 17
+ * has index 4.
+ */
+
+/*-----------------------------------------------------------------------
+ * Upper Memory Page 0x01: contains advertising fields that define properties
+ * that are unique to active modules and cable assemblies.
+ * RealOffset = 1 * 0x80 + LocalOffset
+ */
+#define PAG01H_OFFSET				(0x01 * 0x80)
+
+/* Supported Link Length (Page 1) */
+#define QSFP_DD_SMF_LEN_OFFSET			(PAG01H_OFFSET + 0x84)
+#define QSFP_DD_OM5_LEN_OFFSET			(PAG01H_OFFSET + 0x85)
+#define QSFP_DD_OM4_LEN_OFFSET			(PAG01H_OFFSET + 0x86)
+#define QSFP_DD_OM3_LEN_OFFSET			(PAG01H_OFFSET + 0x87)
+#define QSFP_DD_OM2_LEN_OFFSET			(PAG01H_OFFSET + 0x88)
+
+/* Wavelength (Page 1) */
+#define QSFP_DD_NOM_WAVELENGTH_MSB		(PAG01H_OFFSET + 0x8A)
+#define QSFP_DD_NOM_WAVELENGTH_LSB		(PAG01H_OFFSET + 0x8B)
+#define QSFP_DD_WAVELENGTH_TOL_MSB		(PAG01H_OFFSET + 0x8C)
+#define QSFP_DD_WAVELENGTH_TOL_LSB		(PAG01H_OFFSET + 0x8D)
+
+/* Signal integrity controls */
+#define QSFP_DD_SIG_INTEG_TX_OFFSET		(PAG01H_OFFSET + 0xA1)
+#define QSFP_DD_SIG_INTEG_RX_OFFSET		(PAG01H_OFFSET + 0xA2)
+
+/*-----------------------------------------------------------------------
+ * Upper Memory Page 0x02: contains module defined threshdolds and lane-
+ * specific monitors.
+ * RealOffset = 2 * 0x80 + LocalOffset
+ */
+#define PAG02H_OFFSET				(0x02 * 0x80)
+#define QSFP_DD_TEMP_THRS_START_OFFSET		(PAG02H_OFFSET + 0x80)
+#define QSFP_DD_VOLT_THRS_START_OFFSET		(PAG02H_OFFSET + 0x88)
+#define QSFP_DD_TXPW_THRS_START_OFFSET		(PAG02H_OFFSET + 0xB0)
+#define QSFP_DD_TXBI_THRS_START_OFFSET		(PAG02H_OFFSET + 0xB8)
+#define QSFP_DD_RXPW_THRS_START_OFFSET		(PAG02H_OFFSET + 0xC0)
+
+/*-----------------------------------------------------------------------
+ * Upper Memory Page 0x10: contains dynamic control bytes.
+ * RealOffset = 3 * 0x80 + LocalOffset
+ */
+#define PAG10H_OFFSET				(0x03 * 0x80)
+
+/*-----------------------------------------------------------------------
+ * Upper Memory Page 0x11: contains lane dynamic status bytes.
+ * RealOffset = 4 * 0x80 + LocalOffset
+ */
+#define PAG11H_OFFSET				(0x04 * 0x80)
+#define QSFP_DD_TX_PWR_START_OFFSET		(PAG11H_OFFSET + 0x9A)
+#define QSFP_DD_TX_BIAS_START_OFFSET		(PAG11H_OFFSET + 0xAA)
+#define QSFP_DD_RX_PWR_START_OFFSET		(PAG11H_OFFSET + 0xBA)
+
+/* HA = High Alarm; LA = Low Alarm
+ * HW = High Warning; LW = Low Warning
+ */
+#define QSFP_DD_TX_HA_OFFSET			(PAG11H_OFFSET + 0x8B)
+#define QSFP_DD_TX_LA_OFFSET			(PAG11H_OFFSET + 0x8C)
+#define QSFP_DD_TX_HW_OFFSET			(PAG11H_OFFSET + 0x8D)
+#define QSFP_DD_TX_LW_OFFSET			(PAG11H_OFFSET + 0x8E)
+
+#define QSFP_DD_RX_HA_OFFSET			(PAG11H_OFFSET + 0x95)
+#define QSFP_DD_RX_LA_OFFSET			(PAG11H_OFFSET + 0x96)
+#define QSFP_DD_RX_HW_OFFSET			(PAG11H_OFFSET + 0x97)
+#define QSFP_DD_RX_LW_OFFSET			(PAG11H_OFFSET + 0x98)
+
+#define YESNO(x) (((x) != 0) ? "Yes" : "No")
+#define ONOFF(x) (((x) != 0) ? "On" : "Off")
+
+void qsfp_dd_show_all(const __u8 *id, __u32 eeprom_len);
+
+#endif /* QSFP_DD_H__ */
diff --git a/qsfp.c b/qsfp.c
index a8b69c9..2f740bb 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -58,6 +58,7 @@
 #include "internal.h"
 #include "sff-common.h"
 #include "qsfp.h"
+#include "qsfp-dd.h"
 
 #define MAX_DESC_SIZE	42
 
@@ -579,9 +580,9 @@ static void sff8636_show_rate_identifier(const __u8 *id)
 			id[SFF8636_EXT_RS_OFFSET]);
 }
 
-static void sff8636_show_oui(const __u8 *id)
+static void sff8636_show_oui(const __u8 *id, int id_offset)
 {
-	sff8024_show_oui(id, SFF8636_VENDOR_OUI_OFFSET);
+	sff8024_show_oui(id, id_offset);
 }
 
 static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
@@ -662,38 +663,7 @@ static void sff8636_show_wavelength_or_copper_compliance(const __u8 *id)
 
 static void sff8636_show_revision_compliance(const __u8 *id)
 {
-	static const char *pfx =
-		"\tRevision Compliance                       :";
-
-	switch (id[SFF8636_REV_COMPLIANCE_OFFSET]) {
-	case SFF8636_REV_UNSPECIFIED:
-		printf("%s Revision not specified\n", pfx);
-		break;
-	case SFF8636_REV_8436_48:
-		printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx);
-		break;
-	case SFF8636_REV_8436_8636:
-		printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx);
-		break;
-	case SFF8636_REV_8636_13:
-		printf("%s SFF-8636 Rev 1.3 or earlier\n", pfx);
-		break;
-	case SFF8636_REV_8636_14:
-		printf("%s SFF-8636 Rev 1.4\n", pfx);
-		break;
-	case SFF8636_REV_8636_15:
-		printf("%s SFF-8636 Rev 1.5\n", pfx);
-		break;
-	case SFF8636_REV_8636_20:
-		printf("%s SFF-8636 Rev 2.0\n", pfx);
-		break;
-	case SFF8636_REV_8636_27:
-		printf("%s SFF-8636 Rev 2.5/2.6/2.7\n", pfx);
-		break;
-	default:
-		printf("%s Unallocated\n", pfx);
-		break;
-	}
+	sff_show_revision_compliance(id, SFF8636_REV_COMPLIANCE_OFFSET);
 }
 
 /*
@@ -846,10 +816,15 @@ static void sff8636_show_dom(const __u8 *id, __u32 eeprom_len)
 
 		sff_show_thresholds(sd);
 	}
-
 }
+
 void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
 {
+	if (id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_DD) {
+		qsfp_dd_show_all(id, eeprom_len);
+		return;
+	}
+
 	sff8636_show_identifier(id);
 	if ((id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP) ||
 		(id[SFF8636_ID_OFFSET] == SFF8024_ID_QSFP_PLUS) ||
@@ -858,6 +833,7 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
 		sff8636_show_connector(id);
 		sff8636_show_transceiver(id);
 		sff8636_show_encoding(id);
+
 		sff_show_value_with_unit(id, SFF8636_BR_NOMINAL_OFFSET,
 				"BR, Nominal", 100, "Mbps");
 		sff8636_show_rate_identifier(id);
@@ -872,17 +848,19 @@ void sff8636_show_all(const __u8 *id, __u32 eeprom_len)
 		sff_show_value_with_unit(id, SFF8636_CBL_LEN_OFFSET,
 			     "Length (Copper or Active cable)", 1, "m");
 		sff8636_show_wavelength_or_copper_compliance(id);
+
 		sff_show_ascii(id, SFF8636_VENDOR_NAME_START_OFFSET,
-			       SFF8636_VENDOR_NAME_END_OFFSET, "Vendor name");
-		sff8636_show_oui(id);
+				SFF8636_VENDOR_NAME_END_OFFSET, "Vendor name");
+		sff8636_show_oui(id, SFF8636_VENDOR_OUI_OFFSET);
 		sff_show_ascii(id, SFF8636_VENDOR_PN_START_OFFSET,
-			       SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN");
+				SFF8636_VENDOR_PN_END_OFFSET, "Vendor PN");
 		sff_show_ascii(id, SFF8636_VENDOR_REV_START_OFFSET,
-			       SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev");
+				SFF8636_VENDOR_REV_END_OFFSET, "Vendor rev");
 		sff_show_ascii(id, SFF8636_VENDOR_SN_START_OFFSET,
-			       SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN");
+				SFF8636_VENDOR_SN_END_OFFSET, "Vendor SN");
 		sff_show_ascii(id, SFF8636_DATE_YEAR_OFFSET,
-			       SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
+				SFF8636_DATE_VENDOR_LOT_OFFSET + 1, "Date code");
+
 		sff8636_show_revision_compliance(id);
 		sff8636_show_dom(id, eeprom_len);
 	}
diff --git a/qsfp.h b/qsfp.h
index 3215932..9636b0c 100644
--- a/qsfp.h
+++ b/qsfp.h
@@ -31,14 +31,6 @@
 #define	SFF8636_ID_OFFSET	0x00
 
 #define	SFF8636_REV_COMPLIANCE_OFFSET	0x01
-#define	 SFF8636_REV_UNSPECIFIED		0x00
-#define	 SFF8636_REV_8436_48			0x01
-#define	 SFF8636_REV_8436_8636			0x02
-#define	 SFF8636_REV_8636_13			0x03
-#define	 SFF8636_REV_8636_14			0x04
-#define	 SFF8636_REV_8636_15			0x05
-#define	 SFF8636_REV_8636_20			0x06
-#define	 SFF8636_REV_8636_27			0x07
 
 #define	SFF8636_STATUS_2_OFFSET	0x02
 /* Flat Memory:0- Paging, 1- Page 0 only */
diff --git a/sff-common.c b/sff-common.c
index 7700cbe..5490b5f 100644
--- a/sff-common.c
+++ b/sff-common.c
@@ -46,6 +46,7 @@ void sff_show_ascii(const __u8 *id, unsigned int first_reg,
 	printf("\t%-41s : ", name);
 	while (first_reg <= last_reg && id[last_reg] == ' ')
 		last_reg--;
+
 	for (reg = first_reg; reg <= last_reg; reg++) {
 		val = id[reg];
 		putchar(((val >= 32) && (val <= 126)) ? val : '_');
@@ -136,6 +137,9 @@ void sff8024_show_identifier(const __u8 *id, int id_offset)
 	case SFF8024_ID_MICRO_QSFP:
 		printf(" (microQSFP)\n");
 		break;
+	case SFF8024_ID_QSFP_DD:
+		printf(" (QSFP-DD Double Density 8X Pluggable Transceiver (INF-8628))\n");
+		break;
 	default:
 		printf(" (reserved or unknown)\n");
 		break;
@@ -203,6 +207,18 @@ void sff8024_show_connector(const __u8 *id, int ctor_offset)
 	case SFF8024_CTOR_MXC_2x16:
 		printf(" (MXC 2x16)\n");
 		break;
+	case SFF8024_CTOR_CS_OPTICAL:
+		printf(" (CS optical connector)\n");
+		break;
+	case SFF8024_CTOR_CS_OPTICAL_MINI:
+		printf(" (Mini CS optical connector)\n");
+		break;
+	case SFF8024_CTOR_MPO_2X12:
+		printf(" (MPO 2x12)\n");
+		break;
+	case SFF8024_CTOR_MPO_1X16:
+		printf(" (MPO 1x16)\n");
+		break;
 	default:
 		printf(" (reserved or unknown)\n");
 		break;
@@ -302,3 +318,39 @@ void sff_show_thresholds(struct sff_diags sd)
 	PRINT_xX_PWR("Laser rx power low warning threshold",
 		     sd.rx_power[LWARN]);
 }
+
+void sff_show_revision_compliance(const __u8 *id, int rev_offset)
+{
+	static const char *pfx =
+		"\tRevision Compliance                       :";
+
+	switch (id[rev_offset]) {
+	case SFF8636_REV_UNSPECIFIED:
+		printf("%s Revision not specified\n", pfx);
+		break;
+	case SFF8636_REV_8436_48:
+		printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx);
+		break;
+	case SFF8636_REV_8436_8636:
+		printf("%s SFF-8436 Rev 4.8 or earlier\n", pfx);
+		break;
+	case SFF8636_REV_8636_13:
+		printf("%s SFF-8636 Rev 1.3 or earlier\n", pfx);
+		break;
+	case SFF8636_REV_8636_14:
+		printf("%s SFF-8636 Rev 1.4\n", pfx);
+		break;
+	case SFF8636_REV_8636_15:
+		printf("%s SFF-8636 Rev 1.5\n", pfx);
+		break;
+	case SFF8636_REV_8636_20:
+		printf("%s SFF-8636 Rev 2.0\n", pfx);
+		break;
+	case SFF8636_REV_8636_27:
+		printf("%s SFF-8636 Rev 2.5/2.6/2.7\n", pfx);
+		break;
+	default:
+		printf("%s Unallocated\n", pfx);
+		break;
+	}
+}
diff --git a/sff-common.h b/sff-common.h
index 5562b4d..0d04851 100644
--- a/sff-common.h
+++ b/sff-common.h
@@ -26,7 +26,17 @@
 #include <stdio.h>
 #include "internal.h"
 
-#define SFF8024_ID_OFFSET				0x00
+/* Revision compliance */
+#define	 SFF8636_REV_UNSPECIFIED		0x00
+#define	 SFF8636_REV_8436_48			0x01
+#define	 SFF8636_REV_8436_8636			0x02
+#define	 SFF8636_REV_8636_13			0x03
+#define	 SFF8636_REV_8636_14			0x04
+#define	 SFF8636_REV_8636_15			0x05
+#define	 SFF8636_REV_8636_20			0x06
+#define	 SFF8636_REV_8636_27			0x07
+
+#define  SFF8024_ID_OFFSET				0x00
 #define  SFF8024_ID_UNKNOWN				0x00
 #define  SFF8024_ID_GBIC				0x01
 #define  SFF8024_ID_SOLDERED_MODULE		0x02
@@ -51,7 +61,8 @@
 #define  SFF8024_ID_HD8X_FANOUT			0x15
 #define  SFF8024_ID_CDFP_S3				0x16
 #define  SFF8024_ID_MICRO_QSFP			0x17
-#define  SFF8024_ID_LAST				SFF8024_ID_MICRO_QSFP
+#define  SFF8024_ID_QSFP_DD				0x18
+#define  SFF8024_ID_LAST				SFF8024_ID_QSFP_DD
 #define  SFF8024_ID_UNALLOCATED_LAST	0x7F
 #define  SFF8024_ID_VENDOR_START		0x80
 #define  SFF8024_ID_VENDOR_LAST			0xFF
@@ -76,8 +87,14 @@
 #define  SFF8024_CTOR_RJ45				0x22
 #define  SFF8024_CTOR_NO_SEPARABLE		0x23
 #define  SFF8024_CTOR_MXC_2x16			0x24
-#define  SFF8024_CTOR_LAST				SFF8024_CTOR_MXC_2x16
-#define  SFF8024_CTOR_UNALLOCATED_LAST	0x7F
+#define  SFF8024_CTOR_CS_OPTICAL		0x25
+#define  SFF8024_CTOR_CS_OPTICAL_MINI		0x26
+#define  SFF8024_CTOR_MPO_2X12		    	0x27
+#define  SFF8024_CTOR_MPO_1X16		    	0x28
+#define  SFF8024_CTOR_LAST			SFF8024_CTOR_MPO_1X16
+
+#define  SFF8024_CTOR_NO_SEP_QSFP_DD 		0x6F
+#define  SFF8024_CTOR_UNALLOCATED_LAST		0x7F
 #define  SFF8024_CTOR_VENDOR_START		0x80
 #define  SFF8024_CTOR_VENDOR_LAST		0xFF
 
@@ -185,5 +202,6 @@ void sff8024_show_oui(const __u8 *id, int id_offset);
 void sff8024_show_identifier(const __u8 *id, int id_offset);
 void sff8024_show_connector(const __u8 *id, int ctor_offset);
 void sff8024_show_encoding(const __u8 *id, int encoding_offset, int sff_type);
+void sff_show_revision_compliance(const __u8 *id, int rev_offset);
 
 #endif /* SFF_COMMON_H__ */
-- 
2.17.1


^ permalink raw reply related

* [PATCH v3 iproute2-next] devlink: Add board.serial_number to info subcommand.
From: Vasundhara Volam @ 2020-07-31 10:46 UTC (permalink / raw)
  To: netdev; +Cc: dsahern, stephen, davem, jiri, kuba, michael.chan,
	Vasundhara Volam

Add support for reading board serial_number to devlink info
subcommand. Example:

$ devlink dev info pci/0000:af:00.0 -jp
{
    "info": {
        "pci/0000:af:00.0": {
            "driver": "bnxt_en",
            "serial_number": "00-10-18-FF-FE-AD-1A-00",
            "board.serial_number": "433551F+172300000",
            "versions": {
                "fixed": {
                    "board.id": "7339763 Rev 0.",
                    "asic.id": "16D7",
                    "asic.rev": "1"
                },
                "running": {
                    "fw": "216.1.216.0",
                    "fw.psid": "0.0.0",
                    "fw.mgmt": "216.1.192.0",
                    "fw.mgmt.api": "1.10.1",
                    "fw.ncsi": "0.0.0.0",
                    "fw.roce": "216.1.16.0"
                }
            }
        }
    }
}

Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
---
v2: Rebase. Resending the patch as I see this patch didn't make it to
mailing list.
v3: Rebase the patch and remove the line from commit message
"This patch has dependency on updated include/uapi/linux/devlink.h file."
as the headers are updated.
---
 devlink/devlink.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 7dbe9c7e..f4230dac 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -648,6 +648,7 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_REGION_CHUNK_LEN] = MNL_TYPE_U64,
 	[DEVLINK_ATTR_INFO_DRIVER_NAME] = MNL_TYPE_STRING,
 	[DEVLINK_ATTR_INFO_SERIAL_NUMBER] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER] = MNL_TYPE_STRING,
 	[DEVLINK_ATTR_INFO_VERSION_FIXED] = MNL_TYPE_NESTED,
 	[DEVLINK_ATTR_INFO_VERSION_RUNNING] = MNL_TYPE_NESTED,
 	[DEVLINK_ATTR_INFO_VERSION_STORED] = MNL_TYPE_NESTED,
@@ -2979,6 +2980,16 @@ static void pr_out_info(struct dl *dl, const struct nlmsghdr *nlh,
 		print_string(PRINT_ANY, "serial_number", "serial_number %s",
 			     mnl_attr_get_str(nla_sn));
 	}
+
+	if (tb[DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER]) {
+		struct nlattr *nla_bsn = tb[DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER];
+
+		if (!dl->json_output)
+			__pr_out_newline();
+		check_indent_newline(dl);
+		print_string(PRINT_ANY, "board.serial_number", "board.serial_number %s",
+			     mnl_attr_get_str(nla_bsn));
+	}
 	__pr_out_indent_dec();
 
 	if (has_versions) {
@@ -3014,6 +3025,7 @@ static int cmd_versions_show_cb(const struct nlmsghdr *nlh, void *data)
 		tb[DEVLINK_ATTR_INFO_VERSION_STORED];
 	has_info = tb[DEVLINK_ATTR_INFO_DRIVER_NAME] ||
 		tb[DEVLINK_ATTR_INFO_SERIAL_NUMBER] ||
+		tb[DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER] ||
 		has_versions;
 
 	if (has_info)
-- 
2.18.2


^ permalink raw reply related

* [PATCH][v2] i40e: optimise prefetch page refcount
From: Li RongQing @ 2020-07-31 10:37 UTC (permalink / raw)
  To: netdev, intel-wired-lan, kuba, andrewx.bowers, anthony.l.nguyen

refcount of rx_buffer page will be added here originally, so prefetchw
is needed, but after commit 1793668c3b8c ("i40e/i40evf: Update code to
 better handle incrementing page count"), and refcount is not added
everytime, so change prefetchw as prefetch,

now it mainly services page_address(), but which accesses struct page
only when WANT_PAGE_VIRTUAL or HASHED_PAGE_VIRTUAL is defined otherwise
it returns address based on offset, so we prefetch it conditionally

Jakub suggested to define prefetch_page_address in a common header

Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
diff with v1: create a common function prefetch_page_address

 drivers/net/ethernet/intel/i40e/i40e_txrx.c | 2 +-
 include/linux/prefetch.h                    | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 62f5b2d35f63..5f9fe55bb66d 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -1953,7 +1953,7 @@ static struct i40e_rx_buffer *i40e_get_rx_buffer(struct i40e_ring *rx_ring,
 	struct i40e_rx_buffer *rx_buffer;
 
 	rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean);
-	prefetchw(rx_buffer->page);
+	prefetch_page_address(rx_buffer->page);
 
 	/* we are reusing so sync this buffer for CPU use */
 	dma_sync_single_range_for_cpu(rx_ring->dev,
diff --git a/include/linux/prefetch.h b/include/linux/prefetch.h
index 13eafebf3549..1e0283982dd3 100644
--- a/include/linux/prefetch.h
+++ b/include/linux/prefetch.h
@@ -62,4 +62,11 @@ static inline void prefetch_range(void *addr, size_t len)
 #endif
 }
 
+static inline void prefetch_page_address(struct page *page)
+{
+#if defined(WANT_PAGE_VIRTUAL) || defined(HASHED_PAGE_VIRTUAL)
+	prefetch(page);
+#endif
+}
+
 #endif
-- 
2.16.2


^ permalink raw reply related

* RE: [PATCH v2] ravb: Fixed the problem that rmmod can not be done
From: ashiduka @ 2020-07-31 10:18 UTC (permalink / raw)
  To: 'Sergei Shtylyov'
  Cc: netdev@vger.kernel.org, linux-renesas-soc@vger.kernel.org
In-Reply-To: <ce81e95d-b3b0-7f1c-8f97-8bdcb23d5a8e@gmail.com>

Hi Sergei,

I understand that the commit log needs to be corrected.
(Shimoda-san's point is also correct)

If there is anything else that needs to be corrected, please point it out.

>    That seems a common pattern, inlluding the Renesas sh_eth
> driver...

Yes.
If I can get an R-Car Gen2 board, I will also fix sh_eth driver.

>    No, the driver's remove() method calls ravb_mdio_release() and
> that one calls
> free_mdio_bitbang() that calls module_put(); the actual reason lies
> somewehre deeper than this...

No.
Running rmmod calls delete_module() in kernel/module.c before ravb_mdio_release() is called.
delete_module()
   -> try_stop_module()
     -> try_release_module_ref()
In try_release_module_ref(), check refcnt and if it is counted up, ravb_mdio_release() is not
called and rmmod is terminated.

Thanks & Best Regards,
Yuusuke Ashizuka <ashiduka@fujitsu.com>

> -----Original Message-----
> From: Sergei Shtylyov <sergei.shtylyov@gmail.com>
> Sent: Friday, July 31, 2020 1:04 AM
> To: Ashizuka, Yuusuke/芦塚 雄介 <ashiduka@fujitsu.com>
> Cc: netdev@vger.kernel.org; linux-renesas-soc@vger.kernel.org
> Subject: Re: [PATCH v2] ravb: Fixed the problem that rmmod can not
> be done
> 
> Hello!
> 
> On 7/30/20 1:01 PM, Yuusuke Ashizuka wrote:
> 
> > ravb is a module driver, but I cannot rmmod it after insmod it.
> 
>    Modular. And "insmod'ing it".
> 
> > ravb does mdio_init() at the time of probe, and module->refcnt
> is incremented
> > by alloc_mdio_bitbang() called after that.
> 
>    That seems a common pattern, inlluding the Renesas sh_eth
> driver...
> 
> > Therefore, even if ifup is not performed, the driver is in use
> and rmmod cannot
> > be performed.
> 
>    No, the driver's remove() method calls ravb_mdio_release() and
> that one calls
> free_mdio_bitbang() that calls module_put(); the actual reason lies
> somewehre deeper
> than this... Unfortunately I don't have the affected hardware
> anymore... :-(
> 
> [...]
> 
> MBR, Sergei

^ permalink raw reply

* [PATCH -next v2] net: ice: Fix pointer cast warnings
From: Bixuan Cui @ 2020-07-31 10:07 UTC (permalink / raw)
  To: davem, kuba; +Cc: jeffrey.t.kirsher, intel-wired-lan, netdev, linux-next
In-Reply-To: <20200731105721.18511-1-cuibixuan@huawei.com>

pointers should be casted to unsigned long to avoid
-Wpointer-to-int-cast warnings:

drivers/net/ethernet/intel/ice/ice_flow.h:197:33: warning:
    cast from pointer to integer of different size
drivers/net/ethernet/intel/ice/ice_flow.h:198:32: warning:
    cast to pointer from integer of different size

Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
---
v2->v1: add fix:
 ice_flow.h:198:32: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
 #define ICE_FLOW_ENTRY_PTR(h) ((struct ice_flow_entry *)(h))

 drivers/net/ethernet/intel/ice/ice_flow.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_flow.h b/drivers/net/ethernet/intel/ice/ice_flow.h
index 3913da2116d2..829f90b1e998 100644
--- a/drivers/net/ethernet/intel/ice/ice_flow.h
+++ b/drivers/net/ethernet/intel/ice/ice_flow.h
@@ -194,8 +194,8 @@ struct ice_flow_entry {
 	u16 entry_sz;
 };

-#define ICE_FLOW_ENTRY_HNDL(e)	((u64)e)
-#define ICE_FLOW_ENTRY_PTR(h)	((struct ice_flow_entry *)(h))
+#define ICE_FLOW_ENTRY_HNDL(e)	((u64)(uintptr_t)e)
+#define ICE_FLOW_ENTRY_PTR(h)	((struct ice_flow_entry *)(uintptr_t)(h))

 struct ice_flow_prof {
 	struct list_head l_entry;
--
2.17.1


.



^ permalink raw reply related

* Re: [PATCH v3 1/9] ptp: Add generic ptp v2 header parsing function
From: Kurt Kanzenbach @ 2020-07-31 10:06 UTC (permalink / raw)
  To: Petr Machata
  Cc: Richard Cochran, Andrew Lunn, Vivien Didelot, Florian Fainelli,
	David S. Miller, Jakub Kicinski, Jiri Pirko, Ido Schimmel,
	Heiner Kallweit, Russell King, Grygorii Strashko, Ivan Khoronzhuk,
	Samuel Zou, netdev, Russell King
In-Reply-To: <87lfj1gvgq.fsf@mellanox.com>

[-- Attachment #1: Type: text/plain, Size: 640 bytes --]

On Thu Jul 30 2020, Petr Machata wrote:
> Kurt Kanzenbach <kurt@linutronix.de> writes:
>
>> @@ -107,6 +107,37 @@ unsigned int ptp_classify_raw(const struct sk_buff *skb)
>>  }
>>  EXPORT_SYMBOL_GPL(ptp_classify_raw);
>>  
>> +struct ptp_header *ptp_parse_header(struct sk_buff *skb, unsigned int type)
>> +{
>> +	u8 *data = skb_mac_header(skb);
>> +	u8 *ptr = data;
>
> One of the "data" and "ptr" variables is superfluous.

Yeah. Can be shortened to u8 *ptr = skb_mac_header(skb);

However, I'll wait a bit before sending the next version. So, that the
other maintainers have time to test their drivers.

Thanks,
Kurt

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

^ permalink raw reply

* Re: [Linux-kernel-mentees] [PATCH net] rds: Prevent kernel-infoleak in rds_notify_queue_get()
From: Dan Carpenter @ 2020-07-31  9:59 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Peilin Ye, Santosh Shilimkar, David S. Miller, Jakub Kicinski,
	Arnd Bergmann, Greg Kroah-Hartman, linux-kernel-mentees, netdev,
	linux-rdma, rds-devel, linux-kernel
In-Reply-To: <20200731045301.GI75549@unreal>

On Fri, Jul 31, 2020 at 07:53:01AM +0300, Leon Romanovsky wrote:
> On Thu, Jul 30, 2020 at 03:20:26PM -0400, Peilin Ye wrote:
> > rds_notify_queue_get() is potentially copying uninitialized kernel stack
> > memory to userspace since the compiler may leave a 4-byte hole at the end
> > of `cmsg`.
> >
> > In 2016 we tried to fix this issue by doing `= { 0 };` on `cmsg`, which
> > unfortunately does not always initialize that 4-byte hole. Fix it by using
> > memset() instead.
> 
> Of course, this is the difference between "{ 0 }" and "{}" initializations.
> 

No, there is no difference.  Even struct assignments like:

	foo = *bar;

can leave struct holes uninitialized.  Depending on the compiler the
assignment can be implemented as a memset() or as a series of struct
member assignments.

regards,
dan carpenter


^ permalink raw reply

* [PATCH -next] net: ice: Fix pointer cast warnings
From: Bixuan Cui @ 2020-07-31 10:57 UTC (permalink / raw)
  To: davem, kuba; +Cc: jeffrey.t.kirsher, intel-wired-lan, netdev, linux-next

pointers should be casted to unsigned long to avoid
-Wpointer-to-int-cast warnings:

drivers/net/ethernet/intel/ice/ice_flow.h:197:33: warning:
    cast from pointer to integer of different size

Signed-off-by: Bixuan Cui <cuibixuan@huawei.com>
---
 drivers/net/ethernet/intel/ice/ice_flow.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_flow.h b/drivers/net/ethernet/intel/ice/ice_flow.h
index 3913da2116d2..b9a5c208e484 100644
--- a/drivers/net/ethernet/intel/ice/ice_flow.h
+++ b/drivers/net/ethernet/intel/ice/ice_flow.h
@@ -194,7 +194,7 @@ struct ice_flow_entry {
 	u16 entry_sz;
 };

-#define ICE_FLOW_ENTRY_HNDL(e)	((u64)e)
+#define ICE_FLOW_ENTRY_HNDL(e)	((uintptr_t)e)
 #define ICE_FLOW_ENTRY_PTR(h)	((struct ice_flow_entry *)(h))

 struct ice_flow_prof {
--
2.17.1


^ permalink raw reply related

* Re: [PATCH net] net: mvpp2: fix memory leak in mvpp2_rx
From: Matteo Croce @ 2020-07-31  9:38 UTC (permalink / raw)
  To: Lorenzo Bianconi, netdev@vger.kernel.org
  Cc: davem@davemloft.net, lorenzo.bianconi@redhat.com, mw@semihalf.com
In-Reply-To: <c1c2f9c0b79d4a84701d374c6e63f69ec3f42098.1596184502.git.lorenzo@kernel.org>

> Release skb memory in mvpp2_rx() if mvpp2_rx_refill routine fails
> 
> Fixes: b5015854674b ("net: mvpp2: fix refilling BM pools in RX path")
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>

I think that mvpp2_rx() has changed a bit in net-next due to the XDP support, but it should apply too.

Acked-by: Matteo Croce <mcroce@microsoft.com>

^ permalink raw reply

* Re: WARNING in cancel_delayed_work
From: syzbot @ 2020-07-31  8:44 UTC (permalink / raw)
  To: davem, johan.hedberg, johannes.berg, johannes, kuba,
	linux-bluetooth, linux-kernel, linux-wireless, luciano.coelho,
	marcel, netdev, syzkaller-bugs
In-Reply-To: <000000000000f6d80505abb42b60@google.com>

syzbot has bisected this issue to:

commit fbd05e4a6e82fd573d3aa79e284e424b8d78c149
Author: Luca Coelho <luciano.coelho@intel.com>
Date:   Thu Sep 15 15:15:09 2016 +0000

    cfg80211: add helper to find an IE that matches a byte-array

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=1790af82900000
start commit:   83bdc727 random32: remove net_rand_state from the latent e..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1050af82900000
kernel config:  https://syzkaller.appspot.com/x/.config?x=e59ee776d5aa8d55
dashboard link: https://syzkaller.appspot.com/bug?extid=35e70efb794757d7e175
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=1160faa2900000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=11816098900000

Reported-by: syzbot+35e70efb794757d7e175@syzkaller.appspotmail.com
Fixes: fbd05e4a6e82 ("cfg80211: add helper to find an IE that matches a byte-array")

For information about bisection process see: https://goo.gl/tpsmEJ#bisection

^ permalink raw reply

* [PATCH net] net: mvpp2: fix memory leak in mvpp2_rx
From: Lorenzo Bianconi @ 2020-07-31  8:38 UTC (permalink / raw)
  To: netdev; +Cc: davem, lorenzo.bianconi, mw, mcroce

Release skb memory in mvpp2_rx() if mvpp2_rx_refill routine fails

Fixes: b5015854674b ("net: mvpp2: fix refilling BM pools in RX path")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 24f4d8e0da98..ee72397813d4 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -2981,6 +2981,7 @@ static int mvpp2_rx(struct mvpp2_port *port, struct napi_struct *napi,
 		err = mvpp2_rx_refill(port, bm_pool, pool);
 		if (err) {
 			netdev_err(port->dev, "failed to refill BM pools\n");
+			dev_kfree_skb_any(skb);
 			goto err_drop_frame;
 		}
 
-- 
2.26.2


^ permalink raw reply related

* [PATCH bpf-next v3] Documentation/bpf: Use valid and new links in index.rst
From: Tiezhu Yang @ 2020-07-31  8:29 UTC (permalink / raw)
  To: Jonathan Corbet, Alexei Starovoitov, Daniel Borkmann
  Cc: Martin KaFai Lau, Song Liu, Yonghong Song, Andrii Nakryiko,
	John Fastabend, KP Singh, David S. Miller, Jakub Kicinski,
	Tobin C. Harding, Mauro Carvalho Chehab, linux-doc, netdev, bpf,
	linux-kernel

There exists an error "404 Not Found" when I click the html link of
"Documentation/networking/filter.rst" in the BPF documentation [1],
fix it.

Additionally, use the new links about "BPF and XDP Reference Guide"
and "bpf(2)" to avoid redirects.

[1] https://www.kernel.org/doc/html/latest/bpf/

Fixes: d9b9170a2653 ("docs: bpf: Rename README.rst to index.rst")
Fixes: cb3f0d56e153 ("docs: networking: convert filter.txt to ReST")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
---
 Documentation/bpf/index.rst         | 12 ++++++------
 Documentation/networking/filter.rst |  2 ++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/Documentation/bpf/index.rst b/Documentation/bpf/index.rst
index 26f4bb3..44ca8ea 100644
--- a/Documentation/bpf/index.rst
+++ b/Documentation/bpf/index.rst
@@ -5,10 +5,10 @@ BPF Documentation
 This directory contains documentation for the BPF (Berkeley Packet
 Filter) facility, with a focus on the extended BPF version (eBPF).
 
-This kernel side documentation is still work in progress.  The main
+This kernel side documentation is still work in progress. The main
 textual documentation is (for historical reasons) described in
-`Documentation/networking/filter.rst`_, which describe both classical
-and extended BPF instruction-set.
+:ref:`networking-filter`, which describe both classical and extended
+BPF instruction-set.
 The Cilium project also maintains a `BPF and XDP Reference Guide`_
 that goes into great technical depth about the BPF Architecture.
 
@@ -68,7 +68,7 @@ Testing and debugging BPF
 
 
 .. Links:
-.. _Documentation/networking/filter.rst: ../networking/filter.txt
+.. _networking-filter: ../networking/filter.rst
 .. _man-pages: https://www.kernel.org/doc/man-pages/
-.. _bpf(2): http://man7.org/linux/man-pages/man2/bpf.2.html
-.. _BPF and XDP Reference Guide: http://cilium.readthedocs.io/en/latest/bpf/
+.. _bpf(2): https://man7.org/linux/man-pages/man2/bpf.2.html
+.. _BPF and XDP Reference Guide: https://docs.cilium.io/en/latest/bpf/
diff --git a/Documentation/networking/filter.rst b/Documentation/networking/filter.rst
index a1d3e19..debb59e 100644
--- a/Documentation/networking/filter.rst
+++ b/Documentation/networking/filter.rst
@@ -1,5 +1,7 @@
 .. SPDX-License-Identifier: GPL-2.0
 
+.. _networking-filter:
+
 =======================================================
 Linux Socket Filtering aka Berkeley Packet Filter (BPF)
 =======================================================
-- 
2.1.0


^ permalink raw reply related

* Ktls offload in cx6 of mellanox
From: wenxu @ 2020-07-31  8:09 UTC (permalink / raw)
  To: Saeed Mahameed; +Cc: Linux Kernel Network Developers

Hi mellanox team,


I test the ktls offload feature with CX6 dx with net-next tree.


fw version is the latest 22.28.1002

# ethtool -i net3
driver: mlx5_core
version: 5.0-0
firmware-version: 22.28.1002 (MT_0000000430)
expansion-rom-version:
bus-info: 0000:07:00.1
supports-statistics: yes
supports-test: yes
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: yes

# ethtool -K net3 |  grep tls-hw

tls-hw-tx-offload: on
tls-hw-rx-offload: off [fixed]


I found the rx offload is not supported currently?


BR

wenxu


^ permalink raw reply


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