* Re: [PATCH net-next v6 06/15] ethtool: netlink bitset handling
From: Michal Kubecek @ 2019-07-04 12:53 UTC (permalink / raw)
To: netdev
Cc: Johannes Berg, Jiri Pirko, David Miller, Jakub Kicinski,
Andrew Lunn, Florian Fainelli, John Linville, Stephen Hemminger,
linux-kernel
In-Reply-To: <2f1a8edb0b000b4eb7adcaca0d1fb05fdd73a587.camel@sipsolutions.net>
On Thu, Jul 04, 2019 at 02:21:52PM +0200, Johannes Berg wrote:
> On Thu, 2019-07-04 at 14:17 +0200, Michal Kubecek wrote:
> > On Thu, Jul 04, 2019 at 02:03:02PM +0200, Johannes Berg wrote:
> > > On Thu, 2019-07-04 at 13:52 +0200, Michal Kubecek wrote:
> > > >
> > > > There is still the question if it it should be implemented as a nested
> > > > attribute which could look like the current compact form without the
> > > > "list" flag (if there is no mask, it's a list). Or an unstructured data
> > > > block consisting of u32 bit length
> > >
> > > You wouldn't really need the length, since the attribute has a length
> > > already :-)
> >
> > It has byte length, not bit length. The bitmaps we are dealing with
> > can have any bit length, not necessarily multiples of 8 (or even 32).
>
> Not sure why that matters? You have the mask, so you don't really need
> to additionally say that you're only going up to a certain bit?
>
> I mean, say you want to set some bits <=17, why would you need to say
> that they're <=17 if you have a
> value: 0b00000000'000000xx'xxxxxxxx'xxxxxxxx
> mask: 0b00000000'00000011'11111111'11111111
One scenario that I can see from the top of my head would be user
running
ethtool -s <dev> advertise 0x...
with hex value representing some subset of link modes. Now if ethtool
version is behind kernel and recognizes fewer link modes than kernel
but in a way that the number rounded up to bytes or words would be the
same, kernel has no way to recognize of those zero bits on top of the
mask are zero on purpose or just because userspace doesn't know about
them. In general, I believe the absence of bit length information is
something protocols would have to work around sometimes.
The submitted implementation doesn't have this problem as it can tell
kernel "this is a list" (i.e. I'm not sending a value/mask pair, I want
exactly these bits to be set). Thus it can easily implement requests of
both types (value/mask or just value):
ethtool -s <dev> advertise 0x2f
ethtool -s <dev> advertise 0x08/0x0c
ethtool -s <dev> advertise 100baseT/Full off 1000baseT/Full on
and could be as easily extended to support also
ethtool -s <dev> advertise 100baseT/Full 1000baseT/Full
Michal
^ permalink raw reply
* RE: [PATCH net-next 3/3] net: stmmac: Introducing support for Page Pool
From: Jose Abreu @ 2019-07-04 12:59 UTC (permalink / raw)
To: Ilias Apalodimas, Jesper Dangaard Brouer
Cc: Jose Abreu, linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org, Joao Pinto,
David S . Miller, Giuseppe Cavallaro, Alexandre Torgue,
Maxime Coquelin, Maxime Ripard, Chen-Yu Tsai
In-Reply-To: <20190704120441.GA6866@apalos>
Thank you all for your review comments !
From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> That's why i was concerned on what will happen on > 1000b frames and what the
> memory pressure is going to be.
> The trade off here is copying vs mapping/unmapping.
Well, the performance numbers I mentioned are for TSO with default MTU
(1500) and using iperf3 with zero-copy. Here follows netperf:
---
# netperf -c -C -H 1.2.3.2 -T 7,7 -t TCP_SENDFILE
TCP SENDFILE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to 1.2.3.2
(1.2.3.2) port 0 AF_INET : demo : cpu bind
Recv Send Send Utilization Service
Demand
Socket Socket Message Elapsed Send Recv Send
Recv
Size Size Size Time Throughput local remote local
remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB
us/KB
131072 16384 16384 10.00 9132.37 6.13 11.79 0.440
0.846
---
# netperf -c -C -H 1.2.3.2 -T 7,7 -t TCP_STREAM
MIGRATED TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
1.2.3.2 (1.2.3.2) port 0 AF_INET : demo : cpu bind
Recv Send Send Utilization Service
Demand
Socket Socket Message Elapsed Send Recv Send
Recv
Size Size Size Time Throughput local remote local
remote
bytes bytes bytes secs. 10^6bits/s % S % S us/KB
us/KB
131072 16384 16384 10.01 9041.21 3.20 11.75 0.232
0.852
---
# netperf -c -C -H 1.2.3.2 -T 7,7 -t UDP_STREAM
MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
1.2.3.2 (1.2.3.2) port 0 AF_INET : demo : cpu bind
Socket Message Elapsed Messages CPU
Service
Size Size Time Okay Errors Throughput Util Demand
bytes bytes secs # # 10^6bits/sec % SS us/KB
212992 65507 10.00 114455 0 5997.0 12.55 1.371
212992 10.00 114455 5997.0 8.12 0.887
---
# netperf -c -C -H 1.2.3.2 -T 7,7 -t UDP_STREAM -- -m 64
MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
1.2.3.2 (1.2.3.2) port 0 AF_INET : demo : cpu bind
Socket Message Elapsed Messages CPU
Service
Size Size Time Okay Errors Throughput Util Demand
bytes bytes secs # # 10^6bits/sec % SS us/KB
212992 64 10.00 4013480 0 205.4 12.51 39.918
212992 10.00 4013480 205.4 7.99 25.482
---
# netperf -c -C -H 1.2.3.2 -T 7,7 -t UDP_STREAM -- -m 128
MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
1.2.3.2 (1.2.3.2) port 0 AF_INET : demo : cpu bind
Socket Message Elapsed Messages CPU
Service
Size Size Time Okay Errors Throughput Util Demand
bytes bytes secs # # 10^6bits/sec % SS us/KB
212992 128 10.00 3950480 0 404.4 12.50 20.255
212992 10.00 3950442 404.4 7.70 12.485
---
# netperf -c -C -H 1.2.3.2 -T 7,7 -t UDP_STREAM -- -m 1024
MIGRATED UDP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to
1.2.3.2 (1.2.3.2) port 0 AF_INET : demo : cpu bind
Socket Message Elapsed Messages CPU
Service
Size Size Time Okay Errors Throughput Util Demand
bytes bytes secs # # 10^6bits/sec % SS us/KB
212992 1024 10.00 3466506 0 2838.8 12.50 2.886
212992 10.00 3466506 2838.8 7.39 1.707
^ permalink raw reply
* Re: [PATCH 1/1] tools/dtrace: initial implementation of DTrace
From: Peter Zijlstra @ 2019-07-04 13:03 UTC (permalink / raw)
To: Kris Van Hees
Cc: netdev, bpf, dtrace-devel, linux-kernel, rostedt, mhiramat, acme,
ast, daniel, Chris Mason
In-Reply-To: <201907040314.x643EUoA017906@aserv0122.oracle.com>
On Wed, Jul 03, 2019 at 08:14:30PM -0700, Kris Van Hees wrote:
> +/*
> + * Read the data_head offset from the header page of the ring buffer. The
> + * argument is declared 'volatile' because it references a memory mapped page
> + * that the kernel may be writing to while we access it here.
> + */
> +static u64 read_rb_head(volatile struct perf_event_mmap_page *rb_page)
> +{
> + u64 head = rb_page->data_head;
> +
> + asm volatile("" ::: "memory");
> +
> + return head;
> +}
> +
> +/*
> + * Write the data_tail offset in the header page of the ring buffer. The
> + * argument is declared 'volatile' because it references a memory mapped page
> + * that the kernel may be writing to while we access it here.
s/writing/reading/
> + */
> +static void write_rb_tail(volatile struct perf_event_mmap_page *rb_page,
> + u64 tail)
> +{
> + asm volatile("" ::: "memory");
> +
> + rb_page->data_tail = tail;
> +}
That volatile usage is atrocious (kernel style would have you use
{READ,WRITE}_ONCE()). Also your comments fail to mark these as
load_acquire and store_release. And by only using a compiler barrier
you're hard assuming TSO, which is somewhat fragile at best.
Alternatively, you can use the C11 bits and write:
return __atomic_load_n(&rb_page->data_head, __ATOMIC_ACQUIRE);
__atomic_store_n(&rb_page->data_tail, tail, __ATOMIC_RELEASE);
> +/*
> + * Process and output the probe data at the supplied address.
> + */
> +static int output_event(int cpu, u64 *buf)
> +{
> + u8 *data = (u8 *)buf;
> + struct perf_event_header *hdr;
> +
> + hdr = (struct perf_event_header *)data;
> + data += sizeof(struct perf_event_header);
> +
> + if (hdr->type == PERF_RECORD_SAMPLE) {
> + u8 *ptr = data;
> + u32 i, size, probe_id;
> +
> + /*
> + * struct {
> + * struct perf_event_header header;
> + * u32 size;
> + * u32 probe_id;
> + * u32 gap;
> + * u64 data[n];
> + * }
> + * and data points to the 'size' member at this point.
> + */
> + if (ptr > (u8 *)buf + hdr->size) {
> + fprintf(stderr, "BAD: corrupted sample header\n");
> + goto out;
> + }
> +
> + size = *(u32 *)data;
> + data += sizeof(size);
> + ptr += sizeof(size) + size;
> + if (ptr != (u8 *)buf + hdr->size) {
> + fprintf(stderr, "BAD: invalid sample size\n");
> + goto out;
> + }
> +
> + probe_id = *(u32 *)data;
> + data += sizeof(probe_id);
> + size -= sizeof(probe_id);
> + data += sizeof(u32); /* skip 32-bit gap */
> + size -= sizeof(u32);
> + buf = (u64 *)data;
> +
> + printf("%3d %6d ", cpu, probe_id);
> + for (i = 0, size /= sizeof(u64); i < size; i++)
> + printf("%#016lx ", buf[i]);
> + printf("\n");
> + } else if (hdr->type == PERF_RECORD_LOST) {
> + u64 lost;
> +
> + /*
> + * struct {
> + * struct perf_event_header header;
> + * u64 id;
> + * u64 lost;
> + * }
> + * and data points to the 'id' member at this point.
> + */
> + lost = *(u64 *)(data + sizeof(u64));
> +
> + printf("[%ld probes dropped]\n", lost);
> + } else
> + fprintf(stderr, "UNKNOWN: record type %d\n", hdr->type);
> +
> +out:
> + return hdr->size;
> +}
I see a distinct lack of wrapping support. AFAICT when buf+hdr->size
wraps you're doing out-of-bounds accesses.
> +/*
> + * Process the available probe data in the given buffer.
> + */
> +static void process_data(struct dtrace_buffer *buf)
> +{
> + /* This is volatile because the kernel may be updating the content. */
> + volatile struct perf_event_mmap_page *rb_page = buf->base;
> + u8 *base = (u8 *)buf->base +
> + buf->page_size;
> + u64 head = read_rb_head(rb_page);
> +
> + while (rb_page->data_tail != head) {
> + u64 tail = rb_page->data_tail;
> + u64 *ptr = (u64 *)(base + tail % buf->data_size);
> + int len;
> +
> + len = output_event(buf->cpu, ptr);
> +
> + write_rb_tail(rb_page, tail + len);
> + head = read_rb_head(rb_page);
> + }
> +}
more volatile yuck.
Also:
for (;;) {
head = __atomic_load_n(&rb_page->data_head, __ATOMIC_ACQUIRE);
tail = __atomic_load_n(&rb_page->data_tail, __ATOMIC_RELAXED);
if (head == tail)
break;
do {
hdr = buf->base + (tail & ((1UL << buf->data_shift) - 1));
if ((tail >> buf->data_shift) !=
((tail + hdr->size) >> buf->data_shift))
/* handle wrap case */
else
/* normal case */
tail += hdr->size;
} while (tail != head);
__atomic_store_n(&rb_page->data_tail, tail, __ATOMIC_RELEASE);
}
Or something.
> +/*
> + * Wait for data to become available in any of the buffers.
> + */
> +int dt_buffer_poll(int epoll_fd, int timeout)
> +{
> + struct epoll_event events[dt_numcpus];
> + int i, cnt;
> +
> + cnt = epoll_wait(epoll_fd, events, dt_numcpus, timeout);
> + if (cnt < 0)
> + return -errno;
> +
> + for (i = 0; i < cnt; i++)
> + process_data((struct dtrace_buffer *)events[i].data.ptr);
> +
> + return cnt;
> +}
Or make sure to read on the CPU by having a poll thread per CPU, then
you can do away with the memory barriers.
^ permalink raw reply
* Re: [PATCH 1/1] tools/dtrace: initial implementation of DTrace
From: Peter Zijlstra @ 2019-07-04 13:05 UTC (permalink / raw)
To: Kris Van Hees
Cc: netdev, bpf, dtrace-devel, linux-kernel, rostedt, mhiramat, acme,
ast, daniel, Chris Mason
In-Reply-To: <201907040314.x643EUoA017906@aserv0122.oracle.com>
On Wed, Jul 03, 2019 at 08:14:30PM -0700, Kris Van Hees wrote:
> +int dt_bpf_attach(int event_id, int bpf_fd)
> +{
> + int event_fd;
> + int rc;
> + struct perf_event_attr attr = {};
> +
> + attr.type = PERF_TYPE_TRACEPOINT;
> + attr.sample_type = PERF_SAMPLE_RAW;
> + attr.sample_period = 1;
> + attr.wakeup_events = 1;
> + attr.config = event_id;
> +
> + /* Register the event (based on its id), and obtain a fd. */
> + event_fd = perf_event_open(&attr, -1, 0, -1, 0);
> + if (event_fd < 0) {
> + perror("sys_perf_event_open");
> + return -1;
> + }
> +
> + /* Enable the probe. */
> + rc = ioctl(event_fd, PERF_EVENT_IOC_ENABLE, 0);
AFAICT you didn't use attr.disabled = 1, so this IOC_ENABLE is
completely superfluous.
> + if (rc < 0) {
> + perror("PERF_EVENT_IOC_ENABLE");
> + return -1;
> + }
> +
> + /* Associate the BPF program with the event. */
> + rc = ioctl(event_fd, PERF_EVENT_IOC_SET_BPF, bpf_fd);
> + if (rc < 0) {
> + perror("PERF_EVENT_IOC_SET_BPF");
> + return -1;
> + }
> +
> + return 0;
> +}
^ permalink raw reply
* Re: [PATCH net-next 3/3] net: stmmac: Introducing support for Page Pool
From: Ilias Apalodimas @ 2019-07-04 13:06 UTC (permalink / raw)
To: Jose Abreu
Cc: Jesper Dangaard Brouer, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org, Joao Pinto,
David S . Miller, Giuseppe Cavallaro, Alexandre Torgue,
Maxime Coquelin, Maxime Ripard, Chen-Yu Tsai
In-Reply-To: <BYAPR12MB3269D4FAAC5307A224D60A08D3FA0@BYAPR12MB3269.namprd12.prod.outlook.com>
Hi Jose,
> Thank you all for your review comments !
>
> From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
>
> > That's why i was concerned on what will happen on > 1000b frames and what the
> > memory pressure is going to be.
> > The trade off here is copying vs mapping/unmapping.
>
> Well, the performance numbers I mentioned are for TSO with default MTU
> (1500) and using iperf3 with zero-copy. Here follows netperf:
>
Ok i guess this should be fine. Here's why.
You'll allocate an extra memory from page pool API which equals
the number of descriptors * 1 page.
You also allocate SKB's to copy the data and recycle the page pool buffers.
So page_pool won't add any significant memory pressure since we expect *all*
it's buffers to be recycled.
The SKBs are allocated anyway in the current driver so bottom line you trade off
some memory (the page_pool buffers) + a memcpy per packet and skip the dma
map/unmap which is the bottleneck in your hardware.
I think it's fine
Cheers
/Ilias
^ permalink raw reply
* Re: [PATCH net-next v6 06/15] ethtool: netlink bitset handling
From: Johannes Berg @ 2019-07-04 13:10 UTC (permalink / raw)
To: Michal Kubecek, netdev
Cc: Jiri Pirko, David Miller, Jakub Kicinski, Andrew Lunn,
Florian Fainelli, John Linville, Stephen Hemminger, linux-kernel
In-Reply-To: <20190704125315.GT20101@unicorn.suse.cz>
On Thu, 2019-07-04 at 14:53 +0200, Michal Kubecek wrote:
>
> > value: 0b00000000'000000xx'xxxxxxxx'xxxxxxxx
> > mask: 0b00000000'00000011'11111111'11111111
>
> One scenario that I can see from the top of my head would be user
> running
>
> ethtool -s <dev> advertise 0x...
The "0x..." here would be the *value* in the NLA_BITFIELD32 parlance,
right?
What would the "selector" be? I assume the selector would be "whatever
ethtool knows about"?
> with hex value representing some subset of link modes. Now if ethtool
> version is behind kernel and recognizes fewer link modes than kernel
> but in a way that the number rounded up to bytes or words would be the
> same, kernel has no way to recognize of those zero bits on top of the
> mask are zero on purpose or just because userspace doesn't know about
> them. In general, I believe the absence of bit length information is
> something protocols would have to work around sometimes.
>
> The submitted implementation doesn't have this problem as it can tell
> kernel "this is a list" (i.e. I'm not sending a value/mask pair, I want
> exactly these bits to be set).
OK, here I guess I see what you mean. You're saying if ethtool were to
send a value/mask of "0..0100/0..0111" you wouldn't know what to do with
BIT(4) as long as the kernel knows about that bit?
I guess the difference now is depending on the operation. NLA_BITFIELD32
is sort of built on the assumption of having a "toggle" operation. If
you want to have a "set to" operation, then you don't really need the
selector/mask at all, just the value.
johannes
^ permalink raw reply
* [PATCH net-next v2 0/4] qed*/devlink: Devlink support for config attributes.
From: Sudarsana Reddy Kalluru @ 2019-07-04 13:20 UTC (permalink / raw)
To: davem; +Cc: netdev, mkalderon, aelior
The patch series adds support for managing the config attributes using
devlink interfaces.
Patch (1) adds the APIs for publishing the devlink port params. Clubbing
this qed patches as per the review comment (i.e., need at least one
consumer for the new APIs).
Patches (2)-(4) adds the qed/qede devlink support for managing the
device/port attributes.
Please consider applying it to 'net-next' tree.
Sudarsana Reddy Kalluru (4):
devlink: Add APIs to publish/unpublish the port parameters.
qed: Add APIs for device attributes configuration.
qed*: Add new file for devlink implementation.
qed*: Add devlink support for configuration attributes.
Documentation/networking/devlink-params-qede.txt | 72 ++++++
drivers/net/ethernet/qlogic/qed/qed.h | 1 -
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 17 ++
drivers/net/ethernet/qlogic/qed/qed_main.c | 160 ++++--------
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 64 +++++
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 14 ++
drivers/net/ethernet/qlogic/qede/Makefile | 2 +-
drivers/net/ethernet/qlogic/qede/qede.h | 5 +
drivers/net/ethernet/qlogic/qede/qede_devlink.c | 294 +++++++++++++++++++++++
drivers/net/ethernet/qlogic/qede/qede_devlink.h | 41 ++++
drivers/net/ethernet/qlogic/qede/qede_main.c | 13 +
include/linux/qed/qed_if.h | 19 ++
include/net/devlink.h | 2 +
net/core/devlink.c | 42 ++++
14 files changed, 634 insertions(+), 112 deletions(-)
create mode 100644 Documentation/networking/devlink-params-qede.txt
create mode 100644 drivers/net/ethernet/qlogic/qede/qede_devlink.c
create mode 100644 drivers/net/ethernet/qlogic/qede/qede_devlink.h
--
1.8.3.1
^ permalink raw reply
* [PATCH net-next v2 1/4] devlink: Add APIs to publish/unpublish the port parameters.
From: Sudarsana Reddy Kalluru @ 2019-07-04 13:20 UTC (permalink / raw)
To: davem; +Cc: netdev, mkalderon, aelior
In-Reply-To: <20190704132011.13600-1-skalluru@marvell.com>
Kernel has no interface to publish the devlink port parameters. This is
required for exporting the port params to the user space, so that user
can read or update the port params.
This patch adds devlink interfaces (for drivers) to publish/unpublish the
devlink port parameters.
Signed-off-by: Sudarsana Reddy Kalluru <skalluru@marvell.com>
Signed-off-by: Ariel Elior <aelior@marvell.com>
---
include/net/devlink.h | 2 ++
net/core/devlink.c | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 6625ea0..47a1e8f 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -653,6 +653,8 @@ int devlink_port_params_register(struct devlink_port *devlink_port,
void devlink_port_params_unregister(struct devlink_port *devlink_port,
const struct devlink_param *params,
size_t params_count);
+void devlink_port_params_publish(struct devlink_port *devlink_port);
+void devlink_port_params_unpublish(struct devlink_port *ddevlink_port);
int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
union devlink_param_value *init_val);
int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 89c5337..0cd7994 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -6380,6 +6380,48 @@ void devlink_port_params_unregister(struct devlink_port *devlink_port,
}
EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
+/**
+ * devlink_port_params_publish - publish port configuration parameters
+ *
+ * @devlink_port: devlink port
+ *
+ * Publish previously registered port configuration parameters.
+ */
+void devlink_port_params_publish(struct devlink_port *devlink_port)
+{
+ struct devlink_param_item *param_item;
+
+ list_for_each_entry(param_item, &devlink_port->param_list, list) {
+ if (param_item->published)
+ continue;
+ param_item->published = true;
+ devlink_param_notify(devlink_port->devlink, devlink_port->index,
+ param_item, DEVLINK_CMD_PORT_PARAM_NEW);
+ }
+}
+EXPORT_SYMBOL_GPL(devlink_port_params_publish);
+
+/**
+ * devlink_port_params_unpublish - unpublish port configuration parameters
+ *
+ * @devlink_port: devlink port
+ *
+ * Unpublish previously registered port configuration parameters.
+ */
+void devlink_port_params_unpublish(struct devlink_port *devlink_port)
+{
+ struct devlink_param_item *param_item;
+
+ list_for_each_entry(param_item, &devlink_port->param_list, list) {
+ if (!param_item->published)
+ continue;
+ param_item->published = false;
+ devlink_param_notify(devlink_port->devlink, devlink_port->index,
+ param_item, DEVLINK_CMD_PORT_PARAM_DEL);
+ }
+}
+EXPORT_SYMBOL_GPL(devlink_port_params_unpublish);
+
static int
__devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
union devlink_param_value *init_val)
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v2 2/4] qed: Add APIs for device attributes configuration.
From: Sudarsana Reddy Kalluru @ 2019-07-04 13:20 UTC (permalink / raw)
To: davem; +Cc: netdev, mkalderon, aelior
In-Reply-To: <20190704132011.13600-1-skalluru@marvell.com>
The patch adds driver APIs for reading/configuring the device attributes.
Signed-off-by: Sudarsana Reddy Kalluru <skalluru@marvell.com>
Signed-off-by: Ariel Elior <aelior@marvell.com>
---
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 17 ++++++++
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 64 +++++++++++++++++++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 14 +++++++
3 files changed, 95 insertions(+)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index e054f6c..557a12e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -12580,6 +12580,8 @@ struct public_drv_mb {
#define DRV_MSG_CODE_BW_UPDATE_ACK 0x32000000
#define DRV_MSG_CODE_NIG_DRAIN 0x30000000
#define DRV_MSG_CODE_S_TAG_UPDATE_ACK 0x3b000000
+#define DRV_MSG_CODE_GET_NVM_CFG_OPTION 0x003e0000
+#define DRV_MSG_CODE_SET_NVM_CFG_OPTION 0x003f0000
#define DRV_MSG_CODE_INITIATE_PF_FLR 0x02010000
#define DRV_MSG_CODE_VF_DISABLED_DONE 0xc0000000
#define DRV_MSG_CODE_CFG_VF_MSIX 0xc0010000
@@ -12748,6 +12750,21 @@ struct public_drv_mb {
#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002
#define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_SHIFT 0
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_MASK 0x0000FFFF
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_SHIFT 16
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_MASK 0x00010000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_SHIFT 17
+#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_MASK 0x00020000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_SHIFT 18
+#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_MASK 0x00040000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_SHIFT 19
+#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_MASK 0x00080000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_SHIFT 20
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_MASK 0x00100000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_SHIFT 24
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_MASK 0x0f000000
+
u32 fw_mb_header;
#define FW_MSG_CODE_MASK 0xffff0000
#define FW_MSG_CODE_UNSUPPORTED 0x00000000
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 758702c..573911a 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -3750,3 +3750,67 @@ int qed_mcp_get_ppfid_bitmap(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
return 0;
}
+
+int qed_mcp_nvm_get_cfg(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ u16 option_id, u8 entity_id, u16 flags, u8 *p_buf,
+ u32 *p_len)
+{
+ u32 mb_param = 0, resp, param;
+ int rc;
+
+ QED_MFW_SET_FIELD(mb_param, DRV_MB_PARAM_NVM_CFG_OPTION_ID, option_id);
+ if (flags & QED_NVM_CFG_OPTION_INIT)
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_INIT, 1);
+ if (flags & QED_NVM_CFG_OPTION_FREE)
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_FREE, 1);
+ if (flags & QED_NVM_CFG_OPTION_ENTITY_SEL) {
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL, 1);
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID,
+ entity_id);
+ }
+
+ rc = qed_mcp_nvm_rd_cmd(p_hwfn, p_ptt,
+ DRV_MSG_CODE_GET_NVM_CFG_OPTION,
+ mb_param, &resp, ¶m, p_len, (u32 *)p_buf);
+
+ return rc;
+}
+
+int qed_mcp_nvm_set_cfg(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ u16 option_id, u8 entity_id, u16 flags, u8 *p_buf,
+ u32 len)
+{
+ u32 mb_param = 0, resp, param;
+ int rc;
+
+ QED_MFW_SET_FIELD(mb_param, DRV_MB_PARAM_NVM_CFG_OPTION_ID, option_id);
+ if (flags & QED_NVM_CFG_OPTION_ALL)
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_ALL, 1);
+ if (flags & QED_NVM_CFG_OPTION_INIT)
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_INIT, 1);
+ if (flags & QED_NVM_CFG_OPTION_COMMIT)
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT, 1);
+ if (flags & QED_NVM_CFG_OPTION_FREE)
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_FREE, 1);
+ if (flags & QED_NVM_CFG_OPTION_ENTITY_SEL) {
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL, 1);
+ QED_MFW_SET_FIELD(mb_param,
+ DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID,
+ entity_id);
+ }
+
+ rc = qed_mcp_nvm_wr_cmd(p_hwfn, p_ptt,
+ DRV_MSG_CODE_SET_NVM_CFG_OPTION,
+ mb_param, &resp, ¶m, len, (u32 *)p_buf);
+
+ return rc;
+}
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
index e4f8fe4..550b4dd 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
@@ -251,6 +251,12 @@ struct qed_mfw_tlv_generic {
struct qed_mfw_tlv_iscsi iscsi;
};
+#define QED_NVM_CFG_OPTION_ALL BIT(0)
+#define QED_NVM_CFG_OPTION_INIT BIT(1)
+#define QED_NVM_CFG_OPTION_COMMIT BIT(2)
+#define QED_NVM_CFG_OPTION_FREE BIT(3)
+#define QED_NVM_CFG_OPTION_ENTITY_SEL BIT(4)
+
/**
* @brief - returns the link params of the hw function
*
@@ -1202,4 +1208,12 @@ void qed_mcp_resc_lock_default_init(struct qed_resc_lock_params *p_lock,
*/
int qed_mcp_get_ppfid_bitmap(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
+int qed_mcp_nvm_get_cfg(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ u16 option_id, u8 entity_id, u16 flags, u8 *p_buf,
+ u32 *p_len);
+
+int qed_mcp_nvm_set_cfg(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+ u16 option_id, u8 entity_id, u16 flags, u8 *p_buf,
+ u32 len);
+
#endif
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v2 3/4] qed*: Add new file for devlink implementation.
From: Sudarsana Reddy Kalluru @ 2019-07-04 13:20 UTC (permalink / raw)
To: davem; +Cc: netdev, mkalderon, aelior
In-Reply-To: <20190704132011.13600-1-skalluru@marvell.com>
Moving devlink implementation from qed to qede driver. The change is
required as qede is the actual PCI driver and qed is only the control
driver.
Signed-off-by: Sudarsana Reddy Kalluru <skalluru@marvell.com>
Signed-off-by: Ariel Elior <aelior@marvell.com>
---
drivers/net/ethernet/qlogic/qed/qed.h | 1 -
drivers/net/ethernet/qlogic/qed/qed_main.c | 122 +++---------------------
drivers/net/ethernet/qlogic/qede/Makefile | 2 +-
drivers/net/ethernet/qlogic/qede/qede.h | 2 +
drivers/net/ethernet/qlogic/qede/qede_devlink.c | 94 ++++++++++++++++++
drivers/net/ethernet/qlogic/qede/qede_devlink.h | 18 ++++
drivers/net/ethernet/qlogic/qede/qede_main.c | 13 +++
include/linux/qed/qed_if.h | 3 +
8 files changed, 143 insertions(+), 112 deletions(-)
create mode 100644 drivers/net/ethernet/qlogic/qede/qede_devlink.c
create mode 100644 drivers/net/ethernet/qlogic/qede/qede_devlink.h
diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 89fe091..cebd822 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -864,7 +864,6 @@ struct qed_dev {
u32 rdma_max_srq_sge;
u16 tunn_feature_mask;
- struct devlink *dl;
bool iwarp_cmt;
};
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 829dd60..f0183e2 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -48,7 +48,6 @@
#include <linux/crc32.h>
#include <linux/qed/qed_if.h>
#include <linux/qed/qed_ll2_if.h>
-#include <net/devlink.h>
#include "qed.h"
#include "qed_sriov.h"
@@ -343,107 +342,6 @@ static int qed_set_power_state(struct qed_dev *cdev, pci_power_t state)
return 0;
}
-struct qed_devlink {
- struct qed_dev *cdev;
-};
-
-enum qed_devlink_param_id {
- QED_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
- QED_DEVLINK_PARAM_ID_IWARP_CMT,
-};
-
-static int qed_dl_param_get(struct devlink *dl, u32 id,
- struct devlink_param_gset_ctx *ctx)
-{
- struct qed_devlink *qed_dl;
- struct qed_dev *cdev;
-
- qed_dl = devlink_priv(dl);
- cdev = qed_dl->cdev;
- ctx->val.vbool = cdev->iwarp_cmt;
-
- return 0;
-}
-
-static int qed_dl_param_set(struct devlink *dl, u32 id,
- struct devlink_param_gset_ctx *ctx)
-{
- struct qed_devlink *qed_dl;
- struct qed_dev *cdev;
-
- qed_dl = devlink_priv(dl);
- cdev = qed_dl->cdev;
- cdev->iwarp_cmt = ctx->val.vbool;
-
- return 0;
-}
-
-static const struct devlink_param qed_devlink_params[] = {
- DEVLINK_PARAM_DRIVER(QED_DEVLINK_PARAM_ID_IWARP_CMT,
- "iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
- BIT(DEVLINK_PARAM_CMODE_RUNTIME),
- qed_dl_param_get, qed_dl_param_set, NULL),
-};
-
-static const struct devlink_ops qed_dl_ops;
-
-static int qed_devlink_register(struct qed_dev *cdev)
-{
- union devlink_param_value value;
- struct qed_devlink *qed_dl;
- struct devlink *dl;
- int rc;
-
- dl = devlink_alloc(&qed_dl_ops, sizeof(*qed_dl));
- if (!dl)
- return -ENOMEM;
-
- qed_dl = devlink_priv(dl);
-
- cdev->dl = dl;
- qed_dl->cdev = cdev;
-
- rc = devlink_register(dl, &cdev->pdev->dev);
- if (rc)
- goto err_free;
-
- rc = devlink_params_register(dl, qed_devlink_params,
- ARRAY_SIZE(qed_devlink_params));
- if (rc)
- goto err_unregister;
-
- value.vbool = false;
- devlink_param_driverinit_value_set(dl,
- QED_DEVLINK_PARAM_ID_IWARP_CMT,
- value);
-
- devlink_params_publish(dl);
- cdev->iwarp_cmt = false;
-
- return 0;
-
-err_unregister:
- devlink_unregister(dl);
-
-err_free:
- cdev->dl = NULL;
- devlink_free(dl);
-
- return rc;
-}
-
-static void qed_devlink_unregister(struct qed_dev *cdev)
-{
- if (!cdev->dl)
- return;
-
- devlink_params_unregister(cdev->dl, qed_devlink_params,
- ARRAY_SIZE(qed_devlink_params));
-
- devlink_unregister(cdev->dl);
- devlink_free(cdev->dl);
-}
-
/* probing */
static struct qed_dev *qed_probe(struct pci_dev *pdev,
struct qed_probe_params *params)
@@ -472,12 +370,6 @@ static struct qed_dev *qed_probe(struct pci_dev *pdev,
}
DP_INFO(cdev, "PCI init completed successfully\n");
- rc = qed_devlink_register(cdev);
- if (rc) {
- DP_INFO(cdev, "Failed to register devlink.\n");
- goto err2;
- }
-
rc = qed_hw_prepare(cdev, QED_PCI_DEFAULT);
if (rc) {
DP_ERR(cdev, "hw prepare failed\n");
@@ -507,8 +399,6 @@ static void qed_remove(struct qed_dev *cdev)
qed_set_power_state(cdev, PCI_D3hot);
- qed_devlink_unregister(cdev);
-
qed_free_cdev(cdev);
}
@@ -2488,6 +2378,16 @@ static u8 qed_get_affin_hwfn_idx(struct qed_dev *cdev)
return QED_AFFIN_HWFN_IDX(cdev);
}
+static bool qed_get_iwarp_cmt(struct qed_dev *cdev)
+{
+ return cdev->iwarp_cmt;
+}
+
+static void qed_set_iwarp_cmt(struct qed_dev *cdev, bool iwarp_cmt)
+{
+ cdev->iwarp_cmt = iwarp_cmt;
+}
+
static struct qed_selftest_ops qed_selftest_ops_pass = {
.selftest_memory = &qed_selftest_memory,
.selftest_interrupt = &qed_selftest_interrupt,
@@ -2536,6 +2436,8 @@ static u8 qed_get_affin_hwfn_idx(struct qed_dev *cdev)
.db_recovery_del = &qed_db_recovery_del,
.read_module_eeprom = &qed_read_module_eeprom,
.get_affin_hwfn_idx = &qed_get_affin_hwfn_idx,
+ .get_iwarp_cmt = &qed_get_iwarp_cmt,
+ .set_iwarp_cmt = &qed_set_iwarp_cmt,
};
void qed_get_protocol_stats(struct qed_dev *cdev,
diff --git a/drivers/net/ethernet/qlogic/qede/Makefile b/drivers/net/ethernet/qlogic/qede/Makefile
index 3fc91d1..4585864 100644
--- a/drivers/net/ethernet/qlogic/qede/Makefile
+++ b/drivers/net/ethernet/qlogic/qede/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_QEDE) := qede.o
-qede-y := qede_main.o qede_fp.o qede_filter.o qede_ethtool.o qede_ptp.o
+qede-y := qede_main.o qede_fp.o qede_filter.o qede_ethtool.o qede_ptp.o qede_devlink.o
qede-$(CONFIG_DCB) += qede_dcbnl.o
qede-$(CONFIG_QED_RDMA) += qede_rdma.o
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index b972ab0..35ad5cd 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -262,6 +262,8 @@ struct qede_dev {
struct qede_rdma_dev rdma_info;
struct bpf_prog *xdp_prog;
+
+ struct devlink *dl;
};
enum QEDE_STATE {
diff --git a/drivers/net/ethernet/qlogic/qede/qede_devlink.c b/drivers/net/ethernet/qlogic/qede/qede_devlink.c
new file mode 100644
index 0000000..3f362ac
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qede/qede_devlink.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "qede.h"
+#include "qede_devlink.h"
+
+static int qede_dl_param_get(struct devlink *dl, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct qede_devlink *qede_dl;
+ struct qede_dev *edev;
+
+ qede_dl = devlink_priv(dl);
+ edev = qede_dl->edev;
+ ctx->val.vbool = edev->ops->common->get_iwarp_cmt(edev->cdev);
+
+ return 0;
+}
+
+static int qede_dl_param_set(struct devlink *dl, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ struct qede_devlink *qede_dl;
+ struct qede_dev *edev;
+
+ qede_dl = devlink_priv(dl);
+ edev = qede_dl->edev;
+ edev->ops->common->set_iwarp_cmt(edev->cdev, ctx->val.vbool);
+
+ return 0;
+}
+
+static const struct devlink_param qede_devlink_params[] = {
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_PARAM_ID_IWARP_CMT,
+ "iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+ qede_dl_param_get, qede_dl_param_set, NULL),
+};
+
+static const struct devlink_ops qede_dl_ops;
+
+int qede_devlink_register(struct qede_dev *edev)
+{
+ union devlink_param_value value;
+ struct qede_devlink *qede_dl;
+ struct devlink *dl;
+ int rc;
+
+ dl = devlink_alloc(&qede_dl_ops, sizeof(*qede_dl));
+ if (!dl)
+ return -ENOMEM;
+
+ qede_dl = devlink_priv(dl);
+
+ edev->dl = dl;
+ qede_dl->edev = edev;
+
+ rc = devlink_register(dl, &edev->pdev->dev);
+ if (rc)
+ goto err_free;
+
+ rc = devlink_params_register(dl, qede_devlink_params,
+ ARRAY_SIZE(qede_devlink_params));
+ if (rc)
+ goto err_unregister;
+
+ value.vbool = false;
+ devlink_param_driverinit_value_set(dl, QEDE_DEVLINK_PARAM_ID_IWARP_CMT,
+ value);
+
+ devlink_params_publish(dl);
+ edev->ops->common->set_iwarp_cmt(edev->cdev, false);
+
+ return 0;
+
+err_unregister:
+ devlink_unregister(dl);
+
+err_free:
+ edev->dl = NULL;
+ devlink_free(dl);
+
+ return rc;
+}
+
+void qede_devlink_unregister(struct qede_dev *edev)
+{
+ if (!edev->dl)
+ return;
+
+ devlink_params_unregister(edev->dl, qede_devlink_params,
+ ARRAY_SIZE(qede_devlink_params));
+
+ devlink_unregister(edev->dl);
+ devlink_free(edev->dl);
+}
diff --git a/drivers/net/ethernet/qlogic/qede/qede_devlink.h b/drivers/net/ethernet/qlogic/qede/qede_devlink.h
new file mode 100644
index 0000000..5aa79dd
--- /dev/null
+++ b/drivers/net/ethernet/qlogic/qede/qede_devlink.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _QEDE_DEVLINK_H
+#define _QEDE_DEVLINK_H
+#include <net/devlink.h>
+
+struct qede_devlink {
+ struct qede_dev *edev;
+};
+
+enum qede_devlink_param_id {
+ QEDE_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+ QEDE_DEVLINK_PARAM_ID_IWARP_CMT,
+};
+
+int qede_devlink_register(struct qede_dev *edev);
+void qede_devlink_unregister(struct qede_dev *edev);
+
+#endif
diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index d4a2966..cef946f 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -62,6 +62,7 @@
#include <linux/vmalloc.h>
#include "qede.h"
#include "qede_ptp.h"
+#include "qede_devlink.h"
static char version[] =
"QLogic FastLinQ 4xxxx Ethernet Driver qede " DRV_MODULE_VERSION "\n";
@@ -1177,8 +1178,18 @@ static int __qede_probe(struct pci_dev *pdev, u32 dp_module, u8 dp_level,
edev->rx_copybreak = QEDE_RX_HDR_SIZE;
qede_log_probe(edev);
+
+ rc = qede_devlink_register(edev);
+ if (rc) {
+ DP_INFO(edev, "Failed to register devlink.\n");
+ goto err5;
+ }
+
return 0;
+err5:
+ if (!is_vf)
+ qede_ptp_disable(edev);
err4:
qede_rdma_dev_remove(edev, (mode == QEDE_PROBE_RECOVERY));
err3:
@@ -1227,6 +1238,8 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
DP_INFO(edev, "Starting qede_remove\n");
+ qede_devlink_unregister(edev);
+
qede_rdma_dev_remove(edev, (mode == QEDE_REMOVE_RECOVERY));
if (mode != QEDE_REMOVE_RECOVERY) {
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index eef02e6..7c41304 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -1131,6 +1131,9 @@ struct qed_common_ops {
* @param cdev
*/
u8 (*get_affin_hwfn_idx)(struct qed_dev *cdev);
+
+ bool (*get_iwarp_cmt)(struct qed_dev *cdev);
+ void (*set_iwarp_cmt)(struct qed_dev *cdev, bool iwarp_cmt);
};
#define MASK_FIELD(_name, _value) \
--
1.8.3.1
^ permalink raw reply related
* [PATCH net-next v2 4/4] qed*: Add devlink support for configuration attributes.
From: Sudarsana Reddy Kalluru @ 2019-07-04 13:20 UTC (permalink / raw)
To: davem; +Cc: netdev, mkalderon, aelior
In-Reply-To: <20190704132011.13600-1-skalluru@marvell.com>
This patch adds implementation for devlink callbacks for reading and
configuring the device attributes.
Signed-off-by: Sudarsana Reddy Kalluru <skalluru@marvell.com>
Signed-off-by: Ariel Elior <aelior@marvell.com>
---
Documentation/networking/devlink-params-qede.txt | 72 ++++++++
drivers/net/ethernet/qlogic/qed/qed_main.c | 38 +++++
drivers/net/ethernet/qlogic/qede/qede.h | 3 +
drivers/net/ethernet/qlogic/qede/qede_devlink.c | 202 ++++++++++++++++++++++-
drivers/net/ethernet/qlogic/qede/qede_devlink.h | 23 +++
include/linux/qed/qed_if.h | 16 ++
6 files changed, 353 insertions(+), 1 deletion(-)
create mode 100644 Documentation/networking/devlink-params-qede.txt
diff --git a/Documentation/networking/devlink-params-qede.txt b/Documentation/networking/devlink-params-qede.txt
new file mode 100644
index 0000000..f78a993
--- /dev/null
+++ b/Documentation/networking/devlink-params-qede.txt
@@ -0,0 +1,72 @@
+enable_sriov [DEVICE, GENERIC]
+ Configuration mode: Permanent
+
+iwarp_cmt [DEVICE, DRIVER-SPECIFIC]
+ Enable iWARP support over 100G device (CMT mode).
+ Type: Boolean
+ Configuration mode: runtime
+
+entity_id [DEVICE, DRIVER-SPECIFIC]
+ Set the entity ID value to be used for this device
+ while reading/configuring the devlink attributes.
+ Type: u8
+ Configuration mode: runtime
+
+device_capabilities [DEVICE, DRIVER-SPECIFIC]
+ Set the entity ID value to be used for this device
+ while reading/configuring the devlink attributes.
+ Type: u8
+ Configuration mode: runtime
+
+mf_mode [DEVICE, DRIVER-SPECIFIC]
+ Configure Multi Function mode for the device.
+ Supported MF modes and the assoicated values are,
+ MF allowed(0), Default(1), SPIO4(2), NPAR1.0(3),
+ NPAR1.5(4), NPAR2.0(5), BD(6) and UFP(7)
+ Type: u8
+ Configuration mode: Permanent
+
+dcbx_mode [PORT, DRIVER-SPECIFIC]
+ Configure DCBX mode for the device.
+ Supported dcbx modes are,
+ Disabled(0), IEEE(1), CEE(2) and Dynamic(3)
+ Type: u8
+ Configuration mode: Permanent
+
+preboot_oprom [PORT, DRIVER-SPECIFIC]
+ Enable Preboot Option ROM.
+ Type: Boolean
+ Configuration mode: Permanent
+
+preboot_boot_protocol [PORT, DRIVER-SPECIFIC]
+ Configure preboot Boot protocol.
+ Possible values are,
+ PXE(0), iSCSI Boot(3), FCoE Boot(4) and NONE(7)
+ Type: u8
+ Configuration mode: Permanent
+
+preboot_vlan [PORT, DRIVER-SPECIFIC]
+ Preboot VLAN.
+ Type: u16
+ Configuration mode: Permanent
+
+preboot_vlan_value [PORT, DRIVER-SPECIFIC]
+ Configure Preboot VLAN value.
+ Type: u16
+ Configuration mode: Permanent
+
+mba_delay_time [PORT, DRIVER-SPECIFIC]
+ Configure MBA Delay Time. Supported range is [0-15].
+ Type: u8
+ Configuration mode: Permanent
+
+mba_setup_hot_key [PORT, DRIVER-SPECIFIC]
+ Configure MBA setup Hot Key. Possible values are,
+ Ctrl S(0) and Ctrl B(1).
+ Type: u8
+ Configuration mode: Permanent
+
+mba_hide_setup_prompt [PORT, DRIVER-SPECIFIC]
+ Configure MBA hide setup prompt.
+ Type: Boolean
+ Configuration mode: Permanent
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index f0183e2..3d43140 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -2388,6 +2388,42 @@ static void qed_set_iwarp_cmt(struct qed_dev *cdev, bool iwarp_cmt)
cdev->iwarp_cmt = iwarp_cmt;
}
+static int qed_get_cfg_attr(struct qed_dev *cdev, u16 cmd, u8 entity, u32 flags,
+ u8 *buf, int *len)
+{
+ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
+ struct qed_ptt *ptt;
+ int status = 0;
+
+ ptt = qed_ptt_acquire(hwfn);
+ if (!ptt)
+ return -EAGAIN;
+
+ status = qed_mcp_nvm_get_cfg(hwfn, ptt, cmd, entity, flags, buf, len);
+
+ qed_ptt_release(hwfn, ptt);
+
+ return status;
+}
+
+static int qed_set_cfg_attr(struct qed_dev *cdev, u16 cmd, u8 entity, u32 flags,
+ u8 *buf, int len)
+{
+ struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
+ struct qed_ptt *ptt;
+ int status = 0;
+
+ ptt = qed_ptt_acquire(hwfn);
+ if (!ptt)
+ return -EAGAIN;
+
+ status = qed_mcp_nvm_set_cfg(hwfn, ptt, cmd, entity, flags, buf, len);
+
+ qed_ptt_release(hwfn, ptt);
+
+ return status;
+}
+
static struct qed_selftest_ops qed_selftest_ops_pass = {
.selftest_memory = &qed_selftest_memory,
.selftest_interrupt = &qed_selftest_interrupt,
@@ -2438,6 +2474,8 @@ static void qed_set_iwarp_cmt(struct qed_dev *cdev, bool iwarp_cmt)
.get_affin_hwfn_idx = &qed_get_affin_hwfn_idx,
.get_iwarp_cmt = &qed_get_iwarp_cmt,
.set_iwarp_cmt = &qed_set_iwarp_cmt,
+ .get_cfg_attr = &qed_get_cfg_attr,
+ .set_cfg_attr = &qed_set_cfg_attr,
};
void qed_get_protocol_stats(struct qed_dev *cdev,
diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h
index 35ad5cd..e175d30 100644
--- a/drivers/net/ethernet/qlogic/qede/qede.h
+++ b/drivers/net/ethernet/qlogic/qede/qede.h
@@ -54,6 +54,7 @@
#include <net/pkt_cls.h>
#include <net/tc_act/tc_gact.h>
+#include <net/devlink.h>
#define QEDE_MAJOR_VERSION 8
#define QEDE_MINOR_VERSION 37
@@ -264,6 +265,8 @@ struct qede_dev {
struct bpf_prog *xdp_prog;
struct devlink *dl;
+ struct devlink_port dl_port;
+ u8 cfg_entity_id;
};
enum QEDE_STATE {
diff --git a/drivers/net/ethernet/qlogic/qede/qede_devlink.c b/drivers/net/ethernet/qlogic/qede/qede_devlink.c
index 3f362ac..076a66a 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_devlink.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_devlink.c
@@ -2,6 +2,31 @@
#include "qede.h"
#include "qede_devlink.h"
+static const struct qede_devlink_cfg_param cfg_params[] = {
+ {DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV, QED_NVM_CFG_ID_ENABLE_SRIOV,
+ DEVLINK_PARAM_TYPE_BOOL},
+ {QEDE_DEVLINK_ENTITY_ID, 0, DEVLINK_PARAM_TYPE_U8},
+ {QEDE_DEVLINK_DEVICE_CAPABILITIES,
+ QED_NVM_CFG_ID_DEVICE_CAPABILITIES, DEVLINK_PARAM_TYPE_U8},
+ {QEDE_DEVLINK_MF_MODE, QED_NVM_CFG_ID_MF_MODE, DEVLINK_PARAM_TYPE_U8},
+ {QEDE_DEVLINK_DCBX_MODE, QED_NVM_CFG_ID_DCBX_MODE,
+ DEVLINK_PARAM_TYPE_U8},
+ {QEDE_DEVLINK_PREBOOT_OPROM, QED_NVM_CFG_ID_PREBOOT_OPROM,
+ DEVLINK_PARAM_TYPE_BOOL},
+ {QEDE_DEVLINK_PREBOOT_BOOT_PROTOCOL,
+ QED_NVM_CFG_ID_PREBOOT_BOOT_PROTOCOL, DEVLINK_PARAM_TYPE_U8},
+ {QEDE_DEVLINK_PREBOOT_VLAN, QED_NVM_CFG_ID_PREBOOT_VLAN,
+ DEVLINK_PARAM_TYPE_U16},
+ {QEDE_DEVLINK_PREBOOT_VLAN_VALUE, QED_NVM_CFG_ID_PREBOOT_VLAN_VALUE,
+ DEVLINK_PARAM_TYPE_U16},
+ {QEDE_DEVLINK_MBA_DELAY_TIME, QED_NVM_CFG_ID_MBA_DELAY_TIME,
+ DEVLINK_PARAM_TYPE_U8},
+ {QEDE_DEVLINK_MBA_SETUP_HOT_KEY, QED_NVM_CFG_ID_MBA_SETUP_HOT_KEY,
+ DEVLINK_PARAM_TYPE_U8},
+ {QEDE_DEVLINK_MBA_HIDE_SETUP_PROMPT,
+ QED_NVM_CFG_ID_MBA_HIDE_SETUP_PROMPT, DEVLINK_PARAM_TYPE_BOOL},
+};
+
static int qede_dl_param_get(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx)
{
@@ -28,11 +53,159 @@ static int qede_dl_param_set(struct devlink *dl, u32 id,
return 0;
}
+static int qede_dl_get_perm_cfg(struct devlink *dl, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ u8 buf[QEDE_DL_PARAM_BUF_LEN];
+ struct qede_devlink *qede_dl;
+ int rc, idx, len = 0;
+ struct qede_dev *edev;
+ u32 flags;
+
+ qede_dl = devlink_priv(dl);
+ edev = qede_dl->edev;
+
+ if (id == QEDE_DEVLINK_ENTITY_ID) {
+ ctx->val.vu8 = edev->cfg_entity_id;
+ return 0;
+ }
+
+ for (idx = 0; idx < ARRAY_SIZE(cfg_params); idx++)
+ if (cfg_params[idx].id == id)
+ break;
+
+ if (idx == ARRAY_SIZE(cfg_params)) {
+ DP_ERR(edev, "Invalid command id %d\n", id);
+ return -EINVAL;
+ }
+
+ memset(buf, 0, QEDE_DL_PARAM_BUF_LEN);
+ flags = edev->cfg_entity_id ? QEDE_DL_PARAM_PF_GET_FLAGS :
+ QEDE_DL_PARAM_GET_FLAGS;
+
+ rc = edev->ops->common->get_cfg_attr(edev->cdev, cfg_params[idx].cmd,
+ edev->cfg_entity_id, flags, buf,
+ &len);
+ if (rc)
+ DP_ERR(edev, "Error = %d\n", rc);
+ else
+ memcpy(&ctx->val, buf, len);
+
+ return rc;
+}
+
+static int qede_dl_set_perm_cfg(struct devlink *dl, u32 id,
+ struct devlink_param_gset_ctx *ctx)
+{
+ u8 buf[QEDE_DL_PARAM_BUF_LEN];
+ struct qede_devlink *qede_dl;
+ int rc, idx, len = 0;
+ struct qede_dev *edev;
+ u32 flags;
+
+ qede_dl = devlink_priv(dl);
+ edev = qede_dl->edev;
+
+ if (id == QEDE_DEVLINK_ENTITY_ID) {
+ edev->cfg_entity_id = ctx->val.vu8;
+ return 0;
+ }
+
+ for (idx = 0; idx < ARRAY_SIZE(cfg_params); idx++)
+ if (cfg_params[idx].id == id)
+ break;
+
+ if (idx == ARRAY_SIZE(cfg_params)) {
+ DP_ERR(edev, "Invalid command id %d\n", id);
+ return -EINVAL;
+ }
+
+ memset(buf, 0, QEDE_DL_PARAM_BUF_LEN);
+ switch (cfg_params[idx].type) {
+ case DEVLINK_PARAM_TYPE_BOOL:
+ len = 1;
+ break;
+ case DEVLINK_PARAM_TYPE_U8:
+ len = 1;
+ break;
+ case DEVLINK_PARAM_TYPE_U16:
+ len = 2;
+ break;
+ case DEVLINK_PARAM_TYPE_U32:
+ len = 4;
+ break;
+ case DEVLINK_PARAM_TYPE_STRING:
+ len = strlen(ctx->val.vstr);
+ break;
+ }
+
+ memcpy(buf, &ctx->val, len);
+ flags = edev->cfg_entity_id ? QEDE_DL_PARAM_PF_SET_FLAGS :
+ QEDE_DL_PARAM_SET_FLAGS;
+
+ rc = edev->ops->common->set_cfg_attr(edev->cdev, cfg_params[idx].cmd,
+ edev->cfg_entity_id, flags, buf,
+ len);
+ if (rc)
+ DP_ERR(edev, "Error = %d\n", rc);
+
+ return rc;
+}
+
static const struct devlink_param qede_devlink_params[] = {
DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_PARAM_ID_IWARP_CMT,
"iwarp_cmt", DEVLINK_PARAM_TYPE_BOOL,
BIT(DEVLINK_PARAM_CMODE_RUNTIME),
qede_dl_param_get, qede_dl_param_set, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_ENTITY_ID,
+ "entity_id", DEVLINK_PARAM_TYPE_U8,
+ BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_GENERIC(ENABLE_SRIOV, BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_MF_MODE,
+ "mf_mode", DEVLINK_PARAM_TYPE_U8,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_DEVICE_CAPABILITIES,
+ "device_capabilities", DEVLINK_PARAM_TYPE_U8,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+};
+
+static const struct devlink_param qede_devlink_port_params[] = {
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_DCBX_MODE,
+ "dcbx_mode", DEVLINK_PARAM_TYPE_U8,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_PREBOOT_OPROM,
+ "preboot_oprom", DEVLINK_PARAM_TYPE_BOOL,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_PREBOOT_BOOT_PROTOCOL,
+ "preboot_boot_protocol", DEVLINK_PARAM_TYPE_U8,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_PREBOOT_VLAN,
+ "preboot_vlan", DEVLINK_PARAM_TYPE_U16,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_PREBOOT_VLAN_VALUE,
+ "preboot_vlan_value", DEVLINK_PARAM_TYPE_U16,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_MBA_DELAY_TIME,
+ "mba_delay_time", DEVLINK_PARAM_TYPE_U8,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_MBA_SETUP_HOT_KEY,
+ "mba_setup_hot_key", DEVLINK_PARAM_TYPE_U8,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
+ DEVLINK_PARAM_DRIVER(QEDE_DEVLINK_MBA_HIDE_SETUP_PROMPT,
+ "mba_hide_setup_prompt", DEVLINK_PARAM_TYPE_BOOL,
+ BIT(DEVLINK_PARAM_CMODE_PERMANENT),
+ qede_dl_get_perm_cfg, qede_dl_set_perm_cfg, NULL),
};
static const struct devlink_ops qede_dl_ops;
@@ -66,11 +239,34 @@ int qede_devlink_register(struct qede_dev *edev)
devlink_param_driverinit_value_set(dl, QEDE_DEVLINK_PARAM_ID_IWARP_CMT,
value);
+ devlink_port_attrs_set(&edev->dl_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
+ 0, false, 0, NULL, 0);
+ rc = devlink_port_register(dl, &edev->dl_port, 0);
+ if (rc) {
+ DP_ERR(edev, "devlink_port_register failed");
+ goto err_param_unregister;
+ }
+ devlink_port_type_eth_set(&edev->dl_port, edev->ndev);
+
+ rc = devlink_port_params_register(&edev->dl_port,
+ qede_devlink_port_params,
+ ARRAY_SIZE(qede_devlink_port_params));
+ if (rc) {
+ DP_ERR(edev, "devlink_port_params_register failed");
+ goto err_port_unregister;
+ }
+
devlink_params_publish(dl);
+ devlink_port_params_publish(&edev->dl_port);
edev->ops->common->set_iwarp_cmt(edev->cdev, false);
return 0;
+err_port_unregister:
+ devlink_port_unregister(&edev->dl_port);
+err_param_unregister:
+ devlink_params_unregister(edev->dl, qede_devlink_params,
+ ARRAY_SIZE(qede_devlink_params));
err_unregister:
devlink_unregister(dl);
@@ -86,9 +282,13 @@ void qede_devlink_unregister(struct qede_dev *edev)
if (!edev->dl)
return;
+ devlink_port_params_unpublish(&edev->dl_port);
+ devlink_params_unpublish(edev->dl);
+ devlink_port_params_unregister(&edev->dl_port, qede_devlink_port_params,
+ ARRAY_SIZE(qede_devlink_port_params));
devlink_params_unregister(edev->dl, qede_devlink_params,
ARRAY_SIZE(qede_devlink_params));
-
+ devlink_port_unregister(&edev->dl_port);
devlink_unregister(edev->dl);
devlink_free(edev->dl);
}
diff --git a/drivers/net/ethernet/qlogic/qede/qede_devlink.h b/drivers/net/ethernet/qlogic/qede/qede_devlink.h
index 5aa79dd..57b5fcc 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_devlink.h
+++ b/drivers/net/ethernet/qlogic/qede/qede_devlink.h
@@ -3,6 +3,12 @@
#define _QEDE_DEVLINK_H
#include <net/devlink.h>
+#define QEDE_DL_PARAM_GET_FLAGS 0xA
+#define QEDE_DL_PARAM_SET_FLAGS 0xE
+#define QEDE_DL_PARAM_PF_GET_FLAGS 0x1A
+#define QEDE_DL_PARAM_PF_SET_FLAGS 0x1E
+#define QEDE_DL_PARAM_BUF_LEN 32
+
struct qede_devlink {
struct qede_dev *edev;
};
@@ -10,6 +16,23 @@ struct qede_devlink {
enum qede_devlink_param_id {
QEDE_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
QEDE_DEVLINK_PARAM_ID_IWARP_CMT,
+ QEDE_DEVLINK_ENTITY_ID,
+ QEDE_DEVLINK_DEVICE_CAPABILITIES,
+ QEDE_DEVLINK_MF_MODE,
+ QEDE_DEVLINK_DCBX_MODE,
+ QEDE_DEVLINK_PREBOOT_OPROM,
+ QEDE_DEVLINK_PREBOOT_BOOT_PROTOCOL,
+ QEDE_DEVLINK_PREBOOT_VLAN,
+ QEDE_DEVLINK_PREBOOT_VLAN_VALUE,
+ QEDE_DEVLINK_MBA_DELAY_TIME,
+ QEDE_DEVLINK_MBA_SETUP_HOT_KEY,
+ QEDE_DEVLINK_MBA_HIDE_SETUP_PROMPT,
+};
+
+struct qede_devlink_cfg_param {
+ u16 id;
+ u16 cmd;
+ enum devlink_param_type type;
};
int qede_devlink_register(struct qede_dev *edev);
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index 7c41304..6430762 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -48,6 +48,18 @@
#include <linux/qed/qed_chain.h>
#include <linux/io-64-nonatomic-lo-hi.h>
+#define QED_NVM_CFG_ID_MF_MODE 9
+#define QED_NVM_CFG_ID_DCBX_MODE 26
+#define QED_NVM_CFG_ID_PREBOOT_OPROM 59
+#define QED_NVM_CFG_ID_MBA_DELAY_TIME 61
+#define QED_NVM_CFG_ID_MBA_SETUP_HOT_KEY 62
+#define QED_NVM_CFG_ID_MBA_HIDE_SETUP_PROMPT 63
+#define QED_NVM_CFG_ID_PREBOOT_BOOT_PROTOCOL 69
+#define QED_NVM_CFG_ID_ENABLE_SRIOV 70
+#define QED_NVM_CFG_ID_DEVICE_CAPABILITIES 117
+#define QED_NVM_CFG_ID_PREBOOT_VLAN_VALUE 132
+#define QED_NVM_CFG_ID_PREBOOT_VLAN 133
+
enum dcbx_protocol_type {
DCBX_PROTOCOL_ISCSI,
DCBX_PROTOCOL_FCOE,
@@ -1134,6 +1146,10 @@ struct qed_common_ops {
bool (*get_iwarp_cmt)(struct qed_dev *cdev);
void (*set_iwarp_cmt)(struct qed_dev *cdev, bool iwarp_cmt);
+ int (*get_cfg_attr)(struct qed_dev *cdev, u16 cmd, u8 entity, u32 flags,
+ u8 *buf, int *len);
+ int (*set_cfg_attr)(struct qed_dev *cdev, u16 cmd, u8 entity, u32 flags,
+ u8 *buf, int len);
};
#define MASK_FIELD(_name, _value) \
--
1.8.3.1
^ permalink raw reply related
* Re: i.mx6ul with DSA in multi chip addressing mode - no MDIO access
From: Andrew Lunn @ 2019-07-04 13:27 UTC (permalink / raw)
To: Benjamin Beckmeyer; +Cc: netdev
In-Reply-To: <d1181129-ec9d-01c1-3102-e1dc5dec0378@eks-engel.de>
On Thu, Jul 04, 2019 at 10:54:47AM +0200, Benjamin Beckmeyer wrote:
>
> On 03.07.19 17:55, Andrew Lunn wrote:
> > On Wed, Jul 03, 2019 at 03:10:34PM +0200, Benjamin Beckmeyer wrote:
> >> Hey folks,
> >>
> >> I'm having a problem with a custom i.mx6ul board. When DSA is loaded I can't
> >> get access to the switch via MDIO, but the DSA is working properly. I set up
> >> a bridge for testing and the switch is in forwarding mode and i can ping the
> >> board. But the MDIO access isn't working at address 2 for the switch. When I
> >> delete the DSA from the devicetree and start the board up, I can access the
> >> switch via MDIO.
> >>
> >> With DSA up and running:
> >>
> >> mii -i 2 0 0x9800
> >> mii -i 2 1
> >> phyid:2, reg:0x01 -> 0x4000
> >> mii -i 2 0 0x9803
> >> mii -i 2 1
> >> phyid:2, reg:0x01 -> 0x4000
> >> mii -i 2 1 0x1883
> >> mii -i 2 1
> >> phyid:2, reg:0x01 -> 0x4000
> > Hi Benjamin
> >
> > I'm guessing that the driver is also using register 0 and 1 at the
> > same time you are, e.g. to poll the PHYs for link status etc.
> >
> > There are trace points for MDIO, so you can get the kernel to log all
> > registers access. That should confirm if i'm right.
> >
> > Andrew
>
> Hi Andrew,
> you were absolutly right. The bus is really busy the whole time, I've
> checked that with the tracepoints in mdio_access.
>
> But I'm still wondering why isn't that with a single chip addressing
> mode configured switch? I mean, okay, the switch has more ports, but
> I've checked the accesses for both. The 6321(single chip addressing
> mode) has around 4-5 accesses to the MDIO bus and the 6390(multi chip
> addressing mode) has around 600 accesses per second.
Hi Benjamin
In single chip mode, reading a register is atomic. With multi-chip,
you need to access two registers, so it clearly is not atomic. And so
any other action on the bus will cause you problems when doing things
from user space without being able to take the register mutex.
But 4-5 vs 600 suggests you don't have the interrupt line in your
device tree. If you have the interrupt line connected to a GPIO, and
the driver knows about it, it has no need to poll the PHYs. I also
added support for 'polled interrupts', as a fall back when then
interrupt is not listed in device tree. 10 times a second the driver
polls the interrupt status register, and if any interrupts have
happened within the switch, it triggers the needed handlers. Reading
one status register every 100ms is much less effort than reading all
the PHY status registers once per second.
Still, 600 per second sounds too high. Do you have an SNMP agent
getting statistics?
Andrew
^ permalink raw reply
* Re: [PATCH net-next v5 5/5] selftests: tc-tests: actions: add MPLS tests
From: John Hurley @ 2019-07-04 13:40 UTC (permalink / raw)
To: Davide Caratti
Cc: Linux Netdev List, David Miller, Jiri Pirko, Cong Wang,
David Ahern, Willem de Bruijn, Simon Horman, Jakub Kicinski,
oss-drivers
In-Reply-To: <0130c56ef79f8bf360ddb0b01db5e7684f0bf62a.camel@redhat.com>
On Thu, Jul 4, 2019 at 9:40 AM Davide Caratti <dcaratti@redhat.com> wrote:
>
> On Wed, 2019-07-03 at 01:25 +0100, John Hurley wrote:
> > Add a new series of selftests to verify the functionality of act_mpls in
> > TC.
> >
> > Signed-off-by: John Hurley <john.hurley@netronome.com>
> > Reviewed-by: Simon Horman <simon.horman@netronome.com>
> > Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> > ---
> > .../tc-testing/tc-tests/actions/mpls.json | 812 +++++++++++++++++++++
> > 1 file changed, 812 insertions(+)
> > create mode 100644 tools/testing/selftests/tc-testing/tc-tests/actions/mpls.json
> >
>
> hello John,
>
> (sorry for noticing this late). some scripts use
>
> tools/testing/selftests/tc-testing/config
>
> to rebuild vmlinux before running TDC. I think you should add a line
> there that sets CONFIG_NET_ACT_MPLS=y.
>
> WDYT?
Hi Davide,
Thanks for pointing this out.
Yes, I'll add it.
Thanks
>
> thanks!
> --
> davide
>
^ permalink raw reply
* Re: [net-next 1/3] ice: Initialize and register platform device to provide RDMA
From: Greg KH @ 2019-07-04 13:46 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Jeff Kirsher, davem@davemloft.net, dledford@redhat.com,
Tony Nguyen, netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
nhorman@redhat.com, sassmann@redhat.com, poswald@suse.com,
mustafa.ismail@intel.com, shiraz.saleem@intel.com, Dave Ertman,
Andrew Bowers
In-Reply-To: <20190704124824.GK3401@mellanox.com>
On Thu, Jul 04, 2019 at 12:48:29PM +0000, Jason Gunthorpe wrote:
> On Thu, Jul 04, 2019 at 02:42:47PM +0200, Greg KH wrote:
> > On Thu, Jul 04, 2019 at 12:37:33PM +0000, Jason Gunthorpe wrote:
> > > On Thu, Jul 04, 2019 at 02:29:50PM +0200, Greg KH wrote:
> > > > On Thu, Jul 04, 2019 at 12:16:41PM +0000, Jason Gunthorpe wrote:
> > > > > On Wed, Jul 03, 2019 at 07:12:50PM -0700, Jeff Kirsher wrote:
> > > > > > From: Tony Nguyen <anthony.l.nguyen@intel.com>
> > > > > >
> > > > > > The RDMA block does not advertise on the PCI bus or any other bus.
> > > > > > Thus the ice driver needs to provide access to the RDMA hardware block
> > > > > > via a virtual bus; utilize the platform bus to provide this access.
> > > > > >
> > > > > > This patch initializes the driver to support RDMA as well as creates
> > > > > > and registers a platform device for the RDMA driver to register to. At
> > > > > > this point the driver is fully initialized to register a platform
> > > > > > driver, however, can not yet register as the ops have not been
> > > > > > implemented.
> > > > >
> > > > > I think you need Greg's ack on all this driver stuff - particularly
> > > > > that a platform_device is OK.
> > > >
> > > > A platform_device is almost NEVER ok.
> > > >
> > > > Don't abuse it, make a real device on a real bus. If you don't have a
> > > > real bus and just need to create a device to hang other things off of,
> > > > then use the virtual one, that's what it is there for.
> > >
> > > Ideally I'd like to see all the RDMA drivers that connect to ethernet
> > > drivers use some similar scheme.
> >
> > Why? They should be attached to a "real" device, why make any up?
>
> ? A "real" device, like struct pci_device, can only bind to one
> driver. How can we bind it concurrently to net, rdma, scsi, etc?
MFD was designed for this very problem.
> > > This is for a PCI device that plugs into multiple subsystems in the
> > > kernel, ie it has net driver functionality, rdma functionality, some
> > > even have SCSI functionality
> >
> > Sounds like a MFD device, why aren't you using that functionality
> > instead?
>
> This was also my advice, but in another email Jeff says:
>
> MFD architecture was also considered, and we selected the simpler
> platform model. Supporting a MFD architecture would require an
> additional MFD core driver, individual platform netdev, RDMA function
> drivers, and stripping a large portion of the netdev drivers into
> MFD core. The sub-devices registered by MFD core for function
> drivers are indeed platform devices.
So, "mfd is too hard, let's abuse a platform device" is ok?
People have been wanting to do MFD drivers for PCI devices for a long
time, it's about time someone actually did the work for it, I bet it
will not be all that complex if tiny embedded drivers can do it :)
thanks,
greg k-h
^ permalink raw reply
* Re: [net-next 1/3] ice: Initialize and register platform device to provide RDMA
From: Jason Gunthorpe @ 2019-07-04 13:53 UTC (permalink / raw)
To: Greg KH
Cc: Jeff Kirsher, davem@davemloft.net, dledford@redhat.com,
Tony Nguyen, netdev@vger.kernel.org, linux-rdma@vger.kernel.org,
nhorman@redhat.com, sassmann@redhat.com, poswald@suse.com,
mustafa.ismail@intel.com, shiraz.saleem@intel.com, Dave Ertman,
Andrew Bowers
In-Reply-To: <20190704134612.GB10963@kroah.com>
On Thu, Jul 04, 2019 at 03:46:12PM +0200, Greg KH wrote:
> On Thu, Jul 04, 2019 at 12:48:29PM +0000, Jason Gunthorpe wrote:
> > On Thu, Jul 04, 2019 at 02:42:47PM +0200, Greg KH wrote:
> > > On Thu, Jul 04, 2019 at 12:37:33PM +0000, Jason Gunthorpe wrote:
> > > > On Thu, Jul 04, 2019 at 02:29:50PM +0200, Greg KH wrote:
> > > > > On Thu, Jul 04, 2019 at 12:16:41PM +0000, Jason Gunthorpe wrote:
> > > > > > On Wed, Jul 03, 2019 at 07:12:50PM -0700, Jeff Kirsher wrote:
> > > > > > > From: Tony Nguyen <anthony.l.nguyen@intel.com>
> > > > > > >
> > > > > > > The RDMA block does not advertise on the PCI bus or any other bus.
> > > > > > > Thus the ice driver needs to provide access to the RDMA hardware block
> > > > > > > via a virtual bus; utilize the platform bus to provide this access.
> > > > > > >
> > > > > > > This patch initializes the driver to support RDMA as well as creates
> > > > > > > and registers a platform device for the RDMA driver to register to. At
> > > > > > > this point the driver is fully initialized to register a platform
> > > > > > > driver, however, can not yet register as the ops have not been
> > > > > > > implemented.
> > > > > >
> > > > > > I think you need Greg's ack on all this driver stuff - particularly
> > > > > > that a platform_device is OK.
> > > > >
> > > > > A platform_device is almost NEVER ok.
> > > > >
> > > > > Don't abuse it, make a real device on a real bus. If you don't have a
> > > > > real bus and just need to create a device to hang other things off of,
> > > > > then use the virtual one, that's what it is there for.
> > > >
> > > > Ideally I'd like to see all the RDMA drivers that connect to ethernet
> > > > drivers use some similar scheme.
> > >
> > > Why? They should be attached to a "real" device, why make any up?
> >
> > ? A "real" device, like struct pci_device, can only bind to one
> > driver. How can we bind it concurrently to net, rdma, scsi, etc?
>
> MFD was designed for this very problem.
>
> > > > This is for a PCI device that plugs into multiple subsystems in the
> > > > kernel, ie it has net driver functionality, rdma functionality, some
> > > > even have SCSI functionality
> > >
> > > Sounds like a MFD device, why aren't you using that functionality
> > > instead?
> >
> > This was also my advice, but in another email Jeff says:
> >
> > MFD architecture was also considered, and we selected the simpler
> > platform model. Supporting a MFD architecture would require an
> > additional MFD core driver, individual platform netdev, RDMA function
> > drivers, and stripping a large portion of the netdev drivers into
> > MFD core. The sub-devices registered by MFD core for function
> > drivers are indeed platform devices.
>
> So, "mfd is too hard, let's abuse a platform device" is ok?
>
> People have been wanting to do MFD drivers for PCI devices for a long
> time, it's about time someone actually did the work for it, I bet it
> will not be all that complex if tiny embedded drivers can do it :)
Okay, sounds like a NAK to me. I'll drop these patches from the RDMA
patchworks and Jeff can work through the MFD stuff first.
Jason
^ permalink raw reply
* Re: [PATCH v1 net-next] net: stmmac: enable clause 45 mdio support
From: Andrew Lunn @ 2019-07-04 13:54 UTC (permalink / raw)
To: Voon, Weifeng
Cc: David S. Miller, Maxime Coquelin, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, Jose Abreu, Giuseppe Cavallaro,
Florian Fainelli, Alexandre Torgue, biao huang, Ong, Boon Leong,
Kweh, Hock Leong
In-Reply-To: <D6759987A7968C4889FDA6FA91D5CBC81473862D@PGSMSX103.gar.corp.intel.com>
On Thu, Jul 04, 2019 at 06:05:23AM +0000, Voon, Weifeng wrote:
> > > > > @@ -155,22 +171,26 @@ static int stmmac_mdio_read(struct mii_bus
> > > > > *bus,
> > > > int phyaddr, int phyreg)
> > > > > struct stmmac_priv *priv = netdev_priv(ndev);
> > > > > unsigned int mii_address = priv->hw->mii.addr;
> > > > > unsigned int mii_data = priv->hw->mii.data;
> > > > > - u32 v;
> > > > > - int data;
> > > > > u32 value = MII_BUSY;
> > > > > + int data = 0;
> > > > > + u32 v;
> > > > >
> > > > > value |= (phyaddr << priv->hw->mii.addr_shift)
> > > > > & priv->hw->mii.addr_mask;
> > > > > value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw-
> > > > >mii.reg_mask;
> > > > > value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
> > > > > & priv->hw->mii.clk_csr_mask;
> > > > > - if (priv->plat->has_gmac4)
> > > > > + if (priv->plat->has_gmac4) {
> > > > > value |= MII_GMAC4_READ;
> > > > > + if (phyreg & MII_ADDR_C45)
> > > > > + stmmac_mdio_c45_setup(priv, phyreg, &value, &data);
> > > > > + }
> > > > >
> > > > > if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v &
> > > > MII_BUSY),
> > > > > 100, 10000))
> > > > > return -EBUSY;
> > > > >
> > > > > + writel(data, priv->ioaddr + mii_data);
> > > >
> > > > That looks odd. Could you explain why it is needed.
> > > >
> > > > Thanks
> > > > Andrew
> > >
> > > Hi Andrew,
> > > This mdio c45 support needed to access DWC xPCS which is a Clause-45
> >
> > I mean it looks odd doing a write to the data register in the middle of
> > stmmac_mdio_read().
>
> MAC is using an indirect access to access mdio devices. In order to read,
> the driver needs to write into both mii_data and mii_address to select
> c45, read/write command, phy address, address to read, and etc.
Yes, that is all clear. The stmmac_mdio_c45_setup() does part of this
setup. There is also a write to mii_address which i snipped out when
replying. But why do you need to write to the data registers during a
read? C22 does not need this write. Are there some bits in the top of
the data register which are relevant to C45?
Thanks
Andrew
^ permalink raw reply
* [PATCH net-next 0/9] net: hns3: some cleanups & bugfixes
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Huazhong Tan
This patch-set includes cleanups and bugfixes for
the HNS3 ethernet controller driver.
[patch 1/9] fixes VF's broadcast promisc mode not enabled after
initializing.
[patch 2/9] adds hints for fibre port not support flow control.
[patch 3/9] fixes a port capbility updating issue.
[patch 4/9 - 9/9] adds some cleanups for HNS3 driver.
Jian Shen (3):
net: hns3: enable broadcast promisc mode when initializing VF
net: hns3: fix flow control configure issue for fibre port
net: hns3: fix port capbility updating issue
Peng Li (4):
net: hns3: add all IMP return code
net: hns3: set default value for param "type" in
hclgevf_bind_ring_to_vector
net: hns3: add default value for tc_size and tc_offset
net: hns3: set maximum length to resp_data_len for exceptional case
Weihang Li (1):
net: hns3: check msg_data before memcpy in hclgevf_send_mbx_msg
Yonglong Liu (1):
net: hns3: bitwise operator should use unsigned type
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 9 +--
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 43 ++++++++++---
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 8 +++
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 74 ++++++++++++----------
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c | 38 +++++++++--
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h | 14 +++-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 19 ++++--
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 3 +-
10 files changed, 149 insertions(+), 65 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH net-next 5/9] net: hns3: set default value for param "type" in hclgevf_bind_ring_to_vector
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Peng Li <lipeng321@huawei.com>
The value of param type is always not changed in
hclgevf_bind_ring_to_vector, move the assignment to
front of "for {}" can reduce the redundant assignment.
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index ff7e8cb..a13a0e1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -994,6 +994,8 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
u8 type;
req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data;
+ type = en ? HCLGE_MBX_MAP_RING_TO_VECTOR :
+ HCLGE_MBX_UNMAP_RING_TO_VECTOR;
for (node = ring_chain; node; node = node->next) {
int idx_offset = HCLGE_MBX_RING_MAP_BASIC_MSG_NUM +
@@ -1003,9 +1005,6 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
hclgevf_cmd_setup_basic_desc(&desc,
HCLGEVF_OPC_MBX_VF_TO_PF,
false);
- type = en ?
- HCLGE_MBX_MAP_RING_TO_VECTOR :
- HCLGE_MBX_UNMAP_RING_TO_VECTOR;
req->msg[0] = type;
req->msg[1] = vector_id;
}
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 6/9] net: hns3: check msg_data before memcpy in hclgevf_send_mbx_msg
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Weihang Li, Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Weihang Li <liweihang@hisilicon.com>
The value of msg_data may be NULL in some cases, which will cause
errors reported by some compiler.
So this patch adds a check to fix it.
Signed-off-by: Weihang Li <liweihang@hisilicon.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
index 30f2e93..f60b80b 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
@@ -102,7 +102,8 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode,
~HCLGE_MBX_NEED_RESP_BIT;
req->msg[0] = code;
req->msg[1] = subcode;
- memcpy(&req->msg[2], msg_data, msg_len);
+ if (msg_data)
+ memcpy(&req->msg[2], msg_data, msg_len);
/* synchronous send */
if (need_resp) {
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 4/9] net: hns3: add all IMP return code
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Peng Li <lipeng321@huawei.com>
Currently, the HNS3 driver just defines part of IMP return code,
This patch supplements all the remaining IMP return code, and adds
a function to convert this code to the error number.
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 43 +++++++++++++++++-----
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 8 ++++
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c | 38 ++++++++++++++++---
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h | 14 +++++--
4 files changed, 85 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 667c3be..22f6acd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -188,12 +188,43 @@ static bool hclge_is_special_opcode(u16 opcode)
return false;
}
+static int hclge_cmd_convert_err_code(u16 desc_ret)
+{
+ switch (desc_ret) {
+ case HCLGE_CMD_EXEC_SUCCESS:
+ return 0;
+ case HCLGE_CMD_NO_AUTH:
+ return -EPERM;
+ case HCLGE_CMD_NOT_SUPPORTED:
+ return -EOPNOTSUPP;
+ case HCLGE_CMD_QUEUE_FULL:
+ return -EXFULL;
+ case HCLGE_CMD_NEXT_ERR:
+ return -ENOSR;
+ case HCLGE_CMD_UNEXE_ERR:
+ return -ENOTBLK;
+ case HCLGE_CMD_PARA_ERR:
+ return -EINVAL;
+ case HCLGE_CMD_RESULT_ERR:
+ return -ERANGE;
+ case HCLGE_CMD_TIMEOUT:
+ return -ETIME;
+ case HCLGE_CMD_HILINK_ERR:
+ return -ENOLINK;
+ case HCLGE_CMD_QUEUE_ILLEGAL:
+ return -ENXIO;
+ case HCLGE_CMD_INVALID:
+ return -EBADR;
+ default:
+ return -EIO;
+ }
+}
+
static int hclge_cmd_check_retval(struct hclge_hw *hw, struct hclge_desc *desc,
int num, int ntc)
{
u16 opcode, desc_ret;
int handle;
- int retval;
opcode = le16_to_cpu(desc[0].opcode);
for (handle = 0; handle < num; handle++) {
@@ -207,17 +238,9 @@ static int hclge_cmd_check_retval(struct hclge_hw *hw, struct hclge_desc *desc,
else
desc_ret = le16_to_cpu(desc[0].retval);
- if (desc_ret == HCLGE_CMD_EXEC_SUCCESS)
- retval = 0;
- else if (desc_ret == HCLGE_CMD_NO_AUTH)
- retval = -EPERM;
- else if (desc_ret == HCLGE_CMD_NOT_SUPPORTED)
- retval = -EOPNOTSUPP;
- else
- retval = -EIO;
hw->cmq.last_status = desc_ret;
- return retval;
+ return hclge_cmd_convert_err_code(desc_ret);
}
/**
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
index d23ab2b..96840d8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
@@ -41,6 +41,14 @@ enum hclge_cmd_return_status {
HCLGE_CMD_NO_AUTH = 1,
HCLGE_CMD_NOT_SUPPORTED = 2,
HCLGE_CMD_QUEUE_FULL = 3,
+ HCLGE_CMD_NEXT_ERR = 4,
+ HCLGE_CMD_UNEXE_ERR = 5,
+ HCLGE_CMD_PARA_ERR = 6,
+ HCLGE_CMD_RESULT_ERR = 7,
+ HCLGE_CMD_TIMEOUT = 8,
+ HCLGE_CMD_HILINK_ERR = 9,
+ HCLGE_CMD_QUEUE_ILLEGAL = 10,
+ HCLGE_CMD_INVALID = 11,
};
enum hclge_cmd_status {
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
index 31db6d6..652b796 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
@@ -177,6 +177,38 @@ void hclgevf_cmd_setup_basic_desc(struct hclgevf_desc *desc,
desc->flag &= cpu_to_le16(~HCLGEVF_CMD_FLAG_WR);
}
+static int hclgevf_cmd_convert_err_code(u16 desc_ret)
+{
+ switch (desc_ret) {
+ case HCLGEVF_CMD_EXEC_SUCCESS:
+ return 0;
+ case HCLGEVF_CMD_NO_AUTH:
+ return -EPERM;
+ case HCLGEVF_CMD_NOT_SUPPORTED:
+ return -EOPNOTSUPP;
+ case HCLGEVF_CMD_QUEUE_FULL:
+ return -EXFULL;
+ case HCLGEVF_CMD_NEXT_ERR:
+ return -ENOSR;
+ case HCLGEVF_CMD_UNEXE_ERR:
+ return -ENOTBLK;
+ case HCLGEVF_CMD_PARA_ERR:
+ return -EINVAL;
+ case HCLGEVF_CMD_RESULT_ERR:
+ return -ERANGE;
+ case HCLGEVF_CMD_TIMEOUT:
+ return -ETIME;
+ case HCLGEVF_CMD_HILINK_ERR:
+ return -ENOLINK;
+ case HCLGEVF_CMD_QUEUE_ILLEGAL:
+ return -ENXIO;
+ case HCLGEVF_CMD_INVALID:
+ return -EBADR;
+ default:
+ return -EIO;
+ }
+}
+
/* hclgevf_cmd_send - send command to command queue
* @hw: pointer to the hw struct
* @desc: prefilled descriptor for describing the command
@@ -259,11 +291,7 @@ int hclgevf_cmd_send(struct hclgevf_hw *hw, struct hclgevf_desc *desc, int num)
else
retval = le16_to_cpu(desc[0].retval);
- if ((enum hclgevf_cmd_return_status)retval ==
- HCLGEVF_CMD_EXEC_SUCCESS)
- status = 0;
- else
- status = -EIO;
+ status = hclgevf_cmd_convert_err_code(retval);
hw->cmq.last_status = (enum hclgevf_cmd_status)retval;
ntc++;
handle++;
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
index 47030b4..127a434 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h
@@ -46,9 +46,17 @@ struct hclgevf_cmq_ring {
enum hclgevf_cmd_return_status {
HCLGEVF_CMD_EXEC_SUCCESS = 0,
- HCLGEVF_CMD_NO_AUTH = 1,
- HCLGEVF_CMD_NOT_EXEC = 2,
- HCLGEVF_CMD_QUEUE_FULL = 3,
+ HCLGEVF_CMD_NO_AUTH = 1,
+ HCLGEVF_CMD_NOT_SUPPORTED = 2,
+ HCLGEVF_CMD_QUEUE_FULL = 3,
+ HCLGEVF_CMD_NEXT_ERR = 4,
+ HCLGEVF_CMD_UNEXE_ERR = 5,
+ HCLGEVF_CMD_PARA_ERR = 6,
+ HCLGEVF_CMD_RESULT_ERR = 7,
+ HCLGEVF_CMD_TIMEOUT = 8,
+ HCLGEVF_CMD_HILINK_ERR = 9,
+ HCLGEVF_CMD_QUEUE_ILLEGAL = 10,
+ HCLGEVF_CMD_INVALID = 11,
};
enum hclgevf_cmd_status {
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 8/9] net: hns3: bitwise operator should use unsigned type
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Yonglong Liu, Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Yonglong Liu <liuyonglong@huawei.com>
There are some bitwise operator used signed type, this patch fixes
them with unsigned type.
Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 9 +++--
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 43 ++++++++++++----------
3 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index ab5a339..310afa70 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -951,8 +951,9 @@ static int hns3_set_l2l3l4(struct sk_buff *skb, u8 ol4_proto,
static void hns3_set_txbd_baseinfo(u16 *bdtp_fe_sc_vld_ra_ri, int frag_end)
{
/* Config bd buffer end */
- hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_FE_B, !!frag_end);
- hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_VLD_B, 1);
+ if (!!frag_end)
+ hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_FE_B, 1U);
+ hns3_set_field(*bdtp_fe_sc_vld_ra_ri, HNS3_TXD_VLD_B, 1U);
}
static int hns3_fill_desc_vtags(struct sk_buff *skb,
@@ -2575,7 +2576,7 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
}
}
-static int hns3_alloc_skb(struct hns3_enet_ring *ring, int length,
+static int hns3_alloc_skb(struct hns3_enet_ring *ring, unsigned int length,
unsigned char *va)
{
#define HNS3_NEED_ADD_FRAG 1
@@ -2818,8 +2819,8 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
struct sk_buff *skb = ring->skb;
struct hns3_desc_cb *desc_cb;
struct hns3_desc *desc;
+ unsigned int length;
u32 bd_base_info;
- int length;
int ret;
desc = &ring->desc[ring->next_to_clean];
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index a2b73d6..848b866 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -610,7 +610,7 @@ static inline bool hns3_nic_resetting(struct net_device *netdev)
#define hnae3_buf_size(_ring) ((_ring)->buf_size)
#define hnae3_page_order(_ring) (get_order(hnae3_buf_size(_ring)))
-#define hnae3_page_size(_ring) (PAGE_SIZE << hnae3_page_order(_ring))
+#define hnae3_page_size(_ring) (PAGE_SIZE << (u32)hnae3_page_order(_ring))
/* iterator for handling rings in ring group */
#define hns3_for_each_ring(pos, head) \
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 2abd5f5..3fde5471 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -1360,8 +1360,9 @@ static int hclge_map_tqps_to_func(struct hclge_dev *hdev, u16 func_id,
req = (struct hclge_tqp_map_cmd *)desc.data;
req->tqp_id = cpu_to_le16(tqp_pid);
req->tqp_vf = func_id;
- req->tqp_flag = !is_pf << HCLGE_TQP_MAP_TYPE_B |
- 1 << HCLGE_TQP_MAP_EN_B;
+ req->tqp_flag = 1U << HCLGE_TQP_MAP_EN_B;
+ if (!is_pf)
+ req->tqp_flag |= 1U << HCLGE_TQP_MAP_TYPE_B;
req->tqp_vid = cpu_to_le16(tqp_vid);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
@@ -2320,7 +2321,8 @@ static int hclge_set_autoneg_en(struct hclge_dev *hdev, bool enable)
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_AN_MODE, false);
req = (struct hclge_config_auto_neg_cmd *)desc.data;
- hnae3_set_bit(flag, HCLGE_MAC_CFG_AN_EN_B, !!enable);
+ if (enable)
+ hnae3_set_bit(flag, HCLGE_MAC_CFG_AN_EN_B, 1U);
req->cfg_an_cmd_flag = cpu_to_le32(flag);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
@@ -5935,20 +5937,20 @@ static void hclge_cfg_mac_mode(struct hclge_dev *hdev, bool enable)
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_MAC_MODE, false);
- hnae3_set_bit(loop_en, HCLGE_MAC_TX_EN_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_RX_EN_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_PAD_TX_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_PAD_RX_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_1588_TX_B, 0);
- hnae3_set_bit(loop_en, HCLGE_MAC_1588_RX_B, 0);
- hnae3_set_bit(loop_en, HCLGE_MAC_APP_LP_B, 0);
- hnae3_set_bit(loop_en, HCLGE_MAC_LINE_LP_B, 0);
- hnae3_set_bit(loop_en, HCLGE_MAC_FCS_TX_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_RX_FCS_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_RX_FCS_STRIP_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_TX_OVERSIZE_TRUNCATE_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_RX_OVERSIZE_TRUNCATE_B, enable);
- hnae3_set_bit(loop_en, HCLGE_MAC_TX_UNDER_MIN_ERR_B, enable);
+
+ if (enable) {
+ hnae3_set_bit(loop_en, HCLGE_MAC_TX_EN_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_RX_EN_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_PAD_TX_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_PAD_RX_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_FCS_TX_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_RX_FCS_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_RX_FCS_STRIP_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_TX_OVERSIZE_TRUNCATE_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_RX_OVERSIZE_TRUNCATE_B, 1U);
+ hnae3_set_bit(loop_en, HCLGE_MAC_TX_UNDER_MIN_ERR_B, 1U);
+ }
+
req->txrx_pad_fcs_loop_en = cpu_to_le32(loop_en);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
@@ -6310,8 +6312,8 @@ static int hclge_update_desc_vfid(struct hclge_desc *desc, int vfid, bool clr)
{
#define HCLGE_VF_NUM_IN_FIRST_DESC 192
- int word_num;
- int bit_num;
+ unsigned int word_num;
+ unsigned int bit_num;
if (vfid > 255 || vfid < 0)
return -EIO;
@@ -7972,7 +7974,8 @@ static int hclge_send_reset_tqp_cmd(struct hclge_dev *hdev, u16 queue_id,
req = (struct hclge_reset_tqp_queue_cmd *)desc.data;
req->tqp_id = cpu_to_le16(queue_id & HCLGE_RING_ID_MASK);
- hnae3_set_bit(req->reset_req, HCLGE_TQP_RESET_B, enable);
+ if (enable)
+ hnae3_set_bit(req->reset_req, HCLGE_TQP_RESET_B, 1U);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 9/9] net: hns3: set maximum length to resp_data_len for exceptional case
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Peng Li <lipeng321@huawei.com>
If HCLGE_MBX_MAX_RESP_DATA_SIZE > HCLGE_MBX_MAX_RESP_DATA_SIZE,
the memcpy will cause out of memory. So this patch just set
resp_data_len to the maximum length for this case.
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
index 9adeba9..a38ac7c 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
@@ -29,6 +29,10 @@ static int hclge_gen_resp_to_vf(struct hclge_vport *vport,
"PF fail to gen resp to VF len %d exceeds max len %d\n",
resp_data_len,
HCLGE_MBX_MAX_RESP_DATA_SIZE);
+ /* If resp_data_len is too long, set the value to max length
+ * and return the msg to VF
+ */
+ resp_data_len = HCLGE_MBX_MAX_RESP_DATA_SIZE;
}
hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false);
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 7/9] net: hns3: add default value for tc_size and tc_offset
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Peng Li <lipeng321@huawei.com>
This patch adds default value for tc_size and tc_offset, or it may
get random value and used later.
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 94c94e1..2abd5f5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -4092,11 +4092,11 @@ int hclge_rss_init_hw(struct hclge_dev *hdev)
struct hclge_vport *vport = hdev->vport;
u8 *rss_indir = vport[0].rss_indirection_tbl;
u16 rss_size = vport[0].alloc_rss_size;
+ u16 tc_offset[HCLGE_MAX_TC_NUM] = {0};
+ u16 tc_size[HCLGE_MAX_TC_NUM] = {0};
u8 *key = vport[0].rss_hash_key;
u8 hfunc = vport[0].rss_algo;
- u16 tc_offset[HCLGE_MAX_TC_NUM];
u16 tc_valid[HCLGE_MAX_TC_NUM];
- u16 tc_size[HCLGE_MAX_TC_NUM];
u16 roundup_size;
unsigned int i;
int ret;
@@ -9036,12 +9036,12 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num,
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
+ u16 tc_offset[HCLGE_MAX_TC_NUM] = {0};
struct hclge_dev *hdev = vport->back;
+ u16 tc_size[HCLGE_MAX_TC_NUM] = {0};
int cur_rss_size = kinfo->rss_size;
int cur_tqps = kinfo->num_tqps;
- u16 tc_offset[HCLGE_MAX_TC_NUM];
u16 tc_valid[HCLGE_MAX_TC_NUM];
- u16 tc_size[HCLGE_MAX_TC_NUM];
u16 roundup_size;
u32 *rss_indir;
unsigned int i;
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 2/9] net: hns3: fix flow control configure issue for fibre port
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Jian Shen, Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Jian Shen <shenjian15@huawei.com>
Flow control autoneg is unsupported for fibre port. It takes no
effect for flow control when restart autoneg. This patch fixes
it, return -EOPNOTSUPP when user tries to enable flow control
autoneg.
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 62c6263..2ecc10a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -8179,8 +8179,9 @@ static void hclge_get_pauseparam(struct hnae3_handle *handle, u32 *auto_neg,
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
+ struct phy_device *phydev = hdev->hw.mac.phydev;
- *auto_neg = hclge_get_autoneg(handle);
+ *auto_neg = phydev ? hclge_get_autoneg(handle) : 0;
if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) {
*rx_en = 0;
@@ -8211,11 +8212,13 @@ static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg,
struct phy_device *phydev = hdev->hw.mac.phydev;
u32 fc_autoneg;
- fc_autoneg = hclge_get_autoneg(handle);
- if (auto_neg != fc_autoneg) {
- dev_info(&hdev->pdev->dev,
- "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
- return -EOPNOTSUPP;
+ if (phydev) {
+ fc_autoneg = hclge_get_autoneg(handle);
+ if (auto_neg != fc_autoneg) {
+ dev_info(&hdev->pdev->dev,
+ "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
+ return -EOPNOTSUPP;
+ }
}
if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) {
@@ -8226,16 +8229,13 @@ static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg,
hclge_set_flowctrl_adv(hdev, rx_en, tx_en);
- if (!fc_autoneg)
+ if (!auto_neg)
return hclge_cfg_pauseparam(hdev, rx_en, tx_en);
if (phydev)
return phy_start_aneg(phydev);
- if (hdev->pdev->revision == 0x20)
- return -EOPNOTSUPP;
-
- return hclge_restart_autoneg(handle);
+ return -EOPNOTSUPP;
}
static void hclge_get_ksettings_an_result(struct hnae3_handle *handle,
--
2.7.4
^ permalink raw reply related
* [PATCH net-next 3/9] net: hns3: fix port capbility updating issue
From: Huazhong Tan @ 2019-07-04 14:04 UTC (permalink / raw)
To: davem
Cc: netdev, linux-kernel, salil.mehta, yisen.zhuang, linuxarm,
Jian Shen, Peng Li, Huazhong Tan
In-Reply-To: <1562249068-40176-1-git-send-email-tanhuazhong@huawei.com>
From: Jian Shen <shenjian15@huawei.com>
Currently, the driver queries the media port information, and
updates the port capability periodically. But it sets an error
mac->speed_type value, which stops update port capability.
Fixes: 88d10bd6f730 ("net: hns3: add support for multiple media type")
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 2ecc10a..94c94e1 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2663,6 +2663,7 @@ static int hclge_get_sfp_info(struct hclge_dev *hdev, struct hclge_mac *mac)
mac->speed_ability = le32_to_cpu(resp->speed_ability);
mac->autoneg = resp->autoneg;
mac->support_autoneg = resp->autoneg_ability;
+ mac->speed_type = QUERY_ACTIVE_SPEED;
if (!resp->active_fec)
mac->fec_mode = 0;
else
--
2.7.4
^ 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