Netdev List
 help / color / mirror / Atom feed
* [PATCH net 0/3] net/smc: fixes 2018-08-08
From: Ursula Braun @ 2018-08-08 12:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, schwidefsky, heiko.carstens, raspl,
	linux-kernel

Dave,

here are small fixes for SMC: The first patch makes sure, shutdown code
is not executed for sockets in state SMC_LISTEN. The second patch resets
send and receive buffer values for accepted sockets, since TCP buffer size
optimizations for the internal CLC socket should not be forwarded to the
outer SMC socket. The third patch solves a race between connect and ioctl
reported by syzbot.

Kind regards, Ursula

Ursula Braun (3):
  net/smc: no shutdown in state SMC_LISTEN
  net/smc: allow sysctl rmem and wmem defaults for servers
  net/smc: move sock lock in smc_ioctl()

 net/smc/af_smc.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

-- 
2.16.4

^ permalink raw reply

* [PATCH net-next] mlxsw: spectrum_flower: use PTR_ERR_OR_ZERO()
From: YueHaibing @ 2018-08-08 12:29 UTC (permalink / raw)
  To: davem, jiri; +Cc: linux-kernel, netdev, idosch, YueHaibing

Fix ptr_ret.cocci warnings:
 drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c:543:1-3: WARNING: PTR_ERR_OR_ZERO can be used

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

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
index 8213cb7..ddcd508 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
@@ -540,10 +540,9 @@ int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp,
 					   f->common.chain_index,
 					   MLXSW_SP_ACL_PROFILE_FLOWER,
 					   &rulei.values.elusage);
-	if (IS_ERR(ruleset))
-		return PTR_ERR(ruleset);
+
 	/* keep the reference to the ruleset */
-	return 0;
+	return PTR_ERR_OR_ZERO(ruleset);
 }
 
 void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp,
-- 
2.7.0

^ permalink raw reply related

* [PATCH net-next 0/5] net: aquantia: implement WOL and EEE support
From: Igor Russkikh @ 2018-08-08 10:57 UTC (permalink / raw)
  To: David S . Miller; +Cc: netdev, Igor Russkikh

In this patchset Yana Esina and Nikita Danilov implemented:

- Upload function to interact with FW memory
- Definitions and structures necessary for the correct operation of Wake ON Lan
- The functionality Wake On Lan via ethtool (Magic packet is supported)
- The functionality for Energy-Efficient Ethernet configuration via ethtool

Igor Russkikh (1):
  net: aquantia: bump driver version

Yana Esina (4):
  net: aquantia: fix hw_atl_utils_fw_upload_dwords
  net: aquantia: definitions for WOL patch
  net: aquantia: implement WOL support
  net: aquantia: implement EEE support

 drivers/net/ethernet/aquantia/atlantic/aq_common.h |   5 +
 .../net/ethernet/aquantia/atlantic/aq_ethtool.c    | 108 ++++++++
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h     |  13 +-
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c    |  12 +-
 drivers/net/ethernet/aquantia/atlantic/aq_nic.h    |   4 +
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  33 ++-
 .../aquantia/atlantic/hw_atl/hw_atl_a0_internal.h  |   6 -
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  35 ++-
 .../aquantia/atlantic/hw_atl/hw_atl_b0_internal.h  |   6 -
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c |   7 +
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h |   3 +
 .../aquantia/atlantic/hw_atl/hw_atl_llh_internal.h |  13 +
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c        | 134 ++++++++--
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h        | 127 +++++++++-
 .../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c   | 277 +++++++++++++++++++--
 drivers/net/ethernet/aquantia/atlantic/ver.h       |   2 +-
 16 files changed, 665 insertions(+), 120 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [PATCH net-next 1/5] net: aquantia: fix hw_atl_utils_fw_upload_dwords
From: Igor Russkikh @ 2018-08-08 10:57 UTC (permalink / raw)
  To: David S . Miller; +Cc: netdev, Igor Russkikh, Yana Esina, Nikita Danilov
In-Reply-To: <cover.1533650064.git.igor.russkikh@aquantia.com>

From: Yana Esina <yana.esina@aquantia.com>

This patch fixes the upload function, which worked incorrectly with
some chips.

Signed-off-by: Yana Esina <yana.esina@aquantia.com>
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Tested-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c |  7 ++++
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h |  3 ++
 .../aquantia/atlantic/hw_atl/hw_atl_llh_internal.h | 13 +++++++
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c        | 44 ++++++++++++++--------
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h        |  6 +++
 .../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c   |  7 +++-
 6 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
index 10ba035..d0a6ea7 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c
@@ -1460,3 +1460,10 @@ void hw_atl_reg_glb_cpu_scratch_scp_set(struct aq_hw_s *aq_hw,
 	aq_hw_write_reg(aq_hw, HW_ATL_GLB_CPU_SCRATCH_SCP_ADR(scratch_scp),
 			glb_cpu_scratch_scp);
 }
+
+void hw_atl_mcp_up_force_intr_set(struct aq_hw_s *aq_hw, u32 up_force_intr)
+{
+	aq_hw_write_reg_bit(aq_hw, HW_ATL_MCP_UP_FORCE_INTERRUPT_ADR,
+			    HW_ATL_MCP_UP_FORCE_INTERRUPT_MSK,
+			    HW_ATL_MCP_UP_FORCE_INTERRUPT_SHIFT, up_force_intr);
+}
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
index dfb426f..7056c73 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h
@@ -698,4 +698,7 @@ void hw_atl_msm_reg_wr_strobe_set(struct aq_hw_s *aq_hw, u32 reg_wr_strobe);
 /* set pci register reset disable */
 void hw_atl_pci_pci_reg_res_dis_set(struct aq_hw_s *aq_hw, u32 pci_reg_res_dis);
 
+/* set uP Force Interrupt */
+void hw_atl_mcp_up_force_intr_set(struct aq_hw_s *aq_hw, u32 up_force_intr);
+
 #endif /* HW_ATL_LLH_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
index e0cf701..716674a 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h
@@ -2387,4 +2387,17 @@
 #define HW_ATL_GLB_CPU_SCRATCH_SCP_ADR(scratch_scp) \
 	(0x00000300u + (scratch_scp) * 0x4)
 
+/* register address for bitfield uP Force Interrupt */
+#define HW_ATL_MCP_UP_FORCE_INTERRUPT_ADR 0x00000404
+/* bitmask for bitfield uP Force Interrupt */
+#define HW_ATL_MCP_UP_FORCE_INTERRUPT_MSK 0x00000002
+/* inverted bitmask for bitfield uP Force Interrupt */
+#define HW_ATL_MCP_UP_FORCE_INTERRUPT_MSKN 0xFFFFFFFD
+/* lower bit position of bitfield uP Force Interrupt */
+#define HW_ATL_MCP_UP_FORCE_INTERRUPT_SHIFT 1
+/* width of bitfield uP Force Interrupt */
+#define HW_ATL_MCP_UP_FORCE_INTERRUPT_WIDTH 1
+/* default value of bitfield uP Force Interrupt */
+#define HW_ATL_MCP_UP_FORCE_INTERRUPT_DEFAULT 0x0
+
 #endif /* HW_ATL_LLH_INTERNAL_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index c965e65..b0aaf6f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -325,17 +325,31 @@ static int hw_atl_utils_fw_upload_dwords(struct aq_hw_s *self, u32 a, u32 *p,
 		err = -ETIME;
 		goto err_exit;
 	}
+	if (IS_CHIP_FEATURE(REVISION_B1)) {
+		u32 offset = 0;
+
+		for (; offset < cnt; ++offset) {
+			aq_hw_write_reg(self, 0x328, p[offset]);
+			aq_hw_write_reg(self, 0x32C,
+					(0x80000000 | (0xFFFF & (offset * 4))));
+			hw_atl_mcp_up_force_intr_set(self, 1);
+			/* 1000 times by 10us = 10ms */
+			AQ_HW_WAIT_FOR((aq_hw_read_reg(self,
+						       0x32C) & 0xF0000000) !=
+				       0x80000000,
+				       10, 1000);
+		}
+	} else {
+		u32 offset = 0;
 
-	aq_hw_write_reg(self, 0x00000208U, a);
-
-	for (++cnt; --cnt;) {
-		u32 i = 0U;
+		aq_hw_write_reg(self, 0x208, a);
 
-		aq_hw_write_reg(self, 0x0000020CU, *(p++));
-		aq_hw_write_reg(self, 0x00000200U, 0xC000U);
+		for (; offset < cnt; ++offset) {
+			aq_hw_write_reg(self, 0x20C, p[offset]);
+			aq_hw_write_reg(self, 0x200, 0xC000);
 
-		for (i = 1024U;
-			(0x100U & aq_hw_read_reg(self, 0x00000200U)) && --i;) {
+			AQ_HW_WAIT_FOR((aq_hw_read_reg(self, 0x200U) &
+					0x100) == 0, 10, 1000);
 		}
 	}
 
@@ -399,7 +413,7 @@ struct aq_hw_atl_utils_fw_rpc_tid_s {
 
 #define hw_atl_utils_fw_rpc_init(_H_) hw_atl_utils_fw_rpc_wait(_H_, NULL)
 
-static int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
+int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
 {
 	int err = 0;
 	struct aq_hw_atl_utils_fw_rpc_tid_s sw;
@@ -411,7 +425,7 @@ static int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
 	err = hw_atl_utils_fw_upload_dwords(self, self->rpc_addr,
 					    (u32 *)(void *)&self->rpc,
 					    (rpc_size + sizeof(u32) -
-					    sizeof(u8)) / sizeof(u32));
+					     sizeof(u8)) / sizeof(u32));
 	if (err < 0)
 		goto err_exit;
 
@@ -423,8 +437,8 @@ static int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
 	return err;
 }
 
-static int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
-				    struct hw_aq_atl_utils_fw_rpc **rpc)
+int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
+			     struct hw_aq_atl_utils_fw_rpc **rpc)
 {
 	int err = 0;
 	struct aq_hw_atl_utils_fw_rpc_tid_s sw;
@@ -457,10 +471,10 @@ static int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
 			hw_atl_utils_fw_downld_dwords(self,
 						      self->rpc_addr,
 						      (u32 *)(void *)
-						      &self->rpc,
+						       &self->rpc,
 						      (fw.len + sizeof(u32) -
-						      sizeof(u8)) /
-						      sizeof(u32));
+						       sizeof(u8)) /
+						       sizeof(u32));
 			if (err < 0)
 				goto err_exit;
 		}
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index b875590..aedb911 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -316,9 +316,15 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version);
 int hw_atl_utils_update_stats(struct aq_hw_s *self);
 
 struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);
+
 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
 				  u32 *p, u32 cnt);
 
+int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size);
+
+int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
+			     struct hw_aq_atl_utils_fw_rpc **rpc);
+
 extern const struct aq_fw_ops aq_fw_1x_ops;
 extern const struct aq_fw_ops aq_fw_2x_ops;
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index e379437..3a5ec22 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -21,6 +21,7 @@
 
 #define HW_ATL_FW2X_MPI_EFUSE_ADDR	0x364
 #define HW_ATL_FW2X_MPI_MBOX_ADDR	0x360
+#define HW_ATL_FW2X_MPI_RPC_ADDR        0x334
 
 #define HW_ATL_FW2X_MPI_CONTROL_ADDR	0x368
 #define HW_ATL_FW2X_MPI_CONTROL2_ADDR	0x36C
@@ -38,8 +39,12 @@ static int aq_fw2x_init(struct aq_hw_s *self)
 
 	/* check 10 times by 1ms */
 	AQ_HW_WAIT_FOR(0U != (self->mbox_addr =
-			aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR)),
+		       aq_hw_read_reg(self, HW_ATL_FW2X_MPI_MBOX_ADDR)),
 		       1000U, 10U);
+	AQ_HW_WAIT_FOR(0U != (self->rpc_addr =
+		       aq_hw_read_reg(self, HW_ATL_FW2X_MPI_RPC_ADDR)),
+		       1000U, 100U);
+
 	return err;
 }
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 3/5] net: aquantia: implement WOL support
From: Igor Russkikh @ 2018-08-08 10:57 UTC (permalink / raw)
  To: David S . Miller; +Cc: netdev, Igor Russkikh, Yana Esina, Nikita Danilov
In-Reply-To: <cover.1533650064.git.igor.russkikh@aquantia.com>

From: Yana Esina <yana.esina@aquantia.com>

Add WOL support. Currently only magic packet
(ethtool -s <ethX> wol g) feature is implemented.

Remove hw_set_power and move that to FW_OPS set_power:
because WOL configuration behaves differently on 1x and 2x
firmwares

Signed-off-by: Yana Esina <yana.esina@aquantia.com>
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Tested-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 .../net/ethernet/aquantia/atlantic/aq_ethtool.c    | 32 +++++++
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h     |  5 +-
 drivers/net/ethernet/aquantia/atlantic/aq_nic.c    | 12 +--
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  1 -
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  1 -
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c        | 80 +++++++++++++++--
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h        |  2 +
 .../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c   | 99 +++++++++++++++++++++-
 8 files changed, 215 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index 08c9fa6..f9fe49b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -285,6 +285,36 @@ static int aq_ethtool_set_coalesce(struct net_device *ndev,
 	return aq_nic_update_interrupt_moderation_settings(aq_nic);
 }
 
+static void aq_ethtool_get_wol(struct net_device *ndev,
+			       struct ethtool_wolinfo *wol)
+{
+	struct aq_nic_s *aq_nic = netdev_priv(ndev);
+	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
+
+	wol->supported = WAKE_MAGIC;
+	wol->wolopts = 0;
+
+	if (cfg->wol)
+		wol->wolopts |= WAKE_MAGIC;
+}
+
+static int aq_ethtool_set_wol(struct net_device *ndev,
+			      struct ethtool_wolinfo *wol)
+{
+	struct aq_nic_s *aq_nic = netdev_priv(ndev);
+	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
+	struct pci_dev *pdev = to_pci_dev(ndev->dev.parent);
+	int err = 0;
+
+	if (wol->wolopts & WAKE_MAGIC)
+		cfg->wol |= AQ_NIC_WOL_ENABLED;
+	else
+		cfg->wol &= ~AQ_NIC_WOL_ENABLED;
+	err = device_set_wakeup_enable(&pdev->dev, wol->wolopts);
+
+	return err;
+}
+
 static int aq_ethtool_nway_reset(struct net_device *ndev)
 {
 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
@@ -403,6 +433,8 @@ const struct ethtool_ops aq_ethtool_ops = {
 	.get_drvinfo         = aq_ethtool_get_drvinfo,
 	.get_strings         = aq_ethtool_get_strings,
 	.get_rxfh_indir_size = aq_ethtool_get_rss_indir_size,
+	.get_wol             = aq_ethtool_get_wol,
+	.set_wol             = aq_ethtool_set_wol,
 	.nway_reset          = aq_ethtool_nway_reset,
 	.get_ringparam       = aq_get_ringparam,
 	.set_ringparam       = aq_set_ringparam,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index 6fa7936..403d86ea 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -204,7 +204,6 @@ struct aq_hw_ops {
 
 	int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);
 
-	int (*hw_set_power)(struct aq_hw_s *self, unsigned int power_state);
 };
 
 struct aq_fw_ops {
@@ -228,6 +227,10 @@ struct aq_fw_ops {
 	int (*update_stats)(struct aq_hw_s *self);
 
 	int (*set_flow_control)(struct aq_hw_s *self);
+
+	int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
+			 u8 *mac);
+
 };
 
 #endif /* AQ_HW_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
index 26dc678..439ae61 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -889,11 +889,13 @@ void aq_nic_deinit(struct aq_nic_s *self)
 		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
 		aq_vec_deinit(aq_vec);
 
-	if (self->power_state == AQ_HW_POWER_STATE_D0) {
-		(void)self->aq_fw_ops->deinit(self->aq_hw);
-	} else {
-		(void)self->aq_hw_ops->hw_set_power(self->aq_hw,
-						   self->power_state);
+	(void)self->aq_fw_ops->deinit(self->aq_hw);
+
+	if (self->power_state != AQ_HW_POWER_STATE_D0 ||
+	    self->aq_hw->aq_nic_cfg->wol) {
+		(void)self->aq_fw_ops->set_power(self->aq_hw,
+						 self->power_state,
+						 self->ndev->dev_addr);
 	}
 
 err_exit:;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 97addfa6..1dd0ef4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -877,7 +877,6 @@ static int hw_atl_a0_hw_ring_rx_stop(struct aq_hw_s *self,
 const struct aq_hw_ops hw_atl_ops_a0 = {
 	.hw_set_mac_address   = hw_atl_a0_hw_mac_addr_set,
 	.hw_init              = hw_atl_a0_hw_init,
-	.hw_set_power         = hw_atl_utils_hw_set_power,
 	.hw_reset             = hw_atl_a0_hw_reset,
 	.hw_start             = hw_atl_a0_hw_start,
 	.hw_ring_tx_start     = hw_atl_a0_hw_ring_tx_start,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 4809bf4..6644c96 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -935,7 +935,6 @@ static int hw_atl_b0_hw_ring_rx_stop(struct aq_hw_s *self,
 const struct aq_hw_ops hw_atl_ops_b0 = {
 	.hw_set_mac_address   = hw_atl_b0_hw_mac_addr_set,
 	.hw_init              = hw_atl_b0_hw_init,
-	.hw_set_power         = hw_atl_utils_hw_set_power,
 	.hw_reset             = hw_atl_b0_hw_reset,
 	.hw_start             = hw_atl_b0_hw_start,
 	.hw_ring_tx_start     = hw_atl_b0_hw_ring_tx_start,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index f9c4475..b1a0fb5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -744,14 +744,6 @@ static int hw_atl_fw1x_deinit(struct aq_hw_s *self)
 	return 0;
 }
 
-int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
-			      unsigned int power_state)
-{
-	hw_atl_utils_mpi_set_speed(self, 0);
-	hw_atl_utils_mpi_set_state(self, MPI_POWER);
-	return 0;
-}
-
 int hw_atl_utils_update_stats(struct aq_hw_s *self)
 {
 	struct hw_atl_utils_mbox mbox;
@@ -839,6 +831,77 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version)
 	return 0;
 }
 
+static int aq_fw1x_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac)
+{
+	struct hw_atl_utils_fw_rpc *prpc = NULL;
+	unsigned int rpc_size = 0U;
+	int err = 0;
+
+	err = hw_atl_utils_fw_rpc_wait(self, &prpc);
+	if (err < 0)
+		goto err_exit;
+
+	memset(prpc, 0, sizeof(*prpc));
+
+	if (wol_enabled) {
+		rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);
+
+		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
+		prpc->msg_wol.priority = 0x10000000; /* normal priority */
+		prpc->msg_wol.pattern_id = 1U;
+		prpc->msg_wol.wol_packet_type = 2U; /* Magic Packet */
+
+		ether_addr_copy((u8 *)&prpc->msg_wol.wol_pattern, mac);
+	} else {
+		rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);
+
+		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
+		prpc->msg_wol.pattern_id = 1U;
+	}
+
+	err = hw_atl_utils_fw_rpc_call(self, rpc_size);
+
+err_exit:
+	return err;
+}
+
+int aq_fw1x_set_power(struct aq_hw_s *self, unsigned int power_state,
+		      u8 *mac)
+{
+	struct hw_atl_utils_fw_rpc *prpc = NULL;
+	unsigned int rpc_size = 0U;
+	int err = 0;
+
+	if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
+		err = aq_fw1x_set_wol(self, 1, mac);
+
+		if (err < 0)
+			goto err_exit;
+
+		rpc_size = sizeof(prpc->msg_id) +
+			   sizeof(prpc->msg_enable_wakeup);
+
+		err = hw_atl_utils_fw_rpc_wait(self, &prpc);
+
+		if (err < 0)
+			goto err_exit;
+
+		memset(prpc, 0, rpc_size);
+
+		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP;
+		prpc->msg_enable_wakeup.pattern_mask = 0x00000002;
+
+		err = hw_atl_utils_fw_rpc_call(self, rpc_size);
+		if (err < 0)
+			goto err_exit;
+	}
+	hw_atl_utils_mpi_set_speed(self, 0);
+	hw_atl_utils_mpi_set_state(self, MPI_POWER);
+
+err_exit:
+	return err;
+}
+
 const struct aq_fw_ops aq_fw_1x_ops = {
 	.init = hw_atl_utils_mpi_create,
 	.deinit = hw_atl_fw1x_deinit,
@@ -848,5 +911,6 @@ const struct aq_fw_ops aq_fw_1x_ops = {
 	.set_state = hw_atl_utils_mpi_set_state,
 	.update_link_status = hw_atl_utils_mpi_get_link_status,
 	.update_stats = hw_atl_utils_update_stats,
+	.set_power = aq_fw1x_set_power,
 	.set_flow_control = NULL,
 };
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index 24f0947..3aceb55 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -404,6 +404,8 @@ struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);
 int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
 				  u32 *p, u32 cnt);
 
+int hw_atl_utils_fw_set_wol(struct aq_hw_s *self, bool wol_enabled, u8 *mac);
+
 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size);
 
 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index 4755900..0ad6ac5 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -231,7 +231,7 @@ static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
 	return err;
 }
 
-static int aq_fw2x_update_stats(struct aq_hw_s *self)
+int aq_fw2x_update_stats(struct aq_hw_s *self)
 {
 	int err = 0;
 	u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
@@ -252,6 +252,102 @@ static int aq_fw2x_update_stats(struct aq_hw_s *self)
 	return hw_atl_utils_update_stats(self);
 }
 
+static int aq_fw2x_set_sleep_proxy(struct aq_hw_s *self, u8 *mac)
+{
+	int err = 0;
+	struct hw_atl_utils_fw_rpc *rpc = NULL;
+	struct offload_info *cfg = NULL;
+	unsigned int rpc_size = 0U;
+	u32 mpi_opts;
+
+	rpc_size = sizeof(rpc->msg_id) + sizeof(*cfg);
+
+	err = hw_atl_utils_fw_rpc_wait(self, &rpc);
+	if (err < 0)
+		goto err_exit;
+
+	memset(rpc, 0, rpc_size);
+	cfg = (struct offload_info *)(&rpc->msg_id + 1);
+
+	memcpy(cfg->mac_addr, mac, ETH_ALEN);
+	cfg->len = sizeof(*cfg);
+
+	/* Clear bit 0x36C.23 and 0x36C.22 */
+	mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+	mpi_opts &= ~HW_ATL_FW2X_CTRL_SLEEP_PROXY;
+	mpi_opts &= ~HW_ATL_FW2X_CTRL_LINK_DROP;
+
+	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
+
+	err = hw_atl_utils_fw_rpc_call(self, rpc_size);
+	if (err < 0)
+		goto err_exit;
+
+	/* Set bit 0x36C.23 */
+	mpi_opts |= HW_ATL_FW2X_CTRL_SLEEP_PROXY;
+	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
+
+	AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
+			HW_ATL_FW2X_CTRL_SLEEP_PROXY), 1U, 10000U);
+
+err_exit:
+	return err;
+}
+
+static int aq_fw2x_set_wol_params(struct aq_hw_s *self, u8 *mac)
+{
+	int err = 0;
+	struct fw2x_msg_wol *msg = NULL;
+	u32 mpi_opts;
+
+	struct hw_atl_utils_fw_rpc *rpc = NULL;
+
+	err = hw_atl_utils_fw_rpc_wait(self, &rpc);
+	if (err < 0)
+		goto err_exit;
+
+	msg = (struct fw2x_msg_wol *)rpc;
+
+	msg->msg_id = HAL_ATLANTIC_UTILS_FW2X_MSG_WOL;
+	msg->magic_packet_enabled = true;
+	memcpy(msg->hw_addr, mac, ETH_ALEN);
+
+	mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+	mpi_opts &= ~(HW_ATL_FW2X_CTRL_SLEEP_PROXY | HW_ATL_FW2X_CTRL_WOL);
+
+	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
+
+	err = hw_atl_utils_fw_rpc_call(self, sizeof(*msg));
+	if (err < 0)
+		goto err_exit;
+
+	/* Set bit 0x36C.24 */
+	mpi_opts |= HW_ATL_FW2X_CTRL_WOL;
+	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
+
+	AQ_HW_WAIT_FOR((aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR) &
+			HW_ATL_FW2X_CTRL_WOL), 1U, 10000U);
+
+err_exit:
+	return err;
+}
+
+static int aq_fw2x_set_power(struct aq_hw_s *self, unsigned int power_state,
+			     u8 *mac)
+{
+	int err = 0;
+
+	if (self->aq_nic_cfg->wol & AQ_NIC_WOL_ENABLED) {
+		err = aq_fw2x_set_sleep_proxy(self, mac);
+		if (err < 0)
+			goto err_exit;
+		err = aq_fw2x_set_wol_params(self, mac);
+	}
+
+err_exit:
+	return err;
+}
+
 static int aq_fw2x_renegotiate(struct aq_hw_s *self)
 {
 	u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
@@ -284,5 +380,6 @@ const struct aq_fw_ops aq_fw_2x_ops = {
 	.set_state = aq_fw2x_set_state,
 	.update_link_status = aq_fw2x_update_link_status,
 	.update_stats = aq_fw2x_update_stats,
+	.set_power = aq_fw2x_set_power,
 	.set_flow_control   = aq_fw2x_set_flow_control,
 };
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 4/5] net: aquantia: implement EEE support
From: Igor Russkikh @ 2018-08-08 10:57 UTC (permalink / raw)
  To: David S . Miller; +Cc: netdev, Igor Russkikh, Yana Esina, Nikita Danilov
In-Reply-To: <cover.1533650064.git.igor.russkikh@aquantia.com>

From: Yana Esina <yana.esina@aquantia.com>

Support of Energy-Efficient Ethernet to aQuantia NIC's via ethtool
(according to the IEEE 802.3az specifications)

We do replace some duplicate speed bits definitions here (HW_ATL_B0_RATE_)
with driver generic constants (AQ_NIC_RATE_)

Signed-off-by: Yana Esina <yana.esina@aquantia.com>
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Tested-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_common.h |   5 +
 .../net/ethernet/aquantia/atlantic/aq_ethtool.c    |  76 +++++++++++
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h     |   4 +
 drivers/net/ethernet/aquantia/atlantic/aq_nic.h    |   1 +
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c  |  32 ++---
 .../aquantia/atlantic/hw_atl/hw_atl_a0_internal.h  |   6 -
 .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c  |  34 ++---
 .../aquantia/atlantic/hw_atl/hw_atl_b0_internal.h  |   6 -
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c        |   2 +
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h        |  13 ++
 .../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c   | 141 +++++++++++++++++----
 11 files changed, 250 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_common.h b/drivers/net/ethernet/aquantia/atlantic/aq_common.h
index d52b088..becb578 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_common.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_common.h
@@ -57,4 +57,9 @@
 #define AQ_NIC_RATE_1G         BIT(4)
 #define AQ_NIC_RATE_100M       BIT(5)
 
+#define AQ_NIC_RATE_EEE_10G	BIT(6)
+#define AQ_NIC_RATE_EEE_5G	BIT(7)
+#define AQ_NIC_RATE_EEE_2GS	BIT(8)
+#define AQ_NIC_RATE_EEE_1G	BIT(9)
+
 #endif /* AQ_COMMON_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
index f9fe49b..ec12edf 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -315,6 +315,80 @@ static int aq_ethtool_set_wol(struct net_device *ndev,
 	return err;
 }
 
+static enum hw_atl_fw2x_rate eee_mask_to_ethtool_mask(u32 speed)
+{
+	u32 rate = 0;
+
+	if (speed & AQ_NIC_RATE_EEE_10G)
+		rate |= SUPPORTED_10000baseT_Full;
+
+	if (speed & AQ_NIC_RATE_EEE_2GS)
+		rate |= SUPPORTED_2500baseX_Full;
+
+	if (speed & AQ_NIC_RATE_EEE_1G)
+		rate |= SUPPORTED_1000baseT_Full;
+
+	return rate;
+}
+
+static int aq_ethtool_get_eee(struct net_device *ndev, struct ethtool_eee *eee)
+{
+	struct aq_nic_s *aq_nic = netdev_priv(ndev);
+	int err = 0;
+
+	u32 rate, supported_rates;
+
+	if (!aq_nic->aq_fw_ops->get_eee_rate)
+		return -EOPNOTSUPP;
+
+	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
+					      &supported_rates);
+	if (err < 0)
+		return err;
+
+	eee->supported = eee_mask_to_ethtool_mask(supported_rates);
+
+	if (aq_nic->aq_nic_cfg.eee_speeds)
+		eee->advertised = eee->supported;
+
+	eee->lp_advertised = eee_mask_to_ethtool_mask(rate);
+
+	eee->eee_enabled = !!eee->advertised;
+
+	eee->tx_lpi_enabled = eee->eee_enabled;
+	if (eee->advertised & eee->lp_advertised)
+		eee->eee_active = true;
+
+	return 0;
+}
+
+static int aq_ethtool_set_eee(struct net_device *ndev, struct ethtool_eee *eee)
+{
+	struct aq_nic_s *aq_nic = netdev_priv(ndev);
+	struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic);
+	u32 rate, supported_rates;
+	int err = 0;
+
+	if (unlikely(!aq_nic->aq_fw_ops->get_eee_rate ||
+		     !aq_nic->aq_fw_ops->set_eee_rate))
+		return -EOPNOTSUPP;
+
+	err = aq_nic->aq_fw_ops->get_eee_rate(aq_nic->aq_hw, &rate,
+					      &supported_rates);
+	if (err < 0)
+		return err;
+
+	if (eee->eee_enabled) {
+		rate = supported_rates;
+		cfg->eee_speeds = rate;
+	} else {
+		rate = 0;
+		cfg->eee_speeds = 0;
+	}
+
+	return aq_nic->aq_fw_ops->set_eee_rate(aq_nic->aq_hw, rate);
+}
+
 static int aq_ethtool_nway_reset(struct net_device *ndev)
 {
 	struct aq_nic_s *aq_nic = netdev_priv(ndev);
@@ -438,6 +512,8 @@ const struct ethtool_ops aq_ethtool_ops = {
 	.nway_reset          = aq_ethtool_nway_reset,
 	.get_ringparam       = aq_get_ringparam,
 	.set_ringparam       = aq_set_ringparam,
+	.get_eee             = aq_ethtool_get_eee,
+	.set_eee             = aq_ethtool_set_eee,
 	.get_pauseparam      = aq_ethtool_get_pauseparam,
 	.set_pauseparam      = aq_ethtool_set_pauseparam,
 	.get_rxfh_key_size   = aq_ethtool_get_rss_key_size,
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index 403d86ea..e868924 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -231,6 +231,10 @@ struct aq_fw_ops {
 	int (*set_power)(struct aq_hw_s *self, unsigned int power_state,
 			 u8 *mac);
 
+	int (*set_eee_rate)(struct aq_hw_s *self, u32 speed);
+
+	int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,
+			    u32 *supported_rates);
 };
 
 #endif /* AQ_HW_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
index 2069cbb..c1582f4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -45,6 +45,7 @@ struct aq_nic_cfg_s {
 	bool is_lro;
 	u8  tcs;
 	struct aq_rss_parameters aq_rss;
+	u32 eee_speeds;
 };
 
 #define AQ_NIC_FLAG_STARTED     0x00000004U
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
index 1dd0ef4..f9d88c7 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
@@ -49,37 +49,37 @@
 const struct aq_hw_caps_s hw_atl_a0_caps_aqc100 = {
 	DEFAULT_A0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_FIBRE,
-	.link_speed_msk = HW_ATL_A0_RATE_5G  |
-			  HW_ATL_A0_RATE_2G5 |
-			  HW_ATL_A0_RATE_1G  |
-			  HW_ATL_A0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_5G |
+			  AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 const struct aq_hw_caps_s hw_atl_a0_caps_aqc107 = {
 	DEFAULT_A0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_TP,
-	.link_speed_msk = HW_ATL_A0_RATE_10G |
-			  HW_ATL_A0_RATE_5G  |
-			  HW_ATL_A0_RATE_2G5 |
-			  HW_ATL_A0_RATE_1G  |
-			  HW_ATL_A0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_10G |
+			  AQ_NIC_RATE_5G |
+			  AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 const struct aq_hw_caps_s hw_atl_a0_caps_aqc108 = {
 	DEFAULT_A0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_TP,
-	.link_speed_msk = HW_ATL_A0_RATE_5G  |
-			  HW_ATL_A0_RATE_2G5 |
-			  HW_ATL_A0_RATE_1G  |
-			  HW_ATL_A0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_5G |
+			  AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 const struct aq_hw_caps_s hw_atl_a0_caps_aqc109 = {
 	DEFAULT_A0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_TP,
-	.link_speed_msk = HW_ATL_A0_RATE_2G5 |
-			  HW_ATL_A0_RATE_1G  |
-			  HW_ATL_A0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 static int hw_atl_a0_hw_reset(struct aq_hw_s *self)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
index 3c94cff..a021dc4 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0_internal.h
@@ -62,12 +62,6 @@
 #define HW_ATL_A0_MPI_SPEED_MSK       0xFFFFU
 #define HW_ATL_A0_MPI_SPEED_SHIFT     16U
 
-#define HW_ATL_A0_RATE_10G            BIT(0)
-#define HW_ATL_A0_RATE_5G             BIT(1)
-#define HW_ATL_A0_RATE_2G5            BIT(3)
-#define HW_ATL_A0_RATE_1G             BIT(4)
-#define HW_ATL_A0_RATE_100M           BIT(5)
-
 #define HW_ATL_A0_TXBUF_MAX 160U
 #define HW_ATL_A0_RXBUF_MAX 320U
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 6644c96..5092f1b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -51,38 +51,38 @@
 const struct aq_hw_caps_s hw_atl_b0_caps_aqc100 = {
 	DEFAULT_B0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_FIBRE,
-	.link_speed_msk = HW_ATL_B0_RATE_10G |
-			  HW_ATL_B0_RATE_5G  |
-			  HW_ATL_B0_RATE_2G5 |
-			  HW_ATL_B0_RATE_1G  |
-			  HW_ATL_B0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_10G |
+			  AQ_NIC_RATE_5G |
+			  AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 const struct aq_hw_caps_s hw_atl_b0_caps_aqc107 = {
 	DEFAULT_B0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_TP,
-	.link_speed_msk = HW_ATL_B0_RATE_10G |
-			  HW_ATL_B0_RATE_5G  |
-			  HW_ATL_B0_RATE_2G5 |
-			  HW_ATL_B0_RATE_1G  |
-			  HW_ATL_B0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_10G |
+			  AQ_NIC_RATE_5G |
+			  AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 const struct aq_hw_caps_s hw_atl_b0_caps_aqc108 = {
 	DEFAULT_B0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_TP,
-	.link_speed_msk = HW_ATL_B0_RATE_5G  |
-			  HW_ATL_B0_RATE_2G5 |
-			  HW_ATL_B0_RATE_1G  |
-			  HW_ATL_B0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_5G |
+			  AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 const struct aq_hw_caps_s hw_atl_b0_caps_aqc109 = {
 	DEFAULT_B0_BOARD_BASIC_CAPABILITIES,
 	.media_type = AQ_HW_MEDIA_TYPE_TP,
-	.link_speed_msk = HW_ATL_B0_RATE_2G5 |
-			  HW_ATL_B0_RATE_1G  |
-			  HW_ATL_B0_RATE_100M,
+	.link_speed_msk = AQ_NIC_RATE_2GS |
+			  AQ_NIC_RATE_1G |
+			  AQ_NIC_RATE_100M,
 };
 
 static int hw_atl_b0_hw_reset(struct aq_hw_s *self)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
index 28568f5..b318eef 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
@@ -67,12 +67,6 @@
 #define HW_ATL_B0_MPI_SPEED_MSK         0xFFFFU
 #define HW_ATL_B0_MPI_SPEED_SHIFT       16U
 
-#define HW_ATL_B0_RATE_10G              BIT(0)
-#define HW_ATL_B0_RATE_5G               BIT(1)
-#define HW_ATL_B0_RATE_2G5              BIT(3)
-#define HW_ATL_B0_RATE_1G               BIT(4)
-#define HW_ATL_B0_RATE_100M             BIT(5)
-
 #define HW_ATL_B0_TXBUF_MAX  160U
 #define HW_ATL_B0_RXBUF_MAX  320U
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index b1a0fb5..436b278 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -912,5 +912,7 @@ const struct aq_fw_ops aq_fw_1x_ops = {
 	.update_link_status = hw_atl_utils_mpi_get_link_status,
 	.update_stats = hw_atl_utils_update_stats,
 	.set_power = aq_fw1x_set_power,
+	.set_eee_rate = NULL,
+	.get_eee_rate = NULL,
 	.set_flow_control = NULL,
 };
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index 3aceb55..95419e3 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -171,9 +171,22 @@ struct __packed hw_atl_utils_mbox_header {
 	u32 error;
 };
 
+struct __packed hw_aq_info {
+	u8 reserved[6];
+	u16 phy_fault_code;
+	u16 phy_temperature;
+	u8 cable_len;
+	u8 reserved1;
+	u32 cable_diag_data[4];
+	u8 reserved2[32];
+	u32 caps_lo;
+	u32 caps_hi;
+};
+
 struct __packed hw_atl_utils_mbox {
 	struct hw_atl_utils_mbox_header header;
 	struct hw_atl_stats_s stats;
+	struct hw_aq_info info;
 };
 
 /* fw2x */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index 0ad6ac5..7bd1bea 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -40,6 +40,11 @@
 #define HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE BIT(CTRL_ASYMMETRIC_PAUSE)
 #define HW_ATL_FW2X_CTRL_FORCE_RECONNECT  BIT(CTRL_FORCE_RECONNECT)
 
+#define HW_ATL_FW2X_CAP_EEE_1G_MASK      BIT(CAPS_HI_1000BASET_FD_EEE)
+#define HW_ATL_FW2X_CAP_EEE_2G5_MASK     BIT(CAPS_HI_2P5GBASET_FD_EEE)
+#define HW_ATL_FW2X_CAP_EEE_5G_MASK      BIT(CAPS_HI_5GBASET_FD_EEE)
+#define HW_ATL_FW2X_CAP_EEE_10G_MASK     BIT(CAPS_HI_10GBASET_FD_EEE)
+
 #define HAL_ATLANTIC_WOL_FILTERS_COUNT   8
 #define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL  0x0E
 
@@ -115,6 +120,38 @@ static enum hw_atl_fw2x_rate link_speed_mask_2fw2x_ratemask(u32 speed)
 	return rate;
 }
 
+static u32 fw2x_to_eee_mask(u32 speed)
+{
+	u32 rate = 0;
+
+	if (speed & HW_ATL_FW2X_CAP_EEE_10G_MASK)
+		rate |= AQ_NIC_RATE_EEE_10G;
+	if (speed & HW_ATL_FW2X_CAP_EEE_5G_MASK)
+		rate |= AQ_NIC_RATE_EEE_5G;
+	if (speed & HW_ATL_FW2X_CAP_EEE_2G5_MASK)
+		rate |= AQ_NIC_RATE_EEE_2GS;
+	if (speed & HW_ATL_FW2X_CAP_EEE_1G_MASK)
+		rate |= AQ_NIC_RATE_EEE_1G;
+
+	return rate;
+}
+
+static u32 eee_mask_to_fw2x(u32 speed)
+{
+	u32 rate = 0;
+
+	if (speed & AQ_NIC_RATE_EEE_10G)
+		rate |= HW_ATL_FW2X_CAP_EEE_10G_MASK;
+	if (speed & AQ_NIC_RATE_EEE_5G)
+		rate |= HW_ATL_FW2X_CAP_EEE_5G_MASK;
+	if (speed & AQ_NIC_RATE_EEE_2GS)
+		rate |= HW_ATL_FW2X_CAP_EEE_2G5_MASK;
+	if (speed & AQ_NIC_RATE_EEE_1G)
+		rate |= HW_ATL_FW2X_CAP_EEE_1G_MASK;
+
+	return rate;
+}
+
 static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed)
 {
 	u32 val = link_speed_mask_2fw2x_ratemask(speed);
@@ -124,31 +161,46 @@ static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed)
 	return 0;
 }
 
-static void aq_fw2x_set_mpi_flow_control(struct aq_hw_s *self, u32 *mpi_state)
+static void aq_fw2x_upd_flow_control_bits(struct aq_hw_s *self,
+					  u32 *mpi_state, u32 fc)
 {
-	if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
-		*mpi_state |= BIT(CAPS_HI_PAUSE);
+	if (fc & AQ_NIC_FC_RX)
+		*mpi_state |= HW_ATL_FW2X_CTRL_PAUSE;
 	else
-		*mpi_state &= ~BIT(CAPS_HI_PAUSE);
+		*mpi_state &= ~HW_ATL_FW2X_CTRL_PAUSE;
 
-	if (self->aq_nic_cfg->flow_control & AQ_NIC_FC_TX)
-		*mpi_state |= BIT(CAPS_HI_ASYMMETRIC_PAUSE);
+	if (fc & AQ_NIC_FC_TX)
+		*mpi_state |= HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE;
 	else
-		*mpi_state &= ~BIT(CAPS_HI_ASYMMETRIC_PAUSE);
+		*mpi_state &= ~HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE;
+}
+
+static void aq_fw2x_upd_eee_rate_bits(struct aq_hw_s *self, u32 *mpi_opts,
+				      u32 eee_speeds)
+{
+	*mpi_opts &= ~(HW_ATL_FW2X_CAP_EEE_1G_MASK |
+		       HW_ATL_FW2X_CAP_EEE_2G5_MASK |
+		       HW_ATL_FW2X_CAP_EEE_5G_MASK |
+		       HW_ATL_FW2X_CAP_EEE_10G_MASK);
+
+	*mpi_opts |= eee_mask_to_fw2x(eee_speeds);
 }
 
 static int aq_fw2x_set_state(struct aq_hw_s *self,
 			     enum hal_atl_utils_fw_state_e state)
 {
 	u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+	struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
 
 	switch (state) {
 	case MPI_INIT:
-		mpi_state &= ~BIT(CAPS_HI_LINK_DROP);
-		aq_fw2x_set_mpi_flow_control(self, &mpi_state);
+		mpi_state &= ~HW_ATL_FW2X_CTRL_LINK_DROP;
+		aq_fw2x_upd_eee_rate_bits(self, &mpi_state, cfg->eee_speeds);
+		aq_fw2x_upd_flow_control_bits(self, &mpi_state,
+					      cfg->flow_control);
 		break;
 	case MPI_DEINIT:
-		mpi_state |= BIT(CAPS_HI_LINK_DROP);
+		mpi_state |= HW_ATL_FW2X_CTRL_LINK_DROP;
 		break;
 	case MPI_RESET:
 	case MPI_POWER:
@@ -163,7 +215,7 @@ static int aq_fw2x_update_link_status(struct aq_hw_s *self)
 {
 	u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE_ADDR);
 	u32 speed = mpi_state & (FW2X_RATE_100M | FW2X_RATE_1G |
-				FW2X_RATE_2G5 | FW2X_RATE_5G | FW2X_RATE_10G);
+				 FW2X_RATE_2G5 | FW2X_RATE_5G | FW2X_RATE_10G);
 	struct aq_hw_link_status_s *link_status = &self->aq_link_status;
 
 	if (speed) {
@@ -212,9 +264,7 @@ static int aq_fw2x_get_mac_permanent(struct aq_hw_s *self, u8 *mac)
 
 		get_random_bytes(&rnd, sizeof(unsigned int));
 
-		l = 0xE3000000U
-			| (0xFFFFU & rnd)
-			| (0x00 << 16);
+		l = 0xE3000000U | (0xFFFFU & rnd) | (0x00 << 16);
 		h = 0x8001300EU;
 
 		mac[5] = (u8)(0xFFU & l);
@@ -348,11 +398,49 @@ static int aq_fw2x_set_power(struct aq_hw_s *self, unsigned int power_state,
 	return err;
 }
 
+static int aq_fw2x_set_eee_rate(struct aq_hw_s *self, u32 speed)
+{
+	u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+
+	aq_fw2x_upd_eee_rate_bits(self, &mpi_opts, speed);
+
+	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
+
+	return 0;
+}
+
+static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate,
+				u32 *supported_rates)
+{
+	int err = 0;
+	u32 caps_hi;
+	u32 mpi_state;
+
+	err =
+	hw_atl_utils_fw_downld_dwords(self,
+				      self->mbox_addr +
+				      offsetof(struct hw_atl_utils_mbox,
+					       info) +
+				      offsetof(struct hw_aq_info, caps_hi),
+				      &caps_hi,
+				      sizeof(caps_hi) / sizeof(u32));
+
+	if (err)
+		return err;
+
+	*supported_rates = fw2x_to_eee_mask(caps_hi);
+
+	mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_STATE2_ADDR);
+	*rate = fw2x_to_eee_mask(mpi_state);
+
+	return err;
+}
+
 static int aq_fw2x_renegotiate(struct aq_hw_s *self)
 {
 	u32 mpi_opts = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
 
-	mpi_opts |= BIT(CTRL_FORCE_RECONNECT);
+	mpi_opts |= HW_ATL_FW2X_CTRL_FORCE_RECONNECT;
 
 	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_opts);
 
@@ -363,7 +451,8 @@ static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
 {
 	u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
 
-	aq_fw2x_set_mpi_flow_control(self, &mpi_state);
+	aq_fw2x_upd_flow_control_bits(self, &mpi_state,
+				      self->aq_nic_cfg->flow_control);
 
 	aq_hw_write_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR, mpi_state);
 
@@ -371,15 +460,17 @@ static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
 }
 
 const struct aq_fw_ops aq_fw_2x_ops = {
-	.init = aq_fw2x_init,
-	.deinit = aq_fw2x_deinit,
-	.reset = NULL,
-	.renegotiate = aq_fw2x_renegotiate,
-	.get_mac_permanent = aq_fw2x_get_mac_permanent,
-	.set_link_speed = aq_fw2x_set_link_speed,
-	.set_state = aq_fw2x_set_state,
+	.init               = aq_fw2x_init,
+	.deinit             = aq_fw2x_deinit,
+	.reset              = NULL,
+	.renegotiate        = aq_fw2x_renegotiate,
+	.get_mac_permanent  = aq_fw2x_get_mac_permanent,
+	.set_link_speed     = aq_fw2x_set_link_speed,
+	.set_state          = aq_fw2x_set_state,
 	.update_link_status = aq_fw2x_update_link_status,
-	.update_stats = aq_fw2x_update_stats,
-	.set_power = aq_fw2x_set_power,
+	.update_stats       = aq_fw2x_update_stats,
+	.set_power          = aq_fw2x_set_power,
+	.set_eee_rate       = aq_fw2x_set_eee_rate,
+	.get_eee_rate       = aq_fw2x_get_eee_rate,
 	.set_flow_control   = aq_fw2x_set_flow_control,
 };
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 5/5] net: aquantia: bump driver version
From: Igor Russkikh @ 2018-08-08 10:57 UTC (permalink / raw)
  To: David S . Miller; +Cc: netdev, Igor Russkikh
In-Reply-To: <cover.1533650064.git.igor.russkikh@aquantia.com>

Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/ver.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/ver.h b/drivers/net/ethernet/aquantia/atlantic/ver.h
index 94efc64..b482601 100644
--- a/drivers/net/ethernet/aquantia/atlantic/ver.h
+++ b/drivers/net/ethernet/aquantia/atlantic/ver.h
@@ -12,7 +12,7 @@
 
 #define NIC_MAJOR_DRIVER_VERSION           2
 #define NIC_MINOR_DRIVER_VERSION           0
-#define NIC_BUILD_DRIVER_VERSION           3
+#define NIC_BUILD_DRIVER_VERSION           4
 #define NIC_REVISION_DRIVER_VERSION        0
 
 #define AQ_CFG_DRV_VERSION_SUFFIX "-kern"
-- 
2.7.4

^ permalink raw reply related

* [PATCH net-next 2/5] net: aquantia: definitions for WOL patch
From: Igor Russkikh @ 2018-08-08 10:57 UTC (permalink / raw)
  To: David S . Miller; +Cc: netdev, Igor Russkikh, Yana Esina, Nikita Danilov
In-Reply-To: <cover.1533650064.git.igor.russkikh@aquantia.com>

From: Yana Esina <yana.esina@aquantia.com>

Added definitions and structures needed to support WOL.

Signed-off-by: Yana Esina <yana.esina@aquantia.com>
Signed-off-by: Nikita Danilov <nikita.danilov@aquantia.com>
Tested-by: Nikita Danilov <nikita.danilov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/aq_hw.h     |   4 +-
 drivers/net/ethernet/aquantia/atlantic/aq_nic.h    |   3 +
 .../aquantia/atlantic/hw_atl/hw_atl_utils.c        |  10 +-
 .../aquantia/atlantic/hw_atl/hw_atl_utils.h        | 108 ++++++++++++++++++---
 .../aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c   |  32 ++++++
 5 files changed, 138 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
index 5c00671..6fa7936 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_hw.h
@@ -112,7 +112,7 @@ struct aq_hw_s {
 	const struct aq_fw_ops *aq_fw_ops;
 	void __iomem *mmio;
 	struct aq_hw_link_status_s aq_link_status;
-	struct hw_aq_atl_utils_mbox mbox;
+	struct hw_atl_utils_mbox mbox;
 	struct hw_atl_stats_s last_stats;
 	struct aq_stats_s curr_stats;
 	u64 speed;
@@ -124,7 +124,7 @@ struct aq_hw_s {
 	u32 mbox_addr;
 	u32 rpc_addr;
 	u32 rpc_tid;
-	struct hw_aq_atl_utils_fw_rpc rpc;
+	struct hw_atl_utils_fw_rpc rpc;
 };
 
 struct aq_ring_s;
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
index fecfc40..2069cbb 100644
--- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
+++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.h
@@ -36,6 +36,7 @@ struct aq_nic_cfg_s {
 	u32 flow_control;
 	u32 link_speed_msk;
 	u32 vlan_id;
+	u32 wol;
 	u16 is_mc_list_enabled;
 	u16 mc_list_count;
 	bool is_autoneg;
@@ -54,6 +55,8 @@ struct aq_nic_cfg_s {
 #define AQ_NIC_FLAG_ERR_UNPLUG  0x40000000U
 #define AQ_NIC_FLAG_ERR_HW      0x80000000U
 
+#define AQ_NIC_WOL_ENABLED	BIT(0)
+
 #define AQ_NIC_TCVEC2RING(_NIC_, _TC_, _VEC_) \
 	((_TC_) * AQ_CFG_TCS_MAX + (_VEC_))
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
index b0aaf6f..f9c4475 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
@@ -438,7 +438,7 @@ int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size)
 }
 
 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
-			     struct hw_aq_atl_utils_fw_rpc **rpc)
+			     struct hw_atl_utils_fw_rpc **rpc)
 {
 	int err = 0;
 	struct aq_hw_atl_utils_fw_rpc_tid_s sw;
@@ -503,7 +503,7 @@ static int hw_atl_utils_mpi_create(struct aq_hw_s *self)
 }
 
 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
-			       struct hw_aq_atl_utils_mbox_header *pmbox)
+			       struct hw_atl_utils_mbox_header *pmbox)
 {
 	return hw_atl_utils_fw_downld_dwords(self,
 				      self->mbox_addr,
@@ -512,7 +512,7 @@ int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
 }
 
 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
-				 struct hw_aq_atl_utils_mbox *pmbox)
+				 struct hw_atl_utils_mbox *pmbox)
 {
 	int err = 0;
 
@@ -552,7 +552,7 @@ static int hw_atl_utils_mpi_set_state(struct aq_hw_s *self,
 {
 	int err = 0;
 	u32 transaction_id = 0;
-	struct hw_aq_atl_utils_mbox_header mbox;
+	struct hw_atl_utils_mbox_header mbox;
 	u32 val = aq_hw_read_reg(self, HW_ATL_MPI_CONTROL_ADR);
 
 	if (state == MPI_RESET) {
@@ -754,7 +754,7 @@ int hw_atl_utils_hw_set_power(struct aq_hw_s *self,
 
 int hw_atl_utils_update_stats(struct aq_hw_s *self)
 {
-	struct hw_aq_atl_utils_mbox mbox;
+	struct hw_atl_utils_mbox mbox;
 
 	hw_atl_utils_mpi_read_stats(self, &mbox);
 
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
index aedb911..24f0947 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
@@ -75,7 +75,7 @@ union __packed ip_addr {
 	} v4;
 };
 
-struct __packed hw_aq_atl_utils_fw_rpc {
+struct __packed hw_atl_utils_fw_rpc {
 	u32 msg_id;
 
 	union {
@@ -101,8 +101,6 @@ struct __packed hw_aq_atl_utils_fw_rpc {
 		struct {
 			u32 priority;
 			u32 wol_packet_type;
-			u16 friendly_name_len;
-			u16 friendly_name[65];
 			u32 pattern_id;
 			u32 next_wol_pattern_offset;
 
@@ -134,27 +132,101 @@ struct __packed hw_aq_atl_utils_fw_rpc {
 					u32 pattern_offset;
 					u32 pattern_size;
 				} wol_bit_map_pattern;
+
+				struct {
+					u8 mac_addr[6];
+				} wol_magic_packet_patter;
 			} wol_pattern;
 		} msg_wol;
 
 		struct {
-			u32 is_wake_on_link_down;
-			u32 is_wake_on_link_up;
-		} msg_wolink;
+			union {
+				u32 pattern_mask;
+
+				struct {
+					u32 reason_arp_v4_pkt : 1;
+					u32 reason_ipv4_ping_pkt : 1;
+					u32 reason_ipv6_ns_pkt : 1;
+					u32 reason_ipv6_ping_pkt : 1;
+					u32 reason_link_up : 1;
+					u32 reason_link_down : 1;
+					u32 reason_maximum : 1;
+				};
+			};
+
+			union {
+				u32 offload_mask;
+			};
+		} msg_enable_wakeup;
+
+		struct {
+			u32 id;
+		} msg_del_id;
 	};
 };
 
-struct __packed hw_aq_atl_utils_mbox_header {
+struct __packed hw_atl_utils_mbox_header {
 	u32 version;
 	u32 transaction_id;
 	u32 error;
 };
 
-struct __packed hw_aq_atl_utils_mbox {
-	struct hw_aq_atl_utils_mbox_header header;
+struct __packed hw_atl_utils_mbox {
+	struct hw_atl_utils_mbox_header header;
 	struct hw_atl_stats_s stats;
 };
 
+/* fw2x */
+typedef u32	fw_offset_t;
+
+struct __packed offload_ip_info {
+	u8 v4_local_addr_count;
+	u8 v4_addr_count;
+	u8 v6_local_addr_count;
+	u8 v6_addr_count;
+	fw_offset_t v4_addr;
+	fw_offset_t v4_prefix;
+	fw_offset_t v6_addr;
+	fw_offset_t v6_prefix;
+};
+
+struct __packed offload_port_info {
+	u16 udp_port_count;
+	u16 tcp_port_count;
+	fw_offset_t udp_port;
+	fw_offset_t tcp_port;
+};
+
+struct __packed offload_ka_info {
+	u16 v4_ka_count;
+	u16 v6_ka_count;
+	u32 retry_count;
+	u32 retry_interval;
+	fw_offset_t v4_ka;
+	fw_offset_t v6_ka;
+};
+
+struct __packed offload_rr_info {
+	u32 rr_count;
+	u32 rr_buf_len;
+	fw_offset_t rr_id_x;
+	fw_offset_t rr_buf;
+};
+
+struct __packed offload_info {
+	u32 version;
+	u32 len;
+	u8 mac_addr[6];
+
+	u8 reserved[2];
+
+	struct offload_ip_info ips;
+	struct offload_port_info ports;
+	struct offload_ka_info kas;
+	struct offload_rr_info rrs;
+	u8 buf[0];
+};
+
 #define HAL_ATLANTIC_UTILS_CHIP_MIPS         0x00000001U
 #define HAL_ATLANTIC_UTILS_CHIP_TPO2         0x00000002U
 #define HAL_ATLANTIC_UTILS_CHIP_RPF2         0x00000004U
@@ -181,6 +253,18 @@ enum hal_atl_utils_fw_state_e {
 #define HAL_ATLANTIC_RATE_100M       BIT(5)
 #define HAL_ATLANTIC_RATE_INVALID    BIT(6)
 
+#define HAL_ATLANTIC_UTILS_FW_MSG_PING          0x1U
+#define HAL_ATLANTIC_UTILS_FW_MSG_ARP           0x2U
+#define HAL_ATLANTIC_UTILS_FW_MSG_INJECT        0x3U
+#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD       0x4U
+#define HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL       0x5U
+#define HAL_ATLANTIC_UTILS_FW_MSG_ENABLE_WAKEUP 0x6U
+#define HAL_ATLANTIC_UTILS_FW_MSG_MSM_PFC       0x7U
+#define HAL_ATLANTIC_UTILS_FW_MSG_PROVISIONING  0x8U
+#define HAL_ATLANTIC_UTILS_FW_MSG_OFFLOAD_ADD   0x9U
+#define HAL_ATLANTIC_UTILS_FW_MSG_OFFLOAD_DEL   0xAU
+#define HAL_ATLANTIC_UTILS_FW_MSG_CABLE_DIAG    0xDU
+
 enum hw_atl_fw2x_rate {
 	FW2X_RATE_100M    = 0x20,
 	FW2X_RATE_1G      = 0x100,
@@ -286,10 +370,10 @@ int hw_atl_utils_soft_reset(struct aq_hw_s *self);
 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p);
 
 int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self,
-			       struct hw_aq_atl_utils_mbox_header *pmbox);
+			       struct hw_atl_utils_mbox_header *pmbox);
 
 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self,
-				 struct hw_aq_atl_utils_mbox *pmbox);
+				 struct hw_atl_utils_mbox *pmbox);
 
 void hw_atl_utils_mpi_set(struct aq_hw_s *self,
 			  enum hal_atl_utils_fw_state_e state,
@@ -323,7 +407,7 @@ int hw_atl_utils_fw_downld_dwords(struct aq_hw_s *self, u32 a,
 int hw_atl_utils_fw_rpc_call(struct aq_hw_s *self, unsigned int rpc_size);
 
 int hw_atl_utils_fw_rpc_wait(struct aq_hw_s *self,
-			     struct hw_aq_atl_utils_fw_rpc **rpc);
+			     struct hw_atl_utils_fw_rpc **rpc);
 
 extern const struct aq_fw_ops aq_fw_1x_ops;
 extern const struct aq_fw_ops aq_fw_2x_ops;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
index 3a5ec22..4755900 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -16,6 +16,7 @@
 #include "../aq_pci_func.h"
 #include "../aq_ring.h"
 #include "../aq_vec.h"
+#include "../aq_nic.h"
 #include "hw_atl_utils.h"
 #include "hw_atl_llh.h"
 
@@ -29,6 +30,37 @@
 #define HW_ATL_FW2X_MPI_STATE_ADDR	0x370
 #define HW_ATL_FW2X_MPI_STATE2_ADDR	0x374
 
+#define HW_ATL_FW2X_CAP_SLEEP_PROXY      BIT(CAPS_HI_SLEEP_PROXY)
+#define HW_ATL_FW2X_CAP_WOL              BIT(CAPS_HI_WOL)
+
+#define HW_ATL_FW2X_CTRL_SLEEP_PROXY      BIT(CTRL_SLEEP_PROXY)
+#define HW_ATL_FW2X_CTRL_WOL              BIT(CTRL_WOL)
+#define HW_ATL_FW2X_CTRL_LINK_DROP        BIT(CTRL_LINK_DROP)
+#define HW_ATL_FW2X_CTRL_PAUSE            BIT(CTRL_PAUSE)
+#define HW_ATL_FW2X_CTRL_ASYMMETRIC_PAUSE BIT(CTRL_ASYMMETRIC_PAUSE)
+#define HW_ATL_FW2X_CTRL_FORCE_RECONNECT  BIT(CTRL_FORCE_RECONNECT)
+
+#define HAL_ATLANTIC_WOL_FILTERS_COUNT   8
+#define HAL_ATLANTIC_UTILS_FW2X_MSG_WOL  0x0E
+
+struct __packed fw2x_msg_wol_pattern {
+	u8 mask[16];
+	u32 crc;
+};
+
+struct __packed fw2x_msg_wol {
+	u32 msg_id;
+	u8 hw_addr[6];
+	u8 magic_packet_enabled;
+	u8 filter_count;
+	struct fw2x_msg_wol_pattern filter[HAL_ATLANTIC_WOL_FILTERS_COUNT];
+	u8 link_up_enabled;
+	u8 link_down_enabled;
+	u16 reserved;
+	u32 link_up_timeout;
+	u32 link_down_timeout;
+};
+
 static int aq_fw2x_set_link_speed(struct aq_hw_s *self, u32 speed);
 static int aq_fw2x_set_state(struct aq_hw_s *self,
 			     enum hal_atl_utils_fw_state_e state);
-- 
2.7.4

^ permalink raw reply related

* [PATCH net] net: aquantia: Fix IFF_ALLMULTI flag functionality
From: Igor Russkikh @ 2018-08-08 11:06 UTC (permalink / raw)
  To: David S . Miller; +Cc: netdev, David Arcari, Dmitry Bogdanov

From: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>

It was noticed that NIC always pass all multicast traffic to the host
regardless of IFF_ALLMULTI flag on the interface.
The rule in MC Filter Table in NIC, that is configured to accept any
multicast packets, is turning on if IFF_MULTICAST flag is set on the
interface. It leads to passing all multicast traffic to the host.
This fix changes the condition to turn on that rule by checking
IFF_ALLMULTI flag as it should.

Fixes: b21f502 ("net:ethernet:aquantia: Fix for multicast filter handling.")
Signed-off-by: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
---
 drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
index 956860a69797..3bdab972420b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
@@ -762,7 +762,7 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
 
 	hw_atl_rpfl2promiscuous_mode_en_set(self, IS_FILTER_ENABLED(IFF_PROMISC));
 	hw_atl_rpfl2multicast_flr_en_set(self,
-					 IS_FILTER_ENABLED(IFF_MULTICAST), 0);
+					 IS_FILTER_ENABLED(IFF_ALLMULTI), 0);
 
 	hw_atl_rpfl2_accept_all_mc_packets_set(self,
 					       IS_FILTER_ENABLED(IFF_ALLMULTI));
-- 
2.17.1

^ permalink raw reply related

* Re: [PATCH net-next 12/14] net: sched: act_mirred: remove dependency on rtnl lock
From: Vlad Buslov @ 2018-08-08 11:21 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, jhs, xiyou.wangcong, pablo, kadlec, fw, ast,
	daniel, edumazet, keescook, marcelo.leitner
In-Reply-To: <20180808085408.GD1998@nanopsycho>


On Wed 08 Aug 2018 at 08:54, Jiri Pirko <jiri@resnulli.us> wrote:
> Wed, Aug 08, 2018 at 10:47:04AM CEST, vladbu@mellanox.com wrote:
>>
>>On Wed 08 Aug 2018 at 08:03, Jiri Pirko <jiri@resnulli.us> wrote:
>>> Wed, Aug 08, 2018 at 09:40:35AM CEST, vladbu@mellanox.com wrote:
>>>>
>>>>On Tue 07 Aug 2018 at 16:36, Jiri Pirko <jiri@resnulli.us> wrote:
>>>>> Mon, Aug 06, 2018 at 08:54:23AM CEST, vladbu@mellanox.com wrote:
>>>>>
>>>>> [...]
>>>>>
>>>>>>diff --git a/include/net/tc_act/tc_tunnel_key.h b/include/net/tc_act/tc_tunnel_key.h
>>>>>>index 46b8c7f1c8d5..e6e475d788c6 100644
>>>>>>--- a/include/net/tc_act/tc_tunnel_key.h
>>>>>>+++ b/include/net/tc_act/tc_tunnel_key.h
>>>>>>@@ -30,26 +30,47 @@ struct tcf_tunnel_key {
>>>>>> 
>>>>>> static inline bool is_tcf_tunnel_set(const struct tc_action *a)
>>>>>> {
>>>>>>+	bool ret = false;
>>>>>> #ifdef CONFIG_NET_CLS_ACT
>>>>>> 	struct tcf_tunnel_key *t = to_tunnel_key(a);
>>>>>>-	struct tcf_tunnel_key_params *params = rtnl_dereference(t->params);
>>>>>>+	struct tcf_tunnel_key_params *params;
>>>>>> 
>>>>>>+	rcu_read_lock();
>>>>>>+	params = rcu_dereference(t->params);
>>>>>> 	if (a->ops && a->ops->type == TCA_ACT_TUNNEL_KEY)
>>>>>>-		return params->tcft_action == TCA_TUNNEL_KEY_ACT_SET;
>>>>>>+		ret = params->tcft_action == TCA_TUNNEL_KEY_ACT_SET;
>>>>>>+	rcu_read_unlock();
>>>>>> #endif
>>>>>>-	return false;
>>>>>>+	return ret;
>>>>>> }
>>>>>> 
>>>>>> static inline bool is_tcf_tunnel_release(const struct tc_action *a)
>>>>>
>>>>> Why are these tunnel things in a mirred patch?
>>>>
>>>>Mistake during re-slit. Will move those to tunnel_key patch.
>>>
>>> Are you sure that the changes are safe? I just quickly looked over it
>>> and it smells:
>>> drivers/net/ethernet/mellanox/mlx5/core/en_tc.c:
>>>                 if (is_tcf_tunnel_set(a)) {
>>>                         info = tcf_tunnel_info(a);
>>>
>>> Why the "t->params" can't be nulled in the middle?
>>
>>First of all, no API is actually "unlocked" with this patch. It is a
>>preparation, rtnl mutex is still in use.
>>
>>Callers of these functions will have to be updated, for example, to use
>>their _rcu version while holding rcu_read_lock.
>
> I don't see any rcu version of these. I think that it would be good to
> convert the callers to rcu and you can avoid these changes.

Understood. Will move helper function changes to standalone patch.

^ permalink raw reply

* Re: [PATCH bpf-next 12/13] docs: net: Fix various minor typos
From: Daniel Borkmann @ 2018-08-08 13:45 UTC (permalink / raw)
  To: Jonathan Corbet, Tobin C. Harding
  Cc: Alexei Starovoitov, David S. Miller, linux-doc, netdev,
	linux-kernel
In-Reply-To: <20180808072310.4695cea4@lwn.net>

On 08/08/2018 03:23 PM, Jonathan Corbet wrote:
> On Wed, 8 Aug 2018 11:42:48 +1000
> "Tobin C. Harding" <me@tobin.cc> wrote:
> 
>> Thanks for doing such a careful review that you noticed this.  I'm
>> working on this more ATM and I've moved the document to use double
>> spaces between _all_ full stops.  Currently the document uses mostly
>> single spaces but there are some sections with double space.  The
>> internet tells me this is a 'style' issue not a rule.  And I've seen
>> single and double spacing in tree and do not know if one is favoured.
>>
>> Do you care? 
> 
> I'm not Daniel, but let me just say that, for docs in general, I'm
> absolutely uninterested in patches adjusting the number of spaces after
> periods.  It really doesn't matter one way or the other, and I don't think
> we benefit from that kind of churn.

Yep, agree.

^ permalink raw reply

* lock recursion - was: Re: [4.18 rc7] BUG: sleeping function called from invalid context at mm/slab.h:421
From: Petr Mladek @ 2018-08-08 11:36 UTC (permalink / raw)
  To: Vlastimil Babka
  Cc: David S. Miller, Marcel Holtmann, Johan Hedberg, linux-bluetooth,
	netdev, Mikhail Gavrilov, linux-mm, Steven Rostedt,
	Sergey Senozhatsky, Peter Zijlstra
In-Reply-To: <50f14cef-9c30-7984-bef3-6da033d91483@suse.cz>

On Wed 2018-08-08 11:05:00, Vlastimil Babka wrote:
> On 08/08/2018 11:01 AM, Vlastimil Babka wrote:
> > fbcon_startup() calls kzalloc(sizeof(struct fbcon_ops), GFP_KERNEL) so
> > it tells slab it can sleep. The problem must be higher in the stack,
> > CCing printk people.
> 
> Uh just noticed there was also attached dmesg which my reply converted
> to inline. The first problem there is a lockdep splat.

The lockdep splat might eventually be a valid issue (recursive lock) in the
networking code. But it seems to be unrelated to the later problems
with sleeping in fbcon_startup().

Adding networking people into CC. Please, find below the relevant part
from the dmesg. The full log can be found in the original message at
https://marc.info/?l=linux-mm&m=153370024009996&w=2

Lock recursion in bluetooth code:

[   32.050660] Bluetooth: RFCOMM TTY layer initialized
[   32.050675] Bluetooth: RFCOMM socket layer initialized
[   32.050719] Bluetooth: RFCOMM ver 1.11
[   34.413359] fuse init (API version 7.27)
[   40.562871] rfkill: input handler disabled
[   42.272301] pool (2344) used greatest stack depth: 11320 bytes left
[   42.701283] ISO 9660 Extensions: Microsoft Joliet Level 3
[   42.704062] ISO 9660 Extensions: Microsoft Joliet Level 3
[   42.710375] ISO 9660 Extensions: RRIP_1991A
[   64.930766] tracker-extract (2229) used greatest stack depth: 11176 bytes left
[  465.911281] TaskSchedulerFo (3362) used greatest stack depth: 11112 bytes left
[  491.743600] TaskSchedulerFo (3364) used greatest stack depth: 11032 bytes left
[  507.733884] nf_conntrack: default automatic helper assignment has been turned off \
for security reasons and CT-based  firewall rule not found. Use the iptables CT \
target to attach helpers instead. [  660.384586] kworker/dying (155) used greatest \
stack depth: 10888 bytes left [  699.910094] device enp2s0 entered promiscuous mode
[ 1098.658964] kworker/dying (7) used greatest stack depth: 10712 bytes left
[ 1843.488301] perf: interrupt took too long (2510 > 2500), lowering \
kernel.perf_event_max_sample_rate to 79000 [ 2819.896469] perf: interrupt took too \
long (3138 > 3137), lowering kernel.perf_event_max_sample_rate to 63000 [ \
6120.247124] perf: interrupt took too long (3923 > 3922), lowering \
kernel.perf_event_max_sample_rate to 50000

[ 6829.212232] ============================================
[ 6829.212234] WARNING: possible recursive locking detected
[ 6829.212236] 4.18.0-0.rc7.git1.1.fc29.x86_64 #1 Not tainted
[ 6829.212237] --------------------------------------------
[ 6829.212239] kworker/u17:2/28441 is trying to acquire lock:
[ 6829.212242] 000000004025b723 (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}, at: \
bt_accept_enqueue+0x3c/0xb0 [bluetooth] [ 6829.212260] 
               but task is already holding lock:
[ 6829.212262] 000000004cb71eef (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}, at: \
l2cap_sock_new_connection_cb+0x18/0xa0 [bluetooth] [ 6829.212278] 
               other info that might help us debug this:
[ 6829.212279]  Possible unsafe locking scenario:

[ 6829.212281]        CPU0
[ 6829.212282]        ----
[ 6829.212284]   lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
[ 6829.212286]   lock(sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP);
[ 6829.212288] 
                *** DEADLOCK ***

[ 6829.212290]  May be due to missing lock nesting notation

[ 6829.212293] 5 locks held by kworker/u17:2/28441:
[ 6829.212294]  #0: 000000009af6a4dc ((wq_completion)"%s"hdev->name#2){+.+.}, at: \
process_one_work+0x1f3/0x650 [ 6829.212301]  #1: 000000006f7488f4 \
((work_completion)(&hdev->rx_work)){+.+.}, at: process_one_work+0x1f3/0x650 [ \
6829.212306]  #2: 000000003dba8333 (&conn->chan_lock){+.+.}, at: \
l2cap_connect+0x8f/0x5a0 [bluetooth] [ 6829.212321]  #3: 00000000aaa813b9 \
(&chan->lock/2){+.+.}, at: l2cap_connect+0xa9/0x5a0 [bluetooth] [ 6829.212335]  #4: \
000000004cb71eef (sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP){+.+.}, at: \
l2cap_sock_new_connection_cb+0x18/0xa0 [bluetooth] [ 6829.212350] 
               stack backtrace:
[ 6829.212354] CPU: 6 PID: 28441 Comm: kworker/u17:2 Not tainted \
4.18.0-0.rc7.git1.1.fc29.x86_64 #1 [ 6829.212355] Hardware name: Gigabyte Technology \
Co., Ltd. Z87M-D3H/Z87M-D3H, BIOS F11 08/12/2014 [ 6829.212365] Workqueue: hci0 \
hci_rx_work [bluetooth] [ 6829.212367] Call Trace:
[ 6829.212373]  dump_stack+0x85/0xc0
[ 6829.212377]  __lock_acquire.cold.64+0x158/0x227
[ 6829.212381]  ? mark_held_locks+0x57/0x80
[ 6829.212384]  lock_acquire+0x9e/0x1b0
[ 6829.212394]  ? bt_accept_enqueue+0x3c/0xb0 [bluetooth]
[ 6829.212398]  lock_sock_nested+0x72/0xa0
[ 6829.212407]  ? bt_accept_enqueue+0x3c/0xb0 [bluetooth]
[ 6829.212417]  bt_accept_enqueue+0x3c/0xb0 [bluetooth]
[ 6829.212429]  l2cap_sock_new_connection_cb+0x5d/0xa0 [bluetooth]
[ 6829.212441]  l2cap_connect+0x110/0x5a0 [bluetooth]
[ 6829.212454]  ? l2cap_recv_frame+0x6d0/0x2cb0 [bluetooth]
[ 6829.212458]  ? __mutex_unlock_slowpath+0x4b/0x2b0
[ 6829.212470]  l2cap_recv_frame+0x6e8/0x2cb0 [bluetooth]
[ 6829.212474]  ? __mutex_unlock_slowpath+0x4b/0x2b0
[ 6829.212484]  hci_rx_work+0x1c6/0x5d0 [bluetooth]
[ 6829.212488]  process_one_work+0x27d/0x650
[ 6829.212492]  worker_thread+0x3c/0x390
[ 6829.212494]  ? process_one_work+0x650/0x650
[ 6829.212498]  kthread+0x120/0x140
[ 6829.212501]  ? kthread_create_worker_on_cpu+0x70/0x70
[ 6829.212504]  ret_from_fork+0x3a/0x50
[ 6829.285343] BUG: sleeping function called from invalid context at \
net/core/sock.c:2833 [ 6829.285349] in_atomic(): 1, irqs_disabled(): 0, pid: 1743, \
name: krfcommd [ 6829.285351] INFO: lockdep is turned off.
[ 6829.285355] CPU: 6 PID: 1743 Comm: krfcommd Not tainted \
4.18.0-0.rc7.git1.1.fc29.x86_64 #1 [ 6829.285358] Hardware name: Gigabyte Technology \
Co., Ltd. Z87M-D3H/Z87M-D3H, BIOS F11 08/12/2014 [ 6829.285360] Call Trace:
[ 6829.285368]  dump_stack+0x85/0xc0
[ 6829.285373]  ___might_sleep.cold.72+0xac/0xbc
[ 6829.285378]  lock_sock_nested+0x29/0xa0
[ 6829.285394]  bt_accept_enqueue+0x3c/0xb0 [bluetooth]
[ 6829.285401]  rfcomm_connect_ind+0x21b/0x260 [rfcomm]
[ 6829.285406]  rfcomm_run+0x1611/0x1820 [rfcomm]
[ 6829.285411]  ? do_wait_intr_irq+0xb0/0xb0
[ 6829.285416]  ? rfcomm_check_accept+0x90/0x90 [rfcomm]
[ 6829.285419]  kthread+0x120/0x140
[ 6829.285422]  ? kthread_create_worker_on_cpu+0x70/0x70
[ 6829.285426]  ret_from_fork+0x3a/0x50
[ 6829.476282] input: 04:5D:4B:5F:34:57 as /devices/virtual/input/input35
[ 7273.090391] show_signal_msg: 23 callbacks suppressed
[ 7273.090393] CFileWriterThre[29422]: segfault at 7f078bfe7240 ip 00007f079137843c \
sp 00007f078bb8dcf0 error 4 in steamclient.so[7f0790880000+14d2000] [ 7273.090404] \
Code: 89 df ff d2 8b 45 00 83 f8 02 0f 84 9e 00 00 00 83 f8 03 0f 84 55 05 00 00 83 \
f8 01 74 48 31 ed 4d 85 e4 74 11 48 85 db 74 0c <48> 8b 03 4c 89 e6 48 89 df ff 50 10 \
48 8b b4 24 e8 00 00 00 64 48  [ 7755.656023] rfkill: input handler enabled
[ 7773.439895] rfkill: input handler disabled
[ 8075.232946] BUG: sleeping function called from invalid context at \
net/core/sock.c:2833 [ 8075.232951] in_atomic(): 1, irqs_disabled(): 0, pid: 1743, \
name: krfcommd [ 8075.232952] INFO: lockdep is turned off.
[ 8075.232956] CPU: 5 PID: 1743 Comm: krfcommd Tainted: G        W         \
4.18.0-0.rc7.git1.1.fc29.x86_64 #1 [ 8075.232957] Hardware name: Gigabyte Technology \
Co., Ltd. Z87M-D3H/Z87M-D3H, BIOS F11 08/12/2014 [ 8075.232959] Call Trace:
[ 8075.232965]  dump_stack+0x85/0xc0
[ 8075.232969]  ___might_sleep.cold.72+0xac/0xbc
[ 8075.232973]  lock_sock_nested+0x29/0xa0
[ 8075.232987]  bt_accept_enqueue+0x3c/0xb0 [bluetooth]
[ 8075.232992]  rfcomm_connect_ind+0x21b/0x260 [rfcomm]
[ 8075.232997]  rfcomm_run+0x1611/0x1820 [rfcomm]
[ 8075.233001]  ? do_wait_intr_irq+0xb0/0xb0
[ 8075.233005]  ? rfcomm_check_accept+0x90/0x90 [rfcomm]
[ 8075.233008]  kthread+0x120/0x140
[ 8075.233011]  ? kthread_create_worker_on_cpu+0x70/0x70
[ 8075.233014]  ret_from_fork+0x3a/0x50
[ 8075.413187] input: 04:5D:4B:5F:34:57 as /devices/virtual/input/input36
[13538.300352] steam[4385]: segfault at 0 ip 00000000eabc32d9 sp 00000000ffdca1b0 \
error 4 in vgui2_s.so[eab26000+292000] [13538.300365] Code: 74 03 00 00 00 00 00 00 \
c7 44 24 08 02 00 00 00 c7 44 24 04 10 00 00 00 c7 04 24 44 ac 00 00 e8 1d 40 fb ff \
89 86 74 03 00 00 <8b> 00 8b 78 10 e8 3d 1a fb ff 8b 86 74 03 00 00 dd 5c 24 04 89 04 \
 [14324.004275] pool[443]: segfault at 0 ip 00007f53e2399556 sp 00007f53ceffcc40 \
error 4 in libnssutil3.so[7f53e2395000+12000] [14324.004286] Code: d8 5b 5d 41 5c c3 \
66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 f3 0f 1e fa 41 54 41 bc ff ff ff ff 55 53 \
48 89 fb e8 7a bc ff ff <48> 8b 3b 48 89 c5 e8 9f c1 ff ff 48 8b 43 38 48 39 c5 75 23 \
eb 2d  [14324.007764] rfkill: input handler enabled
[14348.933385] rfkill: input handler disabled
[15930.680376] DMA-API: debugging out of memory - disabling
[16087.451698] vaapi-queue:src (10166) used greatest stack depth: 10616 bytes left
[19689.192082] BUG: sleeping function called from invalid context at \
net/core/sock.c:2833 [19689.192087] in_atomic(): 1, irqs_disabled(): 0, pid: 1743, \
name: krfcommd [19689.192089] INFO: lockdep is turned off.
[19689.192093] CPU: 6 PID: 1743 Comm: krfcommd Tainted: G        W         \
4.18.0-0.rc7.git1.1.fc29.x86_64 #1 [19689.192096] Hardware name: Gigabyte Technology \
Co., Ltd. Z87M-D3H/Z87M-D3H, BIOS F11 08/12/2014 [19689.192098] Call Trace:
[19689.192106]  dump_stack+0x85/0xc0
[19689.192112]  ___might_sleep.cold.72+0xac/0xbc
[19689.192117]  lock_sock_nested+0x29/0xa0
[19689.192142]  bt_accept_enqueue+0x3c/0xb0 [bluetooth]
[19689.192150]  rfcomm_connect_ind+0x21b/0x260 [rfcomm]
[19689.192157]  rfcomm_run+0x1611/0x1820 [rfcomm]
[19689.192163]  ? do_wait_intr_irq+0xb0/0xb0
[19689.192179]  ? rfcomm_check_accept+0x90/0x90 [rfcomm]
[19689.192183]  kthread+0x120/0x140
[19689.192186]  ? kthread_create_worker_on_cpu+0x70/0x70
[19689.192190]  ret_from_fork+0x3a/0x50
[19689.377451] input: 04:5D:4B:5F:34:57 as /devices/virtual/input/input37


Best Regards,
Petr

^ permalink raw reply

* Re: [PATCH net-next v6 11/11] net: sched: change action API to use array of pointers to actions
From: Vlad Buslov @ 2018-08-08 11:41 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Jiri Pirko, Alexei Starovoitov, Daniel Borkmann,
	Yevgeny Kliteynik
In-Reply-To: <CAM_iQpWpxf=yRNadgN+q0rwhd_E0c7pAy7fG+A=asqgk9JRx0Q@mail.gmail.com>


On Tue 07 Aug 2018 at 23:26, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Thu, Jul 5, 2018 at 7:24 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>>         attr_size = tcf_action_full_attrs_size(attr_size);
>>
>>         if (event == RTM_GETACTION)
>> -               ret = tcf_get_notify(net, portid, n, &actions, event, extack);
>> +               ret = tcf_get_notify(net, portid, n, actions, event, extack);
>>         else { /* delete */
>> -               ret = tcf_del_notify(net, n, &actions, portid, attr_size, extack);
>> +               ret = tcf_del_notify(net, n, actions, &acts_deleted, portid,
>> +                                    attr_size, extack);
>>                 if (ret)
>>                         goto err;
>>                 return ret;
>>         }
>>  err:
>> -       tcf_action_put_lst(&actions);
>> +       tcf_action_put_many(&actions[acts_deleted]);
>>         return ret;
>
> How does this even work?
>
> You save an index in 'acts_deleted', but you pass &actions[acts_deleted]
> to tcf_action_put_many(), which seems you want to start from
> where it fails, but inside tcf_action_put_many() it starts from 0
> to TCA_ACT_MAX_PRIO, out-of-bound access at least?

Actions array is declared to be TCA_ACT_MAX_PRIO+1 in size, and
initialized to NULL pointers. In loop inside tcf_action_put_many() there
are two checks: One is that index is less than TCA_ACT_MAX_PRIO and
another one that pointer is not NULL. In this case I rely on extra NULL
pointer at the end of actions array to prevent out-of-bound access.

^ permalink raw reply

* [PATCH] net:9p: change the p9_error_init and p9_trans_fd_init to be void function
From: zhong jiang @ 2018-08-08 14:02 UTC (permalink / raw)
  To: ericvh, rminnich, lucho, davem; +Cc: netdev, linux-kernel

The two functions has return value, but any of the callees do not handle the
return value. So we get out of the return value and make the function to be
void function. 

Signed-off-by: zhong jiang <zhongjiang@huawei.com>
---
 include/net/9p/9p.h | 4 ++--
 net/9p/error.c      | 4 +---
 net/9p/trans_fd.c   | 4 +---
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index b8eb51a..0a9577d 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -571,7 +571,7 @@ struct p9_fcall {
 void p9_idpool_put(int id, struct p9_idpool *p);
 int p9_idpool_check(int id, struct p9_idpool *p);
 
-int p9_error_init(void);
-int p9_trans_fd_init(void);
+void p9_error_init(void);
+void p9_trans_fd_init(void);
 void p9_trans_fd_exit(void);
 #endif /* NET_9P_H */
diff --git a/net/9p/error.c b/net/9p/error.c
index 126fd0d..458e038 100644
--- a/net/9p/error.c
+++ b/net/9p/error.c
@@ -190,7 +190,7 @@ struct errormap {
  *
  */
 
-int p9_error_init(void)
+void p9_error_init(void)
 {
 	struct errormap *c;
 	int bucket;
@@ -206,8 +206,6 @@ int p9_error_init(void)
 		INIT_HLIST_NODE(&c->list);
 		hlist_add_head(&c->list, &hash_errmap[bucket]);
 	}
-
-	return 1;
 }
 EXPORT_SYMBOL(p9_error_init);
 
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index e2ef3c7..e0f36c9 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -1121,13 +1121,11 @@ static void p9_poll_workfn(struct work_struct *work)
 	p9_debug(P9_DEBUG_TRANS, "finish\n");
 }
 
-int p9_trans_fd_init(void)
+void p9_trans_fd_init(void)
 {
 	v9fs_register_trans(&p9_tcp_trans);
 	v9fs_register_trans(&p9_unix_trans);
 	v9fs_register_trans(&p9_fd_trans);
-
-	return 0;
 }
 
 void p9_trans_fd_exit(void)
-- 
1.7.12.4

^ permalink raw reply related

* Re: [PATCH] net: ethernet: cpsw-phy-sel: prefer phandle for phy sel and update binding
From: Andrew Lunn @ 2018-08-08 11:58 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: David Miller, netdev, linux-omap, devicetree, Grygorii Strashko,
	Ivan Khoronzhuk, Mark Rutland, Murali Karicheri, Rob Herring
In-Reply-To: <20180808080354.100146-1-tony@atomide.com>

> +++ b/Documentation/devicetree/bindings/net/cpsw.txt
> @@ -19,6 +19,9 @@ Required properties:
>  - slaves		: Specifies number for slaves
>  - active_slave		: Specifies the slave to use for time stamping,
>  			  ethtool and SIOCGMIIPHY
> +- cpsw-phy-sel		: Specifies the phandle to the CPSW phy mode selection
> +			  device. Note that in legacy cases cpsw-phy-sel may be
> +			  a child device instead of a phandle.

Hi Tony

It would be good to reference cpsw-phy-sel.txt.

>  Optional properties:
>  - ti,hwmods		: Must be "cpgmac0"
> @@ -75,6 +78,7 @@ Examples:
>  		cpts_clock_mult = <0x80000000>;
>  		cpts_clock_shift = <29>;
>  		syscon = <&cm>;
> +		cpsw-phy-sel = <&phy_sel>;
>  		cpsw_emac0: slave@0 {
>  			phy_id = <&davinci_mdio>, <0>;
>  			phy-mode = "rgmii-txid";
> @@ -103,6 +107,7 @@ Examples:
>  		cpts_clock_mult = <0x80000000>;
>  		cpts_clock_shift = <29>;
>  		syscon = <&cm>;
> +		cpsw-phy-sel = <&phy_sel>;
>  		cpsw_emac0: slave@0 {
>  			phy_id = <&davinci_mdio>, <0>;
>  			phy-mode = "rgmii-txid";
> diff --git a/drivers/net/ethernet/ti/cpsw-phy-sel.c b/drivers/net/ethernet/ti/cpsw-phy-sel.c
> --- a/drivers/net/ethernet/ti/cpsw-phy-sel.c
> +++ b/drivers/net/ethernet/ti/cpsw-phy-sel.c
> @@ -170,10 +170,13 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave)
>  	struct device_node *node;
>  	struct cpsw_phy_sel_priv *priv;
>  
> -	node = of_get_child_by_name(dev->of_node, "cpsw-phy-sel");
> +	node = of_parse_phandle(dev->of_node, "cpsw-phy-sel", 0);
>  	if (!node) {

Do you need to handle EPROBE_DEFER here? The phandle points to a
device which has not yet been loaded? I'm not sure exactly where it
will be returned, maybe it is bus_find_device(), but i expect to see
some handling of it somewhere in this function.

> -		dev_err(dev, "Phy mode driver DT not found\n");
> -		return;
> +		node = of_get_child_by_name(dev->of_node, "cpsw-phy-sel");
> +		if (!node) {
> +			dev_err(dev, "Phy mode driver DT not found\n");
> +			return;
> +		}
>  	}

	Andrew

^ permalink raw reply

* Re: [PATCH net-next 1/5] net: aquantia: fix hw_atl_utils_fw_upload_dwords
From: Andrew Lunn @ 2018-08-08 12:03 UTC (permalink / raw)
  To: Igor Russkikh; +Cc: David S . Miller, netdev, Yana Esina, Nikita Danilov
In-Reply-To: <7ad5aaa26e9a478fb4d81dd05412c880c048dce8.1533650064.git.igor.russkikh@aquantia.com>

On Wed, Aug 08, 2018 at 01:57:11PM +0300, Igor Russkikh wrote:
> From: Yana Esina <yana.esina@aquantia.com>
> 
> This patch fixes the upload function, which worked incorrectly with
> some chips.

Hi Igor

This patch contains a few whitespace changes. It is normal to put them
into a separate patch.

Thanks
	Andrew

^ permalink raw reply

* Re: [PATCH v6 8/9] net/mlx5: Do not call pcie_print_link_status()
From: Tal Gilboa @ 2018-08-08 14:23 UTC (permalink / raw)
  To: Leon Romanovsky, Alexandru Gagniuc
  Cc: linux-pci, bhelgaas, jakub.kicinski, keith.busch, alex_gagniuc,
	austin_bolen, shyam_iyer, Ariel Elior, everest-linux-l2,
	David S. Miller, Michael Chan, Ganesh Goudar, Jeff Kirsher,
	Tariq Toukan, Saeed Mahameed, Dirk van der Merwe, netdev,
	linux-kernel, intel-wired-lan, linux-rdma, oss-drivers,
	Saeed Mahameed
In-Reply-To: <20180808060848.GQ13378@mtr-leonro.mtl.com>

On 8/8/2018 9:08 AM, Leon Romanovsky wrote:
> On Mon, Aug 06, 2018 at 06:25:42PM -0500, Alexandru Gagniuc wrote:
>> This is now done by the PCI core to warn of sub-optimal bandwidth.
>>
>> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
>> ---
>>   drivers/net/ethernet/mellanox/mlx5/core/main.c | 4 ----
>>   1 file changed, 4 deletions(-)
>>
> 
> Thanks,
> Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
> 

Alex,
I loaded mlx5 driver with and without these series. The report in dmesg 
is now missing. From what I understood, the status should be reported at 
least once, even if everything is in order. We need this functionality 
to stay.

net-next (dmesg output for 07:00.0):
[270498.625351] mlx5_core 0000:07:00.0: firmware version: 14.22.4020
[270498.632130] mlx5_core 0000:07:00.0: 63.008 Gb/s available PCIe 
bandwidth (8 GT/s x8 link)
[270499.169533] (0000:07:00.0): E-Switch: Total vports 9, per vport: max 
uc(1024) max mc(16384)
[270499.182358] mlx5_core 0000:07:00.0: Port module event: module 0, 
Cable plugged

net-next + patches (dmesg output for 07:00.0):
[  331.608472] mlx5_core 0000:07:00.0: firmware version: 14.22.4020
[  332.564938] (0000:07:00.0): E-Switch: Total vports 9, per vport: max 
uc(1024) max mc(16384)
[  332.616271] mlx5_core 0000:07:00.0: Port module event: module 0, 
Cable plugged

^ permalink raw reply

* [patch net-next] net: sched: fix block->refcnt decrement
From: Jiri Pirko @ 2018-08-08 12:04 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, vladbu, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Currently the refcnt is never decremented in case the value is not 1.
Fix it by adding decrement in case the refcnt is not 1.

Reported-by: Vlad Buslov <vladbu@mellanox.com>
Fixes: f71e0ca4db18 ("net: sched: Avoid implicit chain 0 creation")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_api.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 194c2e0b2737..f922ce27ed5e 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -780,6 +780,8 @@ void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
 		block->refcnt--;
 		if (list_empty(&block->chain_list))
 			kfree(block);
+	} else {
+		block->refcnt--;
 	}
 }
 EXPORT_SYMBOL(tcf_block_put_ext);
-- 
2.14.4

^ permalink raw reply related

* Re: [PATCH net-next v6 10/11] net: sched: atomically check-allocate action
From: Vlad Buslov @ 2018-08-08 12:06 UTC (permalink / raw)
  To: Cong Wang
  Cc: Linux Kernel Network Developers, David Miller, Jamal Hadi Salim,
	Jiri Pirko, Alexei Starovoitov, Daniel Borkmann,
	Yevgeny Kliteynik, Jiri Pirko
In-Reply-To: <CAM_iQpU+tWo4HVmQV+UCcLCmULd=kfsPZg+M+2rVvMbHN=2jww@mail.gmail.com>


On Wed 08 Aug 2018 at 01:20, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Thu, Jul 5, 2018 at 7:24 AM Vlad Buslov <vladbu@mellanox.com> wrote:
>>
>> Implement function that atomically checks if action exists and either takes
>> reference to it, or allocates idr slot for action index to prevent
>> concurrent allocations of actions with same index. Use EBUSY error pointer
>> to indicate that idr slot is reserved.
>
> A dumb question:
>
> How could "concurrent allocations of actions with same index" happen
> as you already take idrinfo->lock for the whole
> tcf_idr_check_alloc()??

I guess my changelog is not precise enough in this description.
Let look into sequence of events of initialization of new action:
1) tcf_idr_check_alloc() is called by action init.
2) idrinfo->lock is taken.
3) Lookup in idr is performed to determine if action with specified
index already exists.
4) EBUSY pointer is inserted to indicate that id is taken.
5) idrinfo->lock is released.
6) tcf_idr_check_alloc() returns to action init code.
7) New action is allocated and initialized.
8) tcf_idr_insert() is called.
9) idrinfo->lock is taken.
10) EBUSY pointer is substituted with pointer to new action.
11) idrinfo->lock is released.
12) tcf_idr_insert() returns.

So in this case "concurrent allocations of actions with same index"
means not the allocation with same index during tcf_idr_check_alloc(),
but during the period when idrinfo->lock was released(6-8).

>
> For me, it should be only one allocation could succeed, all others
> should fail.

Correct! And this change is made specifically to enforce that rule.

Otherwise, multiple processes could try to create new action with same
id at the same time, and all processes that executed 3, before any
process reached 10, will "succeed" by overwriting each others action in
idr. (and leak memory while doing so)

>
> Maybe you are trying to prevent others treat it like existing one,
> but in that case you can just hold the idinfo->lock for all idr operations.
>
> And more importantly, upper layer is able to tell it is a creation or
> just replace, you don't have to check this in this complicated way.
>
> IOW, all of these complicated code should not exist.

Original code was simpler and didn't involve temporary EBUSY pointer.
This change was made according to Jiri's request. He wanted to have
unified API to be used by all actions and suggested this approach
specifically.

^ permalink raw reply

* Re: [PATCH net-next 2/5] net: aquantia: definitions for WOL patch
From: Andrew Lunn @ 2018-08-08 12:06 UTC (permalink / raw)
  To: Igor Russkikh; +Cc: David S . Miller, netdev, Yana Esina, Nikita Danilov
In-Reply-To: <a3e119c80dd7afa6a4622f80eb0d1cc73dabbe81.1533650064.git.igor.russkikh@aquantia.com>

> -struct __packed hw_aq_atl_utils_fw_rpc {
> +struct __packed hw_atl_utils_fw_rpc {
>  	u32 msg_id;

Hi Igor

There is no explanation given as to why you decided to rename this
structure. Please do the rename as a standalone patch, no
functionality change. That makes it easier to review the new
functionality.

	Andrew

^ permalink raw reply

* [PATCH] drivers/net/usb/r8152: change rtl8152_system_suspend to be void function
From: zhong jiang @ 2018-08-08 14:26 UTC (permalink / raw)
  To: davem, edumazet; +Cc: netdev, linux-kernel

rtl8152_system_suspend defines the variable "ret", but it is not modified
after initialization. Further, I find that any of the callees do not
handle the return value. So It is safe to drop the variable and make it to
be void function.

Signed-off-by: zhong jiang <zhongjiang@huawei.com>
---
 drivers/net/usb/r8152.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 124211a..cc51ac8 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4412,10 +4412,9 @@ static int rtl8152_runtime_suspend(struct r8152 *tp)
 	return ret;
 }
 
-static int rtl8152_system_suspend(struct r8152 *tp)
+static void rtl8152_system_suspend(struct r8152 *tp)
 {
 	struct net_device *netdev = tp->netdev;
-	int ret = 0;
 
 	netif_device_detach(netdev);
 
@@ -4429,8 +4428,6 @@ static int rtl8152_system_suspend(struct r8152 *tp)
 		tp->rtl_ops.down(tp);
 		napi_enable(napi);
 	}
-
-	return ret;
 }
 
 static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
@@ -4443,7 +4440,7 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
 	if (PMSG_IS_AUTO(message))
 		ret = rtl8152_runtime_suspend(tp);
 	else
-		ret = rtl8152_system_suspend(tp);
+		rtl8152_system_suspend(tp);
 
 	mutex_unlock(&tp->control);
 
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH net 1/3] net/smc: no shutdown in state SMC_LISTEN
From: Ursula Braun @ 2018-08-08 12:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, schwidefsky, heiko.carstens, raspl,
	linux-kernel
In-Reply-To: <20180808121321.516-1-ubraun@linux.ibm.com>

Invoking shutdown for a socket in state SMC_LISTEN does not make
sense. Nevertheless programs like syzbot fuzzing the kernel may
try to do this. For SMC this means a socket refcounting problem.
This patch makes sure a shutdown call for an SMC socket in state
SMC_LISTEN simply returns with -ENOTCONN.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
---
 net/smc/af_smc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 05e4ffe5aabd..1288c7bf40d5 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1397,8 +1397,7 @@ static int smc_shutdown(struct socket *sock, int how)
 	lock_sock(sk);
 
 	rc = -ENOTCONN;
-	if ((sk->sk_state != SMC_LISTEN) &&
-	    (sk->sk_state != SMC_ACTIVE) &&
+	if ((sk->sk_state != SMC_ACTIVE) &&
 	    (sk->sk_state != SMC_PEERCLOSEWAIT1) &&
 	    (sk->sk_state != SMC_PEERCLOSEWAIT2) &&
 	    (sk->sk_state != SMC_APPCLOSEWAIT1) &&
-- 
2.16.4

^ permalink raw reply related

* [PATCH net 2/3] net/smc: allow sysctl rmem and wmem defaults for servers
From: Ursula Braun @ 2018-08-08 12:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, schwidefsky, heiko.carstens, raspl,
	linux-kernel
In-Reply-To: <20180808121321.516-1-ubraun@linux.ibm.com>

Without setsockopt SO_SNDBUF and SO_RCVBUF settings, the sysctl
defaults net.ipv4.tcp_wmem and net.ipv4.tcp_rmem should be the base
for the sizes of the SMC sndbuf and rcvbuf. Any TCP buffer size
optimizations for servers should be ignored.

Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
---
 net/smc/af_smc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 1288c7bf40d5..0ee7721afbe5 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1122,6 +1122,8 @@ static void smc_tcp_listen_work(struct work_struct *work)
 		sock_hold(lsk); /* sock_put in smc_listen_work */
 		INIT_WORK(&new_smc->smc_listen_work, smc_listen_work);
 		smc_copy_sock_settings_to_smc(new_smc);
+		new_smc->sk.sk_sndbuf = lsmc->sk.sk_sndbuf;
+		new_smc->sk.sk_rcvbuf = lsmc->sk.sk_rcvbuf;
 		sock_hold(&new_smc->sk); /* sock_put in passive closing */
 		if (!schedule_work(&new_smc->smc_listen_work))
 			sock_put(&new_smc->sk);
-- 
2.16.4

^ permalink raw reply related

* [PATCH net 3/3] net/smc: move sock lock in smc_ioctl()
From: Ursula Braun @ 2018-08-08 12:13 UTC (permalink / raw)
  To: davem; +Cc: netdev, linux-s390, schwidefsky, heiko.carstens, raspl,
	linux-kernel
In-Reply-To: <20180808121321.516-1-ubraun@linux.ibm.com>

When an SMC socket is connecting it is decided whether fallback to
TCP is needed. To avoid races between connect and ioctl move the
sock lock before the use_fallback check.

Reported-by: syzbot+5b2cece1a8ecb2ca77d8@syzkaller.appspotmail.com
Reported-by: syzbot+19557374321ca3710990@syzkaller.appspotmail.com
Fixes: 1992d99882af ("net/smc: take sock lock in smc_ioctl()")
Signed-off-by: Ursula Braun <ubraun@linux.ibm.com>
---
 net/smc/af_smc.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c
index 0ee7721afbe5..e7de5f282722 100644
--- a/net/smc/af_smc.c
+++ b/net/smc/af_smc.c
@@ -1522,12 +1522,16 @@ static int smc_ioctl(struct socket *sock, unsigned int cmd,
 
 	smc = smc_sk(sock->sk);
 	conn = &smc->conn;
+	lock_sock(&smc->sk);
 	if (smc->use_fallback) {
-		if (!smc->clcsock)
+		if (!smc->clcsock) {
+			release_sock(&smc->sk);
 			return -EBADF;
-		return smc->clcsock->ops->ioctl(smc->clcsock, cmd, arg);
+		}
+		answ = smc->clcsock->ops->ioctl(smc->clcsock, cmd, arg);
+		release_sock(&smc->sk);
+		return answ;
 	}
-	lock_sock(&smc->sk);
 	switch (cmd) {
 	case SIOCINQ: /* same as FIONREAD */
 		if (smc->sk.sk_state == SMC_LISTEN) {
-- 
2.16.4

^ permalink raw reply related

* Re: [PATCH net-next 3/5] net: aquantia: implement WOL support
From: Andrew Lunn @ 2018-08-08 12:16 UTC (permalink / raw)
  To: Igor Russkikh; +Cc: David S . Miller, netdev, Yana Esina, Nikita Danilov
In-Reply-To: <4b6c2d73c19dac481fbf2656f7a24da90966130b.1533650064.git.igor.russkikh@aquantia.com>

> --- a/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> +++ b/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
> @@ -889,11 +889,13 @@ void aq_nic_deinit(struct aq_nic_s *self)
>  		self->aq_vecs > i; ++i, aq_vec = self->aq_vec[i])
>  		aq_vec_deinit(aq_vec);
>  
> -	if (self->power_state == AQ_HW_POWER_STATE_D0) {
> -		(void)self->aq_fw_ops->deinit(self->aq_hw);
> -	} else {
> -		(void)self->aq_hw_ops->hw_set_power(self->aq_hw,
> -						   self->power_state);
> +	(void)self->aq_fw_ops->deinit(self->aq_hw);

These void casts look a bit ugly. Are they needed? Is the compiler
complaining? If it is complaining, it suggests you should not be
casting anyway...

> +	if (wol_enabled) {
> +		rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_wol);
> +
> +		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_ADD;
> +		prpc->msg_wol.priority = 0x10000000; /* normal priority */
> +		prpc->msg_wol.pattern_id = 1U;
> +		prpc->msg_wol.wol_packet_type = 2U; /* Magic Packet */

Maybe add #defines for these magic numbers?

> +
> +		ether_addr_copy((u8 *)&prpc->msg_wol.wol_pattern, mac);
> +	} else {
> +		rpc_size = sizeof(prpc->msg_id) + sizeof(prpc->msg_del_id);
> +
> +		prpc->msg_id = HAL_ATLANTIC_UTILS_FW_MSG_WOL_DEL;
> +		prpc->msg_wol.pattern_id = 1U;
> +	}
> +
> +	err = hw_atl_utils_fw_rpc_call(self, rpc_size);
> +
> +err_exit:
> +	return err;
> +}

  Andrew

^ permalink raw reply


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