Netdev List
 help / color / mirror / Atom feed
* Re: No traffic with Marvell switch and latest linux-next
From: Florian Fainelli @ 2019-02-24 21:26 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Russell King - ARM Linux admin, Heiner Kallweit,
	netdev@vger.kernel.org
In-Reply-To: <20190224170455.GH26626@lunn.ch>



On February 24, 2019 9:04:55 AM PST, Andrew Lunn <andrew@lunn.ch> wrote:
>> The added difficulty here and the reason why Andrew went with the
>> approach that is used by the code currently is because neither do the
>> CPU or DSA ports are backed by a net_device. It is somewhere on my
>TODO
>> to permit the use of PHYLINK without the need of a net_device to
>cover
>> those specific DSA cases unless we just brute force the whole thing
>and
>> allocate a net_device structure but not register that net_device? Yes
>in
>> fact, why don't we do that?
>
>Hi Florian
>
>At the moment, we are using a phydev which is not connected to a
>MAC. That is rather odd, but the phylib maintainers mostly know about
>this, and keep an eye out for changes which might break any
>assumptions. And the phylib API is quite small.

I would argue that this very thread is a proof against your argument since we all failed to predict that Heiner's changes would change those assumptions. Having a certain of assumptions is fine but given all the recent PHYLIB helpers that have been added I am not sure how well that will scale.

>
>How many assumptions are going to break with a netdev which is not
>registered? The API is much bigger, more people hack on it, and it is
>going to be much harder to review changes to make sure assumptions are
>not changed.

A non registered net_device appears easier to manage and debug since there is state tracking all over the network stack for those cases.

>
>If we are going to do something odd, we should keep the scope as small
>as possible.

Hence my suggestion to allocate a dummy net_device object just so calls to netif_carrier_{on,off} (and possibly more in the future) do nothing. I don't think that teaching either PHYLIB or PHYLINK about a NULL net_device is going to scale really well over time nor make it easier  for respective maintainers. If we make the net_device optional, it will be harder to review changes as well as make sure that we do not create locking/object interactions  issues.

Another approach could be to define a minimal network port object (struct devlink, maybe?) which could be used independently from a net_device, or a lightweight net_device with no visibility into existing namespaces. None of these ideas are new though and would probably require several cycles to get done right.

Heiner, Russell, which approach would you take?
-- 
Florian

^ permalink raw reply

* [PATCH net-next v2 0/2] net: phy: aquantia: add hwmon support
From: Heiner Kallweit @ 2019-02-24 21:34 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, David Miller; +Cc: netdev@vger.kernel.org

This series adds HWMON support for the temperature sensor and the
related alarms on the 107/108/109 chips.

v2:
- remove struct aqr_priv
- rename header file to aquantia.h

Heiner Kallweit (2):
  net: phy: aquantia: rename aquantia.c to aquantia_main.c
  net: phy: aquantia: add hwmon support

 drivers/net/phy/Makefile                      |   1 +
 drivers/net/phy/aquantia.h                    |  16 ++
 drivers/net/phy/aquantia_hwmon.c              | 245 ++++++++++++++++++
 .../net/phy/{aquantia.c => aquantia_main.c}   |   4 +
 4 files changed, 266 insertions(+)
 create mode 100644 drivers/net/phy/aquantia.h
 create mode 100644 drivers/net/phy/aquantia_hwmon.c
 rename drivers/net/phy/{aquantia.c => aquantia_main.c} (99%)

-- 
2.20.1

^ permalink raw reply

* [PATCH net-next v2 1/2] net: phy: aquantia: rename aquantia.c to aquantia_main.c
From: Heiner Kallweit @ 2019-02-24 21:35 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <a12e48d8-f274-c4e0-3232-ee8d32975a65@gmail.com>

Rename aquantia.c to aquantia_main.c to be prepared for adding new
functionality to separate source code files.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/Makefile                        | 1 +
 drivers/net/phy/{aquantia.c => aquantia_main.c} | 0
 2 files changed, 1 insertion(+)
 rename drivers/net/phy/{aquantia.c => aquantia_main.c} (100%)

diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 5805c0b7d..b0845adaf 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -45,6 +45,7 @@ sfp-obj-$(CONFIG_SFP)		+= sfp-bus.o
 obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_AMD_PHY)		+= amd.o
+aquantia-objs			+= aquantia_main.o
 obj-$(CONFIG_AQUANTIA_PHY)	+= aquantia.o
 obj-$(CONFIG_ASIX_PHY)		+= asix.o
 obj-$(CONFIG_AT803X_PHY)	+= at803x.o
diff --git a/drivers/net/phy/aquantia.c b/drivers/net/phy/aquantia_main.c
similarity index 100%
rename from drivers/net/phy/aquantia.c
rename to drivers/net/phy/aquantia_main.c
-- 
2.20.1



^ permalink raw reply related

* [PATCH net-next v2 2/2] net: phy: aquantia: add hwmon support
From: Heiner Kallweit @ 2019-02-24 21:36 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <a12e48d8-f274-c4e0-3232-ee8d32975a65@gmail.com>

This adds HWMON support for the temperature sensor and the related
alarms on the 107/108/109 chips. This patch is based on work from
Nikita and Andrew. I added:
- support for changing alarm thresholds via sysfs
- move HWMON code to a separate source file to improve maintainability
- smaller changes like using IS_REACHABLE instead of ifdef
  (avoids problems if PHY driver is built in and HWMON is a module)

v2:
- remove struct aqr_priv
- rename header file to aquantia.h

Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/Makefile         |   2 +-
 drivers/net/phy/aquantia.h       |  16 ++
 drivers/net/phy/aquantia_hwmon.c | 245 +++++++++++++++++++++++++++++++
 drivers/net/phy/aquantia_main.c  |   4 +
 4 files changed, 266 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/phy/aquantia.h
 create mode 100644 drivers/net/phy/aquantia_hwmon.c

diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index b0845adaf..c48596626 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -45,7 +45,7 @@ sfp-obj-$(CONFIG_SFP)		+= sfp-bus.o
 obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
 
 obj-$(CONFIG_AMD_PHY)		+= amd.o
-aquantia-objs			+= aquantia_main.o
+aquantia-objs			+= aquantia_main.o aquantia_hwmon.o
 obj-$(CONFIG_AQUANTIA_PHY)	+= aquantia.o
 obj-$(CONFIG_ASIX_PHY)		+= asix.o
 obj-$(CONFIG_AT803X_PHY)	+= at803x.o
diff --git a/drivers/net/phy/aquantia.h b/drivers/net/phy/aquantia.h
new file mode 100644
index 000000000..5a16caab7
--- /dev/null
+++ b/drivers/net/phy/aquantia.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * HWMON driver for Aquantia PHY
+ *
+ * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+ * Author: Andrew Lunn <andrew@lunn.ch>
+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
+ */
+
+#include <linux/device.h>
+#include <linux/phy.h>
+
+#if IS_REACHABLE(CONFIG_HWMON)
+int aqr_hwmon_probe(struct phy_device *phydev);
+#else
+static inline int aqr_hwmon_probe(struct phy_device *phydev) { return 0; }
+#endif
diff --git a/drivers/net/phy/aquantia_hwmon.c b/drivers/net/phy/aquantia_hwmon.c
new file mode 100644
index 000000000..9c77d149e
--- /dev/null
+++ b/drivers/net/phy/aquantia_hwmon.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/* HWMON driver for Aquantia PHY
+ *
+ * Author: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+ * Author: Andrew Lunn <andrew@lunn.ch>
+ * Author: Heiner Kallweit <hkallweit1@gmail.com>
+ */
+
+#include <linux/phy.h>
+#include <linux/device.h>
+#include <linux/ctype.h>
+#include <linux/hwmon.h>
+
+#include "aquantia.h"
+
+/* Vendor specific 1, MDIO_MMD_VEND2 */
+#define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL	0xc421
+#define VEND1_THERMAL_PROV_LOW_TEMP_FAIL	0xc422
+#define VEND1_THERMAL_PROV_HIGH_TEMP_WARN	0xc423
+#define VEND1_THERMAL_PROV_LOW_TEMP_WARN	0xc424
+#define VEND1_THERMAL_STAT1			0xc820
+#define VEND1_THERMAL_STAT2			0xc821
+#define VEND1_THERMAL_STAT2_VALID		BIT(0)
+#define VEND1_GENERAL_STAT1			0xc830
+#define VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL	BIT(14)
+#define VEND1_GENERAL_STAT1_LOW_TEMP_FAIL	BIT(13)
+#define VEND1_GENERAL_STAT1_HIGH_TEMP_WARN	BIT(12)
+#define VEND1_GENERAL_STAT1_LOW_TEMP_WARN	BIT(11)
+
+#if IS_REACHABLE(CONFIG_HWMON)
+
+static umode_t aqr_hwmon_is_visible(const void *data,
+				    enum hwmon_sensor_types type,
+				    u32 attr, int channel)
+{
+	if (type != hwmon_temp)
+		return 0;
+
+	switch (attr) {
+	case hwmon_temp_input:
+	case hwmon_temp_min_alarm:
+	case hwmon_temp_max_alarm:
+	case hwmon_temp_lcrit_alarm:
+	case hwmon_temp_crit_alarm:
+		return 0444;
+	case hwmon_temp_min:
+	case hwmon_temp_max:
+	case hwmon_temp_lcrit:
+	case hwmon_temp_crit:
+		return 0644;
+	default:
+		return 0;
+	}
+}
+
+static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
+{
+	int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
+
+	if (temp < 0)
+		return temp;
+
+	/* register value is 2's complement with LSB = 1/256th degree Celsius */
+	if (temp > 0x8000)
+		temp -= 0x10000;
+
+	*value = temp * 1000 / 256;
+
+	return 0;
+}
+
+static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
+{
+	int temp;
+
+	if (value >= 128000 || value < -128000)
+		return -ERANGE;
+
+	temp = value * 256 / 1000;
+
+	if (temp < 0)
+		temp += 0x10000;
+
+	return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, temp);
+}
+
+static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
+{
+	int reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GENERAL_STAT1);
+
+	if (reg < 0)
+		return reg;
+
+	*value = !!(reg & bit);
+
+	return 0;
+}
+
+static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+			  u32 attr, int channel, long *value)
+{
+	struct phy_device *phydev = dev_get_drvdata(dev);
+	int reg;
+
+	if (type != hwmon_temp)
+		return -EOPNOTSUPP;
+
+	switch (attr) {
+	case hwmon_temp_input:
+		reg = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+				   VEND1_THERMAL_STAT2);
+		if (reg < 0)
+			return reg;
+		if (!(reg & VEND1_THERMAL_STAT2_VALID))
+			return -EIO;
+
+		return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
+
+	case hwmon_temp_lcrit:
+		return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
+				     value);
+	case hwmon_temp_min:
+		return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
+				     value);
+	case hwmon_temp_max:
+		return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
+				     value);
+	case hwmon_temp_crit:
+		return aqr_hwmon_get(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
+				     value);
+	case hwmon_temp_lcrit_alarm:
+		return aqr_hwmon_status1(phydev,
+					 VEND1_GENERAL_STAT1_LOW_TEMP_FAIL,
+					 value);
+	case hwmon_temp_min_alarm:
+		return aqr_hwmon_status1(phydev,
+					 VEND1_GENERAL_STAT1_LOW_TEMP_WARN,
+					 value);
+	case hwmon_temp_max_alarm:
+		return aqr_hwmon_status1(phydev,
+					 VEND1_GENERAL_STAT1_HIGH_TEMP_WARN,
+					 value);
+	case hwmon_temp_crit_alarm:
+		return aqr_hwmon_status1(phydev,
+					 VEND1_GENERAL_STAT1_HIGH_TEMP_FAIL,
+					 value);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int aqr_hwmon_write(struct device *dev, enum hwmon_sensor_types type,
+			   u32 attr, int channel, long value)
+{
+	struct phy_device *phydev = dev_get_drvdata(dev);
+
+	if (type != hwmon_temp)
+		return -EOPNOTSUPP;
+
+	switch (attr) {
+	case hwmon_temp_lcrit:
+		return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_FAIL,
+				     value);
+	case hwmon_temp_min:
+		return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_LOW_TEMP_WARN,
+				     value);
+	case hwmon_temp_max:
+		return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_WARN,
+				     value);
+	case hwmon_temp_crit:
+		return aqr_hwmon_set(phydev, VEND1_THERMAL_PROV_HIGH_TEMP_FAIL,
+				     value);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static const struct hwmon_ops aqr_hwmon_ops = {
+	.is_visible = aqr_hwmon_is_visible,
+	.read = aqr_hwmon_read,
+	.write = aqr_hwmon_write,
+};
+
+static u32 aqr_hwmon_chip_config[] = {
+	HWMON_C_REGISTER_TZ,
+	0,
+};
+
+static const struct hwmon_channel_info aqr_hwmon_chip = {
+	.type = hwmon_chip,
+	.config = aqr_hwmon_chip_config,
+};
+
+static u32 aqr_hwmon_temp_config[] = {
+	HWMON_T_INPUT |
+	HWMON_T_MAX | HWMON_T_MIN |
+	HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM |
+	HWMON_T_CRIT | HWMON_T_LCRIT |
+	HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM,
+	0,
+};
+
+static const struct hwmon_channel_info aqr_hwmon_temp = {
+	.type = hwmon_temp,
+	.config = aqr_hwmon_temp_config,
+};
+
+static const struct hwmon_channel_info *aqr_hwmon_info[] = {
+	&aqr_hwmon_chip,
+	&aqr_hwmon_temp,
+	NULL,
+};
+
+static const struct hwmon_chip_info aqr_hwmon_chip_info = {
+	.ops = &aqr_hwmon_ops,
+	.info = aqr_hwmon_info,
+};
+
+int aqr_hwmon_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct device *hwmon_dev;
+	char *hwmon_name;
+	int i, j;
+
+	hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
+	if (!hwmon_name)
+		return -ENOMEM;
+
+	for (i = j = 0; hwmon_name[i]; i++) {
+		if (isalnum(hwmon_name[i])) {
+			if (i != j)
+				hwmon_name[j] = hwmon_name[i];
+			j++;
+		}
+	}
+	hwmon_name[j] = '\0';
+
+	hwmon_dev = devm_hwmon_device_register_with_info(dev, hwmon_name,
+					phydev, &aqr_hwmon_chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+#endif
diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c
index 0f0eb5682..37218e5d7 100644
--- a/drivers/net/phy/aquantia_main.c
+++ b/drivers/net/phy/aquantia_main.c
@@ -12,6 +12,8 @@
 #include <linux/delay.h>
 #include <linux/phy.h>
 
+#include "aquantia.h"
+
 #define PHY_ID_AQ1202	0x03a1b445
 #define PHY_ID_AQ2104	0x03a1b460
 #define PHY_ID_AQR105	0x03a1b4a2
@@ -231,6 +233,7 @@ static struct phy_driver aqr_driver[] = {
 	.name		= "Aquantia AQR107",
 	.aneg_done	= genphy_c45_aneg_done,
 	.get_features	= genphy_c45_pma_read_abilities,
+	.probe		= aqr_hwmon_probe,
 	.config_aneg    = aqr_config_aneg,
 	.config_intr	= aqr_config_intr,
 	.ack_interrupt	= aqr_ack_interrupt,
@@ -241,6 +244,7 @@ static struct phy_driver aqr_driver[] = {
 	.name		= "Aquantia AQCS109",
 	.aneg_done	= genphy_c45_aneg_done,
 	.get_features	= genphy_c45_pma_read_abilities,
+	.probe		= aqr_hwmon_probe,
 	.config_init	= aqcs109_config_init,
 	.config_aneg    = aqr_config_aneg,
 	.config_intr	= aqr_config_intr,
-- 
2.20.1



^ permalink raw reply related

* Re: No traffic with Marvell switch and latest linux-next
From: Heiner Kallweit @ 2019-02-24 21:42 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn
  Cc: Russell King - ARM Linux admin, netdev@vger.kernel.org
In-Reply-To: <2B512084-E971-482D-81FC-B3CEEC1C26C5@gmail.com>

On 24.02.2019 22:26, Florian Fainelli wrote:
> 
> 
> On February 24, 2019 9:04:55 AM PST, Andrew Lunn <andrew@lunn.ch> wrote:
>>> The added difficulty here and the reason why Andrew went with the
>>> approach that is used by the code currently is because neither do the
>>> CPU or DSA ports are backed by a net_device. It is somewhere on my
>> TODO
>>> to permit the use of PHYLINK without the need of a net_device to
>> cover
>>> those specific DSA cases unless we just brute force the whole thing
>> and
>>> allocate a net_device structure but not register that net_device? Yes
>> in
>>> fact, why don't we do that?
>>
>> Hi Florian
>>
>> At the moment, we are using a phydev which is not connected to a
>> MAC. That is rather odd, but the phylib maintainers mostly know about
>> this, and keep an eye out for changes which might break any
>> assumptions. And the phylib API is quite small.
> 
> I would argue that this very thread is a proof against your argument since we all failed to predict that Heiner's changes would change those assumptions. Having a certain of assumptions is fine but given all the recent PHYLIB helpers that have been added I am not sure how well that will scale.
> 
>>
>> How many assumptions are going to break with a netdev which is not
>> registered? The API is much bigger, more people hack on it, and it is
>> going to be much harder to review changes to make sure assumptions are
>> not changed.
> 
> A non registered net_device appears easier to manage and debug since there is state tracking all over the network stack for those cases.
> 
>>
>> If we are going to do something odd, we should keep the scope as small
>> as possible.
> 
> Hence my suggestion to allocate a dummy net_device object just so calls to netif_carrier_{on,off} (and possibly more in the future) do nothing. I don't think that teaching either PHYLIB or PHYLINK about a NULL net_device is going to scale really well over time nor make it easier  for respective maintainers. If we make the net_device optional, it will be harder to review changes as well as make sure that we do not create locking/object interactions  issues.
> 
> Another approach could be to define a minimal network port object (struct devlink, maybe?) which could be used independently from a net_device, or a lightweight net_device with no visibility into existing namespaces. None of these ideas are new though and would probably require several cycles to get done right.
> 
> Heiner, Russell, which approach would you take?
> 
Given my 2 days of experience with DSA (feels like 3 already) I would like to spend few more minutes on thinking before I answer.

Heiner

^ permalink raw reply

* Re: [PATCH net-next 2/2] net: phy: aquantia: add hwmon support
From: Andrew Lunn @ 2019-02-24 21:46 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev@vger.kernel.org
In-Reply-To: <d934bb9a-5edc-6a51-3012-aab9c7d40768@gmail.com>

> I just see that we don't need struct aqr_priv at all for hwmon
> because it uses device-managed versions of the relevant functions.
> So we can add such a struct when it's actually needed.

Hi Heiner

Yes, i had not noticed that.

     Andrew

^ permalink raw reply

* [PATCH] rtl_bt: Update firmware for BT part of RTL8822C
From: Larry Finger @ 2019-02-25  1:12 UTC (permalink / raw)
  To: linux-firmware; +Cc: linux-wireless, Larry Finger, netdev, Max Chou

The file was sent to me by Max Chou <max.chou@realtek.com>.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Max Chou <max.chou@realtek.com>
---
 WHENCE                  |   2 ++
 rtl_bt/rtl8822cu_fw.bin | Bin 22412 -> 41588 bytes
 2 files changed, 2 insertions(+)

diff --git a/WHENCE b/WHENCE
index 853990b..351b312 100644
--- a/WHENCE
+++ b/WHENCE
@@ -3254,6 +3254,8 @@ Files rtl_bt/rtl8822b_* came directly from Realtek. These files are
 updated on April 14, 2017.
 Files rtl_bt/rtl8821c_* and rtl_bt/rtl8723d_* came directly from Realtek.
 File rtl_bt/rtl8822cu_fw.bin came directly from Realtek.
+updated on February 24, 2019
+File rtl_bt/rtl8822cu_fw.bin came directly from Realtek.
 
 --------------------------------------------------------------------------
 
diff --git a/rtl_bt/rtl8822cu_fw.bin b/rtl_bt/rtl8822cu_fw.bin
index 558037c14cb51243528cfb433c6ad4a829b716f7..9a43075277f8a01ab00e9d78a4e33e87d258e8a8 100644
GIT binary patch
delta 22071
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
BMYI3_

delta 4059
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
TbDL1YCx{ZBSZL?&7Q=r5PE^0=

-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH net] net/sched: act_ipt: fix refcount leak when replace fails
From: David Miller @ 2019-02-25  1:31 UTC (permalink / raw)
  To: dcaratti; +Cc: vladbu, xiyou.wangcong, jhs, jiri, netdev
In-Reply-To: <9616212b5203dac35d55d67b25963487a8276191.1550834953.git.dcaratti@redhat.com>

From: Davide Caratti <dcaratti@redhat.com>
Date: Fri, 22 Feb 2019 12:33:25 +0100

> After commit 4e8ddd7f1758 ("net: sched: don't release reference on action
> overwrite"), the error path of all actions was converted to drop refcount
> also when the action was being overwritten. But we forgot act_ipt_init(),
> in case allocation of 'tname' was not successful:
> 
>  # tc action add action xt -j LOG --log-prefix hello index 100
>  tablename: mangle hook: NF_IP_POST_ROUTING
>          target:  LOG level warning prefix "hello" index 100
>  # tc action show action xt
>  total acts 1
> 
>          action order 0: tablename: mangle  hook: NF_IP_POST_ROUTING
>          target  LOG level warning prefix "hello"
>          index 100 ref 1 bind 0
>  # tc action replace action xt -j LOG --log-prefix world index 100
>  tablename: mangle hook: NF_IP_POST_ROUTING
>          target:  LOG level warning prefix "world" index 100
>  RTNETLINK answers: Cannot allocate memory
>  We have an error talking to the kernel
>  # tc action show action xt
>  total acts 1
> 
>          action order 0: tablename: mangle  hook: NF_IP_POST_ROUTING
>          target  LOG level warning prefix "hello"
>          index 100 ref 2 bind 0
> 
> Ensure we call tcf_idr_release(), in case 'tname' allocation failed, also
> when the action is being replaced.
> 
> Fixes: 4e8ddd7f1758 ("net: sched: don't release reference on action overwrite")
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>

Applied and queued up for -stable.

^ permalink raw reply

* Re: [PATCH net] net/sched: act_skbedit: fix refcount leak when replace fails
From: David Miller @ 2019-02-25  1:32 UTC (permalink / raw)
  To: dcaratti; +Cc: vladbu, xiyou.wangcong, jhs, jiri, netdev
In-Reply-To: <8f12357dd5131d64326b05ac5b71eb847afb692a.1550834944.git.dcaratti@redhat.com>

From: Davide Caratti <dcaratti@redhat.com>
Date: Fri, 22 Feb 2019 12:33:26 +0100

> when act_skbedit was converted to use RCU in the data plane, we added an
> error path, but we forgot to drop the action refcount in case of failure
> during a 'replace' operation:
> 
>  # tc actions add action skbedit ptype otherhost pass index 100
>  # tc action show action skbedit
>  total acts 1
> 
>          action order 0: skbedit  ptype otherhost pass
>           index 100 ref 1 bind 0
>  # tc actions replace action skbedit ptype otherhost drop index 100
>  RTNETLINK answers: Cannot allocate memory
>  We have an error talking to the kernel
>  # tc action show action skbedit
>  total acts 1
> 
>          action order 0: skbedit  ptype otherhost pass
>           index 100 ref 2 bind 0
> 
> Ensure we call tcf_idr_release(), in case 'params_new' allocation failed,
> also when the action is being replaced.
> 
> Fixes: c749cdda9089 ("net/sched: act_skbedit: don't use spinlock in the data path")
> Signed-off-by: Davide Caratti <dcaratti@redhat.com>

Also applied and queued up for -stable.

^ permalink raw reply

* Re: [PATCH] NETWORKING: avoid use IPCB in cipso_v4_error
From: David Miller @ 2019-02-25  1:33 UTC (permalink / raw)
  To: s-nazarov; +Cc: paul, netdev, linux-security-module, kuznet, yoshfuji
In-Reply-To: <8873761550853329@myt6-67cd1de25d8a.qloud-c.yandex.net>

From: Nazarov Sergey <s-nazarov@yandex.ru>
Date: Fri, 22 Feb 2019 19:35:29 +0300

> I tried to analyze the cases of using icmp_send in kernel. It
> indirectly used by many protocols: ARP, IP, UDP, Netfilter, IPVS,
> IPIP, GRE over IP, CLIP, XFRM, CIPSOv4.  Different IP tunnels and
> XFRM operating directly over IP layer and if using own skb->cb data,
> having IP header data in front of it. CLIP uses icmp_send for
> packets from arp queue only.  So, If I right, only TCP layer moves
> IP header data and only CIPSOv4 operates on both IP and TCP layers
> now.

Ok.

^ permalink raw reply

* Re: [PATCH v2 0/2] NETWORKING: avoid use IPCB in cipso_v4_error
From: David Miller @ 2019-02-25  1:33 UTC (permalink / raw)
  To: s-nazarov; +Cc: paul, netdev, linux-security-module, kuznet, yoshfuji
In-Reply-To: <33533951550857169@myt3-2475c4d2af83.qloud-c.yandex.net>

From: Nazarov Sergey <s-nazarov@yandex.ru>
Date: Fri, 22 Feb 2019 20:39:29 +0300

> The original discussion is here:
> https://lore.kernel.org/linux-security-module/16659801547571984@sas1-890ba5c2334a.qloud-c.yandex.net/
> 
> Changes in v2:
> - original patch divided on 2 parts: add __icmp_send function, fix cipso_v4_error
> - add __ip_option_compile not using icmp_send in case nof error

Your changes are lacking proper signoffs.

^ permalink raw reply

* Re: [PATCH v2 net-next] net: phy: improve definition of __ETHTOOL_LINK_MODE_MASK_NBITS
From: David Miller @ 2019-02-25  1:34 UTC (permalink / raw)
  To: hkallweit1; +Cc: andrew, f.fainelli, netdev
In-Reply-To: <3ae0478b-810f-904e-e128-7e0a57c7255c@gmail.com>

From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Fri, 22 Feb 2019 19:25:59 +0100

> The way to define __ETHTOOL_LINK_MODE_MASK_NBITS seems to be overly
> complicated, go with a standard approach instead.
> Whilst we're at it, move the comment to the right place.
> 
> v2:
> - rebased
> 
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>

Applied, thanks Heiner.

^ permalink raw reply

* Re: [PATCH] net: dsa: lantiq: Add GPHY firmware files
From: David Miller @ 2019-02-25  1:35 UTC (permalink / raw)
  To: hauke; +Cc: netdev
In-Reply-To: <20190222191113.28167-1-hauke@hauke-m.de>

From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Fri, 22 Feb 2019 20:11:13 +0100

> This adds the file names of the FW files which this driver handles into
> the module description.
> 
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

Applied.

^ permalink raw reply

* Re: [PATCH] net: lantiq: Do not use eth_change_mtu()
From: David Miller @ 2019-02-25  1:35 UTC (permalink / raw)
  To: hauke; +Cc: netdev
In-Reply-To: <20190222191257.28273-1-hauke@hauke-m.de>

From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Fri, 22 Feb 2019 20:12:57 +0100

> eth_change_mtu() is not needed any more, the networking subsystem will
> call it automatically when this callback is not implemented.
> 
> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>

Applied to net-next.

^ permalink raw reply

* Re: [PATCH v2 bpf-next 0/9] bpf: Network Resource Manager (NRM)
From: David Ahern @ 2019-02-25  1:38 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Eric Dumazet, brakmo, netdev, Martin Lau, Alexei Starovoitov,
	Daniel Borkmann, Kernel Team
In-Reply-To: <20190224044815.nqfr6szce7j7g3za@ast-mbp.dhcp.thefacebook.com>

On 2/23/19 11:48 PM, Alexei Starovoitov wrote:
> 'network resources' also include back bone and TOR capacity and
> this mechanism is going to help address that as well.

This appears to be the talk you are referring to:

http://vger.kernel.org/lpc_net2018_talks/LPC%20NRM.pdf

and from my reading it only references throttling at L4 - ie.,
bandwidth. hence my request for a better name than 'network resources'
in the commit logs and code references.

^ permalink raw reply

* Re: [PATCH net-next 0/2] net: switchdev.h inclusion removal
From: David Miller @ 2019-02-25  1:43 UTC (permalink / raw)
  To: f.fainelli; +Cc: netdev
In-Reply-To: <20190222203134.19508-1-f.fainelli@gmail.com>

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Fri, 22 Feb 2019 12:31:32 -0800

> This targets a few drivers that no longer to have net/switchdev.h
> included.

Series applied.

^ permalink raw reply

* Re: [PATCH net-next] net: phy: check PMAPMD link status only in genphy_c45_read_link
From: David Miller @ 2019-02-25  1:43 UTC (permalink / raw)
  To: hkallweit1; +Cc: andrew, f.fainelli, netdev
In-Reply-To: <9c7b68ea-ac30-a7ec-1c88-ae819dbbb7b4@gmail.com>

From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Fri, 22 Feb 2019 22:59:38 +0100

> The current code reports a link as up if all devices (except a few
> blacklisted ones) report the link as up. This breaks Aquantia AQCS109
> for lower speeds because on this PHY the PCS link status reflects a
> 10G link only. For Marvell there's a similar issue, therefore PHYXS
> device isn't checked.
> 
> There may be more PHYs where depending on the mode the link status
> of only selected devices is relevant.
> 
> For now it seems to be sufficient to check the link status of the
> PMAPMD device only. Leave the loop in the code to be prepared in
> case we have to add functionality to check more than one device,
> depending on the mode.
> 
> Successfully tested on a board with an AQCS109.
> 
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next v3 0/6] devlink: make ethtool compat reliable
From: David Miller @ 2019-02-25  1:43 UTC (permalink / raw)
  To: jakub.kicinski; +Cc: jiri, mkubecek, andrew, f.fainelli, netdev, oss-drivers
In-Reply-To: <20190222220758.7117-1-jakub.kicinski@netronome.com>


Jakub please address the feedback you were given.

Thanks.

^ permalink raw reply

* [PATCH net-next] mlxsw: spectrum: remove set but not used variable 'autoneg_status'
From: YueHaibing @ 2019-02-25  2:03 UTC (permalink / raw)
  To: Jiri Pirko, Ido Schimmel, davem
  Cc: YueHaibing, netdev, kernel-janitors, linux-kernel

Fixes gcc '-Wunused-but-set-variable' warning:

drivers/net/ethernet/mellanox/mlxsw/spectrum.c: In function 'mlxsw_sp_port_get_link_ksettings':
drivers/net/ethernet/mellanox/mlxsw/spectrum.c:3062:5: warning:
 variable 'autoneg_status' set but not used [-Wunused-but-set-variable]

It's not used since commit 475b33cb66c9 ("mlxsw: spectrum: Remove unsupported
eth_proto_lp_advertise field in PTYS")

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 40177b9834c4..b00f6f74f91a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3059,7 +3059,6 @@ static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
 	const struct mlxsw_sp_port_type_speed_ops *ops;
 	char ptys_pl[MLXSW_REG_PTYS_LEN];
 	u8 connector_type;
-	u8 autoneg_status;
 	bool autoneg;
 	int err;
 
@@ -3079,8 +3078,6 @@ static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
 	mlxsw_sp_port_get_link_advertise(mlxsw_sp, eth_proto_admin, autoneg,
 					 cmd);
 
-	autoneg_status = mlxsw_reg_ptys_an_status_get(ptys_pl);
-
 	cmd->base.autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 	connector_type = mlxsw_reg_ptys_connector_type_get(ptys_pl);
 	cmd->base.port = mlxsw_sp_port_connector_port(connector_type);




^ permalink raw reply related

* Re: [PATCH net-next v3 3/6] nfp: add .ndo_get_devlink
From: Florian Fainelli @ 2019-02-25  2:05 UTC (permalink / raw)
  To: Jakub Kicinski, davem, jiri; +Cc: mkubecek, andrew, netdev, oss-drivers
In-Reply-To: <20190222220758.7117-4-jakub.kicinski@netronome.com>

Le 2/22/19 à 2:07 PM, Jakub Kicinski a écrit :
> Support getting devlink instance from a new NDO.
> 
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next v3 4/6] nfp: remove ethtool flashing fallback
From: Florian Fainelli @ 2019-02-25  2:06 UTC (permalink / raw)
  To: Jakub Kicinski, davem, jiri; +Cc: mkubecek, andrew, netdev, oss-drivers
In-Reply-To: <20190222220758.7117-5-jakub.kicinski@netronome.com>

Le 2/22/19 à 2:07 PM, Jakub Kicinski a écrit :
> Now that devlink fallback will be called reliably, we can remove
> the ethtool flashing code.
> 
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next v2 2/2] net: phy: aquantia: add hwmon support
From: Florian Fainelli @ 2019-02-25  2:17 UTC (permalink / raw)
  To: Heiner Kallweit, Andrew Lunn, David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <2b46ac62-db6f-b72c-e81b-c6fbf063ab4b@gmail.com>

Le 2/24/19 à 1:36 PM, Heiner Kallweit a écrit :
> This adds HWMON support for the temperature sensor and the related
> alarms on the 107/108/109 chips. This patch is based on work from
> Nikita and Andrew. I added:
> - support for changing alarm thresholds via sysfs
> - move HWMON code to a separate source file to improve maintainability
> - smaller changes like using IS_REACHABLE instead of ifdef
>   (avoids problems if PHY driver is built in and HWMON is a module)
> 
> v2:
> - remove struct aqr_priv
> - rename header file to aquantia.h
> 
> Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>

Should not Nikita be the author for that patch? Some minor nits below:

> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
> ---
>  drivers/net/phy/Makefile         |   2 +-
>  drivers/net/phy/aquantia.h       |  16 ++
>  drivers/net/phy/aquantia_hwmon.c | 245 +++++++++++++++++++++++++++++++
>  drivers/net/phy/aquantia_main.c  |   4 +
>  4 files changed, 266 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/net/phy/aquantia.h
>  create mode 100644 drivers/net/phy/aquantia_hwmon.c
> 
> diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
> index b0845adaf..c48596626 100644
> --- a/drivers/net/phy/Makefile
> +++ b/drivers/net/phy/Makefile
> @@ -45,7 +45,7 @@ sfp-obj-$(CONFIG_SFP)		+= sfp-bus.o
>  obj-y				+= $(sfp-obj-y) $(sfp-obj-m)
>  
>  obj-$(CONFIG_AMD_PHY)		+= amd.o
> -aquantia-objs			+= aquantia_main.o
> +aquantia-objs			+= aquantia_main.o aquantia_hwmon.o

Since you are adding a stub if CONFIG_HWMON is not reachable, does not
that mean you would want to do something like:

ifdef CONFIG_HWMON
aquanti-objs	+= aquantia_hwmon.o
endif

in this makefile?

[snip]

> +static int aqr_hwmon_get(struct phy_device *phydev, int reg, long *value)
> +{
> +	int temp = phy_read_mmd(phydev, MDIO_MMD_VEND1, reg);
> +
> +	if (temp < 0)
> +		return temp;
> +
> +	/* register value is 2's complement with LSB = 1/256th degree Celsius */
> +	if (temp > 0x8000)
> +		temp -= 0x10000;

Would decimal or BIT() notation be easier to use/read here?

> +
> +	*value = temp * 1000 / 256;
> +
> +	return 0;
> +}
> +
> +static int aqr_hwmon_set(struct phy_device *phydev, int reg, long value)
> +{
> +	int temp;
> +
> +	if (value >= 128000 || value < -128000)
> +		return -ERANGE;
> +
> +	temp = value * 256 / 1000;
> +
> +	if (temp < 0)
> +		temp += 0x10000;

Likewise

> +
> +	return phy_write_mmd(phydev, MDIO_MMD_VEND1, reg, temp);
> +}
> +
> +static int aqr_hwmon_status1(struct phy_device *phydev, int bit, long *value)
> +{
> +	int reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GENERAL_STAT1);
> +
> +	if (reg < 0)
> +		return reg;
> +
> +	*value = !!(reg & bit);
> +
> +	return 0;
> +}

Can you also make this function take a register offset as parameter such
that you can eliminate open coding that in the case hwmon_temp_input below?

> +
> +static int aqr_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
> +			  u32 attr, int channel, long *value)
> +{
> +	struct phy_device *phydev = dev_get_drvdata(dev);
> +	int reg;
> +
> +	if (type != hwmon_temp)
> +		return -EOPNOTSUPP;
> +
> +	switch (attr) {
> +	case hwmon_temp_input:
> +		reg = phy_read_mmd(phydev, MDIO_MMD_VEND1,
> +				   VEND1_THERMAL_STAT2);
> +		if (reg < 0)
> +			return reg;
> +		if (!(reg & VEND1_THERMAL_STAT2_VALID))
> +			return -EIO;

And use that helper here.

> +
> +		return aqr_hwmon_get(phydev, VEND1_THERMAL_STAT1, value);
> +

[snip]

> +	hwmon_name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
> +	if (!hwmon_name)
> +		return -ENOMEM;
> +
> +	for (i = j = 0; hwmon_name[i]; i++) {
> +		if (isalnum(hwmon_name[i])) {
> +			if (i != j)
> +				hwmon_name[j] = hwmon_name[i];
> +			j++;
> +		}
> +	}
> +	hwmon_name[j] = '\0';

I am always baffled that drivers need to take care of these details...
but that seems to be the way to go.
-- 
Florian

^ permalink raw reply

* Re: [PATCH 1/3] net: ethernet: add support for PCS and 2.5G speed
From: Florian Fainelli @ 2019-02-25  2:31 UTC (permalink / raw)
  To: Parshuram Thombare, nicolas.ferre, davem, netdev, andrew,
	hkallweit1, linux-kernel, rafalc, piotrs, jank
In-Reply-To: <20190222201225.GA15633@lvlogina.cadence.com>

Le 2/22/19 à 12:12 PM, Parshuram Thombare a écrit :
> This patch add support for PCS (for SGMII interface) and 2.5Gbps MAC
> in Cadence ethernet controller driver.

At a high level you don't seem to be making use of PHYLINK so which
2.5Gbps interfaces do you actually support?

> 
> Signed-off-by: Parshuram Thombare <pthombar@cadence.com>
> ---

[snip]

> @@ -361,26 +361,50 @@ static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
>   * macb_set_tx_clk() - Set a clock to a new frequency
>   * @clk		Pointer to the clock to change
>   * @rate	New frequency in Hz
> + * @interafce	Phy interface

Typo: @interface and this is an unrelated change.

>   * @dev		Pointer to the struct net_device
>   */
> -static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev)
> +static void macb_set_tx_clk(struct clk *clk, int speed,
> +			    phy_interface_t interface, struct net_device *dev)
>  {
>  	long ferr, rate, rate_rounded;
>  
>  	if (!clk)
>  		return;
>  
> -	switch (speed) {
> -	case SPEED_10:
> +	if (interface == PHY_INTERFACE_MODE_GMII ||
> +	    interface == PHY_INTERFACE_MODE_MII) {
> +		switch (speed) {
> +		case SPEED_10:>  		rate = 2500000;

You need to add one tab to align rate and break.

>  		break;
> -	case SPEED_100:
> +		case SPEED_100:
>  		rate = 25000000;
>  		break;
> -	case SPEED_1000:
> +		case SPEED_1000:
>  		rate = 125000000;
>  		break;
> -	default:
> +		default:
> +		return;
> +		}
> +	} else if (interface == PHY_INTERFACE_MODE_SGMII) {
> +		switch (speed) {
> +		case SPEED_10:
> +		rate = 1250000;
> +		break;
> +		case SPEED_100:
> +		rate = 12500000;
> +		break;
> +		case SPEED_1000:
> +		rate = 125000000;
> +		break;
> +		case SPEED_2500:
> +		rate = 312500000;
> +		break;
> +		default:
> +		return;

The indentation is broken here and you can greatly simplify this with a
simple function that returns speed * 1250 and does an initial check for
unsupported speeds.

> +		}
> +	} else {
>  		return;
>  	}
>  
> @@ -410,30 +434,49 @@ static void macb_handle_link_change(struct net_device *dev)
>  
>  	spin_lock_irqsave(&bp->lock, flags);
>  
> -	if (phydev->link) {
> -		if ((bp->speed != phydev->speed) ||
> -		    (bp->duplex != phydev->duplex)) {
> -			u32 reg;
> -
> -			reg = macb_readl(bp, NCFGR);
> -			reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
> -			if (macb_is_gem(bp))
> -				reg &= ~GEM_BIT(GBE);
> +	if (phydev->link && (bp->speed != phydev->speed ||
> +			     bp->duplex != phydev->duplex)) {
> +		u32 reg;
>  
> -			if (phydev->duplex)
> -				reg |= MACB_BIT(FD);
> +		reg = macb_readl(bp, NCFGR);
> +		reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
> +		if (macb_is_gem(bp))
> +			reg &= ~GEM_BIT(GBE);
> +		if (phydev->duplex)
> +			reg |= MACB_BIT(FD);
> +		macb_or_gem_writel(bp, NCFGR, reg);
> +
> +		if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII &&
> +		    (phydev->speed == SPEED_1000 ||
> +		     phydev->speed == SPEED_2500)) {
> +			if (bp->caps & MACB_CAPS_TWO_PT_FIVE_GIG_SPEED) {
> +				reg = gem_readl(bp, NCR) &
> +					~GEM_BIT(TWO_PT_FIVE_GIG);
> +				gem_writel(bp, NCR, reg);
> +			}

If you are making correct use of the capabilities then there is no point
in re-checking them here. If you allowed the MAC to advertise 2.5Gbps
then it is de-facto SGMII capable.

> +			gem_writel(bp, NCFGR, GEM_BIT(GBE) |
> +					gem_readl(bp, NCFGR));
> +			if (bp->caps & MACB_CAPS_TWO_PT_FIVE_GIG_SPEED &&
> +			    phydev->speed == SPEED_2500)
> +				gem_writel(bp, NCR, gem_readl(bp, NCR) |
> +						GEM_BIT(TWO_PT_FIVE_GIG));
> +		} else if (phydev->speed == SPEED_1000) {
> +			gem_writel(bp, NCFGR, GEM_BIT(GBE) |
> +					gem_readl(bp, NCFGR));
> +		} else {
> +			if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
> +				reg = gem_readl(bp, NCFGR);
> +				reg &= ~(GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL));
> +				gem_writel(bp, NCFGR, reg);
> +			}
>  			if (phydev->speed == SPEED_100)
> -				reg |= MACB_BIT(SPD);
> -			if (phydev->speed == SPEED_1000 &&
> -			    bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
> -				reg |= GEM_BIT(GBE);
> -
> -			macb_or_gem_writel(bp, NCFGR, reg);
> -
> -			bp->speed = phydev->speed;
> -			bp->duplex = phydev->duplex;
> -			status_change = 1;
> +				macb_writel(bp, NCFGR, MACB_BIT(SPD) |
> +					macb_readl(bp, NCFGR));
>  		}

There is a lot of repetition while setting the GBE bit which always set
based on speed == 1000 irrespective of the mode, so take that part out
of the if () else if () else () clauses.

> +
> +		bp->speed = phydev->speed;
> +		bp->duplex = phydev->duplex;
> +		status_change = 1;
>  	}
>  
>  	if (phydev->link != bp->link) {
> @@ -453,7 +496,8 @@ static void macb_handle_link_change(struct net_device *dev)
>  			/* Update the TX clock rate if and only if the link is
>  			 * up and there has been a link change.
>  			 */
> -			macb_set_tx_clk(bp->tx_clk, phydev->speed, dev);
> +			macb_set_tx_clk(bp->tx_clk, phydev->speed,
> +					bp->phy_interface, dev);
>  
>  			netif_carrier_on(dev);
>  			netdev_info(dev, "link up (%d/%s)\n",
> @@ -543,10 +587,16 @@ static int macb_mii_probe(struct net_device *dev)
>  	}
>  
>  	/* mask with MAC supported features */
> -	if (macb_is_gem(bp) && bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
> -		phy_set_max_speed(phydev, SPEED_1000);
> -	else
> -		phy_set_max_speed(phydev, SPEED_100);
> +	if (macb_is_gem(bp)) {

You have changed the previous logic that also checked for
MACB_CAPS_GIGABIT_MODE_AVAILABLE, why?

> +		linkmode_copy(phydev->supported, PHY_GBIT_FEATURES);
> +		if (bp->caps & MACB_CAPS_TWO_PT_FIVE_GIG_SPEED)
> +			linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
> +					 phydev->supported);
> +	} else {
> +		linkmode_copy(phydev->supported, PHY_BASIC_FEATURES);
> +	}
> +
> +	linkmode_copy(phydev->advertising, phydev->supported);
>  
>  	if (bp->caps & MACB_CAPS_NO_GIGABIT_HALF)
>  		phy_remove_link_mode(phydev,
> @@ -2217,8 +2267,6 @@ static void macb_init_hw(struct macb *bp)
>  	macb_set_hwaddr(bp);
>  
>  	config = macb_mdc_clk_div(bp);
> -	if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII)
> -		config |= GEM_BIT(SGMIIEN) | GEM_BIT(PCSSEL);
>  	config |= MACB_BF(RBOF, NET_IP_ALIGN);	/* Make eth data aligned */
>  	config |= MACB_BIT(PAE);		/* PAuse Enable */
>  	config |= MACB_BIT(DRFCS);		/* Discard Rx FCS */
> @@ -3255,6 +3303,23 @@ static void macb_configure_caps(struct macb *bp,
>  		dcfg = gem_readl(bp, DCFG1);
>  		if (GEM_BFEXT(IRQCOR, dcfg) == 0)
>  			bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
> +		if (GEM_BFEXT(NO_PCS, dcfg) == 0)
> +			bp->caps |= MACB_CAPS_PCS;
> +		switch (MACB_BFEXT(IDNUM, macb_readl(bp, MID))) {
> +		case MACB_GEM7016_IDNUM:
> +		case MACB_GEM7017_IDNUM:
> +		case MACB_GEM7017A_IDNUM:
> +		case MACB_GEM7020_IDNUM:
> +		case MACB_GEM7021_IDNUM:
> +		case MACB_GEM7021A_IDNUM:
> +		case MACB_GEM7022_IDNUM:
> +		if (bp->caps & MACB_CAPS_PCS)
> +			bp->caps |= MACB_CAPS_TWO_PT_FIVE_GIG_SPEED;
> +		break;
> +
> +		default:
> +		break;
> +		}
>  		dcfg = gem_readl(bp, DCFG2);
>  		if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
>  			bp->caps |= MACB_CAPS_FIFO_MODE;
> @@ -4110,7 +4175,28 @@ static int macb_probe(struct platform_device *pdev)
>  		else
>  			bp->phy_interface = PHY_INTERFACE_MODE_MII;
>  	} else {
> +		switch (err) {
> +		case PHY_INTERFACE_MODE_SGMII:
> +		if (bp->caps & MACB_CAPS_PCS) {
> +			bp->phy_interface = PHY_INTERFACE_MODE_SGMII;
> +			break;
> +		}

If SGMII was selected on a version of the IP that does not support it,
then falling back to GMII or MII does not sound correct, this is a hard
error that must be handled as such.
-- 
Florian

^ permalink raw reply

* [PATCH net-next] switchdev: Complete removal of switchdev_port_attr_get()
From: Florian Fainelli @ 2019-02-25  2:39 UTC (permalink / raw)
  To: netdev
  Cc: idosch, Florian Fainelli, Jiri Pirko, Ivan Vecera,
	David S. Miller, open list

We have no more in tree users of switchdev_port_attr_get() after
d0e698d57a94 ("Merge branch 'net-Get-rid-of-switchdev_port_attr_get'")
so completely remove the function signature and body.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 include/net/switchdev.h   |  4 ----
 net/switchdev/switchdev.c | 42 ---------------------------------------
 2 files changed, 46 deletions(-)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 45310ddf2d7e..be4b13e66668 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -115,13 +115,9 @@ typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
 /**
  * struct switchdev_ops - switchdev operations
  *
- * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
- *
  * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
  */
 struct switchdev_ops {
-	int	(*switchdev_port_attr_get)(struct net_device *dev,
-					   struct switchdev_attr *attr);
 	int	(*switchdev_port_attr_set)(struct net_device *dev,
 					   const struct switchdev_attr *attr,
 					   struct switchdev_trans *trans);
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 7e1357db33d7..362413c9b389 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -174,48 +174,6 @@ static int switchdev_deferred_enqueue(struct net_device *dev,
 	return 0;
 }
 
-/**
- *	switchdev_port_attr_get - Get port attribute
- *
- *	@dev: port device
- *	@attr: attribute to get
- */
-int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
-{
-	const struct switchdev_ops *ops = dev->switchdev_ops;
-	struct net_device *lower_dev;
-	struct list_head *iter;
-	struct switchdev_attr first = {
-		.id = SWITCHDEV_ATTR_ID_UNDEFINED
-	};
-	int err = -EOPNOTSUPP;
-
-	if (ops && ops->switchdev_port_attr_get)
-		return ops->switchdev_port_attr_get(dev, attr);
-
-	if (attr->flags & SWITCHDEV_F_NO_RECURSE)
-		return err;
-
-	/* Switch device port(s) may be stacked under
-	 * bond/team/vlan dev, so recurse down to get attr on
-	 * each port.  Return -ENODATA if attr values don't
-	 * compare across ports.
-	 */
-
-	netdev_for_each_lower_dev(dev, lower_dev, iter) {
-		err = switchdev_port_attr_get(lower_dev, attr);
-		if (err)
-			break;
-		if (first.id == SWITCHDEV_ATTR_ID_UNDEFINED)
-			first = *attr;
-		else if (memcmp(&first, attr, sizeof(*attr)))
-			return -ENODATA;
-	}
-
-	return err;
-}
-EXPORT_SYMBOL_GPL(switchdev_port_attr_get);
-
 static int __switchdev_port_attr_set(struct net_device *dev,
 				     const struct switchdev_attr *attr,
 				     struct switchdev_trans *trans)
-- 
2.19.1


^ permalink raw reply related

* [PATCH][net-next] net: Use RCU_POINTER_INITIALIZER() to init static variable
From: Li RongQing @ 2019-02-25  2:43 UTC (permalink / raw)
  To: netdev

This pointer is RCU protected, so proper primitives should be used.

Signed-off-by: Zhang Yu <zhangyu31@baidu.com>
Signed-off-by: Li RongQing <lirongqing@baidu.com>
---
 net/sched/sch_generic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 38e5add14fab..7bcee8b8f803 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -559,7 +559,7 @@ struct Qdisc_ops noop_qdisc_ops __read_mostly = {
 };
 
 static struct netdev_queue noop_netdev_queue = {
-	.qdisc		=	&noop_qdisc,
+	RCU_POINTER_INITIALIZER(qdisc, &noop_qdisc),
 	.qdisc_sleeping	=	&noop_qdisc,
 };
 
-- 
2.16.2


^ permalink raw reply related


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