* [PATCH net-next v1 01/16] tipc: return early for non-blocking sockets at link congestion
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
In-Reply-To: <1477578157-13256-1-git-send-email-parthasarathy.bhuvaragan@ericsson.com>
Until now, in stream/mcast send() we pass the message to the link
layer even when the link is congested and add the socket to the
link's wakeup queue. This is unnecessary for non-blocking sockets.
If a socket is set to non-blocking and sends multicast with zero
back off time while receiving EAGAIN, we exhaust the memory.
In this commit, we return immediately at stream/mcast send() for
non-blocking sockets.
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
---
net/tipc/socket.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index f9f5f3c3dab5..adf3e6ecf61e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -697,6 +697,9 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
uint mtu;
int rc;
+ if (!timeo && tsk->link_cong)
+ return -ELINKCONG;
+
msg_set_type(mhdr, TIPC_MCAST_MSG);
msg_set_lookup_scope(mhdr, TIPC_CLUSTER_SCOPE);
msg_set_destport(mhdr, 0);
@@ -1072,6 +1075,9 @@ static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
}
timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
+ if (!timeo && tsk->link_cong)
+ return -ELINKCONG;
+
dnode = tsk_peer_node(tsk);
skb_queue_head_init(&pktchain);
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply related
* [PATCH net-next v1 00/16] tipc: socket layer improvements
From: Parthasarathy Bhuvaragan @ 2016-10-27 14:22 UTC (permalink / raw)
To: netdev; +Cc: jon.maloy, tipc-discussion
The following issues with the current socket layer hinders socket diagnostics
implementation, which led to this patch series.
1. tipc socket state is derived from multiple variables like
sock->state, tsk->probing_state and tsk->connected. This style forces
us to export multiple attributes to the user space, which has to be
backward compatible.
2. Abuse of sock->state cannot be exported to user-space without
requiring tipc specific hacks in the user-space.
- For connection less (CL) sockets sock->state is overloaded to
tipc state SS_READY.
- For connection oriented (CO) listening socket sock->state is
overloaded to tipc state SS_LISTEN.
This series is split into four:
1. Bug fixes in patch #1,2,3.
2. Minor cleanups in patch#4-5.
3. Express all tipc states using a single variable in patch#6-8.
4. Migrate the new tipc states to sk->sk_state in patch#9-16.
The figures below represents the FSM after this series:
For connectionless sockets:
+-----------+ +--------------+
| TIPC_OPEN |------>| TIPC_CLOSING |
+-----------+ +--------------+
Stream Server Listening Socket:
+-----------+ +-------------+
| TIPC_OPEN |------>| TIPC_LISTEN |
+-----------+ +-------------+
|
+--------------+ |
| TIPC_CLOSING |<-----------+
+--------------+
Stream Server Data Socket:
+-----------+ +------------------+
| TIPC_OPEN |------>| TIPC_ESTABLISHED |<---+
+-----------+ +------------------+ |
^ | | |
| | +----------+
| v
+--------------+
| TIPC_PROBING |
+--------------+
|
|
v
+--------------+ +--------------------+
| TIPC_CLOSING |<---| TIPC_DISCONNECTING |
+--------------+ +--------------------+
Stream Socket Client:
+-----------+ +-----------------+
| TIPC_OPEN |------>| TIPC_CONNECTING |
+-----------+ +-----------------+
|
|
v
+------------------+
| TIPC_ESTABLISHED |<---+
+------------------+ |
^ | | |
| | +---------+
| v
+--------------+
| TIPC_PROBING |
+--------------+
|
|
v
+--------------+ +--------------------+
| TIPC_CLOSING |<---| TIPC_DISCONNECTING |
+--------------+ +--------------------+
NOTE:
This is just a base refractoring required for socket diagnostics.
TIPC socket diagnostics support will be introduced in a later series.
Parthasarathy Bhuvaragan (16):
tipc: return early for non-blocking sockets at link congestion
tipc: wakeup sleeping users at disconnect
tipc: set kern=0 in sk_alloc() during tipc_accept()
tipc: rename struct tipc_skb_cb member handle to bytes_read
tipc: rename tsk->remote to tsk->peer for consistent naming
tipc: remove tsk->connected for connectionless sockets
tipc: remove tsk->connected from tipc_sock
tipc: remove probing_intv from tipc_sock
tipc: remove socket state SS_READY
tipc: create TIPC_LISTEN as a new sk_state
tipc: create TIPC_PROBING/TIPC_ESTABLISHED as new sk_states
tipc: create TIPC_OPEN as a new sk_state
tipc: create TIPC_DISCONNECTING as a new sk_state
tipc: create TIPC_CLOSING as a new sk_state
tipc: create TIPC_CONNECTING as a new sk_state
tipc: remove SS_CONNECTED sock state
include/uapi/linux/tipc.h | 13 ++
net/tipc/msg.h | 2 +-
net/tipc/socket.c | 385 +++++++++++++++++++++++++---------------------
3 files changed, 222 insertions(+), 178 deletions(-)
--
2.1.4
------------------------------------------------------------------------------
The Command Line: Reinvented for Modern Developers
Did the resurgence of CLI tooling catch you by surprise?
Reconnect with the command line and become more productive.
Learn the new .NET and ASP.NET CLI. Get your free copy!
http://sdm.link/telerik
^ permalink raw reply
* [PATCH v4] iproute2: macvlan: add "source" mode
From: Michael Braun @ 2016-10-27 10:44 UTC (permalink / raw)
To: netdev; +Cc: Michael Braun, projekt-wlan, steweg
Adjusting iproute2 utility to support new macvlan link type mode called
"source".
Example of commands that can be applied:
ip link add link eth0 name macvlan0 type macvlan mode source
ip link set link dev macvlan0 type macvlan macaddr add 00:11:11:11:11:11
ip link set link dev macvlan0 type macvlan macaddr del 00:11:11:11:11:11
ip link set link dev macvlan0 type macvlan macaddr flush
ip -details link show dev macvlan0
Based on previous work of Stefan Gula <steweg@gmail.com>
Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
Cc: steweg@gmail.com
v4:
- add MACADDR_SET support
- skip FLAG_UNICAST / FLAG_UNICAST_ALL as this is not upstream
- fix man page
---
ip/iplink_macvlan.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++---
man/man8/ip-link.8.in | 42 ++++++++++++++++-
2 files changed, 157 insertions(+), 8 deletions(-)
diff --git a/ip/iplink_macvlan.c b/ip/iplink_macvlan.c
index 53cd4f4..9a4dd5e 100644
--- a/ip/iplink_macvlan.c
+++ b/ip/iplink_macvlan.c
@@ -15,6 +15,7 @@
#include <string.h>
#include <sys/socket.h>
#include <linux/if_link.h>
+#include <linux/if_ether.h>
#include "rt_names.h"
#include "utils.h"
@@ -29,7 +30,11 @@
static void print_explain(struct link_util *lu, FILE *f)
{
fprintf(f,
- "Usage: ... %s mode { private | vepa | bridge | passthru [nopromisc] }\n",
+ "Usage: ... %s mode MODE [flag MODE_FLAG] MODE_OPTS\n"
+ "MODE: private | vepa | bridge | passthru | source\n"
+ "MODE_FLAG: null | nopromisc \n"
+ "MODE_OPTS: for mode \"source\":\n"
+ "\tmacaddr { { add | del } <macaddr> | set [ <macaddr> [ <macaddr> ... ] ] | flush }\n",
lu->id
);
}
@@ -41,7 +46,14 @@ static void explain(struct link_util *lu)
static int mode_arg(const char *arg)
{
- fprintf(stderr, "Error: argument of \"mode\" must be \"private\", \"vepa\", \"bridge\" or \"passthru\", not \"%s\"\n",
+ fprintf(stderr, "Error: argument of \"mode\" must be \"private\", \"vepa\", \"bridge\", \"passthru\" or \"source\", not \"%s\"\n",
+ arg);
+ return -1;
+}
+
+static int flag_arg(const char *arg)
+{
+ fprintf(stderr, "Error: argument of \"flag\" must be \"nopromisc\" or \"null\", not \"%s\"\n",
arg);
return -1;
}
@@ -51,6 +63,10 @@ static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
{
__u32 mode = 0;
__u16 flags = 0;
+ __u32 mac_mode = 0;
+ int has_flags = 0;
+ char mac[ETH_ALEN];
+ struct rtattr *nmac;
while (argc > 0) {
if (matches(*argv, "mode") == 0) {
@@ -64,10 +80,72 @@ static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
mode = MACVLAN_MODE_BRIDGE;
else if (strcmp(*argv, "passthru") == 0)
mode = MACVLAN_MODE_PASSTHRU;
+ else if (strcmp(*argv, "source") == 0)
+ mode = MACVLAN_MODE_SOURCE;
else
return mode_arg(*argv);
+ } else if (matches(*argv, "flag") == 0) {
+ NEXT_ARG();
+
+ if (strcmp(*argv, "nopromisc") == 0)
+ flags |= MACVLAN_FLAG_NOPROMISC;
+ else if (strcmp(*argv, "null") == 0)
+ flags |= 0;
+ else
+ return flag_arg(*argv);
+
+ has_flags = 1;
+
+ } else if (matches(*argv, "macaddr") == 0) {
+ NEXT_ARG();
+
+ if (strcmp(*argv, "add") == 0) {
+ mac_mode = MACVLAN_MACADDR_ADD;
+ } else if (strcmp(*argv, "del") == 0) {
+ mac_mode = MACVLAN_MACADDR_DEL;
+ } else if (strcmp(*argv, "set") == 0) {
+ mac_mode = MACVLAN_MACADDR_SET;
+ } else if (strcmp(*argv, "flush") == 0) {
+ mac_mode = MACVLAN_MACADDR_FLUSH;
+ } else {
+ explain(lu);
+ return -1;
+ }
+
+ addattr32(n, 1024, IFLA_MACVLAN_MACADDR_MODE, mac_mode);
+
+ if (mac_mode == MACVLAN_MACADDR_ADD ||
+ mac_mode == MACVLAN_MACADDR_DEL) {
+ NEXT_ARG();
+
+ if (ll_addr_a2n(mac, sizeof(mac),
+ *argv) != ETH_ALEN)
+ return -1;
+
+ addattr_l(n, 1024, IFLA_MACVLAN_MACADDR, &mac,
+ ETH_ALEN);
+ }
+
+ if (mac_mode == MACVLAN_MACADDR_SET) {
+ nmac = addattr_nest(n, 1024,
+ IFLA_MACVLAN_MACADDR_DATA);
+ while (NEXT_ARG_OK()) {
+ NEXT_ARG_FWD();
+
+ if (ll_addr_a2n(mac, sizeof(mac),
+ *argv) != ETH_ALEN) {
+ PREV_ARG();
+ break;
+ }
+
+ addattr_l(n, 1024, IFLA_MACVLAN_MACADDR,
+ &mac, ETH_ALEN);
+ }
+ addattr_nest_end(n, nmac);
+ }
} else if (matches(*argv, "nopromisc") == 0) {
flags |= MACVLAN_FLAG_NOPROMISC;
+ has_flags = 1;
} else if (matches(*argv, "help") == 0) {
explain(lu);
return -1;
@@ -82,7 +160,7 @@ static int macvlan_parse_opt(struct link_util *lu, int argc, char **argv,
if (mode)
addattr32(n, 1024, IFLA_MACVLAN_MODE, mode);
- if (flags) {
+ if (has_flags) {
if (flags & MACVLAN_FLAG_NOPROMISC &&
mode != MACVLAN_MODE_PASSTHRU) {
pfx_err(lu, "nopromisc flag only valid in passthru mode");
@@ -98,6 +176,10 @@ static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]
{
__u32 mode;
__u16 flags;
+ __u32 count;
+ unsigned char *addr;
+ int len;
+ struct rtattr *rta;
if (!tb)
return;
@@ -107,20 +189,49 @@ static void macvlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[]
return;
mode = rta_getattr_u32(tb[IFLA_MACVLAN_MODE]);
- fprintf(f, " mode %s ",
+ fprintf(f, "mode %s ",
mode == MACVLAN_MODE_PRIVATE ? "private"
: mode == MACVLAN_MODE_VEPA ? "vepa"
: mode == MACVLAN_MODE_BRIDGE ? "bridge"
: mode == MACVLAN_MODE_PASSTHRU ? "passthru"
+ : mode == MACVLAN_MODE_SOURCE ? "source"
: "unknown");
if (!tb[IFLA_MACVLAN_FLAGS] ||
RTA_PAYLOAD(tb[IFLA_MACVLAN_FLAGS]) < sizeof(__u16))
- return;
+ flags = 0;
+ else
+ flags = rta_getattr_u16(tb[IFLA_MACVLAN_FLAGS]);
- flags = rta_getattr_u16(tb[IFLA_MACVLAN_FLAGS]);
if (flags & MACVLAN_FLAG_NOPROMISC)
fprintf(f, "nopromisc ");
+
+ /* in source mode, there are more options to print */
+
+ if (mode != MACVLAN_MODE_SOURCE)
+ return;
+
+ if (!tb[IFLA_MACVLAN_MACADDR_COUNT] ||
+ RTA_PAYLOAD(tb[IFLA_MACVLAN_MACADDR_COUNT]) < sizeof(__u32))
+ return;
+
+ count = rta_getattr_u32(tb[IFLA_MACVLAN_MACADDR_COUNT]);
+ fprintf(f, "remotes (%d) ", count);
+
+ if (!tb[IFLA_MACVLAN_MACADDR_DATA])
+ return;
+
+ rta = RTA_DATA(tb[IFLA_MACVLAN_MACADDR_DATA]);
+ len = RTA_PAYLOAD(tb[IFLA_MACVLAN_MACADDR_DATA]);
+
+ for (; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
+ if (rta->rta_type != IFLA_MACVLAN_MACADDR ||
+ RTA_PAYLOAD(rta) < 6)
+ continue;
+ addr = RTA_DATA(rta);
+ fprintf(f, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x ", addr[0],
+ addr[1], addr[2], addr[3], addr[4], addr[5]);
+ }
}
static void macvlan_print_help(struct link_util *lu, int argc, char **argv,
diff --git a/man/man8/ip-link.8.in b/man/man8/ip-link.8.in
index ffc4160..0da55fb 100644
--- a/man/man8/ip-link.8.in
+++ b/man/man8/ip-link.8.in
@@ -138,7 +138,12 @@ ip-link \- network device configuration
.IR NAME " ]"
.br
.RB "[ " addrgenmode " { " eui64 " | " none " | " stable_secret " | " random " } ]"
-
+.br
+.RB "[ " macaddr " { " flush " | { " add " | " del " } "
+.IR MACADDR " | set [ "
+.IR MACADDR " [ "
+.IR MACADDR " [ ... ] ] ] } ]"
+.br
.ti -8
.B ip link show
@@ -873,7 +878,7 @@ the following additional arguments are supported:
.BI "ip link add link " DEVICE " name " NAME
.BR type " { " macvlan " | " macvtap " } "
.BR mode " { " private " | " vepa " | " bridge " | " passthru
-.RB " [ " nopromisc " ] } "
+.RB " [ " nopromisc " ] | " source " } "
.in +8
.sp
@@ -910,6 +915,13 @@ the interface or create vlan interfaces on top of it. By default, this mode
forces the underlying interface into promiscuous mode. Passing the
.BR nopromisc " flag prevents this, so the promisc flag may be controlled "
using standard tools.
+
+.B mode source
+- allows one to set a list of allowed mac address, which is used to match
+against source mac address from received frames on underlying interface. This
+allows creating mac based VLAN associations, instead of standard port or tag
+based. The feature is useful to deploy 802.1x mac based behavior,
+where drivers of underlying interfaces doesn't allows that.
.in -8
.TP
@@ -1441,6 +1453,32 @@ the following additional arguments are supported:
.in -8
+.TP
+MACVLAN and MACVTAP Support
+Modify list of allowed macaddr for link in source mode.
+
+.B "ip link set type { macvlan | macvap } "
+[
+.BI macaddr " " "" COMMAND " " MACADDR " ..."
+]
+
+Commands:
+.in +8
+.B add
+- add MACADDR to allowed list
+.sp
+.B set
+- replace allowed list
+.sp
+.B del
+- remove MACADDR from allowed list
+.sp
+.B flush
+- flush whole allowed list
+.sp
+.in -8
+
+
.SS ip link show - display device attributes
.TP
--
2.1.4
^ permalink raw reply related
* [patch net-next 5/5] mlxsw: switchx2: Set physical device for port netdevice
From: Jiri Pirko @ 2016-10-27 13:13 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz
In-Reply-To: <1477573981-26546-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Do this so the sysfs has "device" link correctly set.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index 938e22d..dc3c5ed 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -968,6 +968,7 @@ static int mlxsw_sx_port_create(struct mlxsw_sx *mlxsw_sx, u8 local_port)
dev = alloc_etherdev(sizeof(struct mlxsw_sx_port));
if (!dev)
return -ENOMEM;
+ SET_NETDEV_DEV(dev, mlxsw_sx->bus_info->dev);
mlxsw_sx_port = netdev_priv(dev);
mlxsw_sx_port->dev = dev;
mlxsw_sx_port->mlxsw_sx = mlxsw_sx;
--
2.5.5
^ permalink raw reply related
* [patch net-next 4/5] mlxsw: spectrum: Set physical device for port netdevice
From: Jiri Pirko @ 2016-10-27 13:13 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz
In-Reply-To: <1477573981-26546-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
Do this so the sysfs has "device" link correctly set.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 7805240..d652f7f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -2222,6 +2222,7 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
dev = alloc_etherdev(sizeof(struct mlxsw_sp_port));
if (!dev)
return -ENOMEM;
+ SET_NETDEV_DEV(dev, mlxsw_sp->bus_info->dev);
mlxsw_sp_port = netdev_priv(dev);
mlxsw_sp_port->dev = dev;
mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
--
2.5.5
^ permalink raw reply related
* [patch net-next 3/5] mlxsw: Move PCI id table definitions into driver modules
From: Jiri Pirko @ 2016-10-27 13:12 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz
In-Reply-To: <1477573981-26546-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
So far, mlxsw_pci.ko is the module that registers PCI table for all
drivers (spectrum and switchx2). That is problematic for example with
dracut. Since mlxsw_spectrum.ko and mlxsw_switchx2.ko are loaded
dynamically from within mlxsw_core.ko, dracut does not have track of
them and avoids them from being included in initramfs.
So make this in an ordinary way and define the PCI tables in individual
driver modules, so it can be properly loaded and included in dracut
initramfs image. As a side effect, this patch could remove no longer
necessary driver "kind" strings which were used to link PCI ids with
individual mlxsw drivers.
Suggested-by: Ivan Vecera <ivecera@redhat.com>
Tested-by: Ivan Vecera <ivecera@redhat.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/Kconfig | 4 +-
drivers/net/ethernet/mellanox/mlxsw/core.c | 14 ------
drivers/net/ethernet/mellanox/mlxsw/core.h | 8 ----
drivers/net/ethernet/mellanox/mlxsw/pci.c | 56 ++++++++---------------
drivers/net/ethernet/mellanox/mlxsw/pci.h | 63 ++++++++++++++++++++++++++
drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | 2 -
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 25 ++++++++--
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 34 ++++++++++++--
8 files changed, 135 insertions(+), 71 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlxsw/pci.h
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Kconfig b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
index 5989f7c..d0bcf59 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
@@ -31,7 +31,7 @@ config MLXSW_PCI
config MLXSW_SWITCHX2
tristate "Mellanox Technologies SwitchX-2 support"
- depends on MLXSW_CORE && NET_SWITCHDEV
+ depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV
default m
---help---
This driver supports Mellanox Technologies SwitchX-2 Ethernet
@@ -42,7 +42,7 @@ config MLXSW_SWITCHX2
config MLXSW_SPECTRUM
tristate "Mellanox Technologies Spectrum support"
- depends on MLXSW_CORE && NET_SWITCHDEV && VLAN_8021Q
+ depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV && VLAN_8021Q
default m
---help---
This driver supports Mellanox Technologies Spectrum Ethernet
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index a37d471..02183f6 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -823,17 +823,6 @@ static struct mlxsw_driver *mlxsw_core_driver_get(const char *kind)
spin_lock(&mlxsw_core_driver_list_lock);
mlxsw_driver = __driver_find(kind);
- if (!mlxsw_driver) {
- spin_unlock(&mlxsw_core_driver_list_lock);
- request_module(MLXSW_MODULE_ALIAS_PREFIX "%s", kind);
- spin_lock(&mlxsw_core_driver_list_lock);
- mlxsw_driver = __driver_find(kind);
- }
- if (mlxsw_driver) {
- if (!try_module_get(mlxsw_driver->owner))
- mlxsw_driver = NULL;
- }
-
spin_unlock(&mlxsw_core_driver_list_lock);
return mlxsw_driver;
}
@@ -845,9 +834,6 @@ static void mlxsw_core_driver_put(const char *kind)
spin_lock(&mlxsw_core_driver_list_lock);
mlxsw_driver = __driver_find(kind);
spin_unlock(&mlxsw_core_driver_list_lock);
- if (!mlxsw_driver)
- return;
- module_put(mlxsw_driver->owner);
}
static int mlxsw_core_debugfs_init(struct mlxsw_core *mlxsw_core)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 94a846d..0cf721c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -51,13 +51,6 @@
#include "cmd.h"
#include "resources.h"
-#define MLXSW_MODULE_ALIAS_PREFIX "mlxsw-driver-"
-#define MODULE_MLXSW_DRIVER_ALIAS(kind) \
- MODULE_ALIAS(MLXSW_MODULE_ALIAS_PREFIX kind)
-
-#define MLXSW_DEVICE_KIND_SWITCHX2 "switchx2"
-#define MLXSW_DEVICE_KIND_SPECTRUM "spectrum"
-
struct mlxsw_core;
struct mlxsw_driver;
struct mlxsw_bus;
@@ -221,7 +214,6 @@ struct mlxsw_config_profile {
struct mlxsw_driver {
struct list_head list;
const char *kind;
- struct module *owner;
size_t priv_size;
int (*init)(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *mlxsw_bus_info);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index 209630c..63d89f7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -49,6 +49,7 @@
#include <linux/string.h>
#include "pci_hw.h"
+#include "pci.h"
#include "core.h"
#include "cmd.h"
#include "port.h"
@@ -56,26 +57,8 @@
static const char mlxsw_pci_driver_name[] = "mlxsw_pci";
-static const struct pci_device_id mlxsw_pci_id_table[] = {
- {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SWITCHX2), 0},
- {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0},
- {0, }
-};
-
static struct dentry *mlxsw_pci_dbg_root;
-static const char *mlxsw_pci_device_kind_get(const struct pci_device_id *id)
-{
- switch (id->device) {
- case PCI_DEVICE_ID_MELLANOX_SWITCHX2:
- return MLXSW_DEVICE_KIND_SWITCHX2;
- case PCI_DEVICE_ID_MELLANOX_SPECTRUM:
- return MLXSW_DEVICE_KIND_SPECTRUM;
- default:
- BUG();
- }
-}
-
#define mlxsw_pci_write32(mlxsw_pci, reg, val) \
iowrite32be(val, (mlxsw_pci)->hw_addr + (MLXSW_PCI_ ## reg))
#define mlxsw_pci_read32(mlxsw_pci, reg) \
@@ -1553,7 +1536,7 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
err = request_irq(mlxsw_pci->msix_entry.vector,
mlxsw_pci_eq_irq_handler, 0,
- mlxsw_pci_driver_name, mlxsw_pci);
+ mlxsw_pci->bus_info.device_kind, mlxsw_pci);
if (err) {
dev_err(&pdev->dev, "IRQ request failed\n");
goto err_request_eq_irq;
@@ -1793,6 +1776,7 @@ static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci)
static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ const char *driver_name = pdev->driver->name;
struct mlxsw_pci *mlxsw_pci;
int err;
@@ -1806,7 +1790,7 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_pci_enable_device;
}
- err = pci_request_regions(pdev, mlxsw_pci_driver_name);
+ err = pci_request_regions(pdev, driver_name);
if (err) {
dev_err(&pdev->dev, "pci_request_regions failed\n");
goto err_pci_request_regions;
@@ -1857,7 +1841,7 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_msix_init;
}
- mlxsw_pci->bus_info.device_kind = mlxsw_pci_device_kind_get(id);
+ mlxsw_pci->bus_info.device_kind = driver_name;
mlxsw_pci->bus_info.device_name = pci_name(mlxsw_pci->pdev);
mlxsw_pci->bus_info.dev = &pdev->dev;
@@ -1909,33 +1893,30 @@ static void mlxsw_pci_remove(struct pci_dev *pdev)
kfree(mlxsw_pci);
}
-static struct pci_driver mlxsw_pci_driver = {
- .name = mlxsw_pci_driver_name,
- .id_table = mlxsw_pci_id_table,
- .probe = mlxsw_pci_probe,
- .remove = mlxsw_pci_remove,
-};
+int mlxsw_pci_driver_register(struct pci_driver *pci_driver)
+{
+ pci_driver->probe = mlxsw_pci_probe;
+ pci_driver->remove = mlxsw_pci_remove;
+ return pci_register_driver(pci_driver);
+}
+EXPORT_SYMBOL(mlxsw_pci_driver_register);
-static int __init mlxsw_pci_module_init(void)
+void mlxsw_pci_driver_unregister(struct pci_driver *pci_driver)
{
- int err;
+ pci_unregister_driver(pci_driver);
+}
+EXPORT_SYMBOL(mlxsw_pci_driver_unregister);
+static int __init mlxsw_pci_module_init(void)
+{
mlxsw_pci_dbg_root = debugfs_create_dir(mlxsw_pci_driver_name, NULL);
if (!mlxsw_pci_dbg_root)
return -ENOMEM;
- err = pci_register_driver(&mlxsw_pci_driver);
- if (err)
- goto err_register_driver;
return 0;
-
-err_register_driver:
- debugfs_remove_recursive(mlxsw_pci_dbg_root);
- return err;
}
static void __exit mlxsw_pci_module_exit(void)
{
- pci_unregister_driver(&mlxsw_pci_driver);
debugfs_remove_recursive(mlxsw_pci_dbg_root);
}
@@ -1945,4 +1926,3 @@ module_exit(mlxsw_pci_module_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
MODULE_DESCRIPTION("Mellanox switch PCI interface driver");
-MODULE_DEVICE_TABLE(pci, mlxsw_pci_id_table);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.h b/drivers/net/ethernet/mellanox/mlxsw/pci.h
new file mode 100644
index 0000000..35a0011
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.h
@@ -0,0 +1,63 @@
+/*
+ * drivers/net/ethernet/mellanox/mlxsw/pci.h
+ * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MLXSW_PCI_H
+#define _MLXSW_PCI_H
+
+#include <linux/pci.h>
+
+#define PCI_DEVICE_ID_MELLANOX_SWITCHX2 0xc738
+#define PCI_DEVICE_ID_MELLANOX_SPECTRUM 0xcb84
+
+#if IS_ENABLED(CONFIG_MLXSW_PCI)
+
+int mlxsw_pci_driver_register(struct pci_driver *pci_driver);
+void mlxsw_pci_driver_unregister(struct pci_driver *pci_driver);
+
+#else
+
+static inline int
+mlxsw_pci_driver_register(struct pci_driver *pci_driver)
+{
+ return 0;
+}
+
+static inline void
+mlxsw_pci_driver_unregister(struct pci_driver *pci_driver)
+{
+}
+
+#endif
+
+#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
index 45bc1979..708736f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -39,8 +39,6 @@
#include "item.h"
-#define PCI_DEVICE_ID_MELLANOX_SWITCHX2 0xc738
-#define PCI_DEVICE_ID_MELLANOX_SPECTRUM 0xcb84
#define MLXSW_PCI_BAR0_SIZE (1024 * 1024) /* 1MB */
#define MLXSW_PCI_PAGE_SIZE 4096
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 5d8f1d5..7805240 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -37,6 +37,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
@@ -59,6 +60,7 @@
#include <net/netevent.h>
#include "spectrum.h"
+#include "pci.h"
#include "core.h"
#include "reg.h"
#include "port.h"
@@ -3066,8 +3068,7 @@ static struct mlxsw_config_profile mlxsw_sp_config_profile = {
};
static struct mlxsw_driver mlxsw_sp_driver = {
- .kind = MLXSW_DEVICE_KIND_SPECTRUM,
- .owner = THIS_MODULE,
+ .kind = mlxsw_sp_driver_name,
.priv_size = sizeof(struct mlxsw_sp),
.init = mlxsw_sp_init,
.fini = mlxsw_sp_fini,
@@ -4662,6 +4663,16 @@ static struct notifier_block mlxsw_sp_router_netevent_nb __read_mostly = {
.notifier_call = mlxsw_sp_router_netevent_event,
};
+static const struct pci_device_id mlxsw_sp_pci_id_table[] = {
+ {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0},
+ {0, },
+};
+
+static struct pci_driver mlxsw_sp_pci_driver = {
+ .name = mlxsw_sp_driver_name,
+ .id_table = mlxsw_sp_pci_id_table,
+};
+
static int __init mlxsw_sp_module_init(void)
{
int err;
@@ -4673,8 +4684,15 @@ static int __init mlxsw_sp_module_init(void)
err = mlxsw_core_driver_register(&mlxsw_sp_driver);
if (err)
goto err_core_driver_register;
+
+ err = mlxsw_pci_driver_register(&mlxsw_sp_pci_driver);
+ if (err)
+ goto err_pci_driver_register;
+
return 0;
+err_pci_driver_register:
+ mlxsw_core_driver_unregister(&mlxsw_sp_driver);
err_core_driver_register:
unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
@@ -4684,6 +4702,7 @@ static int __init mlxsw_sp_module_init(void)
static void __exit mlxsw_sp_module_exit(void)
{
+ mlxsw_pci_driver_unregister(&mlxsw_sp_pci_driver);
mlxsw_core_driver_unregister(&mlxsw_sp_driver);
unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
@@ -4696,4 +4715,4 @@ module_exit(mlxsw_sp_module_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
MODULE_DESCRIPTION("Mellanox Spectrum driver");
-MODULE_MLXSW_DRIVER_ALIAS(MLXSW_DEVICE_KIND_SPECTRUM);
+MODULE_DEVICE_TABLE(pci, mlxsw_sp_pci_id_table);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index 963618d..938e22d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -37,6 +37,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
+#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/slab.h>
@@ -46,6 +47,7 @@
#include <net/switchdev.h>
#include <generated/utsrelease.h>
+#include "pci.h"
#include "core.h"
#include "reg.h"
#include "port.h"
@@ -1544,8 +1546,7 @@ static struct mlxsw_config_profile mlxsw_sx_config_profile = {
};
static struct mlxsw_driver mlxsw_sx_driver = {
- .kind = MLXSW_DEVICE_KIND_SWITCHX2,
- .owner = THIS_MODULE,
+ .kind = mlxsw_sx_driver_name,
.priv_size = sizeof(struct mlxsw_sx),
.init = mlxsw_sx_init,
.fini = mlxsw_sx_fini,
@@ -1554,13 +1555,38 @@ static struct mlxsw_driver mlxsw_sx_driver = {
.profile = &mlxsw_sx_config_profile,
};
+static const struct pci_device_id mlxsw_sx_pci_id_table[] = {
+ {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SWITCHX2), 0},
+ {0, },
+};
+
+static struct pci_driver mlxsw_sx_pci_driver = {
+ .name = mlxsw_sx_driver_name,
+ .id_table = mlxsw_sx_pci_id_table,
+};
+
static int __init mlxsw_sx_module_init(void)
{
- return mlxsw_core_driver_register(&mlxsw_sx_driver);
+ int err;
+
+ err = mlxsw_core_driver_register(&mlxsw_sx_driver);
+ if (err)
+ return err;
+
+ err = mlxsw_pci_driver_register(&mlxsw_sx_pci_driver);
+ if (err)
+ goto err_pci_driver_register;
+
+ return 0;
+
+err_pci_driver_register:
+ mlxsw_core_driver_unregister(&mlxsw_sx_driver);
+ return err;
}
static void __exit mlxsw_sx_module_exit(void)
{
+ mlxsw_pci_driver_unregister(&mlxsw_sx_pci_driver);
mlxsw_core_driver_unregister(&mlxsw_sx_driver);
}
@@ -1570,4 +1596,4 @@ module_exit(mlxsw_sx_module_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
MODULE_DESCRIPTION("Mellanox SwitchX-2 driver");
-MODULE_MLXSW_DRIVER_ALIAS(MLXSW_DEVICE_KIND_SWITCHX2);
+MODULE_DEVICE_TABLE(pci, mlxsw_sx_pci_id_table);
--
2.5.5
^ permalink raw reply related
* [patch net-next 2/5] mlxsw: pci: Rename header with HW definitions
From: Jiri Pirko @ 2016-10-27 13:12 UTC (permalink / raw)
To: netdev; +Cc: davem, idosch, eladr, yotamg, nogahf, ogerlitz
In-Reply-To: <1477573981-26546-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@mellanox.com>
pci.h needs to be used for inner function declarations. So move the
original one to more appropriate name, pci_hw.h.
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/pci.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/pci.h | 231 ---------------------------
drivers/net/ethernet/mellanox/mlxsw/pci_hw.h | 231 +++++++++++++++++++++++++++
3 files changed, 232 insertions(+), 232 deletions(-)
delete mode 100644 drivers/net/ethernet/mellanox/mlxsw/pci.h
create mode 100644 drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
index c88f2ab..209630c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -48,7 +48,7 @@
#include <linux/seq_file.h>
#include <linux/string.h>
-#include "pci.h"
+#include "pci_hw.h"
#include "core.h"
#include "cmd.h"
#include "port.h"
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.h b/drivers/net/ethernet/mellanox/mlxsw/pci.h
deleted file mode 100644
index d942a3e..0000000
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * drivers/net/ethernet/mellanox/mlxsw/pci.h
- * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2015 Jiri Pirko <jiri@mellanox.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MLXSW_PCI_H
-#define _MLXSW_PCI_H
-
-#include <linux/bitops.h>
-
-#include "item.h"
-
-#define PCI_DEVICE_ID_MELLANOX_SWITCHX2 0xc738
-#define PCI_DEVICE_ID_MELLANOX_SPECTRUM 0xcb84
-#define MLXSW_PCI_BAR0_SIZE (1024 * 1024) /* 1MB */
-#define MLXSW_PCI_PAGE_SIZE 4096
-
-#define MLXSW_PCI_CIR_BASE 0x71000
-#define MLXSW_PCI_CIR_IN_PARAM_HI MLXSW_PCI_CIR_BASE
-#define MLXSW_PCI_CIR_IN_PARAM_LO (MLXSW_PCI_CIR_BASE + 0x04)
-#define MLXSW_PCI_CIR_IN_MODIFIER (MLXSW_PCI_CIR_BASE + 0x08)
-#define MLXSW_PCI_CIR_OUT_PARAM_HI (MLXSW_PCI_CIR_BASE + 0x0C)
-#define MLXSW_PCI_CIR_OUT_PARAM_LO (MLXSW_PCI_CIR_BASE + 0x10)
-#define MLXSW_PCI_CIR_TOKEN (MLXSW_PCI_CIR_BASE + 0x14)
-#define MLXSW_PCI_CIR_CTRL (MLXSW_PCI_CIR_BASE + 0x18)
-#define MLXSW_PCI_CIR_CTRL_GO_BIT BIT(23)
-#define MLXSW_PCI_CIR_CTRL_EVREQ_BIT BIT(22)
-#define MLXSW_PCI_CIR_CTRL_OPCODE_MOD_SHIFT 12
-#define MLXSW_PCI_CIR_CTRL_STATUS_SHIFT 24
-#define MLXSW_PCI_CIR_TIMEOUT_MSECS 1000
-
-#define MLXSW_PCI_SW_RESET 0xF0010
-#define MLXSW_PCI_SW_RESET_RST_BIT BIT(0)
-#define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 5000
-#define MLXSW_PCI_FW_READY 0xA1844
-#define MLXSW_PCI_FW_READY_MASK 0xFF
-#define MLXSW_PCI_FW_READY_MAGIC 0x5E
-
-#define MLXSW_PCI_DOORBELL_SDQ_OFFSET 0x000
-#define MLXSW_PCI_DOORBELL_RDQ_OFFSET 0x200
-#define MLXSW_PCI_DOORBELL_CQ_OFFSET 0x400
-#define MLXSW_PCI_DOORBELL_EQ_OFFSET 0x600
-#define MLXSW_PCI_DOORBELL_ARM_CQ_OFFSET 0x800
-#define MLXSW_PCI_DOORBELL_ARM_EQ_OFFSET 0xA00
-
-#define MLXSW_PCI_DOORBELL(offset, type_offset, num) \
- ((offset) + (type_offset) + (num) * 4)
-
-#define MLXSW_PCI_CQS_MAX 96
-#define MLXSW_PCI_EQS_COUNT 2
-#define MLXSW_PCI_EQ_ASYNC_NUM 0
-#define MLXSW_PCI_EQ_COMP_NUM 1
-
-#define MLXSW_PCI_AQ_PAGES 8
-#define MLXSW_PCI_AQ_SIZE (MLXSW_PCI_PAGE_SIZE * MLXSW_PCI_AQ_PAGES)
-#define MLXSW_PCI_WQE_SIZE 32 /* 32 bytes per element */
-#define MLXSW_PCI_CQE_SIZE 16 /* 16 bytes per element */
-#define MLXSW_PCI_EQE_SIZE 16 /* 16 bytes per element */
-#define MLXSW_PCI_WQE_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_WQE_SIZE)
-#define MLXSW_PCI_CQE_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_CQE_SIZE)
-#define MLXSW_PCI_EQE_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_EQE_SIZE)
-#define MLXSW_PCI_EQE_UPDATE_COUNT 0x80
-
-#define MLXSW_PCI_WQE_SG_ENTRIES 3
-#define MLXSW_PCI_WQE_TYPE_ETHERNET 0xA
-
-/* pci_wqe_c
- * If set it indicates that a completion should be reported upon
- * execution of this descriptor.
- */
-MLXSW_ITEM32(pci, wqe, c, 0x00, 31, 1);
-
-/* pci_wqe_lp
- * Local Processing, set if packet should be processed by the local
- * switch hardware:
- * For Ethernet EMAD (Direct Route and non Direct Route) -
- * must be set if packet destination is local device
- * For InfiniBand CTL - must be set if packet destination is local device
- * Otherwise it must be clear
- * Local Process packets must not exceed the size of 2K (including payload
- * and headers).
- */
-MLXSW_ITEM32(pci, wqe, lp, 0x00, 30, 1);
-
-/* pci_wqe_type
- * Packet type.
- */
-MLXSW_ITEM32(pci, wqe, type, 0x00, 23, 4);
-
-/* pci_wqe_byte_count
- * Size of i-th scatter/gather entry, 0 if entry is unused.
- */
-MLXSW_ITEM16_INDEXED(pci, wqe, byte_count, 0x02, 0, 14, 0x02, 0x00, false);
-
-/* pci_wqe_address
- * Physical address of i-th scatter/gather entry.
- * Gather Entries must be 2Byte aligned.
- */
-MLXSW_ITEM64_INDEXED(pci, wqe, address, 0x08, 0, 64, 0x8, 0x0, false);
-
-/* pci_cqe_lag
- * Packet arrives from a port which is a LAG
- */
-MLXSW_ITEM32(pci, cqe, lag, 0x00, 23, 1);
-
-/* pci_cqe_system_port/lag_id
- * When lag=0: System port on which the packet was received
- * When lag=1:
- * bits [15:4] LAG ID on which the packet was received
- * bits [3:0] sub_port on which the packet was received
- */
-MLXSW_ITEM32(pci, cqe, system_port, 0x00, 0, 16);
-MLXSW_ITEM32(pci, cqe, lag_id, 0x00, 4, 12);
-MLXSW_ITEM32(pci, cqe, lag_port_index, 0x00, 0, 4);
-
-/* pci_cqe_wqe_counter
- * WQE count of the WQEs completed on the associated dqn
- */
-MLXSW_ITEM32(pci, cqe, wqe_counter, 0x04, 16, 16);
-
-/* pci_cqe_byte_count
- * Byte count of received packets including additional two
- * Reserved Bytes that are append to the end of the frame.
- * Reserved for Send CQE.
- */
-MLXSW_ITEM32(pci, cqe, byte_count, 0x04, 0, 14);
-
-/* pci_cqe_trap_id
- * Trap ID that captured the packet.
- */
-MLXSW_ITEM32(pci, cqe, trap_id, 0x08, 0, 8);
-
-/* pci_cqe_crc
- * Length include CRC. Indicates the length field includes
- * the packet's CRC.
- */
-MLXSW_ITEM32(pci, cqe, crc, 0x0C, 8, 1);
-
-/* pci_cqe_e
- * CQE with Error.
- */
-MLXSW_ITEM32(pci, cqe, e, 0x0C, 7, 1);
-
-/* pci_cqe_sr
- * 1 - Send Queue
- * 0 - Receive Queue
- */
-MLXSW_ITEM32(pci, cqe, sr, 0x0C, 6, 1);
-
-/* pci_cqe_dqn
- * Descriptor Queue (DQ) Number.
- */
-MLXSW_ITEM32(pci, cqe, dqn, 0x0C, 1, 5);
-
-/* pci_cqe_owner
- * Ownership bit.
- */
-MLXSW_ITEM32(pci, cqe, owner, 0x0C, 0, 1);
-
-/* pci_eqe_event_type
- * Event type.
- */
-MLXSW_ITEM32(pci, eqe, event_type, 0x0C, 24, 8);
-#define MLXSW_PCI_EQE_EVENT_TYPE_COMP 0x00
-#define MLXSW_PCI_EQE_EVENT_TYPE_CMD 0x0A
-
-/* pci_eqe_event_sub_type
- * Event type.
- */
-MLXSW_ITEM32(pci, eqe, event_sub_type, 0x0C, 16, 8);
-
-/* pci_eqe_cqn
- * Completion Queue that triggeret this EQE.
- */
-MLXSW_ITEM32(pci, eqe, cqn, 0x0C, 8, 7);
-
-/* pci_eqe_owner
- * Ownership bit.
- */
-MLXSW_ITEM32(pci, eqe, owner, 0x0C, 0, 1);
-
-/* pci_eqe_cmd_token
- * Command completion event - token
- */
-MLXSW_ITEM32(pci, eqe, cmd_token, 0x08, 16, 16);
-
-/* pci_eqe_cmd_status
- * Command completion event - status
- */
-MLXSW_ITEM32(pci, eqe, cmd_status, 0x08, 0, 8);
-
-/* pci_eqe_cmd_out_param_h
- * Command completion event - output parameter - higher part
- */
-MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x0C, 0, 32);
-
-/* pci_eqe_cmd_out_param_l
- * Command completion event - output parameter - lower part
- */
-MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x10, 0, 32);
-
-#endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
new file mode 100644
index 0000000..45bc1979
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
@@ -0,0 +1,231 @@
+/*
+ * drivers/net/ethernet/mellanox/mlxsw/pci_hw.h
+ * Copyright (c) 2015-2016 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2015-2016 Jiri Pirko <jiri@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MLXSW_PCI_HW_H
+#define _MLXSW_PCI_HW_H
+
+#include <linux/bitops.h>
+
+#include "item.h"
+
+#define PCI_DEVICE_ID_MELLANOX_SWITCHX2 0xc738
+#define PCI_DEVICE_ID_MELLANOX_SPECTRUM 0xcb84
+#define MLXSW_PCI_BAR0_SIZE (1024 * 1024) /* 1MB */
+#define MLXSW_PCI_PAGE_SIZE 4096
+
+#define MLXSW_PCI_CIR_BASE 0x71000
+#define MLXSW_PCI_CIR_IN_PARAM_HI MLXSW_PCI_CIR_BASE
+#define MLXSW_PCI_CIR_IN_PARAM_LO (MLXSW_PCI_CIR_BASE + 0x04)
+#define MLXSW_PCI_CIR_IN_MODIFIER (MLXSW_PCI_CIR_BASE + 0x08)
+#define MLXSW_PCI_CIR_OUT_PARAM_HI (MLXSW_PCI_CIR_BASE + 0x0C)
+#define MLXSW_PCI_CIR_OUT_PARAM_LO (MLXSW_PCI_CIR_BASE + 0x10)
+#define MLXSW_PCI_CIR_TOKEN (MLXSW_PCI_CIR_BASE + 0x14)
+#define MLXSW_PCI_CIR_CTRL (MLXSW_PCI_CIR_BASE + 0x18)
+#define MLXSW_PCI_CIR_CTRL_GO_BIT BIT(23)
+#define MLXSW_PCI_CIR_CTRL_EVREQ_BIT BIT(22)
+#define MLXSW_PCI_CIR_CTRL_OPCODE_MOD_SHIFT 12
+#define MLXSW_PCI_CIR_CTRL_STATUS_SHIFT 24
+#define MLXSW_PCI_CIR_TIMEOUT_MSECS 1000
+
+#define MLXSW_PCI_SW_RESET 0xF0010
+#define MLXSW_PCI_SW_RESET_RST_BIT BIT(0)
+#define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 5000
+#define MLXSW_PCI_FW_READY 0xA1844
+#define MLXSW_PCI_FW_READY_MASK 0xFF
+#define MLXSW_PCI_FW_READY_MAGIC 0x5E
+
+#define MLXSW_PCI_DOORBELL_SDQ_OFFSET 0x000
+#define MLXSW_PCI_DOORBELL_RDQ_OFFSET 0x200
+#define MLXSW_PCI_DOORBELL_CQ_OFFSET 0x400
+#define MLXSW_PCI_DOORBELL_EQ_OFFSET 0x600
+#define MLXSW_PCI_DOORBELL_ARM_CQ_OFFSET 0x800
+#define MLXSW_PCI_DOORBELL_ARM_EQ_OFFSET 0xA00
+
+#define MLXSW_PCI_DOORBELL(offset, type_offset, num) \
+ ((offset) + (type_offset) + (num) * 4)
+
+#define MLXSW_PCI_CQS_MAX 96
+#define MLXSW_PCI_EQS_COUNT 2
+#define MLXSW_PCI_EQ_ASYNC_NUM 0
+#define MLXSW_PCI_EQ_COMP_NUM 1
+
+#define MLXSW_PCI_AQ_PAGES 8
+#define MLXSW_PCI_AQ_SIZE (MLXSW_PCI_PAGE_SIZE * MLXSW_PCI_AQ_PAGES)
+#define MLXSW_PCI_WQE_SIZE 32 /* 32 bytes per element */
+#define MLXSW_PCI_CQE_SIZE 16 /* 16 bytes per element */
+#define MLXSW_PCI_EQE_SIZE 16 /* 16 bytes per element */
+#define MLXSW_PCI_WQE_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_WQE_SIZE)
+#define MLXSW_PCI_CQE_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_CQE_SIZE)
+#define MLXSW_PCI_EQE_COUNT (MLXSW_PCI_AQ_SIZE / MLXSW_PCI_EQE_SIZE)
+#define MLXSW_PCI_EQE_UPDATE_COUNT 0x80
+
+#define MLXSW_PCI_WQE_SG_ENTRIES 3
+#define MLXSW_PCI_WQE_TYPE_ETHERNET 0xA
+
+/* pci_wqe_c
+ * If set it indicates that a completion should be reported upon
+ * execution of this descriptor.
+ */
+MLXSW_ITEM32(pci, wqe, c, 0x00, 31, 1);
+
+/* pci_wqe_lp
+ * Local Processing, set if packet should be processed by the local
+ * switch hardware:
+ * For Ethernet EMAD (Direct Route and non Direct Route) -
+ * must be set if packet destination is local device
+ * For InfiniBand CTL - must be set if packet destination is local device
+ * Otherwise it must be clear
+ * Local Process packets must not exceed the size of 2K (including payload
+ * and headers).
+ */
+MLXSW_ITEM32(pci, wqe, lp, 0x00, 30, 1);
+
+/* pci_wqe_type
+ * Packet type.
+ */
+MLXSW_ITEM32(pci, wqe, type, 0x00, 23, 4);
+
+/* pci_wqe_byte_count
+ * Size of i-th scatter/gather entry, 0 if entry is unused.
+ */
+MLXSW_ITEM16_INDEXED(pci, wqe, byte_count, 0x02, 0, 14, 0x02, 0x00, false);
+
+/* pci_wqe_address
+ * Physical address of i-th scatter/gather entry.
+ * Gather Entries must be 2Byte aligned.
+ */
+MLXSW_ITEM64_INDEXED(pci, wqe, address, 0x08, 0, 64, 0x8, 0x0, false);
+
+/* pci_cqe_lag
+ * Packet arrives from a port which is a LAG
+ */
+MLXSW_ITEM32(pci, cqe, lag, 0x00, 23, 1);
+
+/* pci_cqe_system_port/lag_id
+ * When lag=0: System port on which the packet was received
+ * When lag=1:
+ * bits [15:4] LAG ID on which the packet was received
+ * bits [3:0] sub_port on which the packet was received
+ */
+MLXSW_ITEM32(pci, cqe, system_port, 0x00, 0, 16);
+MLXSW_ITEM32(pci, cqe, lag_id, 0x00, 4, 12);
+MLXSW_ITEM32(pci, cqe, lag_port_index, 0x00, 0, 4);
+
+/* pci_cqe_wqe_counter
+ * WQE count of the WQEs completed on the associated dqn
+ */
+MLXSW_ITEM32(pci, cqe, wqe_counter, 0x04, 16, 16);
+
+/* pci_cqe_byte_count
+ * Byte count of received packets including additional two
+ * Reserved Bytes that are append to the end of the frame.
+ * Reserved for Send CQE.
+ */
+MLXSW_ITEM32(pci, cqe, byte_count, 0x04, 0, 14);
+
+/* pci_cqe_trap_id
+ * Trap ID that captured the packet.
+ */
+MLXSW_ITEM32(pci, cqe, trap_id, 0x08, 0, 8);
+
+/* pci_cqe_crc
+ * Length include CRC. Indicates the length field includes
+ * the packet's CRC.
+ */
+MLXSW_ITEM32(pci, cqe, crc, 0x0C, 8, 1);
+
+/* pci_cqe_e
+ * CQE with Error.
+ */
+MLXSW_ITEM32(pci, cqe, e, 0x0C, 7, 1);
+
+/* pci_cqe_sr
+ * 1 - Send Queue
+ * 0 - Receive Queue
+ */
+MLXSW_ITEM32(pci, cqe, sr, 0x0C, 6, 1);
+
+/* pci_cqe_dqn
+ * Descriptor Queue (DQ) Number.
+ */
+MLXSW_ITEM32(pci, cqe, dqn, 0x0C, 1, 5);
+
+/* pci_cqe_owner
+ * Ownership bit.
+ */
+MLXSW_ITEM32(pci, cqe, owner, 0x0C, 0, 1);
+
+/* pci_eqe_event_type
+ * Event type.
+ */
+MLXSW_ITEM32(pci, eqe, event_type, 0x0C, 24, 8);
+#define MLXSW_PCI_EQE_EVENT_TYPE_COMP 0x00
+#define MLXSW_PCI_EQE_EVENT_TYPE_CMD 0x0A
+
+/* pci_eqe_event_sub_type
+ * Event type.
+ */
+MLXSW_ITEM32(pci, eqe, event_sub_type, 0x0C, 16, 8);
+
+/* pci_eqe_cqn
+ * Completion Queue that triggeret this EQE.
+ */
+MLXSW_ITEM32(pci, eqe, cqn, 0x0C, 8, 7);
+
+/* pci_eqe_owner
+ * Ownership bit.
+ */
+MLXSW_ITEM32(pci, eqe, owner, 0x0C, 0, 1);
+
+/* pci_eqe_cmd_token
+ * Command completion event - token
+ */
+MLXSW_ITEM32(pci, eqe, cmd_token, 0x08, 16, 16);
+
+/* pci_eqe_cmd_status
+ * Command completion event - status
+ */
+MLXSW_ITEM32(pci, eqe, cmd_status, 0x08, 0, 8);
+
+/* pci_eqe_cmd_out_param_h
+ * Command completion event - output parameter - higher part
+ */
+MLXSW_ITEM32(pci, eqe, cmd_out_param_h, 0x0C, 0, 32);
+
+/* pci_eqe_cmd_out_param_l
+ * Command completion event - output parameter - lower part
+ */
+MLXSW_ITEM32(pci, eqe, cmd_out_param_l, 0x10, 0, 32);
+
+#endif
--
2.5.5
^ permalink raw reply related
* Re: [RFC net-next iproute2 1/2] libnetlink: Add test for error code returned from netlink reply
From: Cyrill Gorcunov @ 2016-10-27 8:24 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Eric Dumazet, David Ahern, Andrey Vagin
In-Reply-To: <20161027065253.GB1867@uranus.lan>
On Thu, Oct 27, 2016 at 09:52:53AM +0300, Cyrill Gorcunov wrote:
...
> >
> > This looks like a mistake in how you implemented the functionality in the kernel.
> > Despite what it looks like, all netlink request/reply functionality reports
> > errors in current implementation by returning error to the sendmsg request.
> >
> > What you added implies that the new kernel api is wrong, or many other usages
> > are wrong. Please fix the kernel.
>
> No. This is not my code. This code has been in kernel for the really long time.
> I don't know why you've not been doing such test in libnetlink before.
>
> Actually I've hit this problem accidentaly -- I made a patch 2 from this
> set and run it on the machine where kernel was unpatched, ie without
> raw-diag module, and I found that we can't figure out if kernel notified
> us that some diag module simply not present in the system. And here is
> the only way to find it out.
Also, drop this series for a while, I'll resend new one: the status of
diag should not be tested unconditionally with NLMSG_DONE because the
rtnl_dump_filter_l helper is used not only for diag talks but overall
the iproute2, thus I need to test for status only for specified requests.
And I need to narrow down why not all device bound interfaces are killed
in one pass.
Cyrill
^ permalink raw reply
* Re: [bnx2] [Regression 4.8] Driver loading fails without firmware
From: Paul Menzel @ 2016-10-27 13:21 UTC (permalink / raw)
To: Baoquan He
Cc: Sony Chacko, Dept-HSGLinuxNICDev, netdev, David S. Miller, dvteam
In-Reply-To: <20161026120021.GA4402@x1>
[-- Attachment #1: Type: text/plain, Size: 1536 bytes --]
Dear Baoquan,
On 10/26/16 14:00, Baoquan He wrote:
> On 10/26/16 at 12:31pm, Paul Menzel wrote:
>>>> dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
>>>> @@ -8607,6 +8608,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct
>>>> pci_device_id *ent)
>>>> return 0;
>>>>
>>>> error:
>>>> + bnx2_release_firmware(bp);
>>>> pci_iounmap(pdev, bp->regview);
>>>> pci_release_regions(pdev);
>>>> pci_disable_device(pdev);
>>
>> Baoquan, could you please fix this regression. My suggestion is, that you
>> add the old code back, but check if the firmware has been loaded. If it
>> hasn’t, load it again.
>>
>> That way, people can update their Linux kernel, and it continues working
>> without changing the initramfs, or anything else.
>
> I saw your mail but I am also not familiar with bnx2 driver. As the
> commit log says I just tried to make bnx2 driver reset itself earlier.
>
> So you did a git bisect and found this commit caused the regression,
> right? If yes, and network developers have no action, I will look into
> the code and see if I have idea to fix it.
Well, I looked through the commits and found that one, which would
explain the changed behavior.
To be sure, and to follow your request, I took Linux 4.8.4 and reverted
your commit (attached). Then I deleted the firmware again from the
initramfs, and rebooted. The devices showed up just fine as before.
So to summarize, the commit is indeed the culprit.
Thank you for looking into this.
Kind regards,
Paul
[-- Attachment #2: 0001-Revert-bnx2-Reset-device-during-driver-initializatio.patch --]
[-- Type: text/x-patch, Size: 1579 bytes --]
>From 61b8dac8796343a797858b4a2eb0a59a0cfcd735 Mon Sep 17 00:00:00 2001
From: Paul Menzel <pmenzel@molgen.mpg.de>
Date: Thu, 27 Oct 2016 11:34:52 +0200
Subject: [PATCH] Revert "bnx2: Reset device during driver initialization"
This reverts commit 3e1be7ad2d38c6bd6aeef96df9bd0a7822f4e51c.
---
drivers/net/ethernet/broadcom/bnx2.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
index 27f11a5..ecd357d 100644
--- a/drivers/net/ethernet/broadcom/bnx2.c
+++ b/drivers/net/ethernet/broadcom/bnx2.c
@@ -6356,6 +6356,10 @@ bnx2_open(struct net_device *dev)
struct bnx2 *bp = netdev_priv(dev);
int rc;
+ rc = bnx2_request_firmware(bp);
+ if (rc < 0)
+ goto out;
+
netif_carrier_off(dev);
bnx2_disable_int(bp);
@@ -6424,6 +6428,7 @@ bnx2_open(struct net_device *dev)
bnx2_free_irq(bp);
bnx2_free_mem(bp);
bnx2_del_napi(bp);
+ bnx2_release_firmware(bp);
goto out;
}
@@ -8570,12 +8575,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
- rc = bnx2_request_firmware(bp);
- if (rc < 0)
- goto error;
-
-
- bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
@@ -8608,7 +8607,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
error:
- bnx2_release_firmware(bp);
pci_iounmap(pdev, bp->regview);
pci_release_regions(pdev);
pci_disable_device(pdev);
--
2.4.1
^ permalink raw reply related
* Re: [PATCH 0/2] at803x: don't power-down SGMII link
From: Zefir Kurtisi @ 2016-10-27 8:05 UTC (permalink / raw)
To: Timur Tabi, netdev; +Cc: andrew, f.fainelli
In-Reply-To: <580F96E9.8090208@codeaurora.org>
On 10/25/2016 07:31 PM, Timur Tabi wrote:
> Zefir Kurtisi wrote:
>> In a device where the ar8031 operates in SGMII mode, we
>> observed that after a suspend-resume cycle in very rare
>> cases the copper side autonegotiation secceeds but the
>> SGMII side fails to come up.
>>
>> As a work-around, a patch was provided that on suspend and
>> resume powers the SGMII link down and up along with the
>> copper side. This fixed the observed failure, but
>> introduced a regression Timur Tabi observed: once the SGMII
>> is powered down, the PHY is inaccessible by the CPU and
>> with that e.g. can't be re-initialized after suspend.
>>
>> Since the original issue could not be reproduced by others,
>> this series provides an alternative handling:
>> * the first patch reverts the prvious fix that powers down
>> SGMII
>> * the second patch adds double-checking for the observed
>> failure condition
>>
>> Zefir Kurtisi (2):
>> Revert "at803x: fix suspend/resume for SGMII link"
>> at803x: double check SGMII side autoneg
>
> Tested-by: Timur Tabi <timur@codeaurora.org>
>
> With these patches, the problem I was seeing no longer occurs, and the new code
> does not appear to break anything. As before, I still have never seen the
> original problem, but this patchset seems to work for both of us.
>
Thanks for testing.
I could make the double checking configurable and disabled by default, but this
would render it useless to detect the potential issue in the field.
^ permalink raw reply
* [PATCH net 10/10] net/mlx4_en: Save slave ethtool stats command
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
Following the previous patch, as an optimization, the slave will
not even bother sending the DUMP_ETH_STATS command over the
comm channel.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 314f54c8dbed..12c99a2655f2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1917,8 +1917,9 @@ static void mlx4_en_clear_stats(struct net_device *dev)
struct mlx4_en_dev *mdev = priv->mdev;
int i;
- if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
- en_dbg(HW, priv, "Failed dumping statistics\n");
+ if (!mlx4_is_slave(mdev->dev))
+ if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
+ en_dbg(HW, priv, "Failed dumping statistics\n");
memset(&priv->pstats, 0, sizeof(priv->pstats));
memset(&priv->pkstats, 0, sizeof(priv->pkstats));
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 09/10] net/mlx4_en: Fix potential deadlock in port statistics flow
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Jack Morgenstein, Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Jack Morgenstein <jackm@dev.mellanox.co.il>
mlx4_en_DUMP_ETH_STATS took the *counter mutex* and then
called the FW command, with WRAPPED attribute. As a result, the fw command
is wrapped on the Hypervisor when it calls mlx4_en_DUMP_ETH_STATS.
The FW command wrapper flow on the hypervisor takes the *slave_cmd_mutex*
during processing.
At the same time, a VF could be in the process of coming up, and could
call mlx4_QUERY_FUNC_CAP. On the hypervisor, the command flow takes the
*slave_cmd_mutex*, then executes mlx4_QUERY_FUNC_CAP_wrapper.
mlx4_QUERY_FUNC_CAP wrapper calls mlx4_get_default_counter_index(),
which takes the *counter mutex*. DEADLOCK.
The fix is that the DUMP_ETH_STATS fw command should be called with
the NATIVE attribute, so that on the hypervisor, this command does not
enter the wrapper flow.
Since the Hypervisor no longer goes through the wrapper code, we also
simply return 0 in mlx4_DUMP_ETH_STATS_wrapper (i.e.the function succeeds,
but the returned data will be all zeroes).
No need to test if it is the Hypervisor going through the wrapper.
Fixes: f9baff509f8a ("mlx4_core: Add "native" argument to mlx4_cmd ...")
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/en_port.c | 4 ++--
drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 --
drivers/net/ethernet/mellanox/mlx4/port.c | 13 +------------
3 files changed, 3 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c
index 5aa8b751f417..59473a0ebcdf 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c
@@ -166,7 +166,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
return PTR_ERR(mailbox);
err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, in_mod, 0,
MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
- MLX4_CMD_WRAPPED);
+ MLX4_CMD_NATIVE);
if (err)
goto out;
@@ -322,7 +322,7 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma,
in_mod | MLX4_DUMP_ETH_STATS_FLOW_CONTROL,
0, MLX4_CMD_DUMP_ETH_STATS,
- MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
+ MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE);
if (err)
goto out;
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index 7aad07644289..88ee7d8a5923 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -1330,8 +1330,6 @@ int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_cmd_info *cmd);
int mlx4_common_set_vlan_fltr(struct mlx4_dev *dev, int function,
int port, void *buf);
-int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave, u32 in_mod,
- struct mlx4_cmd_mailbox *outbox);
int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr,
struct mlx4_cmd_mailbox *inbox,
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c
index c5b2064297a1..b656dd5772e5 100644
--- a/drivers/net/ethernet/mellanox/mlx4/port.c
+++ b/drivers/net/ethernet/mellanox/mlx4/port.c
@@ -1728,24 +1728,13 @@ int mlx4_SET_VLAN_FLTR_wrapper(struct mlx4_dev *dev, int slave,
return err;
}
-int mlx4_common_dump_eth_stats(struct mlx4_dev *dev, int slave,
- u32 in_mod, struct mlx4_cmd_mailbox *outbox)
-{
- return mlx4_cmd_box(dev, 0, outbox->dma, in_mod, 0,
- MLX4_CMD_DUMP_ETH_STATS, MLX4_CMD_TIME_CLASS_B,
- MLX4_CMD_NATIVE);
-}
-
int mlx4_DUMP_ETH_STATS_wrapper(struct mlx4_dev *dev, int slave,
struct mlx4_vhcr *vhcr,
struct mlx4_cmd_mailbox *inbox,
struct mlx4_cmd_mailbox *outbox,
struct mlx4_cmd_info *cmd)
{
- if (slave != dev->caps.function)
- return 0;
- return mlx4_common_dump_eth_stats(dev, slave,
- vhcr->in_modifier, outbox);
+ return 0;
}
int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 07/10] net/mlx4_core: Do not access comm channel if it has not yet been initialized
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Jack Morgenstein, Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Jack Morgenstein <jackm@dev.mellanox.co.il>
In the Hypervisor, there are several FW commands which are invoked
before the comm channel is initialized (in mlx4_multi_func_init).
These include MOD_STAT_CONFIG, QUERY_DEV_CAP, INIT_HCA, and others.
If any of these commands fails, say with a timeout, the Hypervisor
driver enters the internal error reset flow. In this flow, the driver
attempts to notify all slaves via the comm channel that an internal error
has occurred.
Since the comm channel has not yet been initialized (i.e., mapped via
ioremap), this will cause dereferencing a NULL pointer.
To fix this, do not access the comm channel in the internal error flow
if it has not yet been initialized.
Fixes: 55ad359225b2 ("net/mlx4_core: Enable device recovery flow with SRIOV")
Fixes: ab9c17a009ee ("mlx4_core: Modify driver initialization flow to accommodate SRIOV for Ethernet")
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c
index b1cef7a0f7ca..e36bebcab3f2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c
@@ -2469,6 +2469,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev)
kfree(priv->mfunc.master.slave_state);
err_comm:
iounmap(priv->mfunc.comm);
+ priv->mfunc.comm = NULL;
err_vhcr:
dma_free_coherent(&dev->persist->pdev->dev, PAGE_SIZE,
priv->mfunc.vhcr,
@@ -2537,6 +2538,13 @@ void mlx4_report_internal_err_comm_event(struct mlx4_dev *dev)
int slave;
u32 slave_read;
+ /* If the comm channel has not yet been initialized,
+ * skip reporting the internal error event to all
+ * the communication channels.
+ */
+ if (!priv->mfunc.comm)
+ return;
+
/* Report an internal error event to all
* communication channels.
*/
@@ -2571,6 +2579,7 @@ void mlx4_multi_func_cleanup(struct mlx4_dev *dev)
}
iounmap(priv->mfunc.comm);
+ priv->mfunc.comm = NULL;
}
void mlx4_cmd_cleanup(struct mlx4_dev *dev, int cleanup_mask)
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 05/10] net/mlx4_en: Process all completions in RX rings after port goes up
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Eran Ben Elisha, Erez Shitrit, Eugenia Emantayev,
Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Erez Shitrit <erezsh@mellanox.com>
Currently there is a race between incoming traffic and
initialization flow. HW is able to receive the packets
after INIT_PORT is done and unicast steering is configured.
Before we set priv->port_up NAPI is not scheduled and
receive queues become full. Therefore we never get
new interrupts about the completions.
This issue could happen if running heavy traffic during
bringing port up.
The resolution is to schedule NAPI once port_up is set.
If receive queues were full this will process all cqes
and release them.
Fixes: c27a02cd94d6 ("mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC")
Signed-off-by: Erez Shitrit <erezsh@mellanox.com>
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index 7e703bed7b82..e25c11dff525 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -1733,6 +1733,13 @@ int mlx4_en_start_port(struct net_device *dev)
udp_tunnel_get_rx_info(dev);
priv->port_up = true;
+
+ /* Process all completions if exist to prevent
+ * the queues freezing if they are full
+ */
+ for (i = 0; i < priv->rx_ring_num; i++)
+ napi_schedule(&priv->rx_cq[i]->napi);
+
netif_tx_start_all_queues(dev);
netif_device_attach(dev);
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 04/10] net/mlx4_en: Resolve dividing by zero in 32-bit system
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Eugenia Emantayev, Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Eugenia Emantayev <eugenia@mellanox.com>
When doing roundup_pow_of_two for large enough number with
bit 31, an overflow will occur and a value equal to 1 will
be returned. In this case 1 will be subtracted from the return
value and division by zero will be reached.
Fixes: 31c128b66e5b ("net/mlx4_en: Choose time-stamping shift value according to HW frequency")
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/en_clock.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
index 08fc5fc56d43..a5fc46bbcbe2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
@@ -245,8 +245,11 @@ static u32 freq_to_shift(u16 freq)
{
u32 freq_khz = freq * 1000;
u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
+ u64 tmp_rounded =
+ roundup_pow_of_two(max_val_cycles) > max_val_cycles ?
+ roundup_pow_of_two(max_val_cycles) - 1 : UINT_MAX;
u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ?
- max_val_cycles : roundup_pow_of_two(max_val_cycles) - 1;
+ max_val_cycles : tmp_rounded;
/* calculate max possible multiplier in order to fit in 64bit */
u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded);
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 06/10] net/mlx4_en: Fix panic during reboot
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Eugenia Emantayev, Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Eugenia Emantayev <eugenia@mellanox.com>
Fix a kernel panic that occurs as a result of an asynchronous event
handled in roce_gid_mgmt:
mlx4_en_get_drvinfo is called and accesses freed resources.
This happens in a shutdown flow only, since pci device is destroyed
while netdevice is still alive.
Fixes: c27a02cd94d6 ("mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC")
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
index e25c11dff525..314f54c8dbed 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
@@ -2201,6 +2201,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
if (!shutdown)
free_netdev(dev);
+ dev->ethtool_ops = NULL;
}
static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 08/10] net/mlx4: Fix firmware command timeout during interrupt test
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Eugenia Emantayev, Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Eugenia Emantayev <eugenia@mellanox.com>
Currently interrupt test that is part of ethtool selftest runs the
check over all interrupt vectors of the device.
In mlx4_en package part of interrupt vectors are uninitialized since
mlx4_ib doesn't exist. This causes NOP FW command to time out.
Change logic to test current port interrupt vectors only.
Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 26 +++++++++-
drivers/net/ethernet/mellanox/mlx4/eq.c | 62 +++++++++++-------------
include/linux/mlx4/device.h | 3 +-
3 files changed, 55 insertions(+), 36 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
index b66e03d9711f..c06346a82496 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_selftest.c
@@ -118,6 +118,29 @@ static int mlx4_en_test_loopback(struct mlx4_en_priv *priv)
return !loopback_ok;
}
+static int mlx4_en_test_interrupts(struct mlx4_en_priv *priv)
+{
+ struct mlx4_en_dev *mdev = priv->mdev;
+ int err = 0;
+ int i = 0;
+
+ err = mlx4_test_async(mdev->dev);
+ /* When not in MSI_X or slave, test only async */
+ if (!(mdev->dev->flags & MLX4_FLAG_MSI_X) || mlx4_is_slave(mdev->dev))
+ return err;
+
+ /* A loop over all completion vectors of current port,
+ * for each vector check whether it works by mapping command
+ * completions to that vector and performing a NOP command
+ */
+ for (i = 0; i < priv->rx_ring_num; i++) {
+ err = mlx4_test_interrupt(mdev->dev, priv->rx_cq[i]->vector);
+ if (err)
+ break;
+ }
+
+ return err;
+}
static int mlx4_en_test_link(struct mlx4_en_priv *priv)
{
@@ -151,7 +174,6 @@ static int mlx4_en_test_speed(struct mlx4_en_priv *priv)
void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf)
{
struct mlx4_en_priv *priv = netdev_priv(dev);
- struct mlx4_en_dev *mdev = priv->mdev;
int i, carrier_ok;
memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST);
@@ -177,7 +199,7 @@ void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf)
netif_carrier_on(dev);
}
- buf[0] = mlx4_test_interrupts(mdev->dev);
+ buf[0] = mlx4_en_test_interrupts(priv);
buf[1] = mlx4_en_test_link(priv);
buf[2] = mlx4_en_test_speed(priv);
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index cf8f8a72a801..cd3638e6fe25 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -1361,53 +1361,49 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev)
kfree(priv->eq_table.uar_map);
}
-/* A test that verifies that we can accept interrupts on all
- * the irq vectors of the device.
+/* A test that verifies that we can accept interrupts
+ * on the vector allocated for asynchronous events
+ */
+int mlx4_test_async(struct mlx4_dev *dev)
+{
+ return mlx4_NOP(dev);
+}
+EXPORT_SYMBOL(mlx4_test_async);
+
+/* A test that verifies that we can accept interrupts
+ * on the given irq vector of the tested port.
* Interrupts are checked using the NOP command.
*/
-int mlx4_test_interrupts(struct mlx4_dev *dev)
+int mlx4_test_interrupt(struct mlx4_dev *dev, int vector)
{
struct mlx4_priv *priv = mlx4_priv(dev);
- int i;
int err;
- err = mlx4_NOP(dev);
- /* When not in MSI_X, there is only one irq to check */
- if (!(dev->flags & MLX4_FLAG_MSI_X) || mlx4_is_slave(dev))
- return err;
-
- /* A loop over all completion vectors, for each vector we will check
- * whether it works by mapping command completions to that vector
- * and performing a NOP command
- */
- for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) {
- /* Make sure request_irq was called */
- if (!priv->eq_table.eq[i].have_irq)
- continue;
-
- /* Temporary use polling for command completions */
- mlx4_cmd_use_polling(dev);
-
- /* Map the new eq to handle all asynchronous events */
- err = mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 0,
- priv->eq_table.eq[i].eqn);
- if (err) {
- mlx4_warn(dev, "Failed mapping eq for interrupt test\n");
- mlx4_cmd_use_events(dev);
- break;
- }
+ /* Temporary use polling for command completions */
+ mlx4_cmd_use_polling(dev);
- /* Go back to using events */
- mlx4_cmd_use_events(dev);
- err = mlx4_NOP(dev);
+ /* Map the new eq to handle all asynchronous events */
+ err = mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 0,
+ priv->eq_table.eq[MLX4_CQ_TO_EQ_VECTOR(vector)].eqn);
+ if (err) {
+ mlx4_warn(dev, "Failed mapping eq for interrupt test\n");
+ goto out;
}
+ /* Go back to using events */
+ mlx4_cmd_use_events(dev);
+ err = mlx4_NOP(dev);
+
/* Return to default */
+ mlx4_cmd_use_polling(dev);
+out:
mlx4_MAP_EQ(dev, get_async_ev_mask(dev), 0,
priv->eq_table.eq[MLX4_EQ_ASYNC].eqn);
+ mlx4_cmd_use_events(dev);
+
return err;
}
-EXPORT_SYMBOL(mlx4_test_interrupts);
+EXPORT_SYMBOL(mlx4_test_interrupt);
bool mlx4_is_eq_vector_valid(struct mlx4_dev *dev, u8 port, int vector)
{
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index f6a164297358..3be7abd6e722 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -1399,7 +1399,8 @@ void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr,
u32 *lkey, u32 *rkey);
int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr);
int mlx4_SYNC_TPT(struct mlx4_dev *dev);
-int mlx4_test_interrupts(struct mlx4_dev *dev);
+int mlx4_test_interrupt(struct mlx4_dev *dev, int vector);
+int mlx4_test_async(struct mlx4_dev *dev);
int mlx4_query_diag_counters(struct mlx4_dev *dev, u8 op_modifier,
const u32 offset[], u32 value[],
size_t array_len, u8 port);
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 03/10] net/mlx4_core: Change the default value of enable_qos
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Moshe Lazer, Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Moshe Lazer <moshel@mellanox.com>
Change the default status of quality of service back to disabled,
as it hurts performance in some cases.
Fixes: 38438f7c7e8c ("net/mlx4: Set enhanced QoS support by default when ...")
Signed-off-by: Moshe Lazer <moshel@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/fw.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index c41ab31a39f8..84bab9f0732e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -49,9 +49,9 @@ enum {
extern void __buggy_use_of_MLX4_GET(void);
extern void __buggy_use_of_MLX4_PUT(void);
-static bool enable_qos = true;
+static bool enable_qos;
module_param(enable_qos, bool, 0444);
-MODULE_PARM_DESC(enable_qos, "Enable Enhanced QoS support (default: on)");
+MODULE_PARM_DESC(enable_qos, "Enable Enhanced QoS support (default: off)");
#define MLX4_GET(dest, source, offset) \
do { \
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 01/10] net/mlx4_core: Fix the resource-type enum in res tracker to conform to FW spec
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Eran Ben Elisha, Jack Morgenstein, Moshe Shemesh,
Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Jack Morgenstein <jackm@dev.mellanox.co.il>
The resource type enum in the resource tracker was incorrect.
RES_EQ was put in the position of RES_NPORT_ID (a FC resource).
Since the remaining resources maintain their current values,
and RES_EQ is not passed from slaves to the hypervisor in any
FW command, this change affects only the hypervisor.
Therefore, there is no backwards-compatibility issue.
Fixes: 623ed84b1f95 ("mlx4_core: initial header-file changes for SRIOV support")
Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/mlx4.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index e4878f31e45d..7aad07644289 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -145,9 +145,10 @@ enum mlx4_resource {
RES_MTT,
RES_MAC,
RES_VLAN,
- RES_EQ,
+ RES_NPORT_ID,
RES_COUNTER,
RES_FS_RULE,
+ RES_EQ,
MLX4_NUM_OF_RESOURCE_TYPE
};
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 02/10] net/mlx4_core: Avoid setting ports to auto when only one port type is supported
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller
Cc: netdev, Eran Ben Elisha, Maor Gottlieb, Moshe Shemesh,
Tariq Toukan
In-Reply-To: <1477574842-29688-1-git-send-email-tariqt@mellanox.com>
From: Maor Gottlieb <maorg@mellanox.com>
When only one port type is supported, it should be read only.
We reject changing requests, even to the auto sense mode.
Fixes: 27bf91d6a0d5 ("mlx4_core: Add link type autosensing")
Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx4/main.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 7183ac4135d2..6f4e67bc3538 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -1102,6 +1102,14 @@ static int __set_port_type(struct mlx4_port_info *info,
int i;
int err = 0;
+ if ((port_type & mdev->caps.supported_type[info->port]) != port_type) {
+ mlx4_err(mdev,
+ "Requested port type for port %d is not supported on this HCA\n",
+ info->port);
+ err = -EINVAL;
+ goto err_sup;
+ }
+
mlx4_stop_sense(mdev);
mutex_lock(&priv->port_mutex);
info->tmp_type = port_type;
@@ -1147,7 +1155,7 @@ static int __set_port_type(struct mlx4_port_info *info,
out:
mlx4_start_sense(mdev);
mutex_unlock(&priv->port_mutex);
-
+err_sup:
return err;
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH net 00/10] mlx4 misc fixes for 4.9
From: Tariq Toukan @ 2016-10-27 13:27 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, Eran Ben Elisha, Tariq Toukan
Hi Dave,
This patchset contains several bug fixes from the team to the
mlx4 Eth and Core drivers.
Series generated against net commit:
ecc515d7238f 'sctp: fix the panic caused by route update'
Thanks,
Tariq.
Erez Shitrit (1):
net/mlx4_en: Process all completions in RX rings after port goes up
Eugenia Emantayev (3):
net/mlx4_en: Resolve dividing by zero in 32-bit system
net/mlx4_en: Fix panic during reboot
net/mlx4: Fix firmware command timeout during interrupt test
Jack Morgenstein (3):
net/mlx4_core: Fix the resource-type enum in res tracker to conform to
FW spec
net/mlx4_core: Do not access comm channel if it has not yet been
initialized
net/mlx4_en: Fix potential deadlock in port statistics flow
Maor Gottlieb (1):
net/mlx4_core: Avoid setting ports to auto when only one port type is
supported
Moshe Lazer (1):
net/mlx4_core: Change the default value of enable_qos
Tariq Toukan (1):
net/mlx4_en: Save slave ethtool stats command
drivers/net/ethernet/mellanox/mlx4/cmd.c | 9 ++++
drivers/net/ethernet/mellanox/mlx4/en_clock.c | 5 +-
drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 13 ++++-
drivers/net/ethernet/mellanox/mlx4/en_port.c | 4 +-
drivers/net/ethernet/mellanox/mlx4/en_selftest.c | 26 +++++++++-
drivers/net/ethernet/mellanox/mlx4/eq.c | 62 +++++++++++-------------
drivers/net/ethernet/mellanox/mlx4/fw.c | 4 +-
drivers/net/ethernet/mellanox/mlx4/main.c | 10 +++-
drivers/net/ethernet/mellanox/mlx4/mlx4.h | 5 +-
drivers/net/ethernet/mellanox/mlx4/port.c | 13 +----
include/linux/mlx4/device.h | 3 +-
11 files changed, 95 insertions(+), 59 deletions(-)
--
1.8.3.1
^ permalink raw reply
* Re: [PATCH v6 3/4] cfg80211: configure multicast to unicast for AP interfaces
From: Johannes Berg @ 2016-10-27 12:20 UTC (permalink / raw)
To: Michael Braun; +Cc: linux-wireless, projekt-wlan, netdev
In-Reply-To: <1476119543-24509-3-git-send-email-michael-dev@fami-braun.de>
On Mon, 2016-10-10 at 19:12 +0200, Michael Braun wrote:
> This add a userspace toggle to configure multicast to unicast.
>
I applied this, with a bunch of fixes and documentation improvements.
johannes
^ permalink raw reply
* [PATCH net-next v3 7/9] ipv6: add source address argument for ipv6_push_nfrag_opts
From: David Lebrun @ 2016-10-27 13:35 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1477575239-11228-1-git-send-email-david.lebrun@uclouvain.be>
This patch prepares for insertion of SRH through setsockopt().
The new source address argument is used when an HMAC field is
present in the SRH, which must be filled. The HMAC signature
process requires the source address as input text.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
include/net/ipv6.h | 3 ++-
net/ipv6/exthdrs.c | 6 +++---
net/ipv6/ip6_output.c | 5 +++--
net/ipv6/ip6_tunnel.c | 2 +-
4 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 8fed1cd..0a3622b 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -932,7 +932,8 @@ int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
*/
void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
- u8 *proto, struct in6_addr **daddr_p);
+ u8 *proto, struct in6_addr **daddr_p,
+ struct in6_addr *saddr);
void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
u8 *proto);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 9b63932..28d2629 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -874,7 +874,7 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
struct ipv6_rt_hdr *opt,
- struct in6_addr **addr_p)
+ struct in6_addr **addr_p, struct in6_addr *saddr)
{
struct rt0_hdr *phdr, *ihdr;
int hops;
@@ -908,10 +908,10 @@ static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv
void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
u8 *proto,
- struct in6_addr **daddr)
+ struct in6_addr **daddr, struct in6_addr *saddr)
{
if (opt->srcrt) {
- ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
+ ipv6_push_rthdr(skb, proto, opt->srcrt, daddr, saddr);
/*
* IPV6_RTHDRDSTOPTS is ignored
* unless IPV6_RTHDR is set (RFC3542).
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6001e78..ddc878d 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -203,7 +203,8 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
if (opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
if (opt->opt_nflen)
- ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
+ ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop,
+ &fl6->saddr);
}
skb_push(skb, sizeof(struct ipv6hdr));
@@ -1672,7 +1673,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk,
if (opt && opt->opt_flen)
ipv6_push_frag_opts(skb, opt, &proto);
if (opt && opt->opt_nflen)
- ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst);
+ ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst, &fl6->saddr);
skb_push(skb, sizeof(struct ipv6hdr));
skb_reset_network_header(skb);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 3a70567..9c894c9 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1155,7 +1155,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
if (encap_limit >= 0) {
init_tel_txopt(&opt, encap_limit);
- ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
+ ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL, NULL);
}
/* Calculate max headroom for all the headers and adjust
--
2.7.3
^ permalink raw reply related
* [PATCH net-next v3 8/9] ipv6: sr: add support for SRH injection through setsockopt
From: David Lebrun @ 2016-10-27 13:35 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1477575239-11228-1-git-send-email-david.lebrun@uclouvain.be>
This patch adds support for per-socket SRH injection with the setsockopt
system call through the IPPROTO_IPV6, IPV6_RTHDR options.
The SRH is pushed through the ipv6_push_nfrag_opts function.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
net/ipv6/exthdrs.c | 79 +++++++++++++++++++++++++++++++++++++++++++++---
net/ipv6/ipv6_sockglue.c | 2 ++
2 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 28d2629..489f9ea 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -872,9 +872,9 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
* for headers.
*/
-static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
- struct ipv6_rt_hdr *opt,
- struct in6_addr **addr_p, struct in6_addr *saddr)
+static void ipv6_push_rthdr0(struct sk_buff *skb, u8 *proto,
+ struct ipv6_rt_hdr *opt,
+ struct in6_addr **addr_p, struct in6_addr *saddr)
{
struct rt0_hdr *phdr, *ihdr;
int hops;
@@ -897,6 +897,62 @@ static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
*proto = NEXTHDR_ROUTING;
}
+static void ipv6_push_rthdr4(struct sk_buff *skb, u8 *proto,
+ struct ipv6_rt_hdr *opt,
+ struct in6_addr **addr_p, struct in6_addr *saddr)
+{
+ struct ipv6_sr_hdr *sr_phdr, *sr_ihdr;
+ int plen, hops;
+
+ sr_ihdr = (struct ipv6_sr_hdr *)opt;
+ plen = (sr_ihdr->hdrlen + 1) << 3;
+
+ sr_phdr = (struct ipv6_sr_hdr *)skb_push(skb, plen);
+ memcpy(sr_phdr, sr_ihdr, sizeof(struct ipv6_sr_hdr));
+
+ hops = sr_ihdr->first_segment + 1;
+ memcpy(sr_phdr->segments + 1, sr_ihdr->segments + 1,
+ (hops - 1) * sizeof(struct in6_addr));
+
+ sr_phdr->segments[0] = **addr_p;
+ *addr_p = &sr_ihdr->segments[hops - 1];
+
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ if (sr_has_hmac(sr_phdr)) {
+ struct net *net = NULL;
+
+ if (skb->dev)
+ net = dev_net(skb->dev);
+ else if (skb->sk)
+ net = sock_net(skb->sk);
+
+ WARN_ON(!net);
+
+ if (net)
+ seg6_push_hmac(net, saddr, sr_phdr);
+ }
+#endif
+
+ sr_phdr->nexthdr = *proto;
+ *proto = NEXTHDR_ROUTING;
+}
+
+static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
+ struct ipv6_rt_hdr *opt,
+ struct in6_addr **addr_p, struct in6_addr *saddr)
+{
+ switch (opt->type) {
+ case IPV6_SRCRT_TYPE_0:
+ ipv6_push_rthdr0(skb, proto, opt, addr_p, saddr);
+ break;
+ case IPV6_SRCRT_TYPE_4:
+ ipv6_push_rthdr4(skb, proto, opt, addr_p, saddr);
+ break;
+ default:
+ break;
+ }
+}
+
static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
{
struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
@@ -1138,7 +1194,22 @@ struct in6_addr *fl6_update_dst(struct flowi6 *fl6,
return NULL;
*orig = fl6->daddr;
- fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
+
+ switch (opt->srcrt->type) {
+ case IPV6_SRCRT_TYPE_0:
+ fl6->daddr = *((struct rt0_hdr *)opt->srcrt)->addr;
+ break;
+ case IPV6_SRCRT_TYPE_4:
+ {
+ struct ipv6_sr_hdr *srh = (struct ipv6_sr_hdr *)opt->srcrt;
+
+ fl6->daddr = srh->segments[srh->first_segment];
+ break;
+ }
+ default:
+ return NULL;
+ }
+
return orig;
}
EXPORT_SYMBOL_GPL(fl6_update_dst);
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 5330262..3fd6371 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -429,6 +429,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
break;
#endif
+ case IPV6_SRCRT_TYPE_4:
+ break;
default:
goto sticky_done;
}
--
2.7.3
^ permalink raw reply related
* [PATCH net-next v3 9/9] ipv6: sr: add documentation file for per-interface sysctls
From: David Lebrun @ 2016-10-27 13:35 UTC (permalink / raw)
To: netdev; +Cc: David Lebrun
In-Reply-To: <1477575239-11228-1-git-send-email-david.lebrun@uclouvain.be>
This patch adds documentation for some SR-related per-interface
sysctls.
Signed-off-by: David Lebrun <david.lebrun@uclouvain.be>
---
Documentation/networking/seg6-sysctl.txt | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 Documentation/networking/seg6-sysctl.txt
diff --git a/Documentation/networking/seg6-sysctl.txt b/Documentation/networking/seg6-sysctl.txt
new file mode 100644
index 0000000..bdbde23
--- /dev/null
+++ b/Documentation/networking/seg6-sysctl.txt
@@ -0,0 +1,18 @@
+/proc/sys/net/conf/<iface>/seg6_* variables:
+
+seg6_enabled - BOOL
+ Accept or drop SR-enabled IPv6 packets on this interface.
+
+ Relevant packets are those with SRH present and DA = local.
+
+ 0 - disabled (default)
+ not 0 - enabled
+
+seg6_require_hmac - INTEGER
+ Define HMAC policy for ingress SR-enabled packets on this interface.
+
+ -1 - Ignore HMAC field
+ 0 - Accept SR packets without HMAC, validate SR packets with HMAC
+ 1 - Drop SR packets without HMAC, validate SR packets with HMAC
+
+ Default is 0.
--
2.7.3
^ 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