* Re: qdisc spin lock
From: Michael Ma @ 2016-04-15 23:05 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Cong Wang, Linux Kernel Network Developers
In-Reply-To: <1460760854.10638.81.camel@edumazet-glaptop3.roam.corp.google.com>
2016-04-15 15:54 GMT-07:00 Eric Dumazet <eric.dumazet@gmail.com>:
> On Fri, 2016-04-15 at 15:46 -0700, Michael Ma wrote:
>> 2016-04-08 7:19 GMT-07:00 Eric Dumazet <eric.dumazet@gmail.com>:
>> > On Thu, 2016-03-31 at 16:48 -0700, Michael Ma wrote:
>> >> I didn't really know that multiple qdiscs can be isolated using MQ so
>> >> that each txq can be associated with a particular qdisc. Also we don't
>> >> really have multiple interfaces...
>> >>
>> >> With this MQ solution we'll still need to assign transmit queues to
>> >> different classes by doing some math on the bandwidth limit if I
>> >> understand correctly, which seems to be less convenient compared with
>> >> a solution purely within HTB.
>> >>
>> >> I assume that with this solution I can still share qdisc among
>> >> multiple transmit queues - please let me know if this is not the case.
>> >
>> > Note that this MQ + HTB thing works well, unless you use a bonding
>> > device. (Or you need the MQ+HTB on the slaves, with no way of sharing
>> > tokens between the slaves)
>> >
>> >
>> > https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=bb1d912323d5dd50e1079e389f4e964be14f0ae3
>> >
>> > bonding can not really be used as a true MQ device yet.
>> >
>> > I might send a patch to disable this 'bonding feature' if no slave sets
>> > a queue_id.
>> >
>> >
>> So there is no way of using this MQ solution when bonding interface is
>> used, right? Then modifying HTB might be the only solution?
>
> I probably can submit a bonding patch very soon if there is interest.
Would definitely appreciate that. If you can share the patch it will
be helpful as well. Let me know if I can help with this...
>
> Modifying HTB is way more complicated :(
>
>
>
^ permalink raw reply
* [PATCH net-next v2 0/7] net: dsa: mv88e6xxx: factorize switch info
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
This patchset factorizes the mv88e6xxx code by sharing a new extendable
info structure to store static data such as switch family, product
number, number of ports, number of databases and the name.
The next step is to add a "flags" bitmap member to the info structure in
order to simplify the shared code with a feature-based logic instead of
checking their family/ID.
This is a step forward having a single mv88e6xxx driver supporting many
similar devices, like any usual Linux driver.
Changes v1 -> v2:
- define PORT_SWITCH_ID_PROD_NUM_* values
- use plain struct mv88e6xxx_info
- remove non used yet ps->rev
Vivien Didelot (7):
net: dsa: mv88e6xxx: drop double ds assignment
net: dsa: mv88e6xxx: drop revision probing
net: dsa: mv88e6xxx: add switch info
net: dsa: mv88e6xxx: add family to info
net: dsa: mv88e6xxx: add number of ports to info
net: dsa: mv88e6xxx: add number of db to info
net: dsa: mv88e6xxx: remove switch ID
drivers/net/dsa/mv88e6123.c | 45 +++++-----
drivers/net/dsa/mv88e6131.c | 53 ++++++------
drivers/net/dsa/mv88e6171.c | 36 +++++---
drivers/net/dsa/mv88e6352.c | 55 ++++++++----
drivers/net/dsa/mv88e6xxx.c | 200 ++++++++++++--------------------------------
drivers/net/dsa/mv88e6xxx.h | 92 +++++++++-----------
6 files changed, 203 insertions(+), 278 deletions(-)
--
2.8.0
^ permalink raw reply
* [PATCH net-next v2 2/7] net: dsa: mv88e6xxx: drop revision probing
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1460762488-2633-1-git-send-email-vivien.didelot@savoirfairelinux.com>
There is no point in having special case for the revision when probing a
switch model. The code gets cluttered with unnecessary defines, and
leads to errors when code such as mv88e6131_setup compares
PORT_SWITCH_ID_6131_B2 to ps->id which mask the revision.
Drop every revision definitions, add a ps->rev variable for eventual
runtime checking and lookup only the product number.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 6 ------
drivers/net/dsa/mv88e6131.c | 2 --
drivers/net/dsa/mv88e6352.c | 6 ------
drivers/net/dsa/mv88e6xxx.c | 13 +------------
drivers/net/dsa/mv88e6xxx.h | 15 ---------------
5 files changed, 1 insertion(+), 41 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 88a812d..00c1121 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -19,14 +19,8 @@
static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
{ PORT_SWITCH_ID_6123, "Marvell 88E6123" },
- { PORT_SWITCH_ID_6123_A1, "Marvell 88E6123 (A1)" },
- { PORT_SWITCH_ID_6123_A2, "Marvell 88E6123 (A2)" },
{ PORT_SWITCH_ID_6161, "Marvell 88E6161" },
- { PORT_SWITCH_ID_6161_A1, "Marvell 88E6161 (A1)" },
- { PORT_SWITCH_ID_6161_A2, "Marvell 88E6161 (A2)" },
{ PORT_SWITCH_ID_6165, "Marvell 88E6165" },
- { PORT_SWITCH_ID_6165_A1, "Marvell 88E6165 (A1)" },
- { PORT_SWITCH_ID_6165_A2, "Marvell 88e6165 (A2)" },
};
static char *mv88e6123_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 6b2bcb0..df534da 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -21,7 +21,6 @@ static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
{ PORT_SWITCH_ID_6085, "Marvell 88E6085" },
{ PORT_SWITCH_ID_6095, "Marvell 88E6095/88E6095F" },
{ PORT_SWITCH_ID_6131, "Marvell 88E6131" },
- { PORT_SWITCH_ID_6131_B2, "Marvell 88E6131 (B2)" },
{ PORT_SWITCH_ID_6185, "Marvell 88E6185" },
};
@@ -109,7 +108,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
ps->num_ports = 11;
break;
case PORT_SWITCH_ID_6131:
- case PORT_SWITCH_ID_6131_B2:
ps->num_ports = 8;
break;
default:
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index dbd920e..30fc5f6 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -27,14 +27,8 @@ static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
{ PORT_SWITCH_ID_6176, "Marvell 88E6176" },
{ PORT_SWITCH_ID_6240, "Marvell 88E6240" },
{ PORT_SWITCH_ID_6320, "Marvell 88E6320" },
- { PORT_SWITCH_ID_6320_A1, "Marvell 88E6320 (A1)" },
- { PORT_SWITCH_ID_6320_A2, "Marvell 88e6320 (A2)" },
{ PORT_SWITCH_ID_6321, "Marvell 88E6321" },
- { PORT_SWITCH_ID_6321_A1, "Marvell 88E6321 (A1)" },
- { PORT_SWITCH_ID_6321_A2, "Marvell 88e6321 (A2)" },
{ PORT_SWITCH_ID_6352, "Marvell 88E6352" },
- { PORT_SWITCH_ID_6352_A0, "Marvell 88E6352 (A0)" },
- { PORT_SWITCH_ID_6352_A1, "Marvell 88E6352 (A1)" },
};
static char *mv88e6352_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 9985a0c..d7e309d 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -3083,20 +3083,9 @@ static char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
/* Look up the exact switch ID */
for (i = 0; i < num; ++i)
- if (table[i].id == ret)
+ if (table[i].id == (ret & 0xfff0))
return table[i].name;
- /* Look up only the product number */
- for (i = 0; i < num; ++i) {
- if (table[i].id == (ret & PORT_SWITCH_ID_PROD_NUM_MASK)) {
- dev_warn(&bus->dev,
- "unknown revision %d, using base switch 0x%x\n",
- ret & PORT_SWITCH_ID_REV_MASK,
- ret & PORT_SWITCH_ID_PROD_NUM_MASK);
- return table[i].name;
- }
- }
-
return NULL;
}
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 5d27dec..9242aea 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -68,8 +68,6 @@
#define PORT_PCS_CTRL_UNFORCED 0x03
#define PORT_PAUSE_CTRL 0x02
#define PORT_SWITCH_ID 0x03
-#define PORT_SWITCH_ID_PROD_NUM_MASK 0xfff0
-#define PORT_SWITCH_ID_REV_MASK 0x000f
#define PORT_SWITCH_ID_6031 0x0310
#define PORT_SWITCH_ID_6035 0x0350
#define PORT_SWITCH_ID_6046 0x0480
@@ -84,18 +82,11 @@
#define PORT_SWITCH_ID_6121 0x1040
#define PORT_SWITCH_ID_6122 0x1050
#define PORT_SWITCH_ID_6123 0x1210
-#define PORT_SWITCH_ID_6123_A1 0x1212
-#define PORT_SWITCH_ID_6123_A2 0x1213
#define PORT_SWITCH_ID_6131 0x1060
-#define PORT_SWITCH_ID_6131_B2 0x1066
#define PORT_SWITCH_ID_6152 0x1a40
#define PORT_SWITCH_ID_6155 0x1a50
#define PORT_SWITCH_ID_6161 0x1610
-#define PORT_SWITCH_ID_6161_A1 0x1612
-#define PORT_SWITCH_ID_6161_A2 0x1613
#define PORT_SWITCH_ID_6165 0x1650
-#define PORT_SWITCH_ID_6165_A1 0x1652
-#define PORT_SWITCH_ID_6165_A2 0x1653
#define PORT_SWITCH_ID_6171 0x1710
#define PORT_SWITCH_ID_6172 0x1720
#define PORT_SWITCH_ID_6175 0x1750
@@ -104,16 +95,10 @@
#define PORT_SWITCH_ID_6185 0x1a70
#define PORT_SWITCH_ID_6240 0x2400
#define PORT_SWITCH_ID_6320 0x1150
-#define PORT_SWITCH_ID_6320_A1 0x1151
-#define PORT_SWITCH_ID_6320_A2 0x1152
#define PORT_SWITCH_ID_6321 0x3100
-#define PORT_SWITCH_ID_6321_A1 0x3101
-#define PORT_SWITCH_ID_6321_A2 0x3102
#define PORT_SWITCH_ID_6350 0x3710
#define PORT_SWITCH_ID_6351 0x3750
#define PORT_SWITCH_ID_6352 0x3520
-#define PORT_SWITCH_ID_6352_A0 0x3521
-#define PORT_SWITCH_ID_6352_A1 0x3522
#define PORT_CONTROL 0x04
#define PORT_CONTROL_USE_CORE_TAG BIT(15)
#define PORT_CONTROL_DROP_ON_LOCK BIT(14)
--
2.8.0
^ permalink raw reply related
* [PATCH net-next v2 3/7] net: dsa: mv88e6xxx: add switch info
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1460762488-2633-1-git-send-email-vivien.didelot@savoirfairelinux.com>
Add a new switch info structure which will be later extended to store
switch models static information, such as product number, name, number
of ports, number of databases, etc.
Merge the lookup function in the probing code, so that we avoid multiple
checking of the MII bus, as well a multiple ID reading.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 15 +++++++++---
drivers/net/dsa/mv88e6131.c | 19 ++++++++++----
drivers/net/dsa/mv88e6171.c | 19 ++++++++++----
drivers/net/dsa/mv88e6352.c | 27 ++++++++++++++------
drivers/net/dsa/mv88e6xxx.c | 60 ++++++++++++++++++++-------------------------
drivers/net/dsa/mv88e6xxx.h | 28 +++++++++++++++++----
6 files changed, 109 insertions(+), 59 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 00c1121..9120fcf 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -17,10 +17,17 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
-static const struct mv88e6xxx_switch_id mv88e6123_table[] = {
- { PORT_SWITCH_ID_6123, "Marvell 88E6123" },
- { PORT_SWITCH_ID_6161, "Marvell 88E6161" },
- { PORT_SWITCH_ID_6165, "Marvell 88E6165" },
+static const struct mv88e6xxx_info mv88e6123_table[] = {
+ {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
+ .name = "Marvell 88E6123",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
+ .name = "Marvell 88E6161",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
+ .name = "Marvell 88E6165",
+ }
};
static char *mv88e6123_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index df534da..82ff0c4 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -17,11 +17,20 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
-static const struct mv88e6xxx_switch_id mv88e6131_table[] = {
- { PORT_SWITCH_ID_6085, "Marvell 88E6085" },
- { PORT_SWITCH_ID_6095, "Marvell 88E6095/88E6095F" },
- { PORT_SWITCH_ID_6131, "Marvell 88E6131" },
- { PORT_SWITCH_ID_6185, "Marvell 88E6185" },
+static const struct mv88e6xxx_info mv88e6131_table[] = {
+ {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
+ .name = "Marvell 88E6095/88E6095F",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
+ .name = "Marvell 88E6085",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
+ .name = "Marvell 88E6131",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
+ .name = "Marvell 88E6185",
+ }
};
static char *mv88e6131_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 40222b0..5e9eb8c 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -17,11 +17,20 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
-static const struct mv88e6xxx_switch_id mv88e6171_table[] = {
- { PORT_SWITCH_ID_6171, "Marvell 88E6171" },
- { PORT_SWITCH_ID_6175, "Marvell 88E6175" },
- { PORT_SWITCH_ID_6350, "Marvell 88E6350" },
- { PORT_SWITCH_ID_6351, "Marvell 88E6351" },
+static const struct mv88e6xxx_info mv88e6171_table[] = {
+ {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
+ .name = "Marvell 88E6171",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
+ .name = "Marvell 88E6175",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
+ .name = "Marvell 88E6350",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
+ .name = "Marvell 88E6351",
+ }
};
static char *mv88e6171_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 30fc5f6..3a53cfb 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -22,13 +22,26 @@
#include <net/dsa.h>
#include "mv88e6xxx.h"
-static const struct mv88e6xxx_switch_id mv88e6352_table[] = {
- { PORT_SWITCH_ID_6172, "Marvell 88E6172" },
- { PORT_SWITCH_ID_6176, "Marvell 88E6176" },
- { PORT_SWITCH_ID_6240, "Marvell 88E6240" },
- { PORT_SWITCH_ID_6320, "Marvell 88E6320" },
- { PORT_SWITCH_ID_6321, "Marvell 88E6321" },
- { PORT_SWITCH_ID_6352, "Marvell 88E6352" },
+static const struct mv88e6xxx_info mv88e6352_table[] = {
+ {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
+ .name = "Marvell 88E6320",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
+ .name = "Marvell 88E6321",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
+ .name = "Marvell 88E6172",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
+ .name = "Marvell 88E6176",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
+ .name = "Marvell 88E6240",
+ }, {
+ .prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
+ .name = "Marvell 88E6352",
+ }
};
static char *mv88e6352_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index d7e309d..c9d016c 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -3068,51 +3068,45 @@ int mv88e6xxx_get_temp_alarm(struct dsa_switch *ds, bool *alarm)
}
#endif /* CONFIG_NET_DSA_HWMON */
-static char *mv88e6xxx_lookup_name(struct mii_bus *bus, int sw_addr,
- const struct mv88e6xxx_switch_id *table,
- unsigned int num)
+char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
+ int sw_addr, void **priv,
+ const struct mv88e6xxx_info *table, unsigned int num)
{
- int i, ret;
+ const struct mv88e6xxx_info *info;
+ struct mv88e6xxx_priv_state *ps;
+ struct mii_bus *bus;
+ int id, i;
+ bus = dsa_host_dev_to_mii_bus(host_dev);
if (!bus)
return NULL;
- ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
- if (ret < 0)
+ id = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID);
+ if (id < 0)
return NULL;
- /* Look up the exact switch ID */
- for (i = 0; i < num; ++i)
- if (table[i].id == (ret & 0xfff0))
- return table[i].name;
+ for (i = 0, info = &table[i]; i < num; info = &table[++i])
+ if (info->prod_num == (id & 0xfff0) >> 4)
+ goto found;
return NULL;
-}
-char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
- int sw_addr, void **priv,
- const struct mv88e6xxx_switch_id *table,
- unsigned int num)
-{
- struct mv88e6xxx_priv_state *ps;
- struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
- char *name;
-
- if (!bus)
+found:
+ ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
+ if (!ps)
return NULL;
- name = mv88e6xxx_lookup_name(bus, sw_addr, table, num);
- if (name) {
- ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
- if (!ps)
- return NULL;
- *priv = ps;
- ps->bus = dsa_host_dev_to_mii_bus(host_dev);
- if (!ps->bus)
- return NULL;
- ps->sw_addr = sw_addr;
- }
- return name;
+ *priv = ps;
+
+ ps->bus = bus;
+ ps->sw_addr = sw_addr;
+ ps->info = info;
+ ps->id = id & 0xfff0;
+
+ dev_info(&ps->bus->dev, "found switch %s, revision %u\n",
+ ps->info->name, id & 0xf);
+
+ return (char *) ps->info->name;
}
static int __init mv88e6xxx_init(void)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 9242aea..52c7e03 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -68,6 +68,23 @@
#define PORT_PCS_CTRL_UNFORCED 0x03
#define PORT_PAUSE_CTRL 0x02
#define PORT_SWITCH_ID 0x03
+#define PORT_SWITCH_ID_PROD_NUM_6085 0x04a
+#define PORT_SWITCH_ID_PROD_NUM_6095 0x095
+#define PORT_SWITCH_ID_PROD_NUM_6131 0x106
+#define PORT_SWITCH_ID_PROD_NUM_6320 0x115
+#define PORT_SWITCH_ID_PROD_NUM_6123 0x121
+#define PORT_SWITCH_ID_PROD_NUM_6161 0x161
+#define PORT_SWITCH_ID_PROD_NUM_6165 0x165
+#define PORT_SWITCH_ID_PROD_NUM_6171 0x171
+#define PORT_SWITCH_ID_PROD_NUM_6172 0x172
+#define PORT_SWITCH_ID_PROD_NUM_6175 0x175
+#define PORT_SWITCH_ID_PROD_NUM_6176 0x176
+#define PORT_SWITCH_ID_PROD_NUM_6185 0x1a7
+#define PORT_SWITCH_ID_PROD_NUM_6240 0x240
+#define PORT_SWITCH_ID_PROD_NUM_6321 0x310
+#define PORT_SWITCH_ID_PROD_NUM_6352 0x352
+#define PORT_SWITCH_ID_PROD_NUM_6350 0x371
+#define PORT_SWITCH_ID_PROD_NUM_6351 0x375
#define PORT_SWITCH_ID_6031 0x0310
#define PORT_SWITCH_ID_6035 0x0350
#define PORT_SWITCH_ID_6046 0x0480
@@ -352,9 +369,9 @@
#define MV88E6XXX_N_FID 4096
-struct mv88e6xxx_switch_id {
- u16 id;
- char *name;
+struct mv88e6xxx_info {
+ u16 prod_num;
+ const char *name;
};
struct mv88e6xxx_atu_entry {
@@ -382,6 +399,8 @@ struct mv88e6xxx_priv_port {
};
struct mv88e6xxx_priv_state {
+ const struct mv88e6xxx_info *info;
+
/* The dsa_switch this private structure is related to */
struct dsa_switch *ds;
@@ -449,8 +468,7 @@ struct mv88e6xxx_hw_stat {
int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active);
char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
int sw_addr, void **priv,
- const struct mv88e6xxx_switch_id *table,
- unsigned int num);
+ const struct mv88e6xxx_info *table, unsigned int num);
int mv88e6xxx_setup_ports(struct dsa_switch *ds);
int mv88e6xxx_setup_common(struct dsa_switch *ds);
--
2.8.0
^ permalink raw reply related
* [PATCH net-next v2 4/7] net: dsa: mv88e6xxx: add family to info
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1460762488-2633-1-git-send-email-vivien.didelot@savoirfairelinux.com>
Add an mv88e6xxx_family enum to the info structure for better family
indentification.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 3 ++
drivers/net/dsa/mv88e6131.c | 4 +++
drivers/net/dsa/mv88e6171.c | 4 +++
drivers/net/dsa/mv88e6352.c | 6 ++++
drivers/net/dsa/mv88e6xxx.c | 71 +++++----------------------------------------
drivers/net/dsa/mv88e6xxx.h | 13 +++++++++
6 files changed, 38 insertions(+), 63 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 9120fcf..93429d2 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -20,12 +20,15 @@
static const struct mv88e6xxx_info mv88e6123_table[] = {
{
.prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
+ .family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6123",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
+ .family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6161",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
+ .family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6165",
}
};
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index 82ff0c4..ec06321 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -20,15 +20,19 @@
static const struct mv88e6xxx_info mv88e6131_table[] = {
{
.prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
+ .family = MV88E6XXX_FAMILY_6095,
.name = "Marvell 88E6095/88E6095F",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
+ .family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6085",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
+ .family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6131",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
+ .family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6185",
}
};
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 5e9eb8c..efe3c0f 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -20,15 +20,19 @@
static const struct mv88e6xxx_info mv88e6171_table[] = {
{
.prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
+ .family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6171",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
+ .family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6175",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
+ .family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6350",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
+ .family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6351",
}
};
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 3a53cfb..c051c02 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -25,21 +25,27 @@
static const struct mv88e6xxx_info mv88e6352_table[] = {
{
.prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
+ .family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6320",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
+ .family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6321",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
+ .family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6172",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
+ .family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6176",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
+ .family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6240",
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
+ .family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6352",
}
};
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index c9d016c..50db324 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -369,111 +369,56 @@ static bool mv88e6xxx_6065_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6031:
- case PORT_SWITCH_ID_6061:
- case PORT_SWITCH_ID_6035:
- case PORT_SWITCH_ID_6065:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6065;
}
static bool mv88e6xxx_6095_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6092:
- case PORT_SWITCH_ID_6095:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6095;
}
static bool mv88e6xxx_6097_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6046:
- case PORT_SWITCH_ID_6085:
- case PORT_SWITCH_ID_6096:
- case PORT_SWITCH_ID_6097:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6097;
}
static bool mv88e6xxx_6165_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6123:
- case PORT_SWITCH_ID_6161:
- case PORT_SWITCH_ID_6165:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6165;
}
static bool mv88e6xxx_6185_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6121:
- case PORT_SWITCH_ID_6122:
- case PORT_SWITCH_ID_6152:
- case PORT_SWITCH_ID_6155:
- case PORT_SWITCH_ID_6182:
- case PORT_SWITCH_ID_6185:
- case PORT_SWITCH_ID_6108:
- case PORT_SWITCH_ID_6131:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6185;
}
static bool mv88e6xxx_6320_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6320:
- case PORT_SWITCH_ID_6321:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6320;
}
static bool mv88e6xxx_6351_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6171:
- case PORT_SWITCH_ID_6175:
- case PORT_SWITCH_ID_6350:
- case PORT_SWITCH_ID_6351:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6351;
}
static bool mv88e6xxx_6352_family(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6172:
- case PORT_SWITCH_ID_6176:
- case PORT_SWITCH_ID_6240:
- case PORT_SWITCH_ID_6352:
- return true;
- }
- return false;
+ return ps->info->family == MV88E6XXX_FAMILY_6352;
}
static unsigned int mv88e6xxx_num_databases(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 52c7e03..8bb2586 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -367,9 +367,22 @@
#define GLOBAL2_QOS_WEIGHT 0x1c
#define GLOBAL2_MISC 0x1d
+enum mv88e6xxx_family {
+ MV88E6XXX_FAMILY_NONE,
+ MV88E6XXX_FAMILY_6065, /* 6031 6035 6061 6065 */
+ MV88E6XXX_FAMILY_6095, /* 6092 6095 */
+ MV88E6XXX_FAMILY_6097, /* 6046 6085 6096 6097 */
+ MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */
+ MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */
+ MV88E6XXX_FAMILY_6320, /* 6320 6321 */
+ MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
+ MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */
+};
+
#define MV88E6XXX_N_FID 4096
struct mv88e6xxx_info {
+ enum mv88e6xxx_family family;
u16 prod_num;
const char *name;
};
--
2.8.0
^ permalink raw reply related
* [PATCH net-next v2 6/7] net: dsa: mv88e6xxx: add number of db to info
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1460762488-2633-1-git-send-email-vivien.didelot@savoirfairelinux.com>
Add the number of databases to the info structure.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 3 +++
drivers/net/dsa/mv88e6131.c | 4 ++++
drivers/net/dsa/mv88e6171.c | 4 ++++
drivers/net/dsa/mv88e6352.c | 6 ++++++
drivers/net/dsa/mv88e6xxx.c | 19 +------------------
drivers/net/dsa/mv88e6xxx.h | 1 +
6 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index e3802b4..b3cbf8e 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -22,16 +22,19 @@ static const struct mv88e6xxx_info mv88e6123_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6123",
+ .num_databases = 4096,
.num_ports = 3,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6161",
+ .num_databases = 4096,
.num_ports = 6,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6165",
+ .num_databases = 4096,
.num_ports = 6,
}
};
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index f6b465b..8a161c5 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -22,21 +22,25 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
.family = MV88E6XXX_FAMILY_6095,
.name = "Marvell 88E6095/88E6095F",
+ .num_databases = 256,
.num_ports = 11,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
.family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6085",
+ .num_databases = 4096,
.num_ports = 10,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6131",
+ .num_databases = 256,
.num_ports = 8,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6185",
+ .num_databases = 256,
.num_ports = 10,
}
};
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index cdfa899..689824f 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -22,21 +22,25 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6171",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6175",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6350",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6351",
+ .num_databases = 4096,
.num_ports = 7,
}
};
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 9aaddca..abd9113 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -27,31 +27,37 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6320",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6321",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6172",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6176",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6240",
+ .num_databases = 4096,
.num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6352",
+ .num_databases = 4096,
.num_ports = 7,
}
};
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 1a5f503..5b0ad7b 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -425,24 +425,7 @@ static unsigned int mv88e6xxx_num_databases(struct dsa_switch *ds)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- /* The following devices have 4-bit identifiers for 16 databases */
- if (ps->id == PORT_SWITCH_ID_6061)
- return 16;
-
- /* The following devices have 6-bit identifiers for 64 databases */
- if (ps->id == PORT_SWITCH_ID_6065)
- return 64;
-
- /* The following devices have 8-bit identifiers for 256 databases */
- if (mv88e6xxx_6095_family(ds) || mv88e6xxx_6185_family(ds))
- return 256;
-
- /* The following devices have 12-bit identifiers for 4096 databases */
- if (mv88e6xxx_6097_family(ds) || mv88e6xxx_6165_family(ds) ||
- mv88e6xxx_6351_family(ds) || mv88e6xxx_6352_family(ds))
- return 4096;
-
- return 0;
+ return ps->info->num_databases;
}
static bool mv88e6xxx_has_fid_reg(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 1f3ab6f..4b3121b 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -385,6 +385,7 @@ struct mv88e6xxx_info {
enum mv88e6xxx_family family;
u16 prod_num;
const char *name;
+ unsigned int num_databases;
unsigned int num_ports;
};
--
2.8.0
^ permalink raw reply related
* [PATCH net-next v2 1/7] net: dsa: mv88e6xxx: drop double ds assignment
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1460762488-2633-1-git-send-email-vivien.didelot@savoirfairelinux.com>
Every driver assigns ps->ds even though it gets assigned in the shared
mv88e6xxx_setup_common function. Kill redundancy.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 2 --
drivers/net/dsa/mv88e6131.c | 2 --
drivers/net/dsa/mv88e6171.c | 2 --
drivers/net/dsa/mv88e6352.c | 2 --
4 files changed, 8 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index c34283d..88a812d 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -76,8 +76,6 @@ static int mv88e6123_setup(struct dsa_switch *ds)
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
- ps->ds = ds;
-
ret = mv88e6xxx_setup_common(ds);
if (ret < 0)
return ret;
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index f5d75fc..6b2bcb0 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -94,8 +94,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
- ps->ds = ds;
-
ret = mv88e6xxx_setup_common(ds);
if (ret < 0)
return ret;
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index f562250..40222b0 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -72,8 +72,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
- ps->ds = ds;
-
ret = mv88e6xxx_setup_common(ds);
if (ret < 0)
return ret;
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index e54ee27..dbd920e 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -84,8 +84,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
- ps->ds = ds;
-
ret = mv88e6xxx_setup_common(ds);
if (ret < 0)
return ret;
--
2.8.0
^ permalink raw reply related
* [PATCH net-next v2 7/7] net: dsa: mv88e6xxx: remove switch ID
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1460762488-2633-1-git-send-email-vivien.didelot@savoirfairelinux.com>
ps->id is not needed anymore, so remove it as well as the related
defined values.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6xxx.c | 3 ---
drivers/net/dsa/mv88e6xxx.h | 32 --------------------------------
2 files changed, 35 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 5b0ad7b..a84f049 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -2595,8 +2595,6 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
ps->ds = ds;
mutex_init(&ps->smi_mutex);
- ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0;
-
INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work);
return 0;
@@ -3029,7 +3027,6 @@ found:
ps->bus = bus;
ps->sw_addr = sw_addr;
ps->info = info;
- ps->id = id & 0xfff0;
dev_info(&ps->bus->dev, "found switch %s, revision %u\n",
ps->info->name, id & 0xf);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 4b3121b..4c5f434 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -85,37 +85,6 @@
#define PORT_SWITCH_ID_PROD_NUM_6352 0x352
#define PORT_SWITCH_ID_PROD_NUM_6350 0x371
#define PORT_SWITCH_ID_PROD_NUM_6351 0x375
-#define PORT_SWITCH_ID_6031 0x0310
-#define PORT_SWITCH_ID_6035 0x0350
-#define PORT_SWITCH_ID_6046 0x0480
-#define PORT_SWITCH_ID_6061 0x0610
-#define PORT_SWITCH_ID_6065 0x0650
-#define PORT_SWITCH_ID_6085 0x04a0
-#define PORT_SWITCH_ID_6092 0x0970
-#define PORT_SWITCH_ID_6095 0x0950
-#define PORT_SWITCH_ID_6096 0x0980
-#define PORT_SWITCH_ID_6097 0x0990
-#define PORT_SWITCH_ID_6108 0x1070
-#define PORT_SWITCH_ID_6121 0x1040
-#define PORT_SWITCH_ID_6122 0x1050
-#define PORT_SWITCH_ID_6123 0x1210
-#define PORT_SWITCH_ID_6131 0x1060
-#define PORT_SWITCH_ID_6152 0x1a40
-#define PORT_SWITCH_ID_6155 0x1a50
-#define PORT_SWITCH_ID_6161 0x1610
-#define PORT_SWITCH_ID_6165 0x1650
-#define PORT_SWITCH_ID_6171 0x1710
-#define PORT_SWITCH_ID_6172 0x1720
-#define PORT_SWITCH_ID_6175 0x1750
-#define PORT_SWITCH_ID_6176 0x1760
-#define PORT_SWITCH_ID_6182 0x1a60
-#define PORT_SWITCH_ID_6185 0x1a70
-#define PORT_SWITCH_ID_6240 0x2400
-#define PORT_SWITCH_ID_6320 0x1150
-#define PORT_SWITCH_ID_6321 0x3100
-#define PORT_SWITCH_ID_6350 0x3710
-#define PORT_SWITCH_ID_6351 0x3750
-#define PORT_SWITCH_ID_6352 0x3520
#define PORT_CONTROL 0x04
#define PORT_CONTROL_USE_CORE_TAG BIT(15)
#define PORT_CONTROL_DROP_ON_LOCK BIT(14)
@@ -457,7 +426,6 @@ struct mv88e6xxx_priv_state {
*/
struct mutex eeprom_mutex;
- int id; /* switch product id */
struct mv88e6xxx_priv_port ports[DSA_MAX_PORTS];
DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS);
--
2.8.0
^ permalink raw reply related
* [PATCH net-next v2 5/7] net: dsa: mv88e6xxx: add number of ports to info
From: Vivien Didelot @ 2016-04-15 23:21 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, Vivien Didelot
In-Reply-To: <1460762488-2633-1-git-send-email-vivien.didelot@savoirfairelinux.com>
Drop the ps->num_ports variable for a new member of the info structure.
This removes the need to assign it at setup time.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6123.c | 16 +++-------------
drivers/net/dsa/mv88e6131.c | 22 +++++-----------------
drivers/net/dsa/mv88e6171.c | 7 ++++---
drivers/net/dsa/mv88e6352.c | 8 ++++++--
drivers/net/dsa/mv88e6xxx.c | 38 +++++++++++++++++++-------------------
drivers/net/dsa/mv88e6xxx.h | 3 +--
6 files changed, 38 insertions(+), 56 deletions(-)
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
index 93429d2..e3802b4 100644
--- a/drivers/net/dsa/mv88e6123.c
+++ b/drivers/net/dsa/mv88e6123.c
@@ -22,14 +22,17 @@ static const struct mv88e6xxx_info mv88e6123_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6123,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6123",
+ .num_ports = 3,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6161,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6161",
+ .num_ports = 6,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6165,
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6165",
+ .num_ports = 6,
}
};
@@ -77,25 +80,12 @@ static int mv88e6123_setup_global(struct dsa_switch *ds)
static int mv88e6123_setup(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
ret = mv88e6xxx_setup_common(ds);
if (ret < 0)
return ret;
- switch (ps->id) {
- case PORT_SWITCH_ID_6123:
- ps->num_ports = 3;
- break;
- case PORT_SWITCH_ID_6161:
- case PORT_SWITCH_ID_6165:
- ps->num_ports = 6;
- break;
- default:
- return -ENODEV;
- }
-
ret = mv88e6xxx_switch_reset(ds, false);
if (ret < 0)
return ret;
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index ec06321..f6b465b 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -22,18 +22,22 @@ static const struct mv88e6xxx_info mv88e6131_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6095,
.family = MV88E6XXX_FAMILY_6095,
.name = "Marvell 88E6095/88E6095F",
+ .num_ports = 11,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
.family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6085",
+ .num_ports = 10,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6131,
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6131",
+ .num_ports = 8,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6185,
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6185",
+ .num_ports = 10,
}
};
@@ -103,7 +107,6 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
static int mv88e6131_setup(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
ret = mv88e6xxx_setup_common(ds);
@@ -112,21 +115,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
mv88e6xxx_ppu_state_init(ds);
- switch (ps->id) {
- case PORT_SWITCH_ID_6085:
- case PORT_SWITCH_ID_6185:
- ps->num_ports = 10;
- break;
- case PORT_SWITCH_ID_6095:
- ps->num_ports = 11;
- break;
- case PORT_SWITCH_ID_6131:
- ps->num_ports = 8;
- break;
- default:
- return -ENODEV;
- }
-
ret = mv88e6xxx_switch_reset(ds, false);
if (ret < 0)
return ret;
@@ -142,7 +130,7 @@ static int mv88e6131_port_to_phy_addr(struct dsa_switch *ds, int port)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- if (port >= 0 && port < ps->num_ports)
+ if (port >= 0 && port < ps->info->num_ports)
return port;
return -EINVAL;
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index efe3c0f..cdfa899 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -22,18 +22,22 @@ static const struct mv88e6xxx_info mv88e6171_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6171,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6171",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6175,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6175",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6350,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6350",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6351,
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6351",
+ .num_ports = 7,
}
};
@@ -82,15 +86,12 @@ static int mv88e6171_setup_global(struct dsa_switch *ds)
static int mv88e6171_setup(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
ret = mv88e6xxx_setup_common(ds);
if (ret < 0)
return ret;
- ps->num_ports = 7;
-
ret = mv88e6xxx_switch_reset(ds, true);
if (ret < 0)
return ret;
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index c051c02..9aaddca 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -27,26 +27,32 @@ static const struct mv88e6xxx_info mv88e6352_table[] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6320,
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6320",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6321,
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6321",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6172,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6172",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6176,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6176",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6240,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6240",
+ .num_ports = 7,
}, {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6352,
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6352",
+ .num_ports = 7,
}
};
@@ -101,8 +107,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
if (ret < 0)
return ret;
- ps->num_ports = 7;
-
mutex_init(&ps->eeprom_mutex);
ret = mv88e6xxx_switch_reset(ds, true);
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 50db324..1a5f503 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -518,7 +518,7 @@ void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
reg |= PORT_PCS_CTRL_DUPLEX_FULL;
if ((mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds)) &&
- (port >= ps->num_ports - 2)) {
+ (port >= ps->info->num_ports - 2)) {
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
@@ -1099,7 +1099,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct net_device *bridge = ps->ports[port].bridge_dev;
- const u16 mask = (1 << ps->num_ports) - 1;
+ const u16 mask = (1 << ps->info->num_ports) - 1;
u16 output_ports = 0;
int reg;
int i;
@@ -1108,7 +1108,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct dsa_switch *ds, int port)
if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
output_ports = mask;
} else {
- for (i = 0; i < ps->num_ports; ++i) {
+ for (i = 0; i < ps->info->num_ports; ++i) {
/* allow sending frames to every group member */
if (bridge && ps->ports[i].bridge_dev == bridge)
output_ports |= BIT(i);
@@ -1249,7 +1249,7 @@ static int _mv88e6xxx_vtu_stu_data_read(struct dsa_switch *ds,
regs[i] = ret;
}
- for (i = 0; i < ps->num_ports; ++i) {
+ for (i = 0; i < ps->info->num_ports; ++i) {
unsigned int shift = (i % 4) * 4 + nibble_offset;
u16 reg = regs[i / 4];
@@ -1268,7 +1268,7 @@ static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds,
int i;
int ret;
- for (i = 0; i < ps->num_ports; ++i) {
+ for (i = 0; i < ps->info->num_ports; ++i) {
unsigned int shift = (i % 4) * 4 + nibble_offset;
u8 data = entry->data[i];
@@ -1600,7 +1600,7 @@ static int _mv88e6xxx_fid_new(struct dsa_switch *ds, u16 *fid)
bitmap_zero(fid_bitmap, MV88E6XXX_N_FID);
/* Set every FID bit used by the (un)bridged ports */
- for (i = 0; i < ps->num_ports; ++i) {
+ for (i = 0; i < ps->info->num_ports; ++i) {
err = _mv88e6xxx_port_fid_get(ds, i, fid);
if (err)
return err;
@@ -1650,7 +1650,7 @@ static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid,
return err;
/* exclude all ports except the CPU and DSA ports */
- for (i = 0; i < ps->num_ports; ++i)
+ for (i = 0; i < ps->info->num_ports; ++i)
vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
: GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
@@ -1739,7 +1739,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
if (vlan.vid > vid_end)
break;
- for (i = 0; i < ps->num_ports; ++i) {
+ for (i = 0; i < ps->info->num_ports; ++i) {
if (dsa_is_dsa_port(ds, i) || dsa_is_cpu_port(ds, i))
continue;
@@ -1888,7 +1888,7 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
/* keep the VLAN unless all ports are excluded */
vlan.valid = false;
- for (i = 0; i < ps->num_ports; ++i) {
+ for (i = 0; i < ps->info->num_ports; ++i) {
if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
continue;
@@ -2197,11 +2197,11 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
mutex_lock(&ps->smi_mutex);
/* Get or create the bridge FID and assign it to the port */
- for (i = 0; i < ps->num_ports; ++i)
+ for (i = 0; i < ps->info->num_ports; ++i)
if (ps->ports[i].bridge_dev == bridge)
break;
- if (i < ps->num_ports)
+ if (i < ps->info->num_ports)
err = _mv88e6xxx_port_fid_get(ds, i, &fid);
else
err = _mv88e6xxx_fid_new(ds, &fid);
@@ -2215,7 +2215,7 @@ int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
/* Assign the bridge and remap each port's VLANTable */
ps->ports[port].bridge_dev = bridge;
- for (i = 0; i < ps->num_ports; ++i) {
+ for (i = 0; i < ps->info->num_ports; ++i) {
if (ps->ports[i].bridge_dev == bridge) {
err = _mv88e6xxx_port_based_vlan_map(ds, i);
if (err)
@@ -2246,7 +2246,7 @@ void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port)
/* Unassign the bridge and remap each port's VLANTable */
ps->ports[port].bridge_dev = NULL;
- for (i = 0; i < ps->num_ports; ++i)
+ for (i = 0; i < ps->info->num_ports; ++i)
if (i == port || ps->ports[i].bridge_dev == bridge)
if (_mv88e6xxx_port_based_vlan_map(ds, i))
netdev_warn(ds->ports[i], "failed to remap\n");
@@ -2265,7 +2265,7 @@ static void mv88e6xxx_bridge_work(struct work_struct *work)
mutex_lock(&ps->smi_mutex);
- for (port = 0; port < ps->num_ports; ++port)
+ for (port = 0; port < ps->info->num_ports; ++port)
if (test_and_clear_bit(port, ps->port_state_update_mask) &&
_mv88e6xxx_port_state(ds, port, ps->ports[port].state))
netdev_warn(ds->ports[port], "failed to update state to %s\n",
@@ -2597,7 +2597,7 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
int ret;
int i;
- for (i = 0; i < ps->num_ports; i++) {
+ for (i = 0; i < ps->info->num_ports; i++) {
ret = mv88e6xxx_setup_port(ds, i);
if (ret < 0)
return ret;
@@ -2677,7 +2677,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
for (i = 0; i < 8; i++)
REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MASK,
0x8000 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) |
- ((1 << ps->num_ports) - 1));
+ ((1 << ps->info->num_ports) - 1));
/* Clear all trunk mappings. */
for (i = 0; i < 16; i++)
@@ -2712,7 +2712,7 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds)
* ingress rate limit registers to their initial
* state.
*/
- for (i = 0; i < ps->num_ports; i++)
+ for (i = 0; i < ps->info->num_ports; i++)
REG_WRITE(REG_GLOBAL2, GLOBAL2_INGRESS_OP,
0x9000 | (i << 8));
}
@@ -2749,7 +2749,7 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active)
int i;
/* Set all ports to the disabled state. */
- for (i = 0; i < ps->num_ports; i++) {
+ for (i = 0; i < ps->info->num_ports; i++) {
ret = REG_READ(REG_PORT(i), PORT_CONTROL);
REG_WRITE(REG_PORT(i), PORT_CONTROL, ret & 0xfffc);
}
@@ -2817,7 +2817,7 @@ static int mv88e6xxx_port_to_phy_addr(struct dsa_switch *ds, int port)
{
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
- if (port >= 0 && port < ps->num_ports)
+ if (port >= 0 && port < ps->info->num_ports)
return port;
return -EINVAL;
}
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index 8bb2586..1f3ab6f 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -385,6 +385,7 @@ struct mv88e6xxx_info {
enum mv88e6xxx_family family;
u16 prod_num;
const char *name;
+ unsigned int num_ports;
};
struct mv88e6xxx_atu_entry {
@@ -456,8 +457,6 @@ struct mv88e6xxx_priv_state {
struct mutex eeprom_mutex;
int id; /* switch product id */
- int num_ports; /* number of switch ports */
-
struct mv88e6xxx_priv_port ports[DSA_MAX_PORTS];
DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS);
--
2.8.0
^ permalink raw reply related
* Re: [PATCH net-next v2 1/7] net: dsa: mv88e6xxx: drop double ds assignment
From: Andrew Lunn @ 2016-04-15 23:39 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1460762488-2633-2-git-send-email-vivien.didelot@savoirfairelinux.com>
On Fri, Apr 15, 2016 at 07:21:22PM -0400, Vivien Didelot wrote:
> Every driver assigns ps->ds even though it gets assigned in the shared
> mv88e6xxx_setup_common function. Kill redundancy.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Thanks
Andrew
> ---
> drivers/net/dsa/mv88e6123.c | 2 --
> drivers/net/dsa/mv88e6131.c | 2 --
> drivers/net/dsa/mv88e6171.c | 2 --
> drivers/net/dsa/mv88e6352.c | 2 --
> 4 files changed, 8 deletions(-)
>
> diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c
> index c34283d..88a812d 100644
> --- a/drivers/net/dsa/mv88e6123.c
> +++ b/drivers/net/dsa/mv88e6123.c
> @@ -76,8 +76,6 @@ static int mv88e6123_setup(struct dsa_switch *ds)
> struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
> int ret;
>
> - ps->ds = ds;
> -
> ret = mv88e6xxx_setup_common(ds);
> if (ret < 0)
> return ret;
> diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
> index f5d75fc..6b2bcb0 100644
> --- a/drivers/net/dsa/mv88e6131.c
> +++ b/drivers/net/dsa/mv88e6131.c
> @@ -94,8 +94,6 @@ static int mv88e6131_setup(struct dsa_switch *ds)
> struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
> int ret;
>
> - ps->ds = ds;
> -
> ret = mv88e6xxx_setup_common(ds);
> if (ret < 0)
> return ret;
> diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
> index f562250..40222b0 100644
> --- a/drivers/net/dsa/mv88e6171.c
> +++ b/drivers/net/dsa/mv88e6171.c
> @@ -72,8 +72,6 @@ static int mv88e6171_setup(struct dsa_switch *ds)
> struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
> int ret;
>
> - ps->ds = ds;
> -
> ret = mv88e6xxx_setup_common(ds);
> if (ret < 0)
> return ret;
> diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
> index e54ee27..dbd920e 100644
> --- a/drivers/net/dsa/mv88e6352.c
> +++ b/drivers/net/dsa/mv88e6352.c
> @@ -84,8 +84,6 @@ static int mv88e6352_setup(struct dsa_switch *ds)
> struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
> int ret;
>
> - ps->ds = ds;
> -
> ret = mv88e6xxx_setup_common(ds);
> if (ret < 0)
> return ret;
> --
> 2.8.0
>
^ permalink raw reply
* Re: [PATCH net-next v2 2/7] net: dsa: mv88e6xxx: drop revision probing
From: Andrew Lunn @ 2016-04-15 23:43 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1460762488-2633-3-git-send-email-vivien.didelot@savoirfairelinux.com>
On Fri, Apr 15, 2016 at 07:21:23PM -0400, Vivien Didelot wrote:
> There is no point in having special case for the revision when probing a
> switch model. The code gets cluttered with unnecessary defines, and
> leads to errors when code such as mv88e6131_setup compares
> PORT_SWITCH_ID_6131_B2 to ps->id which mask the revision.
>
> Drop every revision definitions, add a ps->rev variable for eventual
> runtime checking and lookup only the product number.
You forgot to update the commit message. ps->rev has been removed in
this version.
>
> /* Look up the exact switch ID */
This comment now becomes meaningless. Please delete.
> for (i = 0; i < num; ++i)
> - if (table[i].id == ret)
> + if (table[i].id == (ret & 0xfff0))
> return table[i].name;
Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 3/7] net: dsa: mv88e6xxx: add switch info
From: Andrew Lunn @ 2016-04-15 23:55 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1460762488-2633-4-git-send-email-vivien.didelot@savoirfairelinux.com>
> + for (i = 0, info = &table[i]; i < num; info = &table[++i])
> + if (info->prod_num == (id & 0xfff0) >> 4)
> + goto found;
>
> return NULL;
> -}
>
> -char *mv88e6xxx_drv_probe(struct device *dsa_dev, struct device *host_dev,
> - int sw_addr, void **priv,
> - const struct mv88e6xxx_switch_id *table,
> - unsigned int num)
> -{
> - struct mv88e6xxx_priv_state *ps;
> - struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
> - char *name;
> -
> - if (!bus)
> +found:
> + ps = devm_kzalloc(dsa_dev, sizeof(*ps), GFP_KERNEL);
> + if (!ps)
This looks like a goto to jump around a return NULL. Ugly. I would
keep this lookup in a separate function. You can then avoid ugly stuff
like this.
CodingStyle says:
Chapter 6: Functions
Functions should be short and sweet, and do just one thing. They should
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,
as we all know), and do one thing and do that well.
Andrew
^ permalink raw reply
* Re: qdisc spin lock
From: Eric Dumazet @ 2016-04-15 23:56 UTC (permalink / raw)
To: Michael Ma; +Cc: Cong Wang, Linux Kernel Network Developers
In-Reply-To: <CAAmHdhzbEJAR00akLg8UG9UOwa+TRw+PaeuYyguiJuciYaLroA@mail.gmail.com>
On Fri, 2016-04-15 at 16:05 -0700, Michael Ma wrote:
> Would definitely appreciate that. If you can share the patch it will
> be helpful as well. Let me know if I can help with this...
Sure, here is what I am going to test :
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 941ec99cd3b6..f890ebe78629 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4003,11 +4003,17 @@ static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb,
* skb_tx_hash and will put the skbs in the queue we expect on their
* way down to the bonding driver.
*/
- u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
+ struct bonding *bond = netdev_priv(dev);
+ u16 txq;
/* Save the original txq to restore before passing to the driver */
qdisc_skb_cb(skb)->slave_dev_queue_mapping = skb->queue_mapping;
+ if (!bond->queue_id_selection_enabled)
+ return fallback(dev, skb);
+
+ txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
+
if (unlikely(txq >= dev->real_num_tx_queues)) {
do {
txq -= dev->real_num_tx_queues;
@@ -4020,7 +4026,8 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev
{
struct bonding *bond = netdev_priv(dev);
- if (bond_should_override_tx_queue(bond) &&
+ if (bond->queue_id_selection_enabled &&
+ bond_should_override_tx_queue(bond) &&
!bond_slave_override(bond, skb))
return NETDEV_TX_OK;
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 577e57cad1dc..1a8a5153f027 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -1270,6 +1270,7 @@ static int bond_option_ad_select_set(struct bonding *bond,
static int bond_option_queue_id_set(struct bonding *bond,
const struct bond_opt_value *newval)
{
+ bool queue_id_selection_enabled = false;
struct slave *slave, *update_slave;
struct net_device *sdev;
struct list_head *iter;
@@ -1318,6 +1319,12 @@ static int bond_option_queue_id_set(struct bonding *bond,
/* Actually set the qids for the slave */
update_slave->queue_id = qid;
+ bond_for_each_slave(bond, slave, iter) {
+ if (update_slave->queue_id)
+ queue_id_selection_enabled = true;
+ }
+ bond->queue_id_selection_enabled = queue_id_selection_enabled;
+
out:
return ret;
diff --git a/include/net/bonding.h b/include/net/bonding.h
index 791800ddd6d9..29e29491c571 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -204,6 +204,7 @@ struct bonding {
struct slave __rcu *primary_slave;
struct bond_up_slave __rcu *slave_arr; /* Array of usable slaves */
bool force_primary;
+ bool queue_id_selection_enabled;
s32 slave_cnt; /* never change this value outside the attach/detach wrappers */
int (*recv_probe)(const struct sk_buff *, struct bonding *,
struct slave *);
^ permalink raw reply related
* Re: [PATCH net-next v2 4/7] net: dsa: mv88e6xxx: add family to info
From: Andrew Lunn @ 2016-04-15 23:57 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1460762488-2633-5-git-send-email-vivien.didelot@savoirfairelinux.com>
On Fri, Apr 15, 2016 at 07:21:25PM -0400, Vivien Didelot wrote:
> Add an mv88e6xxx_family enum to the info structure for better family
> indentification.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 5/7] net: dsa: mv88e6xxx: add number of ports to info
From: Andrew Lunn @ 2016-04-15 23:59 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1460762488-2633-6-git-send-email-vivien.didelot@savoirfairelinux.com>
On Fri, Apr 15, 2016 at 07:21:26PM -0400, Vivien Didelot wrote:
> Drop the ps->num_ports variable for a new member of the info structure.
> This removes the need to assign it at setup time.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Thanks
Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 6/7] net: dsa: mv88e6xxx: add number of db to info
From: Andrew Lunn @ 2016-04-16 0:01 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1460762488-2633-7-git-send-email-vivien.didelot@savoirfairelinux.com>
On Fri, Apr 15, 2016 at 07:21:27PM -0400, Vivien Didelot wrote:
> Add the number of databases to the info structure.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Thanks
Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 7/7] net: dsa: mv88e6xxx: remove switch ID
From: Andrew Lunn @ 2016-04-16 0:03 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli
In-Reply-To: <1460762488-2633-8-git-send-email-vivien.didelot@savoirfairelinux.com>
On Fri, Apr 15, 2016 at 07:21:28PM -0400, Vivien Didelot wrote:
> ps->id is not needed anymore, so remove it as well as the related
> defined values.
>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Thanks
Andrew
^ permalink raw reply
* Re: [PATCH net-next] phy: make some bits preserved while setup forced mode
From: David Miller @ 2016-04-16 0:13 UTC (permalink / raw)
To: wangweidong1; +Cc: f.fainelli, netdev, linux-kernel, sergei.shtylyov, andrew
In-Reply-To: <570F4A38.5090201@huawei.com>
From: Weidong Wang <wangweidong1@huawei.com>
Date: Thu, 14 Apr 2016 15:43:52 +0800
> When tested the PHY SGMII Loopback:
> 1.set the LOOPBACK bit,
> 2.set the autoneg to AUTONEG_DISABLE, it calls the
> genphy_setup_forced which will clear the bit.
>
> The BMCR_LOOPBACK bit should be preserved.
>
> As Florian pointed out that other bits should be preserved too.
> So I make the BMCR_ISOLATE and BMCR_PDOWN as well.
>
> Signed-off-by: Weidong Wang <wangweidong1@huawei.com>
Applied, thank you.
^ permalink raw reply
* [PATCH net v2] vlan: pull on __vlan_insert_tag error path and fix csum correction
From: Daniel Borkmann @ 2016-04-16 0:27 UTC (permalink / raw)
To: davem; +Cc: jiri, netdev, Daniel Borkmann
When __vlan_insert_tag() fails from skb_vlan_push() path due to the
skb_cow_head(), we need to undo the __skb_push() in the error path
as well that was done earlier to move skb->data pointer to mac header.
Moreover, I noticed that when in the non-error path the __skb_pull()
is done and the original offset to mac header was non-zero, we fixup
from a wrong skb->data offset in the checksum complete processing.
So the skb_postpush_rcsum() really needs to be done before __skb_pull()
where skb->data still points to the mac header start and thus operates
under the same conditions as in __vlan_insert_tag().
Fixes: 93515d53b133 ("net: move vlan pop/push functions into common code")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
v1 -> v2:
- Resend/code still the same, Jiri gave it a review as well meanwhile.
net/core/skbuff.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index d04c2d1..e561f9f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -4502,13 +4502,16 @@ int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci)
__skb_push(skb, offset);
err = __vlan_insert_tag(skb, skb->vlan_proto,
skb_vlan_tag_get(skb));
- if (err)
+ if (err) {
+ __skb_pull(skb, offset);
return err;
+ }
+
skb->protocol = skb->vlan_proto;
skb->mac_len += VLAN_HLEN;
- __skb_pull(skb, offset);
skb_postpush_rcsum(skb, skb->data + (2 * ETH_ALEN), VLAN_HLEN);
+ __skb_pull(skb, offset);
}
__vlan_hwaccel_put_tag(skb, vlan_proto, vlan_tci);
return 0;
--
1.9.3
^ permalink raw reply related
* RE: [PATCH net-next 2/2] intel: ixgbevf: Support Windows hosts (Hyper-V)
From: KY Srinivasan @ 2016-04-16 0:54 UTC (permalink / raw)
To: Alexander Duyck
Cc: olaf@aepfle.de, Netdev, Jason Wang, linux-kernel@vger.kernel.org,
jackm@mellanox.com, yevgenyp@mellanox.com, John Ronciak,
intel-wired-lan, eli@mellanox.com, Robo Bot,
devel@linuxdriverproject.org, David Miller
In-Reply-To: <BL2PR03MB19089F602DFDE950F02D8BC9A0680@BL2PR03MB1908.namprd03.prod.outlook.com>
> -----Original Message-----
> From: KY Srinivasan
> Sent: Friday, April 15, 2016 9:01 AM
> To: 'Alexander Duyck' <alexander.duyck@gmail.com>
> Cc: David Miller <davem@davemloft.net>; Netdev
> <netdev@vger.kernel.org>; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org; olaf@aepfle.de; Robo Bot
> <apw@canonical.com>; Jason Wang <jasowang@redhat.com>;
> eli@mellanox.com; jackm@mellanox.com; yevgenyp@mellanox.com; John
> Ronciak <john.ronciak@intel.com>; intel-wired-lan <intel-wired-
> lan@lists.osuosl.org>
> Subject: RE: [PATCH net-next 2/2] intel: ixgbevf: Support Windows hosts
> (Hyper-V)
>
>
>
> > -----Original Message-----
> > From: Alexander Duyck [mailto:alexander.duyck@gmail.com]
> > Sent: Friday, April 15, 2016 8:40 AM
> > To: KY Srinivasan <kys@microsoft.com>
> > Cc: David Miller <davem@davemloft.net>; Netdev
> > <netdev@vger.kernel.org>; linux-kernel@vger.kernel.org;
> > devel@linuxdriverproject.org; olaf@aepfle.de; Robo Bot
> > <apw@canonical.com>; Jason Wang <jasowang@redhat.com>;
> > eli@mellanox.com; jackm@mellanox.com; yevgenyp@mellanox.com; John
> > Ronciak <john.ronciak@intel.com>; intel-wired-lan <intel-wired-
> > lan@lists.osuosl.org>
> > Subject: Re: [PATCH net-next 2/2] intel: ixgbevf: Support Windows hosts
> > (Hyper-V)
> >
> > On Thu, Apr 14, 2016 at 7:49 PM, KY Srinivasan <kys@microsoft.com>
> wrote:
> > >
> > >
> > >> -----Original Message-----
> > >> From: Alexander Duyck [mailto:alexander.duyck@gmail.com]
> > >> Sent: Thursday, April 14, 2016 4:18 PM
> > >> To: KY Srinivasan <kys@microsoft.com>
> > >> Cc: David Miller <davem@davemloft.net>; Netdev
> > >> <netdev@vger.kernel.org>; linux-kernel@vger.kernel.org;
> > >> devel@linuxdriverproject.org; olaf@aepfle.de; Robo Bot
> > >> <apw@canonical.com>; Jason Wang <jasowang@redhat.com>;
> > >> eli@mellanox.com; jackm@mellanox.com; yevgenyp@mellanox.com;
> > John
> > >> Ronciak <john.ronciak@intel.com>; intel-wired-lan <intel-wired-
> > >> lan@lists.osuosl.org>
> > >> Subject: Re: [PATCH net-next 2/2] intel: ixgbevf: Support Windows
> hosts
> > >> (Hyper-V)
> > >>
> > >> On Thu, Apr 14, 2016 at 4:55 PM, K. Y. Srinivasan <kys@microsoft.com>
> > >> wrote:
> > >> > On Hyper-V, the VF/PF communication is a via software mediated
> path
> > >> > as opposed to the hardware mailbox. Make the necessary
> > >> > adjustments to support Hyper-V.
> > >> >
> > >> > Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
> > >> > ---
> > >> > drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 11 ++
> > >> > drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 56 ++++++---
> > >> > drivers/net/ethernet/intel/ixgbevf/mbx.c | 12 ++
> > >> > drivers/net/ethernet/intel/ixgbevf/vf.c | 138
> > >> +++++++++++++++++++++
> > >> > drivers/net/ethernet/intel/ixgbevf/vf.h | 2 +
> > >> > 5 files changed, 201 insertions(+), 18 deletions(-)
> > >> >
> > >> > diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> > >> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> > >> > index 5ac60ee..f8d2a0b 100644
> > >> > --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> > >> > +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
> > >> > @@ -460,9 +460,13 @@ enum ixbgevf_state_t {
> > >> >
> > >> > enum ixgbevf_boards {
> > >> > board_82599_vf,
> > >> > + board_82599_vf_hv,
> > >> > board_X540_vf,
> > >> > + board_X540_vf_hv,
> > >> > board_X550_vf,
> > >> > + board_X550_vf_hv,
> > >> > board_X550EM_x_vf,
> > >> > + board_X550EM_x_vf_hv,
> > >> > };
> > >> >
> > >> > enum ixgbevf_xcast_modes {
> > >> > @@ -477,6 +481,13 @@ extern const struct ixgbevf_info
> > >> ixgbevf_X550_vf_info;
> > >> > extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
> > >> > extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
> > >> >
> > >> > +
> > >> > +extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
> > >> > +extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
> > >> > +extern const struct ixgbevf_info ixgbevf_X550_vf_hv_info;
> > >> > +extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info;
> > >> > +extern const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops;
> > >> > +
> > >> > /* needed by ethtool.c */
> > >> > extern const char ixgbevf_driver_name[];
> > >> > extern const char ixgbevf_driver_version[];
> > >> > diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > >> b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > >> > index 007cbe0..4a0ffac 100644
> > >> > --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > >> > +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
> > >> > @@ -49,6 +49,7 @@
> > >> > #include <linux/if.h>
> > >> > #include <linux/if_vlan.h>
> > >> > #include <linux/prefetch.h>
> > >> > +#include <asm/mshyperv.h>
> > >> >
> > >> > #include "ixgbevf.h"
> > >> >
> > >> > @@ -62,10 +63,14 @@ static char ixgbevf_copyright[] =
> > >> > "Copyright (c) 2009 - 2015 Intel Corporation.";
> > >> >
> > >> > static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
> > >> > - [board_82599_vf] = &ixgbevf_82599_vf_info,
> > >> > - [board_X540_vf] = &ixgbevf_X540_vf_info,
> > >> > - [board_X550_vf] = &ixgbevf_X550_vf_info,
> > >> > - [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
> > >> > + [board_82599_vf] = &ixgbevf_82599_vf_info,
> > >> > + [board_82599_vf_hv] = &ixgbevf_82599_vf_hv_info,
> > >> > + [board_X540_vf] = &ixgbevf_X540_vf_info,
> > >> > + [board_X540_vf_hv] = &ixgbevf_X540_vf_hv_info,
> > >> > + [board_X550_vf] = &ixgbevf_X550_vf_info,
> > >> > + [board_X550_vf_hv] = &ixgbevf_X550_vf_hv_info,
> > >> > + [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
> > >> > + [board_X550EM_x_vf_hv] = &ixgbevf_X550EM_x_vf_hv_info,
> > >> > };
> > >> >
> > >> > /* ixgbevf_pci_tbl - PCI Device ID Table
> > >> > @@ -78,9 +83,13 @@ static const struct ixgbevf_info
> > *ixgbevf_info_tbl[] =
> > >> {
> > >> > */
> > >> > static const struct pci_device_id ixgbevf_pci_tbl[] = {
> > >> > {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF), board_82599_vf
> },
> > >> > + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_VF_HV),
> > >> board_82599_vf_hv },
> > >> > {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF), board_X540_vf },
> > >> > + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540_VF_HV),
> > >> board_X540_vf_hv },
> > >> > {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF), board_X550_vf },
> > >> > + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV),
> > >> board_X550_vf_hv },
> > >> > {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF),
> > >> board_X550EM_x_vf },
> > >> > + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV),
> > >> board_X550EM_x_vf_hv},
> > >> > /* required last entry */
> > >> > {0, }
> > >> > };
> > >> > @@ -1809,12 +1818,13 @@ static int ixgbevf_vlan_rx_add_vid(struct
> > >> net_device *netdev,
> > >> > {
> > >> > struct ixgbevf_adapter *adapter = netdev_priv(netdev);
> > >> > struct ixgbe_hw *hw = &adapter->hw;
> > >> > - int err;
> > >> > + int err = 0;
> > >> >
> > >> > spin_lock_bh(&adapter->mbx_lock);
> > >> >
> > >> > /* add VID to filter table */
> > >> > - err = hw->mac.ops.set_vfta(hw, vid, 0, true);
> > >> > + if (hw->mac.ops.set_vfta)
> > >> > + err = hw->mac.ops.set_vfta(hw, vid, 0, true);
> > >> >
> > >> > spin_unlock_bh(&adapter->mbx_lock);
> > >> >
> > >> > @@ -1835,12 +1845,13 @@ static int ixgbevf_vlan_rx_kill_vid(struct
> > >> net_device *netdev,
> > >> > {
> > >> > struct ixgbevf_adapter *adapter = netdev_priv(netdev);
> > >> > struct ixgbe_hw *hw = &adapter->hw;
> > >> > - int err;
> > >> > + int err = 0;
> > >> >
> > >> > spin_lock_bh(&adapter->mbx_lock);
> > >> >
> > >> > /* remove VID from filter table */
> > >> > - err = hw->mac.ops.set_vfta(hw, vid, 0, false);
> > >> > + if (hw->mac.ops.set_vfta)
> > >> > + err = hw->mac.ops.set_vfta(hw, vid, 0, false);
> > >> >
> > >> > spin_unlock_bh(&adapter->mbx_lock);
> > >> >
> > >> > @@ -1873,14 +1884,16 @@ static int
> ixgbevf_write_uc_addr_list(struct
> > >> net_device *netdev)
> > >> > struct netdev_hw_addr *ha;
> > >> >
> > >> > netdev_for_each_uc_addr(ha, netdev) {
> > >> > - hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
> > >> > + if (hw->mac.ops.set_uc_addr)
> > >> > + hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
> > >> > udelay(200);
> > >> > }
> > >> > } else {
> > >> > /* If the list is empty then send message to PF driver to
> > >> > * clear all MAC VLANs on this VF.
> > >> > */
> > >> > - hw->mac.ops.set_uc_addr(hw, 0, NULL);
> > >> > + if (hw->mac.ops.set_uc_addr)
> > >> > + hw->mac.ops.set_uc_addr(hw, 0, NULL);
> > >> > }
> > >> >
> > >> > return count;
> > >>
> > >> So if I am understanding this correctly it looks like you cannot read
> > >> or write any addresses for this device. Would I be correct in
> > >> assuming that you get to have the one unicast address that is provided
> > >> by the PF and that is it?
> > >
> > > That is what I have been told by the Windows folks at Intel.
> >
> > Yeah, so I didn't see the other half of this patchset that has you
> > using a software interface for the multicast and broadcast traffic.
> > What I would recommend doing is just writing up a stub function you
> > can put in vf.c that will allow you to avoid having to add all these
> > if checks to the code.
> >
> > >> If so we may want to look at possibly returning some sort of error on
> > >> these calls so that we can configure the device to indicate that we
> > >> cannot support any of these filters.
> > >
> > > I will do that. So, I am going to check the device ID and return an error.
> > > Would IXGBE_NOT_IMPLEMENTED be appropriate?
> >
> > I'd say don't bother returning an error. You can probably just stub
> > out the function since if I recall correctly it is a void function
> > anyway and doesn't provide a return value.
> >
> > >>
> > >> > @@ -1908,10 +1921,13 @@ static void ixgbevf_set_rx_mode(struct
> > >> net_device *netdev)
> > >> >
> > >> > spin_lock_bh(&adapter->mbx_lock);
> > >> >
> > >> > - hw->mac.ops.update_xcast_mode(hw, netdev, xcast_mode);
> > >> > + if (hw->mac.ops.update_mc_addr_list)
> > >> > + if (hw->mac.ops.update_xcast_mode)
> > >> > + hw->mac.ops.update_xcast_mode(hw, netdev,
> > xcast_mode);
> > >> >
> > >> > /* reprogram multicast list */
> > >> > - hw->mac.ops.update_mc_addr_list(hw, netdev);
> > >> > + if (hw->mac.ops.update_mc_addr_list)
> > >> > + hw->mac.ops.update_mc_addr_list(hw, netdev);
> > >> >
> > >> > ixgbevf_write_uc_addr_list(netdev);
> > >> >
> >
> > Same thing for the multicast list as well.
> >
> > >> > @@ -2074,10 +2090,13 @@ static void ixgbevf_up_complete(struct
> > >> ixgbevf_adapter *adapter)
> > >> >
> > >> > spin_lock_bh(&adapter->mbx_lock);
> > >> >
> > >> > - if (is_valid_ether_addr(hw->mac.addr))
> > >> > - hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0);
> > >> > - else
> > >> > - hw->mac.ops.set_rar(hw, 0, hw->mac.perm_addr, 0);
> > >> > + if (is_valid_ether_addr(hw->mac.addr)) {
> > >> > + if (hw->mac.ops.set_rar)
> > >> > + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0);
> > >> > + } else {
> > >> > + if (hw->mac.ops.set_rar)
> > >> > + hw->mac.ops.set_rar(hw, 0, hw->mac.perm_addr, 0);
> > >> > + }
> > >> >
> > >> > spin_unlock_bh(&adapter->mbx_lock);
> > >> >
> > >>
> > >> Same here. We shouldn't let the user set a MAC address that we
> cannot
> > >> support. We should be returning an error.
> > >
> > > Yes; I will return an error.
> >
> > This is the one that needs to return an error. That way we should be
> > able to prevent MAC address changes.
> >
> > >>
> > >> > @@ -3672,14 +3691,15 @@ static int ixgbevf_set_mac(struct
> net_device
> > >> *netdev, void *p)
> > >> > struct ixgbevf_adapter *adapter = netdev_priv(netdev);
> > >> > struct ixgbe_hw *hw = &adapter->hw;
> > >> > struct sockaddr *addr = p;
> > >> > - int err;
> > >> > + int err = 0;
> > >> >
> > >> > if (!is_valid_ether_addr(addr->sa_data))
> > >> > return -EADDRNOTAVAIL;
> > >> >
> > >> > spin_lock_bh(&adapter->mbx_lock);
> > >> >
> > >> > - err = hw->mac.ops.set_rar(hw, 0, addr->sa_data, 0);
> > >> > + if (hw->mac.ops.set_rar)
> > >> > + err = hw->mac.ops.set_rar(hw, 0, addr->sa_data, 0);
> > >> >
> > >> > spin_unlock_bh(&adapter->mbx_lock);
> > >> >
> > >>
> > >> Specifically here. If hw->mac.ops.set_rar is NULL we cannot allow any
> > >> MAC address change so we should probably return "-EADDRNOTAVAIL".
> > >
> > > Will do.
> > >>
> > >> > diff --git a/drivers/net/ethernet/intel/ixgbevf/mbx.c
> > >> b/drivers/net/ethernet/intel/ixgbevf/mbx.c
> > >> > index dc68fea..298a0da 100644
> > >> > --- a/drivers/net/ethernet/intel/ixgbevf/mbx.c
> > >> > +++ b/drivers/net/ethernet/intel/ixgbevf/mbx.c
> > >> > @@ -346,3 +346,15 @@ const struct ixgbe_mbx_operations
> > >> ixgbevf_mbx_ops = {
> > >> > .check_for_rst = ixgbevf_check_for_rst_vf,
> > >> > };
> > >> >
> > >> > +/**
> > >> > + * Mailbox operations when running on Hyper-V.
> > >> > + * On Hyper-V, PF/VF communiction is not through the
> > >> > + * hardware mailbox; this communication is through
> > >> > + * a software mediated path.
> > >> > + * Most mail box operations are noop while running on
> > >> > + * Hyper-V.
> > >> > + */
> > >> > +const struct ixgbe_mbx_operations ixgbevf_hv_mbx_ops = {
> > >> > + .init_params = ixgbevf_init_mbx_params_vf,
> > >> > + .check_for_rst = ixgbevf_check_for_rst_vf,
> > >> > +};
> > >>
> > >> I'd say if you aren't going to use a mailbox then don't initialize it.
> > >> The code was based off of the same code that runs the ixgbe driver.
> > >> It should be able to function without a mailbox provided the necessary
> > >> calls are updated in the ixgbe_mac_operations that are used by the
> > >> hyperv VF.
> > >>
> > > Ok; I will change the code.
As I am working on addressing your comments, while most mailbox operations are not
used, the mechanism for checking for reset (check_for_rst) is identical even on Hyper-V.
So keeping Hyper-V specific mailbox operations may actually result in fewer changes.
I will shortly send you the updated patch for your review.
> > >
> > >> > diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c
> > >> b/drivers/net/ethernet/intel/ixgbevf/vf.c
> > >> > index 4d613a4..92397fd 100644
> > >> > --- a/drivers/net/ethernet/intel/ixgbevf/vf.c
> > >> > +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c
> > >> > @@ -27,6 +27,13 @@
> > >> > #include "vf.h"
> > >> > #include "ixgbevf.h"
> > >> >
> > >> > +/*
> > >> > + * On Hyper-V, to reset, we need to read from this offset
> > >> > + * from the PCI config space. This is the mechanism used on
> > >> > + * Hyper-V to support PF/VF communication.
> > >> > + */
> > >> > +#define IXGBE_HV_RESET_OFFSET 0x201
> > >> > +
> > >> > /**
> > >> > * ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx
> > >> > * @hw: pointer to hardware structure
> > >> > @@ -126,6 +133,23 @@ static s32 ixgbevf_reset_hw_vf(struct
> > ixgbe_hw
> > >> *hw)
> > >> > }
> > >> >
> > >> > /**
> > >> > + * Hyper-V variant; the VF/PF communication is through the PCI
> > >> > + * config space.
> > >> > + */
> > >> > +static s32 ixgbevf_hv_reset_hw_vf(struct ixgbe_hw *hw)
> > >> > +{
> > >> > + int i;
> > >> > + struct ixgbevf_adapter *adapter = hw->back;
> > >> > +
> > >> > + for (i = 0; i < 6; i++)
> > >> > + pci_read_config_byte(adapter->pdev,
> > >> > + (i + IXGBE_HV_RESET_OFFSET),
> > >> > + &hw->mac.perm_addr[i]);
> > >> > +
> > >> > + return 0;
> > >> > +}
> > >> > +
> > >>
> > >> This bit can be problematic. What about the case where
> PCI_MMCONFIG
> > >> is not defined. In such a case it will kill this function without
> > >> reporting an error other than maybe a MAC address that is all 0s or
> > >> all FF's.
> > >>
> > >> You might want to add some sort of check here with some message if
> > >> such a situation occurs just so it can be easier to debug.
> > >
> > > I am a little confused here. This function will only execute when we are
> > handling Hyper-V
> > > device IDs (while running on Hyper-V). Hyper-V PCI pass-through driver
> will
> > support the
> > > config space access.
> >
> > The kernel has a configuration option called CONFIG_PCI_MMCONFIG. On
> > x86 it is usually enabled by default, but it can be disabled.
> >
> > Right now this bit of code is dependent on it being enabled in order
> > to function correctly. Otherwise you will only have access to the
> > first 256 bytes of the PCI configuration space. You might want to
> > explore the possibility of a Kconfig option that would allow you to
> > only support the HyperV VFs if CONFIG_PCI_MMCONFIG is enabled.
>
> Our PCI pss-through driver depends on this functionality. I will make sure we
> Make that dependency more explicit.
> >
> > >>
> > >> > +/**
> > >> > * ixgbevf_stop_hw_vf - Generic stop Tx/Rx units
> > >> > * @hw: pointer to hardware structure
> > >> > *
> > >> > @@ -656,6 +680,68 @@ out:
> > >> > }
> > >> >
> > >> > /**
> > >> > + * Hyper-V variant; there is no mailbox communication.
> > >> > + */
> > >> > +static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
> > >> > + ixgbe_link_speed *speed,
> > >> > + bool *link_up,
> > >> > + bool autoneg_wait_to_complete)
> > >> > +{
> > >> > + struct ixgbe_mbx_info *mbx = &hw->mbx;
> > >> > + struct ixgbe_mac_info *mac = &hw->mac;
> > >> > + s32 ret_val = 0;
> > >> > + u32 links_reg;
> > >> > +
> > >> > + /* If we were hit with a reset drop the link */
> > >> > + if (!mbx->ops.check_for_rst(hw) || !mbx->timeout)
> > >> > + mac->get_link_status = true;
> > >> > +
> > >> > + if (!mac->get_link_status)
> > >> > + goto out;
> > >> > +
> > >> > + /* if link status is down no point in checking to see if pf is up */
> > >> > + links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
> > >> > + if (!(links_reg & IXGBE_LINKS_UP))
> > >> > + goto out;
> > >> > +
> > >> > + /* for SFP+ modules and DA cables on 82599 it can take up to
> > 500usecs
> > >> > + * before the link status is correct
> > >> > + */
> > >> > + if (mac->type == ixgbe_mac_82599_vf) {
> > >> > + int i;
> > >> > +
> > >> > + for (i = 0; i < 5; i++) {
> > >> > + udelay(100);
> > >> > + links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
> > >> > +
> > >> > + if (!(links_reg & IXGBE_LINKS_UP))
> > >> > + goto out;
> > >> > + }
> > >> > + }
> > >> > +
> > >> > + switch (links_reg & IXGBE_LINKS_SPEED_82599) {
> > >> > + case IXGBE_LINKS_SPEED_10G_82599:
> > >> > + *speed = IXGBE_LINK_SPEED_10GB_FULL;
> > >> > + break;
> > >> > + case IXGBE_LINKS_SPEED_1G_82599:
> > >> > + *speed = IXGBE_LINK_SPEED_1GB_FULL;
> > >> > + break;
> > >> > + case IXGBE_LINKS_SPEED_100_82599:
> > >> > + *speed = IXGBE_LINK_SPEED_100_FULL;
> > >> > + break;
> > >> > + }
> > >> > +
> > >> > + /* if we passed all the tests above then the link is up and we no
> > >> > + * longer need to check for link
> > >> > + */
> > >> > + mac->get_link_status = false;
> > >> > +
> > >> > +out:
> > >> > + *link_up = !mac->get_link_status;
> > >> > + return ret_val;
> > >> > +}
> > >> > +
> > >>
> > >> How does this handle the PF resetting? Seems like you are going to be
> > >> generating Tx hangs in such a case.
> > >
> > > I am not sure how the Windows PF driver communicates this information.
> > > Do you have any suggestions for this.
> >
> > You might want to take a look at the fm10k_get_host_state_generic
> > function. You could probably do something like the trick we did there
> > with the TXDCTL in order to detect cases where the PF has reset the VF
> > so that you could then reset your guest once the PF has come back up.
> > That way at least you would report link down instead of Tx hang if the
> > host has reset you.
>
> I will take a look at your example; thank you.
The code you have in fm10k_get_host_state_generic function is somewhat similar
to what I have in the function ixgbevf_hv_check_mac_link_vf(). We drop the link
if the PF has reset us. I will look at this code some more.
> >
> > >>
> > >> > +/**
> > >> > * ixgbevf_rlpml_set_vf - Set the maximum receive packet length
> > >> > * @hw: pointer to the HW structure
> > >> > * @max_size: value to assign to max frame size
> > >> > @@ -663,6 +749,19 @@ out:
> > >> > void ixgbevf_rlpml_set_vf(struct ixgbe_hw *hw, u16 max_size)
> > >> > {
> > >> > u32 msgbuf[2];
> > >> > + u32 reg;
> > >> > +
> > >> > + if (x86_hyper == &x86_hyper_ms_hyperv) {
> > >> > + /*
> > >> > + * If we are on Hyper-V, we implement
> > >> > + * this functionality differently.
> > >> > + */
> > >> > + reg = IXGBE_READ_REG(hw, IXGBE_VFRXDCTL(0));
> > >> > + /* CRC == 4 */
> > >> > + reg |= ((max_size + 4) | IXGBE_RXDCTL_RLPML_EN);
> > >> > + IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(0), reg);
> > >> > + return;
> > >> > + }
> > >> >
> > >> > msgbuf[0] = IXGBE_VF_SET_LPE;
> > >> > msgbuf[1] = max_size;
> > >>
> > >> You would be better off just implementing a hyperv version of this
> > >> function and avoiding the mailbox call entirely.
> > > Ok; will do.
> > >
> > >>
> > >> > @@ -679,6 +778,16 @@ int ixgbevf_negotiate_api_version(struct
> > >> ixgbe_hw *hw, int api)
> > >> > int err;
> > >> > u32 msg[3];
> > >> >
> > >> > + if (x86_hyper == &x86_hyper_ms_hyperv) {
> > >> > + /*
> > >> > + * Hyper-V only supports api version ixgbe_mbox_api_10
> > >> > + */
> > >> > + if (api != ixgbe_mbox_api_10)
> > >> > + return IXGBE_ERR_INVALID_ARGUMENT;
> > >> > +
> > >> > + return 0;
> > >> > + }
> > >> > +
> > >> > /* Negotiate the mailbox API version */
> > >> > msg[0] = IXGBE_VF_API_NEGOTIATE;
> > >> > msg[1] = api;
> > >>
> > >> Same here. Just implement a hyperv version of this function instead
> > >> of splicing into the existing call. Also you will need to wrap this
> > >> code up so that we can build on all architectures, not just x86.
> > >
> > > Ok; will do.
I now have a check for Hyper-V that is based on the mailbox operations
and that should address compilation issues on non x86 platforms. I will post the new set shortly.
Regards,
K. Y
^ permalink raw reply
* Re: [PATCH 2/2] rtlwifi: Fix reusable codes in core.c
From: Julian Calaby @ 2016-04-16 2:39 UTC (permalink / raw)
To: Kalle Valo
Cc: Byeoungwook Kim, Larry Finger, Chaoming Li, linux-wireless,
netdev, linux-kernel@vger.kernel.org
In-Reply-To: <87bn5apw5a.fsf@kamboji.qca.qualcomm.com>
Hi Kalle,
On Sat, Apr 16, 2016 at 4:25 AM, Kalle Valo <kvalo@codeaurora.org> wrote:
> Byeoungwook Kim <quddnr145@gmail.com> writes:
>
>> rtl_*_delay() functions were reused same codes about addr variable.
>> So i have converted to rtl_addr_delay() from code about addr variable.
>>
>> Signed-off-by: Byeoungwook Kim <quddnr145@gmail.com>
>> Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
>
> Doesn't apply:
>
> Applying: rtlwifi: Fix reusable codes in core.c
> fatal: sha1 information is lacking or useless (drivers/net/wireless/realtek/rtlwifi/core.c).
> Repository lacks necessary blobs to fall back on 3-way merge.
> Cannot fall back to three-way merge.
> Patch failed at 0001 rtlwifi: Fix reusable codes in core.c
>
> Please rebase and resend.
This one is already applied in some form. I thought I'd listed it in
my big list of superseded patches, however I must have missed it.
Thanks,
--
Julian Calaby
Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
^ permalink raw reply
* [PATCH] net: ipv6: Do not fix up linklocal and loopback addresses
From: Mike Manning @ 2016-04-16 3:13 UTC (permalink / raw)
To: netdev
In-Reply-To: <5711AA52.6010400@brocade.com>
f1705ec197e7 added the option to retain user configured addresses on an
admin down. A comment to one of the later revisions suggested using the
IFA_F_PERMANENT flag rather than adding a user_managed boolean to the
ifaddr struct. A side effect of this change is that link local and
loopback addresses are also retained which is not part of the objective
of f1705ec197e7. Add check so that these addresses are not fixed up,
given that a related fix 70af921db6f8 ensures that they are not kept in
the first place, otherwise this incorrect fixup triggers a crash in fib6.
Fixes: f1705ec197e7 ("net: ipv6: Make address flushing on ifdown optional")
Signed-off-by: Mike Manning <mmanning@brocade.com>
---
net/ipv6/addrconf.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 23cec53..cba4e10 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3200,6 +3200,12 @@ static void l3mdev_check_host_rt(struct inet6_dev *idev,
}
#endif
+static bool addr_is_local(const struct in6_addr *addr)
+{
+ return ipv6_addr_type(addr) &
+ (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
+}
+
static int fixup_permanent_addr(struct inet6_dev *idev,
struct inet6_ifaddr *ifp)
{
@@ -3238,6 +3244,7 @@ static void addrconf_permanent_addr(struct net_device *dev)
list_for_each_entry_safe(ifp, tmp, &idev->addr_list, if_list) {
if ((ifp->flags & IFA_F_PERMANENT) &&
+ !addr_is_local(&ifp->addr) &&
fixup_permanent_addr(idev, ifp) < 0) {
write_unlock_bh(&idev->lock);
ipv6_del_addr(ifp);
@@ -3448,12 +3455,6 @@ static void addrconf_type_change(struct net_device *dev, unsigned long event)
ipv6_mc_unmap(idev);
}
-static bool addr_is_local(const struct in6_addr *addr)
-{
- return ipv6_addr_type(addr) &
- (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK);
-}
-
static int addrconf_ifdown(struct net_device *dev, int how)
{
struct net *net = dev_net(dev);
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH net v2] vlan: pull on __vlan_insert_tag error path and fix csum correction
From: David Miller @ 2016-04-16 3:20 UTC (permalink / raw)
To: daniel; +Cc: jiri, netdev
In-Reply-To: <bde2d4bf994b57e3ca25960d4b347212c8077ac6.1460765959.git.daniel@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Sat, 16 Apr 2016 02:27:58 +0200
> When __vlan_insert_tag() fails from skb_vlan_push() path due to the
> skb_cow_head(), we need to undo the __skb_push() in the error path
> as well that was done earlier to move skb->data pointer to mac header.
>
> Moreover, I noticed that when in the non-error path the __skb_pull()
> is done and the original offset to mac header was non-zero, we fixup
> from a wrong skb->data offset in the checksum complete processing.
>
> So the skb_postpush_rcsum() really needs to be done before __skb_pull()
> where skb->data still points to the mac header start and thus operates
> under the same conditions as in __vlan_insert_tag().
>
> Fixes: 93515d53b133 ("net: move vlan pop/push functions into common code")
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
> ---
> v1 -> v2:
> - Resend/code still the same, Jiri gave it a review as well meanwhile.
Applied and queued up for -stable, thanks Daniel.
^ permalink raw reply
* [PATCH net-next v3 0/2] rtnetlink: new message for stats
From: Roopa Prabhu @ 2016-04-16 3:28 UTC (permalink / raw)
To: netdev; +Cc: jhs, davem, tgraf
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This patch adds a new RTM_GETSTATS message to query stats via
netlink from the kernel. RTM_NEWLINK also dumps links stats today, but
RTM_NEWLINK returns a lot more than just stats and is expensive in some
cases when frequent polling for stats from userspace is a common operation.
RTM_GETSTATS is an attempt to provide a light weight netlink message
to explicity query only stats from the kernel. The idea is to also keep
it extensible so that new kinds of stats can be added to it in the future.
Roopa Prabhu (2):
rtnetlink: add new RTM_GETSTATS to dump link stats
ipv6: add support for stats via RTM_GETSTATS
Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
RFC to v1 (apologies for the delay in sending this version out. busy days):
- Addressed feedback from Dave
- removed rtnl_link_stats
- Added hdr struct if_stats_msg to carry ifindex and
filter mask
- new macro IFLA_STATS_FILTER_BIT(ATTR) for filter mask
- split the ipv6 patch into a separate patch, need some more eyes on it
- prefix attributes with IFLA_STATS instead of IFLA_LINK_STATS for
shorter attribute names
v1 - v2:
- move IFLA_STATS_INET6 declaration to the inet6 patch
- get rid of RTM_DELSTATS
- mark ipv6 patch RFC. It can be used as an example for
other AF stats like stats
v2 - v3:
- add required padding to the if_stats_msg structure(suggested by jamal)
- rename netdev stat attributes with IFLA_STATS_LINK prefix
so that they are easily distinguishable with global
stats in the future (after global stats discussion with thomas)
- get rid of unnecessary copy when getting stats with dev_get_stats
(suggested by dave)
include/net/rtnetlink.h | 5 +
include/uapi/linux/if_link.h | 19 ++++
include/uapi/linux/rtnetlink.h | 7 ++
net/core/rtnetlink.c | 201 +++++++++++++++++++++++++++++++++++++++++
net/ipv6/addrconf.c | 77 ++++++++++++++--
5 files changed, 301 insertions(+), 8 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next v3 1/2] rtnetlink: add new RTM_GETSTATS message to query stats
From: Roopa Prabhu @ 2016-04-16 3:28 UTC (permalink / raw)
To: netdev; +Cc: jhs, davem, tgraf
From: Roopa Prabhu <roopa@cumulusnetworks.com>
This patch adds a new RTM_GETSTATS message to query stats via netlink
from the kernel. RTM_NEWLINK also dumps link stats today, but RTM_NEWLINK
returns a lot more than just stats and is expensive in some cases when
frequent polling for stats from userspace is a common operation.
RTM_GETSTATS is an attempt to provide a light weight netlink message
to explicity query only stats from the kernel. The idea is to also
keep it extensible so that new kinds of stats can be added to it in
the future.
This patch adds the following attribute for NETDEV stats:
struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = {
[IFLA_STATS_LINK_64] = { .len = sizeof(struct rtnl_link_stats64) },
};
This patch also allows for af family stats (an example af stats for IPV6
is available with the second patch in the series).
Like any other rtnetlink message, RTM_GETSTATS can be used to get stats of
a single interface or all interfaces with NLM_F_DUMP.
Future possible new types of stat attributes:
- IFLA_STATS_LINK_MPLS (nested. for mpls/mdev stats)
- IFLA_STATS_LINK_EXTENDED (nested. extended software netdev stats like bridge,
vlan, vxlan etc)
- IFLA_STATS_LINK_HW_EXTENDED (nested. extended hardware stats which are
available via ethtool today)
This patch also declares a filter mask for all stat attributes.
User has to provide a mask of stats attributes to query. filter mask
can be specified in the new hdr 'struct if_stats_msg' for stats messages.
Other important field in the header is the ifindex.
This api can be used for global stats (eg tcp) in the future. When global
stats are included in a stats msg, the ifindex in the header
must be zero. A single stats message cannot contain both global and
netdev specific stats. To easily distinguish them, netdev specific stat
attributes name are prefixed with IFLA_STATS_LINK_
Without any attributes in the filter_mask, no stats will be returned.
This patch has been tested with mofified iproute2 ifstat.
Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
include/net/rtnetlink.h | 5 ++
include/uapi/linux/if_link.h | 23 +++++
include/uapi/linux/rtnetlink.h | 5 ++
net/core/rtnetlink.c | 199 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 232 insertions(+)
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 2f87c1b..fa68158 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -131,6 +131,11 @@ struct rtnl_af_ops {
const struct nlattr *attr);
int (*set_link_af)(struct net_device *dev,
const struct nlattr *attr);
+ size_t (*get_link_af_stats_size)(const struct net_device *dev,
+ u32 filter_mask);
+ int (*fill_link_af_stats)(struct sk_buff *skb,
+ const struct net_device *dev,
+ u32 filter_mask);
};
void __rtnl_af_unregister(struct rtnl_af_ops *ops);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 9427f17..ab740fe 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -780,4 +780,27 @@ enum {
#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+/* STATS section */
+
+struct if_stats_msg {
+ __u8 family;
+ __u8 pad1;
+ __u16 pad2;
+ __u32 ifindex;
+ __u32 filter_mask;
+};
+
+/* A stats attribute can be netdev specific or a global stat.
+ * For netdev stats, lets use the prefix IFLA_STATS_LINK_*
+ */
+enum {
+ IFLA_STATS_UNSPEC,
+ IFLA_STATS_LINK_64,
+ __IFLA_STATS_MAX,
+};
+
+#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
+
+#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR))
+
#endif /* _UAPI_LINUX_IF_LINK_H */
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index ca764b5..cc885c4 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -139,6 +139,11 @@ enum {
RTM_GETNSID = 90,
#define RTM_GETNSID RTM_GETNSID
+ RTM_NEWSTATS = 92,
+#define RTM_NEWSTATS RTM_NEWSTATS
+ RTM_GETSTATS = 94,
+#define RTM_GETSTATS RTM_GETSTATS
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a7a3d34..2a8abe0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3444,6 +3444,202 @@ out:
return err;
}
+static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
+ int type, u32 pid, u32 seq, u32 change,
+ unsigned int flags, unsigned int filter_mask)
+{
+ struct if_stats_msg *ifsm;
+ struct nlmsghdr *nlh;
+ struct rtnl_af_ops *af_ops;
+ struct nlattr *attr;
+
+ ASSERT_RTNL();
+
+ nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifsm), flags);
+ if (!nlh)
+ return -EMSGSIZE;
+
+ ifsm = nlmsg_data(nlh);
+ ifsm->ifindex = dev->ifindex;
+ ifsm->filter_mask = filter_mask;
+
+ if (filter_mask & IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_64)) {
+ struct rtnl_link_stats64 *sp;
+
+ attr = nla_reserve(skb, IFLA_STATS_LINK_64,
+ sizeof(struct rtnl_link_stats64));
+ if (!attr)
+ return -EMSGSIZE;
+
+ sp = nla_data(attr);
+ dev_get_stats(dev, sp);
+ }
+
+ list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ if (af_ops->fill_link_af_stats) {
+ int err;
+
+ err = af_ops->fill_link_af_stats(skb, dev, filter_mask);
+ if (err < 0)
+ goto nla_put_failure;
+ }
+ }
+
+ nlmsg_end(skb, nlh);
+
+ return 0;
+
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+
+ return -EMSGSIZE;
+}
+
+static const struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = {
+ [IFLA_STATS_LINK_64] = { .len = sizeof(struct rtnl_link_stats64) },
+};
+
+static size_t rtnl_link_get_af_stats_size(const struct net_device *dev,
+ u32 filter_mask)
+{
+ struct rtnl_af_ops *af_ops;
+ size_t size = 0;
+
+ list_for_each_entry(af_ops, &rtnl_af_ops, list) {
+ if (af_ops->get_link_af_stats_size)
+ size += af_ops->get_link_af_stats_size(dev,
+ filter_mask);
+ }
+
+ return size;
+}
+
+static size_t if_nlmsg_stats_size(const struct net_device *dev,
+ u32 filter_mask)
+{
+ size_t size = 0;
+
+ if (filter_mask & IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_64))
+ size += nla_total_size(sizeof(struct rtnl_link_stats64));
+
+ size += rtnl_link_get_af_stats_size(dev, filter_mask);
+
+ return size;
+}
+
+static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ struct net *net = sock_net(skb->sk);
+ struct if_stats_msg *ifsm;
+ struct net_device *dev = NULL;
+ struct sk_buff *nskb;
+ u32 filter_mask;
+ int err;
+
+ ifsm = nlmsg_data(nlh);
+ if (ifsm->ifindex > 0)
+ dev = __dev_get_by_index(net, ifsm->ifindex);
+ else
+ return -EINVAL;
+
+ if (!dev)
+ return -ENODEV;
+
+ filter_mask = ifsm->filter_mask;
+ if (!filter_mask)
+ return -EINVAL;
+
+ nskb = nlmsg_new(if_nlmsg_stats_size(dev, filter_mask), GFP_KERNEL);
+ if (!nskb)
+ return -ENOBUFS;
+
+ err = rtnl_fill_statsinfo(nskb, dev, RTM_NEWSTATS,
+ NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0,
+ 0, filter_mask);
+ if (err < 0) {
+ /* -EMSGSIZE implies BUG in if_nlmsg_stats_size */
+ WARN_ON(err == -EMSGSIZE);
+ kfree_skb(nskb);
+ } else {
+ err = rtnl_unicast(nskb, net, NETLINK_CB(skb).portid);
+ }
+
+ return err;
+}
+
+static u16 rtnl_stats_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *dev;
+ u16 min_ifinfo_dump_size = 0;
+ struct if_stats_msg *ifsm;
+ u32 filter_mask;
+
+ ifsm = nlmsg_data(nlh);
+ filter_mask = ifsm->filter_mask;
+
+ /* traverse the list of net devices and compute the minimum
+ * buffer size based upon the filter mask.
+ */
+ list_for_each_entry(dev, &net->dev_base_head, dev_list) {
+ min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
+ if_nlmsg_stats_size(dev,
+ filter_mask));
+ }
+
+ return min_ifinfo_dump_size;
+}
+
+static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct net *net = sock_net(skb->sk);
+ struct if_stats_msg *ifsm;
+ int h, s_h;
+ int idx = 0, s_idx;
+ struct net_device *dev;
+ struct hlist_head *head;
+ unsigned int flags = NLM_F_MULTI;
+ u32 filter_mask = 0;
+ int err;
+
+ s_h = cb->args[0];
+ s_idx = cb->args[1];
+
+ cb->seq = net->dev_base_seq;
+
+ ifsm = nlmsg_data(cb->nlh);
+ filter_mask = ifsm->filter_mask;
+
+ for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
+ idx = 0;
+ head = &net->dev_index_head[h];
+ hlist_for_each_entry(dev, head, index_hlist) {
+ if (idx < s_idx)
+ goto cont;
+ err = rtnl_fill_statsinfo(skb, dev, RTM_NEWSTATS,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, 0,
+ flags, filter_mask);
+ /* If we ran out of room on the first message,
+ * we're in trouble
+ */
+ WARN_ON((err == -EMSGSIZE) && (skb->len == 0));
+
+ if (err < 0)
+ goto out;
+
+ nl_dump_check_consistent(cb, nlmsg_hdr(skb));
+cont:
+ idx++;
+ }
+ }
+out:
+ cb->args[1] = idx;
+ cb->args[0] = h;
+
+ return skb->len;
+}
+
/* Process one rtnetlink message. */
static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
@@ -3593,4 +3789,7 @@ void __init rtnetlink_init(void)
rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL);
rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, NULL);
rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL);
+
+ rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump,
+ rtnl_stats_calcit);
}
--
1.9.1
^ 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