* [net 0/7][pull request] Intel Wired LAN Driver Fixes 2018-10-24
From: Jeff Kirsher @ 2018-10-24 21:47 UTC (permalink / raw)
To: davem; +Cc: Jeff Kirsher, netdev, nhorman, sassmann
This series contains fixes for the ice driver.
Anirudh fixes a namespace issue which was introduced with a previous
patch to remove ice_netpoll. Fixed up the device ID define names to
align with the branding string names. Use the capability count returned
by the firmware, instead of calculating the count. Introduced driver
workarounds due to current firmware limitations. Fixed the queue
mapping for a VF, which needs to be set in the config and scatter queue
modes. Fixed the driver which is setup to handle link status events
(LSE), even though the firmware does not have this feature yet, so add
the ability to poll for link status changes while we wait for updated
firmware.
The following are changes since commit 44adbac8f7217040be97928cd19998259d9d4418:
Merge branch 'work.tty-ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue 100GbE
Anirudh Venkataramanan (7):
ice: Make ice_msix_clean_rings static
ice: Change device ID define names to align with branding string
ice: Update expected FW version
ice: Use capability count returned by the firmware
ice: Introduce ice_dev_onetime_setup
ice: Allocate VF interrupts and set queue map
ice: Poll for link status change
drivers/net/ethernet/intel/ice/ice_common.c | 52 ++++----
drivers/net/ethernet/intel/ice/ice_common.h | 9 +-
drivers/net/ethernet/intel/ice/ice_controlq.h | 5 +-
drivers/net/ethernet/intel/ice/ice_devids.h | 6 +-
.../net/ethernet/intel/ice/ice_hw_autogen.h | 8 ++
drivers/net/ethernet/intel/ice/ice_lib.c | 3 +-
drivers/net/ethernet/intel/ice/ice_lib.h | 1 -
drivers/net/ethernet/intel/ice/ice_main.c | 116 ++++--------------
.../net/ethernet/intel/ice/ice_virtchnl_pf.c | 15 ++-
9 files changed, 77 insertions(+), 138 deletions(-)
--
2.17.2
^ permalink raw reply
* [net 6/7] ice: Allocate VF interrupts and set queue map
From: Jeff Kirsher @ 2018-10-24 21:47 UTC (permalink / raw)
To: davem; +Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, Jeff Kirsher
In-Reply-To: <20181024214731.26036-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Allocate VF interrupts using VPINT_ALLOC_PCI. Multiple interrupts are
specified as a range from "first" to "last".
Also, according to the spec, the queue mapping for a VF needs to be set
in both contig and scatter queue modes. So make this change as well.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_hw_autogen.h | 6 ++++++
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c | 15 +++++++++++----
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
index 228afcad6fc3..5fdea6ec7675 100644
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
@@ -157,6 +157,12 @@
#define VPINT_ALLOC_LAST_S 12
#define VPINT_ALLOC_LAST_M ICE_M(0x7FF, 12)
#define VPINT_ALLOC_VALID_M BIT(31)
+#define VPINT_ALLOC_PCI(_VF) (0x0009D000 + ((_VF) * 4))
+#define VPINT_ALLOC_PCI_FIRST_S 0
+#define VPINT_ALLOC_PCI_FIRST_M ICE_M(0x7FF, 0)
+#define VPINT_ALLOC_PCI_LAST_S 12
+#define VPINT_ALLOC_PCI_LAST_M ICE_M(0x7FF, 12)
+#define VPINT_ALLOC_PCI_VALID_M BIT(31)
#define GLLAN_RCTL_0 0x002941F8
#define QRX_CONTEXT(_i, _QRX) (0x00280000 + ((_i) * 8192 + (_QRX) * 4))
#define QRX_CTRL(_QRX) (0x00120000 + ((_QRX) * 4))
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
index c25e486706f3..45f10f8f01dc 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
@@ -173,6 +173,7 @@ static void ice_dis_vf_mappings(struct ice_vf *vf)
vsi = pf->vsi[vf->lan_vsi_idx];
wr32(hw, VPINT_ALLOC(vf->vf_id), 0);
+ wr32(hw, VPINT_ALLOC_PCI(vf->vf_id), 0);
first = vf->first_vector_idx;
last = first + pf->num_vf_msix - 1;
@@ -519,6 +520,10 @@ static void ice_ena_vf_mappings(struct ice_vf *vf)
VPINT_ALLOC_VALID_M);
wr32(hw, VPINT_ALLOC(vf->vf_id), reg);
+ reg = (((first << VPINT_ALLOC_PCI_FIRST_S) & VPINT_ALLOC_PCI_FIRST_M) |
+ ((last << VPINT_ALLOC_PCI_LAST_S) & VPINT_ALLOC_PCI_LAST_M) |
+ VPINT_ALLOC_PCI_VALID_M);
+ wr32(hw, VPINT_ALLOC_PCI(vf->vf_id), reg);
/* map the interrupts to its functions */
for (v = first; v <= last; v++) {
reg = (((abs_vf_id << GLINT_VECT2FUNC_VF_NUM_S) &
@@ -528,10 +533,11 @@ static void ice_ena_vf_mappings(struct ice_vf *vf)
wr32(hw, GLINT_VECT2FUNC(v), reg);
}
+ /* set regardless of mapping mode */
+ wr32(hw, VPLAN_TXQ_MAPENA(vf->vf_id), VPLAN_TXQ_MAPENA_TX_ENA_M);
+
/* VF Tx queues allocation */
if (vsi->tx_mapping_mode == ICE_VSI_MAP_CONTIG) {
- wr32(hw, VPLAN_TXQ_MAPENA(vf->vf_id),
- VPLAN_TXQ_MAPENA_TX_ENA_M);
/* set the VF PF Tx queue range
* VFNUMQ value should be set to (number of queues - 1). A value
* of 0 means 1 queue and a value of 255 means 256 queues
@@ -546,10 +552,11 @@ static void ice_ena_vf_mappings(struct ice_vf *vf)
"Scattered mode for VF Tx queues is not yet implemented\n");
}
+ /* set regardless of mapping mode */
+ wr32(hw, VPLAN_RXQ_MAPENA(vf->vf_id), VPLAN_RXQ_MAPENA_RX_ENA_M);
+
/* VF Rx queues allocation */
if (vsi->rx_mapping_mode == ICE_VSI_MAP_CONTIG) {
- wr32(hw, VPLAN_RXQ_MAPENA(vf->vf_id),
- VPLAN_RXQ_MAPENA_RX_ENA_M);
/* set the VF PF Rx queue range
* VFNUMQ value should be set to (number of queues - 1). A value
* of 0 means 1 queue and a value of 255 means 256 queues
--
2.17.2
^ permalink raw reply related
* [net 2/7] ice: Change device ID define names to align with branding string
From: Jeff Kirsher @ 2018-10-24 21:47 UTC (permalink / raw)
To: davem; +Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, Jeff Kirsher
In-Reply-To: <20181024214731.26036-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Basically remove references to C810 and use E810C (from the branding
string) instead.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_devids.h | 6 +++---
drivers/net/ethernet/intel/ice/ice_main.c | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_devids.h b/drivers/net/ethernet/intel/ice/ice_devids.h
index a6f0a5c0c305..f8d5c661d0ba 100644
--- a/drivers/net/ethernet/intel/ice/ice_devids.h
+++ b/drivers/net/ethernet/intel/ice/ice_devids.h
@@ -6,10 +6,10 @@
/* Device IDs */
/* Intel(R) Ethernet Controller E810-C for backplane */
-#define ICE_DEV_ID_C810_BACKPLANE 0x1591
+#define ICE_DEV_ID_E810C_BACKPLANE 0x1591
/* Intel(R) Ethernet Controller E810-C for QSFP */
-#define ICE_DEV_ID_C810_QSFP 0x1592
+#define ICE_DEV_ID_E810C_QSFP 0x1592
/* Intel(R) Ethernet Controller E810-C for SFP */
-#define ICE_DEV_ID_C810_SFP 0x1593
+#define ICE_DEV_ID_E810C_SFP 0x1593
#endif /* _ICE_DEVIDS_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 8f61b375e768..0084b7290b2b 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -2271,9 +2271,9 @@ static void ice_remove(struct pci_dev *pdev)
* Class, Class Mask, private data (not used) }
*/
static const struct pci_device_id ice_pci_tbl[] = {
- { PCI_VDEVICE(INTEL, ICE_DEV_ID_C810_BACKPLANE), 0 },
- { PCI_VDEVICE(INTEL, ICE_DEV_ID_C810_QSFP), 0 },
- { PCI_VDEVICE(INTEL, ICE_DEV_ID_C810_SFP), 0 },
+ { PCI_VDEVICE(INTEL, ICE_DEV_ID_E810C_BACKPLANE), 0 },
+ { PCI_VDEVICE(INTEL, ICE_DEV_ID_E810C_QSFP), 0 },
+ { PCI_VDEVICE(INTEL, ICE_DEV_ID_E810C_SFP), 0 },
/* required last entry */
{ 0, }
};
--
2.17.2
^ permalink raw reply related
* [net 3/7] ice: Update expected FW version
From: Jeff Kirsher @ 2018-10-24 21:47 UTC (permalink / raw)
To: davem; +Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, Jeff Kirsher
In-Reply-To: <20181024214731.26036-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Update to the current firmware major and minor version which are
1 and 3 respectively.
Also remove an empty comment line.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_controlq.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.h b/drivers/net/ethernet/intel/ice/ice_controlq.h
index 437f832fd7c4..0038a4109c99 100644
--- a/drivers/net/ethernet/intel/ice/ice_controlq.h
+++ b/drivers/net/ethernet/intel/ice/ice_controlq.h
@@ -19,11 +19,10 @@
/* Defines that help manage the driver vs FW API checks.
* Take a look at ice_aq_ver_check in ice_controlq.c for actual usage.
- *
*/
#define EXP_FW_API_VER_BRANCH 0x00
-#define EXP_FW_API_VER_MAJOR 0x00
-#define EXP_FW_API_VER_MINOR 0x01
+#define EXP_FW_API_VER_MAJOR 0x01
+#define EXP_FW_API_VER_MINOR 0x03
/* Different control queue types: These are mainly for SW consumption. */
enum ice_ctl_q {
--
2.17.2
^ permalink raw reply related
* [net 5/7] ice: Introduce ice_dev_onetime_setup
From: Jeff Kirsher @ 2018-10-24 21:47 UTC (permalink / raw)
To: davem; +Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, Jeff Kirsher
In-Reply-To: <20181024214731.26036-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
ice_dev_onetime_setup contains a couple of driver workarounds for current
firmware limitations. These workarounds are expected to go away once
these limitations are fixed in the firmware.
On a firmware release that has these issues addressed, these workarounds
(while unnecessary) will not break anything.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_common.c | 19 +++++++++++++++++++
drivers/net/ethernet/intel/ice/ice_common.h | 3 +++
.../net/ethernet/intel/ice/ice_hw_autogen.h | 2 ++
drivers/net/ethernet/intel/ice/ice_lib.c | 1 +
4 files changed, 25 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 78df54b25bf1..5a91a9087d1e 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -42,6 +42,23 @@ static enum ice_status ice_set_mac_type(struct ice_hw *hw)
return 0;
}
+/**
+ * ice_dev_onetime_setup - Temporary HW/FW workarounds
+ * @hw: pointer to the HW structure
+ *
+ * This function provides temporary workarounds for certain issues
+ * that are expected to be fixed in the HW/FW.
+ */
+void ice_dev_onetime_setup(struct ice_hw *hw)
+{
+ /* configure Rx - set non pxe mode */
+ wr32(hw, GLLAN_RCTL_0, 0x1);
+
+#define MBX_PF_VT_PFALLOC 0x00231E80
+ /* set VFs per PF */
+ wr32(hw, MBX_PF_VT_PFALLOC, rd32(hw, PF_VT_PFALLOC_HIF));
+}
+
/**
* ice_clear_pf_cfg - Clear PF configuration
* @hw: pointer to the hardware structure
@@ -740,6 +757,8 @@ enum ice_status ice_init_hw(struct ice_hw *hw)
if (status)
goto err_unroll_sched;
+ ice_dev_onetime_setup(hw);
+
/* Get MAC information */
/* A single port can report up to two (LAN and WoL) addresses */
mac_buf = devm_kcalloc(ice_hw_to_dev(hw), 2,
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
index 1900681289a4..876347e32b6f 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.h
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
@@ -34,6 +34,9 @@ ice_sq_send_cmd(struct ice_hw *hw, struct ice_ctl_q_info *cq,
struct ice_sq_cd *cd);
void ice_clear_pxe_mode(struct ice_hw *hw);
enum ice_status ice_get_caps(struct ice_hw *hw);
+
+void ice_dev_onetime_setup(struct ice_hw *hw);
+
enum ice_status
ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
u32 rxq_index);
diff --git a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
index a6679a9bfd3a..228afcad6fc3 100644
--- a/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
+++ b/drivers/net/ethernet/intel/ice/ice_hw_autogen.h
@@ -157,6 +157,7 @@
#define VPINT_ALLOC_LAST_S 12
#define VPINT_ALLOC_LAST_M ICE_M(0x7FF, 12)
#define VPINT_ALLOC_VALID_M BIT(31)
+#define GLLAN_RCTL_0 0x002941F8
#define QRX_CONTEXT(_i, _QRX) (0x00280000 + ((_i) * 8192 + (_QRX) * 4))
#define QRX_CTRL(_QRX) (0x00120000 + ((_QRX) * 4))
#define QRX_CTRL_MAX_INDEX 2047
@@ -320,6 +321,7 @@
#define GLV_UPRCL(_i) (0x003B2000 + ((_i) * 8))
#define GLV_UPTCH(_i) (0x0030A004 + ((_i) * 8))
#define GLV_UPTCL(_i) (0x0030A000 + ((_i) * 8))
+#define PF_VT_PFALLOC_HIF 0x0009DD80
#define VSIQF_HKEY_MAX_INDEX 12
#define VSIQF_HLUT_MAX_INDEX 15
#define VFINT_DYN_CTLN(_i) (0x00003800 + ((_i) * 4))
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index e750702bcdce..5bacad01f0c9 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -2529,6 +2529,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
vsi->hw_base_vector = 0;
ice_vsi_clear_rings(vsi);
ice_vsi_free_arrays(vsi, false);
+ ice_dev_onetime_setup(&vsi->back->hw);
ice_vsi_set_num_qs(vsi);
/* Initialize VSI struct elements and create VSI in FW */
--
2.17.2
^ permalink raw reply related
* [net 4/7] ice: Use capability count returned by the firmware
From: Jeff Kirsher @ 2018-10-24 21:47 UTC (permalink / raw)
To: davem; +Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, Jeff Kirsher
In-Reply-To: <20181024214731.26036-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
The firmware now returns the capability count in the command buffer.
Use it.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_common.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index c52f450f2c0d..78df54b25bf1 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -1531,9 +1531,7 @@ ice_aq_discover_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
if (!status)
ice_parse_caps(hw, buf, le32_to_cpu(cmd->count), opc);
else if (hw->adminq.sq_last_status == ICE_AQ_RC_ENOMEM)
- *cap_count =
- DIV_ROUND_UP(le16_to_cpu(desc.datalen),
- sizeof(struct ice_aqc_list_caps_elem));
+ *cap_count = le32_to_cpu(cmd->count);
return status;
}
--
2.17.2
^ permalink raw reply related
* [net 7/7] ice: Poll for link status change
From: Jeff Kirsher @ 2018-10-24 21:47 UTC (permalink / raw)
To: davem; +Cc: Anirudh Venkataramanan, netdev, nhorman, sassmann, Jeff Kirsher
In-Reply-To: <20181024214731.26036-1-jeffrey.t.kirsher@intel.com>
From: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
When the physical link goes up or down, the driver is supposed to
receive a link status event (LSE). The driver currently has the code
to handle LSEs but there is no firmware support for this feature yet.
So this patch adds the ability for the driver to poll for link status
changes. The polling itself is done in ice_watchdog_subtask.
For namespace cleanliness, this patch also removes code that handles
LSE. This code will be reintroduced once the feature is officially
supported.
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/ice/ice_common.c | 29 +-----
drivers/net/ethernet/intel/ice/ice_common.h | 6 --
drivers/net/ethernet/intel/ice/ice_main.c | 110 +++++---------------
3 files changed, 25 insertions(+), 120 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index 5a91a9087d1e..8cd6a2401fd9 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -235,7 +235,7 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
*
* Get Link Status (0x607). Returns the link status of the adapter.
*/
-enum ice_status
+static enum ice_status
ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
struct ice_link_status *link, struct ice_sq_cd *cd)
{
@@ -2004,33 +2004,6 @@ ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
}
-/**
- * ice_aq_set_event_mask
- * @hw: pointer to the hw struct
- * @port_num: port number of the physical function
- * @mask: event mask to be set
- * @cd: pointer to command details structure or NULL
- *
- * Set event mask (0x0613)
- */
-enum ice_status
-ice_aq_set_event_mask(struct ice_hw *hw, u8 port_num, u16 mask,
- struct ice_sq_cd *cd)
-{
- struct ice_aqc_set_event_mask *cmd;
- struct ice_aq_desc desc;
-
- cmd = &desc.params.set_event_mask;
-
- ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_event_mask);
-
- cmd->lport_num = port_num;
-
- cmd->event_mask = cpu_to_le16(mask);
-
- return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
-}
-
/**
* __ice_aq_get_set_rss_lut
* @hw: pointer to the hardware structure
diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h
index 876347e32b6f..cf760c24a6aa 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.h
+++ b/drivers/net/ethernet/intel/ice/ice_common.h
@@ -86,12 +86,6 @@ enum ice_status
ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
struct ice_sq_cd *cd);
enum ice_status
-ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
- struct ice_link_status *link, struct ice_sq_cd *cd);
-enum ice_status
-ice_aq_set_event_mask(struct ice_hw *hw, u8 port_num, u16 mask,
- struct ice_sq_cd *cd);
-enum ice_status
ice_dis_vsi_txq(struct ice_port_info *pi, u8 num_queues, u16 *q_ids,
u32 *q_teids, enum ice_disq_rst_src rst_src, u16 vmvf_num,
struct ice_sq_cd *cmd_details);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 0084b7290b2b..05993451147a 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -456,35 +456,6 @@ static void ice_reset_subtask(struct ice_pf *pf)
}
}
-/**
- * ice_watchdog_subtask - periodic tasks not using event driven scheduling
- * @pf: board private structure
- */
-static void ice_watchdog_subtask(struct ice_pf *pf)
-{
- int i;
-
- /* if interface is down do nothing */
- if (test_bit(__ICE_DOWN, pf->state) ||
- test_bit(__ICE_CFG_BUSY, pf->state))
- return;
-
- /* make sure we don't do these things too often */
- if (time_before(jiffies,
- pf->serv_tmr_prev + pf->serv_tmr_period))
- return;
-
- pf->serv_tmr_prev = jiffies;
-
- /* Update the stats for active netdevs so the network stack
- * can look at updated numbers whenever it cares to
- */
- ice_update_pf_stats(pf);
- for (i = 0; i < pf->num_alloc_vsi; i++)
- if (pf->vsi[i] && pf->vsi[i]->netdev)
- ice_update_vsi_stats(pf->vsi[i]);
-}
-
/**
* ice_print_link_msg - print link up or down message
* @vsi: the VSI whose link status is being queried
@@ -554,36 +525,6 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup)
speed, fc);
}
-/**
- * ice_init_link_events - enable/initialize link events
- * @pi: pointer to the port_info instance
- *
- * Returns -EIO on failure, 0 on success
- */
-static int ice_init_link_events(struct ice_port_info *pi)
-{
- u16 mask;
-
- mask = ~((u16)(ICE_AQ_LINK_EVENT_UPDOWN | ICE_AQ_LINK_EVENT_MEDIA_NA |
- ICE_AQ_LINK_EVENT_MODULE_QUAL_FAIL));
-
- if (ice_aq_set_event_mask(pi->hw, pi->lport, mask, NULL)) {
- dev_dbg(ice_hw_to_dev(pi->hw),
- "Failed to set link event mask for port %d\n",
- pi->lport);
- return -EIO;
- }
-
- if (ice_aq_get_link_info(pi, true, NULL, NULL)) {
- dev_dbg(ice_hw_to_dev(pi->hw),
- "Failed to enable link events for port %d\n",
- pi->lport);
- return -EIO;
- }
-
- return 0;
-}
-
/**
* ice_vsi_link_event - update the vsi's netdev
* @vsi: the vsi on which the link event occurred
@@ -671,27 +612,35 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi)
}
/**
- * ice_handle_link_event - handle link event via ARQ
- * @pf: pf that the link event is associated with
- *
- * Return -EINVAL if port_info is null
- * Return status on succes
+ * ice_watchdog_subtask - periodic tasks not using event driven scheduling
+ * @pf: board private structure
*/
-static int ice_handle_link_event(struct ice_pf *pf)
+static void ice_watchdog_subtask(struct ice_pf *pf)
{
- struct ice_port_info *port_info;
- int status;
+ int i;
- port_info = pf->hw.port_info;
- if (!port_info)
- return -EINVAL;
+ /* if interface is down do nothing */
+ if (test_bit(__ICE_DOWN, pf->state) ||
+ test_bit(__ICE_CFG_BUSY, pf->state))
+ return;
- status = ice_link_event(pf, port_info);
- if (status)
- dev_dbg(&pf->pdev->dev,
- "Could not process link event, error %d\n", status);
+ /* make sure we don't do these things too often */
+ if (time_before(jiffies,
+ pf->serv_tmr_prev + pf->serv_tmr_period))
+ return;
- return status;
+ pf->serv_tmr_prev = jiffies;
+
+ if (ice_link_event(pf, pf->hw.port_info))
+ dev_dbg(&pf->pdev->dev, "ice_link_event failed\n");
+
+ /* Update the stats for active netdevs so the network stack
+ * can look at updated numbers whenever it cares to
+ */
+ ice_update_pf_stats(pf);
+ for (i = 0; i < pf->num_alloc_vsi; i++)
+ if (pf->vsi[i] && pf->vsi[i]->netdev)
+ ice_update_vsi_stats(pf->vsi[i]);
}
/**
@@ -797,11 +746,6 @@ static int __ice_clean_ctrlq(struct ice_pf *pf, enum ice_ctl_q q_type)
opcode = le16_to_cpu(event.desc.opcode);
switch (opcode) {
- case ice_aqc_opc_get_link_status:
- if (ice_handle_link_event(pf))
- dev_err(&pf->pdev->dev,
- "Could not handle link event\n");
- break;
case ice_mbx_opc_send_msg_to_pf:
ice_vc_process_vf_msg(pf, &event);
break;
@@ -2207,12 +2151,6 @@ static int ice_probe(struct pci_dev *pdev,
/* since everything is good, start the service timer */
mod_timer(&pf->serv_tmr, round_jiffies(jiffies + pf->serv_tmr_period));
- err = ice_init_link_events(pf->hw.port_info);
- if (err) {
- dev_err(&pdev->dev, "ice_init_link_events failed: %d\n", err);
- goto err_alloc_sw_unroll;
- }
-
return 0;
err_alloc_sw_unroll:
--
2.17.2
^ permalink raw reply related
* Re: [PATCH] r8169: Add new device ID support
From: Heiner Kallweit @ 2018-10-24 21:44 UTC (permalink / raw)
To: David Miller, shawn.lin; +Cc: nic_swsd, netdev
In-Reply-To: <20181024.142234.2286757776208469261.davem@davemloft.net>
On 24.10.2018 23:22, David Miller wrote:
> From: Shawn Lin <shawn.lin@rock-chips.com>
> Date: Wed, 24 Oct 2018 09:46:47 +0800
>
>> It's found my r8169 ethernet card at hand has a device ID
>> of 0x0000 which wasn't on the list of rtl8169_pci_tbl. Add
>> a new entry to make it work:
>>
>> [2.165785] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
>> [2.165863] r8169 0000:01:00.0: enabling device (0000 -> 0003)
>> [2.167110] r8169 0000:01:00.0 eth0: RTL8168c/8111c at 0xffffff80089be000,
>> 00:e0:4c:21:00:17, XID 1c4000c0 IRQ 208
>> [2.167128] r8169 0000:01:00.0 eth0: jumbo features [frames: 6128
>> bytes, tx checksumming: ko]
>>
>> [root@rk1808:/]# lspci
>> 00:00.0 Class 0604: 1d87:1808
>> 01:00.0 Class 0200: 10ec:0000
>>
>> Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
>
> I'm stil not terribly confident in this change, a device ID of zero is
> really unusual.
>
> Heiner, what do you think?
>
A PCI device ID of zero definitely is a mistake of the card vendor.
Or maybe the card was just a sample and not meant to retail?
If some vendor of cards with a different Realtek network chip makes
the same mistake, then we're in trouble. I don't think we should
accept this risk just to support a broken ancient card.
This card most likely is at least 10 years old, and that we get the
first report only now seems to indicate that it's not something
affecting a lot of people.
The reporter found a way to make the card work on his system,
so I don't see a need for any further action.
^ permalink raw reply
* [PATCH net] net: ethernet: cadence: fix socket buffer corruption problem
From: Tristram.Ha @ 2018-10-24 21:51 UTC (permalink / raw)
To: David S. Miller, Nicolas Ferre; +Cc: Tristram Ha, UNGLinuxDriver, netdev
From: Tristram Ha <Tristram.Ha@microchip.com>
Socket buffer is not re-created when headroom is 2 and tailroom is 1.
Signed-off-by: Tristram Ha <Tristram.Ha@microchip.com>
---
drivers/net/ethernet/cadence/macb_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 8f5bf91..1d86b4d 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1684,7 +1684,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
padlen = 0;
/* No room for FCS, need to reallocate skb. */
else
- padlen = ETH_FCS_LEN - tailroom;
+ padlen = ETH_FCS_LEN;
} else {
/* Add room for FCS. */
padlen += ETH_FCS_LEN;
--
1.9.1
^ permalink raw reply related
* Re: [PATCH bpf 7/7] bpf: make direct packet write unclone more robust
From: Daniel Borkmann @ 2018-10-24 22:08 UTC (permalink / raw)
To: Song Liu; +Cc: Alexei Starovoitov, Networking
In-Reply-To: <CAPhsuW4V46Hi=q_fSma3mgji_JQxhjjpa1hPEtEGjE_WvEamhg@mail.gmail.com>
On 10/24/2018 11:42 PM, Song Liu wrote:
> On Wed, Oct 24, 2018 at 1:06 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
>>
>> Given this seems to be quite fragile and can easily slip through the
>> cracks, lets make direct packet write more robust by requiring that
>> future program types which allow for such write must provide a prologue
>> callback. In case of XDP and sk_msg it's noop, thus add a generic noop
>> handler there. The latter starts out with NULL data/data_end unconditionally
>> when sg pages are shared.
>>
>> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
>> Acked-by: Alexei Starovoitov <ast@kernel.org>
>> ---
>> kernel/bpf/verifier.c | 6 +++++-
>> net/core/filter.c | 11 +++++++++++
>> 2 files changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 5fc9a65..171a2c8 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -5709,7 +5709,11 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
>> bool is_narrower_load;
>> u32 target_size;
>>
>> - if (ops->gen_prologue) {
>> + if (ops->gen_prologue || env->seen_direct_write) {
>> + if (!ops->gen_prologue) {
>> + verbose(env, "bpf verifier is misconfigured\n");
>> + return -EINVAL;
>> + }
>
> nit: how about this?
>
> diff --git i/kernel/bpf/verifier.c w/kernel/bpf/verifier.c
> index 6fbe7a8afed7..d35078024e35 100644
> --- i/kernel/bpf/verifier.c
> +++ w/kernel/bpf/verifier.c
> @@ -5286,6 +5286,11 @@ static int convert_ctx_accesses(struct
> bpf_verifier_env *env)
> bool is_narrower_load;
> u32 target_size;
>
> + if (!ops->gen_prologue && env->seen_direct_write) {
> + verbose(env, "bpf verifier is misconfigured\n");
> + return -EINVAL;
> + }
> +
> if (ops->gen_prologue) {
> cnt = ops->gen_prologue(insn_buf, env->seen_direct_write,
> env->prog);
>
Hm, probably matter of different style preference, personally I'd prefer
the one as is though.
Thanks,
Daniel
^ permalink raw reply
* Re: [PATCH bpf 6/7] bpf: fix leaking uninitialized memory on pop/peek helpers
From: Mauricio Vasquez @ 2018-10-24 22:08 UTC (permalink / raw)
To: Daniel Borkmann, ast; +Cc: netdev
In-Reply-To: <20181024200549.8516-7-daniel@iogearbox.net>
On 10/24/18 3:05 PM, Daniel Borkmann wrote:
> Commit f1a2e44a3aec ("bpf: add queue and stack maps") added helpers
> with ARG_PTR_TO_UNINIT_MAP_VALUE. Meaning, the helper is supposed to
> fill the map value buffer with data instead of reading from it like
> in other helpers such as map update. However, given the buffer is
> allowed to be uninitialized (since we fill it in the helper anyway),
> it also means that the helper is obliged to wipe the memory in case
> of an error in order to not allow for leaking uninitialized memory.
> Given pop/peek is both handled inside __{stack,queue}_map_get(),
> lets wipe it there on error case, that is, empty stack/queue.
>
> Fixes: f1a2e44a3aec ("bpf: add queue and stack maps")
> Signed-off-by: Daniel Borkmann<daniel@iogearbox.net>
> Acked-by: Alexei Starovoitov<ast@kernel.org>
> Cc: Mauricio Vasquez B<mauricio.vasquez@polito.it>
Thanks for the fix Daniel.
Acked-by: Mauricio Vasquez B<mauricio.vasquez@polito.it>
^ permalink raw reply
* [PATCH net-next 1/4] net: core: dev_addr_lists: add auxiliary func to handle reference address updates
From: Ivan Khoronzhuk @ 2018-10-24 22:10 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, alexander.h.duyck, bjorn,
Ivan Khoronzhuk
In-Reply-To: <20181024221059.21834-1-ivan.khoronzhuk@linaro.org>
In order to avoid all table update, and only remove or add new
address, the auxiliary function exists, named __hw_addr_sync_dev().
It allows end driver do nothing when nothing changed and add/rm when
concrete address is firstly added or lastly removed. But it doesn't
include cases when an address of real device or vlan was reused by
other vlans or vlan/macval devices.
For handaling events when address was reused/unreused the patch adds
new auxiliary routine - __hw_addr_ref_sync_dev(). It allows to do
nothing when nothing was changed and do updates only for an address
being added/reused/deleted/unreused. Thus, clone address changes for
vlans can be mirrored in the table. The function is exclusive with
__hw_addr_sync_dev(). It's responsibility of the end driver to
identify address vlan device, if it needs so.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
include/linux/netdevice.h | 10 ++++
net/core/dev_addr_lists.c | 97 +++++++++++++++++++++++++++++++++++++++
2 files changed, 107 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index dc1d9ed33b31..de95f96a6352 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4048,6 +4048,16 @@ int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
int (*sync)(struct net_device *, const unsigned char *),
int (*unsync)(struct net_device *,
const unsigned char *));
+int __hw_addr_ref_sync_dev(struct netdev_hw_addr_list *list,
+ struct net_device *dev,
+ int (*sync)(struct net_device *,
+ const unsigned char *, int),
+ int (*unsync)(struct net_device *,
+ const unsigned char *, int));
+void __hw_addr_ref_unsync_dev(struct netdev_hw_addr_list *list,
+ struct net_device *dev,
+ int (*unsync)(struct net_device *,
+ const unsigned char *, int));
void __hw_addr_unsync_dev(struct netdev_hw_addr_list *list,
struct net_device *dev,
int (*unsync)(struct net_device *,
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index d884d8f5f0e5..81a8cd4ea3bd 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -277,6 +277,103 @@ int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
}
EXPORT_SYMBOL(__hw_addr_sync_dev);
+/**
+ * __hw_addr_ref_sync_dev - Synchronize device's multicast address list taking
+ * into account references
+ * @list: address list to synchronize
+ * @dev: device to sync
+ * @sync: function to call if address or reference on it should be added
+ * @unsync: function to call if address or some reference on it should removed
+ *
+ * This function is intended to be called from the ndo_set_rx_mode
+ * function of devices that require explicit address or references on it
+ * add/remove notifications. The unsync function may be NULL in which case
+ * the addresses or references on it requiring removal will simply be
+ * removed without any notification to the device. That is responsibility of
+ * the driver to identify and distribute address or references on it between
+ * internal address tables.
+ **/
+int __hw_addr_ref_sync_dev(struct netdev_hw_addr_list *list,
+ struct net_device *dev,
+ int (*sync)(struct net_device *,
+ const unsigned char *, int),
+ int (*unsync)(struct net_device *,
+ const unsigned char *, int))
+{
+ struct netdev_hw_addr *ha, *tmp;
+ int err, ref_cnt;
+
+ /* first go through and flush out any unsynced/stale entries */
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ /* sync if address is not used */
+ if ((ha->sync_cnt << 1) <= ha->refcount)
+ continue;
+
+ /* if fails defer unsyncing address */
+ ref_cnt = ha->refcount - ha->sync_cnt;
+ if (unsync && unsync(dev, ha->addr, ref_cnt))
+ continue;
+
+ ha->refcount = (ref_cnt << 1) + 1;
+ ha->sync_cnt = ref_cnt;
+ __hw_addr_del_entry(list, ha, false, false);
+ }
+
+ /* go through and sync updated/new entries to the list */
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ /* sync if address added or reused */
+ if ((ha->sync_cnt << 1) >= ha->refcount)
+ continue;
+
+ ref_cnt = ha->refcount - ha->sync_cnt;
+ err = sync(dev, ha->addr, ref_cnt);
+ if (err)
+ return err;
+
+ ha->refcount = ref_cnt << 1;
+ ha->sync_cnt = ref_cnt;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(__hw_addr_ref_sync_dev);
+
+/**
+ * __hw_addr_ref_unsync_dev - Remove synchronized addresses and references on
+ * it from device
+ * @list: address list to remove synchronized addresses (references on it) from
+ * @dev: device to sync
+ * @unsync: function to call if address and references on it should be removed
+ *
+ * Remove all addresses that were added to the device by
+ * __hw_addr_ref_sync_dev(). This function is intended to be called from the
+ * ndo_stop or ndo_open functions on devices that require explicit address (or
+ * references on it) add/remove notifications. If the unsync function pointer
+ * is NULL then this function can be used to just reset the sync_cnt for the
+ * addresses in the list.
+ **/
+void __hw_addr_ref_unsync_dev(struct netdev_hw_addr_list *list,
+ struct net_device *dev,
+ int (*unsync)(struct net_device *,
+ const unsigned char *, int))
+{
+ struct netdev_hw_addr *ha, *tmp;
+
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ if (!ha->sync_cnt)
+ continue;
+
+ /* if fails defer unsyncing address */
+ if (unsync && unsync(dev, ha->addr, ha->sync_cnt))
+ continue;
+
+ ha->refcount -= ha->sync_cnt - 1;
+ ha->sync_cnt = 0;
+ __hw_addr_del_entry(list, ha, false, false);
+ }
+}
+EXPORT_SYMBOL(__hw_addr_ref_unsync_dev);
+
/**
* __hw_addr_unsync_dev - Remove synchronized addresses from device
* @list: address list to remove synchronized addresses from
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 2/4] net: 8021q: vlan_core: allow use list of vlans for real device
From: Ivan Khoronzhuk @ 2018-10-24 22:10 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, alexander.h.duyck, bjorn,
Ivan Khoronzhuk
In-Reply-To: <20181024221059.21834-1-ivan.khoronzhuk@linaro.org>
It's redundancy for the drivers to hold the list of vlans when
absolutely the same list exists in vlan core. In most cases it's
needed only to traverse the vlan devices, their vids and sync some
settings with h/w, so add API to simplify this.
At least some of these drivers also can benefit:
grep "for_each.*vid" -r drivers/net/ethernet/
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c:
drivers/net/ethernet/synopsys/dwc-xlgmac-hw.c:
drivers/net/ethernet/qlogic/qlge/qlge_main.c:
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c:
drivers/net/ethernet/via/via-rhine.c:
drivers/net/ethernet/via/via-velocity.c:
drivers/net/ethernet/intel/igb/igb_main.c:
drivers/net/ethernet/intel/ice/ice_main.c:
drivers/net/ethernet/intel/e1000/e1000_main.c:
drivers/net/ethernet/intel/i40e/i40e_main.c:
drivers/net/ethernet/intel/e1000e/netdev.c:
drivers/net/ethernet/intel/igbvf/netdev.c:
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c:
drivers/net/ethernet/intel/ixgb/ixgb_main.c:
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:
drivers/net/ethernet/amd/xgbe/xgbe-dev.c:
drivers/net/ethernet/emulex/benet/be_main.c:
drivers/net/ethernet/neterion/vxge/vxge-main.c:
drivers/net/ethernet/adaptec/starfire.c:
drivers/net/ethernet/brocade/bna/bnad.c:
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
include/linux/if_vlan.h | 11 +++++++++++
net/8021q/vlan_core.c | 27 +++++++++++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 83ea4df6ab81..410a14cd856c 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -133,6 +133,9 @@ struct vlan_pcpu_stats {
extern struct net_device *__vlan_find_dev_deep_rcu(struct net_device *real_dev,
__be16 vlan_proto, u16 vlan_id);
+extern int vlan_for_each(struct net_device *dev,
+ int (*action)(struct net_device *dev, int vid,
+ void *arg), void *arg);
extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
extern u16 vlan_dev_vlan_id(const struct net_device *dev);
extern __be16 vlan_dev_vlan_proto(const struct net_device *dev);
@@ -236,6 +239,14 @@ __vlan_find_dev_deep_rcu(struct net_device *real_dev,
return NULL;
}
+static inline int
+vlan_for_each(struct net_device *dev,
+ int (*action)(struct net_device *dev, int vid, void *arg),
+ void *arg)
+{
+ return 0;
+}
+
static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
{
BUG();
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 4f60e86f4b8d..6308b5427a66 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -223,6 +223,33 @@ static int vlan_kill_rx_filter_info(struct net_device *dev, __be16 proto, u16 vi
return -ENODEV;
}
+int vlan_for_each(struct net_device *dev,
+ int (*action)(struct net_device *dev, int vid, void *arg),
+ void *arg)
+{
+ struct vlan_vid_info *vid_info;
+ struct vlan_info *vlan_info;
+ struct net_device *vdev;
+ int ret;
+
+ ASSERT_RTNL();
+
+ vlan_info = rtnl_dereference(dev->vlan_info);
+ if (!vlan_info)
+ return 0;
+
+ list_for_each_entry(vid_info, &vlan_info->vid_list, list) {
+ vdev = vlan_group_get_device(&vlan_info->grp, vid_info->proto,
+ vid_info->vid);
+ ret = action(vdev, vid_info->vid, arg);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(vlan_for_each);
+
int vlan_filter_push_vids(struct vlan_info *vlan_info, __be16 proto)
{
struct net_device *real_dev = vlan_info->real_dev;
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 3/4] net: ethernet: ti: cpsw: fix vlan mcast
From: Ivan Khoronzhuk @ 2018-10-24 22:10 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, alexander.h.duyck, bjorn,
Ivan Khoronzhuk
In-Reply-To: <20181024221059.21834-1-ivan.khoronzhuk@linaro.org>
At this moment, mcast addresses are added for real device only
(reserved vlans for dual-emac mode), even if a mcast address was added
for some vlan only, thus ALE doesn't have corresponding vlan mcast
entries after vlan socket joined multicast group. So ALE drops vlan
frames with mcast addresses intended for vlans and potentially can
receive mcast frames for base ndev. That's not correct. So, fix it by
creating only vlan/mcast entries as requested. Patch doesn't use any
additional lists and is based on device mc address list and cpsw ALE
table entries.
In legacy switch mode ALE table can have untracked vlan addresses, it
can conflict with method used to delete vlan mcast addresses, so for
switch mode, do syncing as it is, leaving ability for a user to modify
table in usual for him sequence.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
drivers/net/ethernet/ti/cpsw.c | 195 +++++++++++++++++++++++++++------
1 file changed, 164 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 500f7ed8c58c..27e0a5d5ccf9 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -570,21 +570,6 @@ static inline int cpsw_get_slave_port(u32 slave_num)
return slave_num + 1;
}
-static void cpsw_add_mcast(struct cpsw_priv *priv, const u8 *addr)
-{
- struct cpsw_common *cpsw = priv->cpsw;
-
- if (cpsw->data.dual_emac) {
- struct cpsw_slave *slave = cpsw->slaves + priv->emac_port;
-
- cpsw_ale_add_mcast(cpsw->ale, addr, ALE_PORT_HOST,
- ALE_VLAN, slave->port_vlan, 0);
- return;
- }
-
- cpsw_ale_add_mcast(cpsw->ale, addr, ALE_ALL_PORTS, 0, 0, 0);
-}
-
static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
{
struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
@@ -640,7 +625,7 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
/* Clear all mcast from ALE */
cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS, -1);
- __dev_mc_unsync(ndev, NULL);
+ __hw_addr_ref_unsync_dev(&ndev->mc, ndev, NULL);
/* Flood All Unicast Packets to Host port */
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
@@ -661,29 +646,174 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
}
}
-static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr)
+static int cpsw_switch_mode(struct net_device *ndev)
{
- struct cpsw_priv *priv = netdev_priv(ndev);
+ struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
- cpsw_add_mcast(priv, addr);
- return 0;
+ return !(cpsw->data.dual_emac || cpsw->data.slaves == 1);
}
-static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr)
+struct addr_sync_ctx {
+ struct net_device *ndev;
+ const u8 *addr; /* address to be synched */
+ int consumed; /* number of address instances */
+ int flush; /* flush flag */
+};
+
+/**
+ * cpsw_set_mc - adds multicast entry to the table if it's not added or deletes
+ * if it's not deleted
+ * @ndev: device to sync
+ * @addr: address to be added or deleted
+ * @vid: vlan id, if vid < 0 set/unset address for real device
+ * @add: add address if the flag is set or remove otherwise
+ */
+static int cpsw_set_mc(struct net_device *ndev, const u8 *addr,
+ int vid, int add)
{
struct cpsw_priv *priv = netdev_priv(ndev);
struct cpsw_common *cpsw = priv->cpsw;
- int vid, flags;
+ int mask, flags, ret;
- if (cpsw->data.dual_emac) {
- vid = cpsw->slaves[priv->emac_port].port_vlan;
- flags = ALE_VLAN;
- } else {
- vid = 0;
- flags = 0;
+ if (vid < 0) {
+ if (cpsw->data.dual_emac)
+ vid = cpsw->slaves[priv->emac_port].port_vlan;
+ else
+ vid = 0;
+ }
+
+ mask = cpsw->data.dual_emac ? ALE_PORT_HOST : ALE_ALL_PORTS;
+ flags = vid ? ALE_VLAN : 0;
+
+ if (add)
+ ret = cpsw_ale_add_mcast(cpsw->ale, addr, mask, flags, vid, 0);
+ else
+ ret = cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid);
+
+ return ret;
+}
+
+static int cpsw_update_vlan_mc(struct net_device *vdev, int vid, void *ctx)
+{
+ struct addr_sync_ctx *sync_ctx = ctx;
+ struct netdev_hw_addr *ha;
+ int found = 0, ret = 0;
+
+ if (!vdev || !(vdev->flags & IFF_UP))
+ return 0;
+
+ /* vlan address is relevant if its sync_cnt != 0 */
+ netdev_for_each_mc_addr(ha, vdev) {
+ if (ether_addr_equal(ha->addr, sync_ctx->addr)) {
+ found = ha->sync_cnt;
+ break;
+ }
+ }
+
+ if (found)
+ sync_ctx->consumed++;
+
+ if (sync_ctx->flush) {
+ if (!found)
+ cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0);
+ return 0;
+ }
+
+ if (found)
+ ret = cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 1);
+
+ return ret;
+}
+
+static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr, int num)
+{
+ struct addr_sync_ctx sync_ctx;
+ int ret;
+
+ /* leave for legacy switch mode untracked ALE entries */
+ if (cpsw_switch_mode(ndev)) {
+ ret = cpsw_set_mc(ndev, addr, -1, 1);
+ return ret;
+ }
+
+ sync_ctx.consumed = 0;
+ sync_ctx.addr = addr;
+ sync_ctx.ndev = ndev;
+ sync_ctx.flush = 0;
+
+ ret = vlan_for_each(ndev, cpsw_update_vlan_mc, &sync_ctx);
+ if (sync_ctx.consumed < num && !ret)
+ ret = cpsw_set_mc(ndev, addr, -1, 1);
+
+ return ret;
+}
+
+static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr, int num)
+{
+ struct addr_sync_ctx sync_ctx;
+
+ /* leave for legacy switch mode untracked ALE entries */
+ if (cpsw_switch_mode(ndev)) {
+ if (!num)
+ cpsw_set_mc(ndev, addr, -1, 0);
+ return 0;
+ }
+
+ sync_ctx.consumed = 0;
+ sync_ctx.addr = addr;
+ sync_ctx.ndev = ndev;
+ sync_ctx.flush = 1;
+
+ vlan_for_each(ndev, cpsw_update_vlan_mc, &sync_ctx);
+ if (sync_ctx.consumed == num)
+ cpsw_set_mc(ndev, addr, -1, 0);
+
+ return 0;
+}
+
+static int cpsw_purge_vlan_mc(struct net_device *vdev, int vid, void *ctx)
+{
+ struct addr_sync_ctx *sync_ctx = ctx;
+ struct netdev_hw_addr *ha;
+ int found = 0;
+
+ if (!vdev || !(vdev->flags & IFF_UP))
+ return 0;
+
+ /* vlan address is relevant if its sync_cnt != 0 */
+ netdev_for_each_mc_addr(ha, vdev) {
+ if (ether_addr_equal(ha->addr, sync_ctx->addr)) {
+ found = ha->sync_cnt;
+ break;
+ }
}
- cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid);
+ if (!found)
+ return 0;
+
+ sync_ctx->consumed++;
+ cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0);
+ return 0;
+}
+
+static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
+{
+ struct addr_sync_ctx sync_ctx;
+
+ /* leave for legacy switch mode untracked ALE entries */
+ if (cpsw_switch_mode(ndev)) {
+ cpsw_set_mc(ndev, addr, -1, 0);
+ return 0;
+ }
+
+ sync_ctx.addr = addr;
+ sync_ctx.ndev = ndev;
+ sync_ctx.consumed = 0;
+
+ vlan_for_each(ndev, cpsw_purge_vlan_mc, &sync_ctx);
+ if (sync_ctx.consumed < num)
+ cpsw_set_mc(ndev, addr, -1, 0);
+
return 0;
}
@@ -704,7 +834,9 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
/* Restore allmulti on vlans if necessary */
cpsw_ale_set_allmulti(cpsw->ale, ndev->flags & IFF_ALLMULTI);
- __dev_mc_sync(ndev, cpsw_add_mc_addr, cpsw_del_mc_addr);
+ /* add/remove mcast address either for real netdev or for vlan */
+ __hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr,
+ cpsw_del_mc_addr);
}
static void cpsw_intr_enable(struct cpsw_common *cpsw)
@@ -1964,7 +2096,7 @@ static int cpsw_ndo_stop(struct net_device *ndev)
struct cpsw_common *cpsw = priv->cpsw;
cpsw_info(priv, ifdown, "shutting down cpsw device\n");
- __dev_mc_unsync(priv->ndev, cpsw_del_mc_addr);
+ __hw_addr_ref_unsync_dev(&ndev->mc, ndev, cpsw_purge_all_mc);
netif_tx_stop_all_queues(priv->ndev);
netif_carrier_off(priv->ndev);
@@ -2415,6 +2547,7 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,
HOST_PORT_NUM, ALE_VLAN, vid);
ret |= cpsw_ale_del_mcast(cpsw->ale, priv->ndev->broadcast,
0, ALE_VLAN, vid);
+ ret |= cpsw_ale_flush_multicast(cpsw->ale, 0, vid);
err:
pm_runtime_put(cpsw->dev);
return ret;
--
2.17.1
^ permalink raw reply related
* [PATCH net-next 4/4] net: ethernet: ti: cpsw: fix vlan configuration while down/up
From: Ivan Khoronzhuk @ 2018-10-24 22:10 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, alexander.h.duyck, bjorn,
Ivan Khoronzhuk
In-Reply-To: <20181024221059.21834-1-ivan.khoronzhuk@linaro.org>
The vlan configuration is not restored after interface donw/up sequence
(if dual-emac - both interfaces). Tested on am572x EVM.
Steps to check:
~# ip link add link eth1 name eth1.100 type vlan id 100
~# ifconfig eth0 down
~# ifconfig eth1 down
Try to remove vid and observe warning:
~# ip link del eth1.100
[ 739.526757] net eth1: removing vlanid 100 from vlan filter
[ 739.533322] failed to kill vid 0081/100 for device eth1
This patch fixes it, restoring only vlan ALE entries and all other
unicast/multicast entries are restored by system calling rx_mode ndo.
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
drivers/net/ethernet/ti/cpsw.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 27e0a5d5ccf9..a061a12e3022 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -565,6 +565,9 @@ static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
(func)(slave++, ##arg); \
} while (0)
+static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,
+ __be16 proto, u16 vid);
+
static inline int cpsw_get_slave_port(u32 slave_num)
{
return slave_num + 1;
@@ -1977,9 +1980,23 @@ static void cpsw_mqprio_resume(struct cpsw_slave *slave, struct cpsw_priv *priv)
slave_write(slave, tx_prio_map, tx_prio_rg);
}
+static int cpsw_restore_vlans(struct net_device *vdev, int vid, void *arg)
+{
+ struct cpsw_priv *priv = arg;
+
+ if (!vdev)
+ return 0;
+
+ cpsw_ndo_vlan_rx_add_vid(priv->ndev, 0, vid);
+ return 0;
+}
+
/* restore resources after port reset */
static void cpsw_restore(struct cpsw_priv *priv)
{
+ /* restore vlan configurations */
+ vlan_for_each(priv->ndev, cpsw_restore_vlans, priv);
+
/* restore MQPRIO offload */
for_each_slave(priv, cpsw_mqprio_resume, priv);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH bpf 5/7] bpf: fix direct packet write into pop/peek helpers
From: Mauricio Vasquez @ 2018-10-24 22:30 UTC (permalink / raw)
To: Daniel Borkmann, ast; +Cc: netdev
In-Reply-To: <20181024200549.8516-6-daniel@iogearbox.net>
On 10/24/18 3:05 PM, Daniel Borkmann wrote:
> Commit f1a2e44a3aec ("bpf: add queue and stack maps") probably just
> copy-pasted .pkt_access for bpf_map_{pop,peek}_elem() helpers, but
> this is buggy in this context since it would allow writes into cloned
> skbs which is invalid. Therefore, disable .pkt_access for the two.
>
> Fixes: f1a2e44a3aec ("bpf: add queue and stack maps")
> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> Acked-by: Alexei Starovoitov <ast@kernel.org>
> Cc: Mauricio Vasquez B <mauricio.vasquez@polito.it>
Thanks for this as well.
Acked-by: Mauricio Vasquez B<mauricio.vasquez@polito.it>
^ permalink raw reply
* Re: [net 0/7][pull request] Intel Wired LAN Driver Fixes 2018-10-24
From: David Miller @ 2018-10-24 23:28 UTC (permalink / raw)
To: jeffrey.t.kirsher; +Cc: netdev, nhorman, sassmann
In-Reply-To: <20181024214731.26036-1-jeffrey.t.kirsher@intel.com>
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 24 Oct 2018 14:47:24 -0700
> This series contains fixes for the ice driver.
>
> Anirudh fixes a namespace issue which was introduced with a previous
> patch to remove ice_netpoll. Fixed up the device ID define names to
> align with the branding string names. Use the capability count returned
> by the firmware, instead of calculating the count. Introduced driver
> workarounds due to current firmware limitations. Fixed the queue
> mapping for a VF, which needs to be set in the config and scatter queue
> modes. Fixed the driver which is setup to handle link status events
> (LSE), even though the firmware does not have this feature yet, so add
> the ability to poll for link status changes while we wait for updated
> firmware.
>
> The following are changes since commit 44adbac8f7217040be97928cd19998259d9d4418:
> Merge branch 'work.tty-ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
> and are available in the git repository at:
> git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue 100GbE
Pulled, thanks Jeff.
^ permalink raw reply
* Re: [PATCH bpf 7/7] bpf: make direct packet write unclone more robust
From: Song Liu @ 2018-10-24 23:36 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Alexei Starovoitov, Networking
In-Reply-To: <a851d791-8477-75aa-f0ca-0400c841f987@iogearbox.net>
On Wed, Oct 24, 2018 at 3:08 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> On 10/24/2018 11:42 PM, Song Liu wrote:
> > On Wed, Oct 24, 2018 at 1:06 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
> >>
> >> Given this seems to be quite fragile and can easily slip through the
> >> cracks, lets make direct packet write more robust by requiring that
> >> future program types which allow for such write must provide a prologue
> >> callback. In case of XDP and sk_msg it's noop, thus add a generic noop
> >> handler there. The latter starts out with NULL data/data_end unconditionally
> >> when sg pages are shared.
> >>
> >> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
> >> Acked-by: Alexei Starovoitov <ast@kernel.org>
> >> ---
> >> kernel/bpf/verifier.c | 6 +++++-
> >> net/core/filter.c | 11 +++++++++++
> >> 2 files changed, 16 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> >> index 5fc9a65..171a2c8 100644
> >> --- a/kernel/bpf/verifier.c
> >> +++ b/kernel/bpf/verifier.c
> >> @@ -5709,7 +5709,11 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
> >> bool is_narrower_load;
> >> u32 target_size;
> >>
> >> - if (ops->gen_prologue) {
> >> + if (ops->gen_prologue || env->seen_direct_write) {
> >> + if (!ops->gen_prologue) {
> >> + verbose(env, "bpf verifier is misconfigured\n");
> >> + return -EINVAL;
> >> + }
> >
> > nit: how about this?
> >
> > diff --git i/kernel/bpf/verifier.c w/kernel/bpf/verifier.c
> > index 6fbe7a8afed7..d35078024e35 100644
> > --- i/kernel/bpf/verifier.c
> > +++ w/kernel/bpf/verifier.c
> > @@ -5286,6 +5286,11 @@ static int convert_ctx_accesses(struct
> > bpf_verifier_env *env)
> > bool is_narrower_load;
> > u32 target_size;
> >
> > + if (!ops->gen_prologue && env->seen_direct_write) {
> > + verbose(env, "bpf verifier is misconfigured\n");
> > + return -EINVAL;
> > + }
> > +
> > if (ops->gen_prologue) {
> > cnt = ops->gen_prologue(insn_buf, env->seen_direct_write,
> > env->prog);
> >
>
> Hm, probably matter of different style preference, personally I'd prefer
> the one as is though.
Yeah, it is just a nitpick.
Thanks!
Acked-by: Song Liu <songliubraving@fb.com>
^ permalink raw reply
* Re: [PATCH 0/3] PM: Renesas: Remove dummy runtime PM callbacks
From: Wolfram Sang @ 2018-10-25 0:20 UTC (permalink / raw)
To: Jarkko Nikula, Magnus Damm
Cc: linux-pm, linux-i2c, Wolfram Sang, netdev, David S . Miller,
Sergei Shtylyov, linux-renesas-soc, linux-usb, Yoshihiro Shimoda
In-Reply-To: <20181024142200.GA5637@kunai>
[-- Attachment #1: Type: text/plain, Size: 313 bytes --]
> At least the I2C driver part of this was on my todo list as well (just a
> bit lower :/). I wanted to find out why they have been there in the
> first place. Do you know if such callbacks were needed "back in the
> days"?
I see now that you referenced the relevant commits in the patch
descriptions. Thanks!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH 1/2] Bluetooth: Add quirk for reading BD_ADDR from fwnode property
From: Matthias Kaehlcke @ 2018-10-25 0:21 UTC (permalink / raw)
To: Marcel Holtmann, Johan Hedberg, David S . Miller, Loic Poulain
Cc: linux-bluetooth, netdev, linux-kernel, Balakrishna Godavarthi,
Brian Norris, Dmitry Grinberg, Matthias Kaehlcke
In-Reply-To: <20181025002134.256791-1-mka@chromium.org>
Add HCI_QUIRK_USE_BDADDR_PROPERTY to allow controllers to retrieve
the public Bluetooth address from the firmware node property
'local-bd-address'. If quirk is set and the property does not exist
or is invalid the controller is marked as unconfigured.
Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
---
hci_dev_get_bd_addr_from_property() currently assumes that the
firmware node with 'local-bd-address' is from hdev->dev.parent, not
sure if this universally true. However if it is true for existing
device that might use this interface we can assume this for now
(unless there is a clear solution now), and cross the bridge of
finding an alternative when we actually encounter the situation.
One option could be to look for the first parent that has a fwnode.
---
include/net/bluetooth/hci.h | 12 +++++++++++
net/bluetooth/hci_core.c | 42 +++++++++++++++++++++++++++++++++++++
net/bluetooth/mgmt.c | 6 ++++--
3 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index cdd9f1fe7cfa..a5d748099752 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -158,6 +158,18 @@ enum {
*/
HCI_QUIRK_INVALID_BDADDR,
+ /* When this quirk is set, the public Bluetooth address
+ * initially reported by HCI Read BD Address command
+ * is considered invalid. The public BD Address can be
+ * specified in the fwnode property 'local-bd-address'.
+ * If this property does not exist or is invalid controller
+ * configuration is required before this device can be used.
+ *
+ * This quirk can be set before hci_register_dev is called or
+ * during the hdev->setup vendor callback.
+ */
+ HCI_QUIRK_USE_BDADDR_PROPERTY,
+
/* When this quirk is set, the duplicate filtering during
* scanning is based on Bluetooth devices addresses. To allow
* RSSI based updates, restart scanning if needed.
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 74b29c7d841c..97214262c4fb 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -30,6 +30,7 @@
#include <linux/rfkill.h>
#include <linux/debugfs.h>
#include <linux/crypto.h>
+#include <linux/property.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
@@ -1355,9 +1356,40 @@ int hci_inquiry(void __user *arg)
return err;
}
+/**
+ * hci_dev_get_bd_addr_from_property - Get the Bluetooth Device Address
+ * (BD_ADDR) for a HCI device from
+ * a firmware node property.
+ * @hdev: The HCI device
+ *
+ * Search the firmware node for 'local-bd-address'.
+ *
+ * All-zero BD addresses are rejected, because those could be properties
+ * that exist in the firmware tables, but were not updated by the firmware. For
+ * example, the DTS could define 'local-bd-address', with zero BD addresses.
+ */
+static int hci_dev_get_bd_addr_from_property(struct hci_dev *hdev)
+{
+ struct fwnode_handle *fwnode = dev_fwnode(hdev->dev.parent);
+ bdaddr_t ba;
+ int ret;
+
+ ret = fwnode_property_read_u8_array(fwnode, "local-bd-address",
+ (u8 *)&ba, sizeof(ba));
+ if (ret < 0)
+ return ret;
+ if (!bacmp(&ba, BDADDR_ANY))
+ return -ENODATA;
+
+ hdev->public_addr = ba;
+
+ return 0;
+}
+
static int hci_dev_do_open(struct hci_dev *hdev)
{
int ret = 0;
+ bool bd_addr_set = false;
BT_DBG("%s %p", hdev->name, hdev);
@@ -1422,6 +1454,16 @@ static int hci_dev_do_open(struct hci_dev *hdev)
if (hdev->setup)
ret = hdev->setup(hdev);
+ if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
+ if (!hci_dev_get_bd_addr_from_property(hdev))
+ if (hdev->set_bdaddr &&
+ !hdev->set_bdaddr(hdev, &hdev->public_addr))
+ bd_addr_set = true;
+
+ if (!bd_addr_set)
+ hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
+ }
+
/* The transport driver can set these quirks before
* creating the HCI device or in its setup callback.
*
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 3bdc8f3ca259..3d9edb752403 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -551,7 +551,8 @@ static bool is_configured(struct hci_dev *hdev)
!hci_dev_test_flag(hdev, HCI_EXT_CONFIGURED))
return false;
- if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
+ if ((test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) ||
+ test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) &&
!bacmp(&hdev->public_addr, BDADDR_ANY))
return false;
@@ -566,7 +567,8 @@ static __le32 get_missing_options(struct hci_dev *hdev)
!hci_dev_test_flag(hdev, HCI_EXT_CONFIGURED))
options |= MGMT_OPTION_EXTERNAL_CONFIG;
- if (test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) &&
+ if ((test_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks) ||
+ test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) &&
!bacmp(&hdev->public_addr, BDADDR_ANY))
options |= MGMT_OPTION_PUBLIC_ADDRESS;
--
2.19.1.568.g152ad8e336-goog
^ permalink raw reply related
* Re: [PATCH 1/4] mfd: altera-sysmgr: Add SOCFPGA System Manager
From: Lee Jones @ 2018-10-25 9:02 UTC (permalink / raw)
To: thor.thayer
Cc: peppe.cavallaro, dinguyen, linux, alexandre.torgue, joabreu,
davem, mchehab+samsung, catalin.marinas, akpm, arnd, aisheng.dong,
linux-kernel, netdev, linux-arm-kernel
In-Reply-To: <1537826946-18942-2-git-send-email-thor.thayer@linux.intel.com>
Arnd,
Would you be so kind as to look at this please?
On Mon, 24 Sep 2018, thor.thayer@linux.intel.com wrote:
> From: Thor Thayer <thor.thayer@linux.intel.com>
>
> The SOCFPGA System Manager register block aggregates different
> peripheral functions into one area.
> On 32 bit ARM parts, the syscon driver is used for accesses.
> On 64 bit ARM parts, the System Manager can only be accessed by
> EL3 secure mode. Since a SMC call to EL3 is required, this new
> driver uses regmaps similar to syscon to handle the SMC call.
>
> Since regmaps abstract out the underlying register access, the
> changes to drivers accessing the System Manager are minimal.
>
> Signed-off-by: Thor Thayer <thor.thayer@linux.intel.com>
> ---
> MAINTAINERS | 6 +
> drivers/mfd/Kconfig | 9 ++
> drivers/mfd/Makefile | 1 +
> drivers/mfd/altera-sysmgr.c | 310 ++++++++++++++++++++++++++++++++++++++
> include/linux/mfd/altera-sysmgr.h | 113 ++++++++++++++
> 5 files changed, 439 insertions(+)
> create mode 100644 drivers/mfd/altera-sysmgr.c
> create mode 100644 include/linux/mfd/altera-sysmgr.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d9e6d86488df..bda6b2173cc6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -692,6 +692,12 @@ L: linux-gpio@vger.kernel.org
> S: Maintained
> F: drivers/gpio/gpio-altera.c
>
> +ALTERA SYSTEM MANAGER DRIVER
> +M: Thor Thayer <thor.thayer@linux.intel.com>
> +S: Maintained
> +F: drivers/mfd/altera-sysmgr.c
> +F: include/linux/mfd/altera-sysgmr.h
> +
> ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT
> M: Thor Thayer <thor.thayer@linux.intel.com>
> S: Maintained
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index f3a5f8d02790..1192a25186c7 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -29,6 +29,15 @@ config MFD_ALTERA_A10SR
> accessing the external gpio extender (LEDs & buttons) and
> power supply alarms (hwmon).
>
> +config MFD_ALTERA_SYSMGR
> + bool "Altera SOCFPGA System Manager"
> + depends on (ARCH_SOCFPGA || ARCH_STRATIX10) && OF
> + select MFD_SYSCON
> + help
> + Select this to get System Manager support for all Altera branded
> + SOCFPGAs. The SOCFPGA System Manager handles all SOCFPGAs by
> + using syscon for ARM32 parts and SMC calls to EL3 for ARM64 parts.
> +
> config MFD_ACT8945A
> tristate "Active-semi ACT8945A"
> select MFD_CORE
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 5856a9489cbd..bc1508e3ff7b 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -232,6 +232,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
> obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
>
> obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
> +obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o
> obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
>
> obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o
> diff --git a/drivers/mfd/altera-sysmgr.c b/drivers/mfd/altera-sysmgr.c
> new file mode 100644
> index 000000000000..29b0bfcb3f69
> --- /dev/null
> +++ b/drivers/mfd/altera-sysmgr.c
> @@ -0,0 +1,310 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2017-2018, Intel Corporation.
> + * Copyright (C) 2012 Freescale Semiconductor, Inc.
> + * Copyright (C) 2012 Linaro Ltd.
> + *
> + * Based on syscon driver.
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/mfd/altera-sysmgr.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +static struct platform_driver sysmgr_driver;
> +
> +/**
> + * struct altr_sysmgr - Altera SOCFPGA System Manager
> + * @regmap: the regmap used for System Manager accesses.
> + * @base : the base address for the System Manager
> + */
> +struct altr_sysmgr {
> + struct regmap *regmap;
> + void __iomem *base;
> +};
> +
> +/**
> + * Only 1 instance of System Manager is needed but many
> + * consumers will want to access it with the matching
> + * functions below.
> + */
> +static struct altr_sysmgr *p_sysmgr;
> +
> +/**
> + * s10_protected_reg_write
> + * Write to a protected SMC register.
> + * @base: Base address of System Manager
> + * @reg: Address offset of register
> + * @val: Value to write
> + * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
> + * INTEL_SIP_SMC_REG_ERROR on error
> + * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
> + */
> +static int s10_protected_reg_write(void __iomem *base,
> + unsigned int reg, unsigned int val)
> +{
> + struct arm_smccc_res result;
> + unsigned long sysmgr_base = (unsigned long)base;
> +
> + arm_smccc_smc(INTEL_SIP_SMC_REG_WRITE, sysmgr_base + reg,
> + val, 0, 0, 0, 0, 0, &result);
> +
> + return (int)result.a0;
> +}
> +
> +/**
> + * s10_protected_reg_read
> + * Read the status of a protected SMC register
> + * @base: Base address of System Manager.
> + * @reg: Address of register
> + * @val: Value read.
> + * Return: INTEL_SIP_SMC_STATUS_OK (0) on success
> + * INTEL_SIP_SMC_REG_ERROR on error
> + * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION if not supported
> + */
> +static int s10_protected_reg_read(void __iomem *base,
> + unsigned int reg, unsigned int *val)
> +{
> + struct arm_smccc_res result;
> + unsigned long sysmgr_base = (unsigned long)base;
> +
> + arm_smccc_smc(INTEL_SIP_SMC_REG_READ, sysmgr_base + reg,
> + 0, 0, 0, 0, 0, 0, &result);
> +
> + *val = (unsigned int)result.a1;
> +
> + return (int)result.a0;
> +}
> +
> +static const struct regmap_config s10_sysmgr_regmap_cfg = {
> + .name = "s10_sysmgr",
> + .reg_bits = 32,
> + .reg_stride = 4,
> + .val_bits = 32,
> + .reg_read = s10_protected_reg_read,
> + .reg_write = s10_protected_reg_write,
> + .fast_io = true,
> + .use_single_rw = true,
> +};
> +
> +/**
> + * socfpga_is_s10
> + * Determine if running on Stratix10 platform.
> + * Return: True if running Stratix10, otherwise false.
> + */
> +static int socfpga_is_s10(void)
> +{
> + return of_machine_is_compatible("altr,socfpga-stratix10");
> +}
> +
> +/**
> + * of_sysmgr_register
> + * Create and register the Altera System Manager regmap.
> + * Return: Pointer to new sysmgr on success.
> + * Pointer error on failure.
> + */
> +static struct altr_sysmgr *of_sysmgr_register(struct device_node *np)
> +{
> + struct altr_sysmgr *sysmgr;
> + struct regmap *regmap;
> + u32 reg_io_width;
> + int ret;
> + struct regmap_config sysmgr_config = s10_sysmgr_regmap_cfg;
> + struct resource res;
> +
> + if (!of_device_is_compatible(np, "altr,sys-mgr"))
> + return ERR_PTR(-EINVAL);
> +
> + sysmgr = kzalloc(sizeof(*sysmgr), GFP_KERNEL);
> + if (!sysmgr)
> + return ERR_PTR(-ENOMEM);
> +
> + if (of_address_to_resource(np, 0, &res)) {
> + ret = -ENOMEM;
> + goto err_map;
> + }
> +
> + /* Need physical address for SMCC call */
> + sysmgr->base = (void __iomem *)res.start;
> +
> + /*
> + * search for reg-io-width property in DT. If it is not provided,
> + * default to 4 bytes. regmap_init will return an error if values
> + * are invalid so there is no need to check them here.
> + */
> + ret = of_property_read_u32(np, "reg-io-width", ®_io_width);
> + if (ret)
> + reg_io_width = 4;
> +
> + sysmgr_config.reg_stride = reg_io_width;
> + sysmgr_config.val_bits = reg_io_width * 8;
> + sysmgr_config.max_register = resource_size(&res) - reg_io_width;
> +
> + regmap = regmap_init(NULL, NULL, sysmgr->base, &sysmgr_config);
> + if (IS_ERR(regmap)) {
> + pr_err("regmap init failed\n");
> + ret = PTR_ERR(regmap);
> + goto err_map;
> + }
> +
> + sysmgr->regmap = regmap;
> +
> + p_sysmgr = sysmgr;
> +
> + return sysmgr;
> +
> +err_map:
> + kfree(sysmgr);
> + return ERR_PTR(ret);
> +}
> +
> +struct regmap *altr_sysmgr_node_to_regmap(struct device_node *np)
> +{
> + struct altr_sysmgr *sysmgr = NULL;
> +
> + if (!socfpga_is_s10())
> + return syscon_node_to_regmap(np);
> +
> + if (!p_sysmgr)
> + sysmgr = of_sysmgr_register(np);
> + else
> + sysmgr = p_sysmgr;
> +
> + if (IS_ERR_OR_NULL(sysmgr))
> + return ERR_CAST(sysmgr);
> +
> + return sysmgr->regmap;
> +}
> +EXPORT_SYMBOL_GPL(altr_sysmgr_node_to_regmap);
> +
> +struct regmap *altr_sysmgr_regmap_lookup_by_compatible(const char *s)
> +{
> + struct device_node *sysmgr_np;
> + struct regmap *regmap;
> +
> + if (!socfpga_is_s10())
> + return syscon_regmap_lookup_by_compatible(s);
> +
> + sysmgr_np = of_find_compatible_node(NULL, NULL, s);
> + if (!sysmgr_np)
> + return ERR_PTR(-ENODEV);
> +
> + regmap = altr_sysmgr_node_to_regmap(sysmgr_np);
> + of_node_put(sysmgr_np);
> +
> + return regmap;
> +}
> +EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_compatible);
> +
> +static int sysmgr_match_pdevname(struct device *dev, void *data)
> +{
> + return !strcmp(dev_name(dev), (const char *)data);
> +}
> +
> +struct regmap *altr_sysmgr_regmap_lookup_by_pdevname(const char *s)
> +{
> + struct device *dev;
> + struct altr_sysmgr *sysmgr;
> +
> + if (!socfpga_is_s10())
> + return syscon_regmap_lookup_by_pdevname(s);
> +
> + dev = driver_find_device(&sysmgr_driver.driver, NULL, (void *)s,
> + sysmgr_match_pdevname);
> + if (!dev)
> + return ERR_PTR(-EPROBE_DEFER);
> +
> + sysmgr = dev_get_drvdata(dev);
> +
> + return sysmgr->regmap;
> +}
> +EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_pdevname);
> +
> +struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
> + const char *property)
> +{
> + struct device_node *sysmgr_np;
> + struct regmap *regmap;
> +
> + if (!socfpga_is_s10())
> + return syscon_regmap_lookup_by_phandle(np, property);
> +
> + if (property)
> + sysmgr_np = of_parse_phandle(np, property, 0);
> + else
> + sysmgr_np = np;
> +
> + if (!sysmgr_np)
> + return ERR_PTR(-ENODEV);
> +
> + regmap = altr_sysmgr_node_to_regmap(sysmgr_np);
> + of_node_put(sysmgr_np);
> +
> + return regmap;
> +}
> +EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle);
> +
> +static int sysmgr_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct altr_sysmgr *sysmgr;
> + struct resource *res;
> +
> + if (!socfpga_is_s10())
> + return -ENODEV;
> +
> + /* Skip Initialization if already created */
> + if (p_sysmgr)
> + goto finish;
> +
> + sysmgr = of_sysmgr_register(pdev->dev.of_node);
> + if (IS_ERR_OR_NULL(sysmgr)) {
> + dev_err(dev, "regmap init failed\n");
> + return -ENODEV;
> + }
> +
> +finish:
> + platform_set_drvdata(pdev, p_sysmgr);
> +
> + dev_dbg(dev, "regmap %pR registered\n", res);
> +
> + return 0;
> +}
> +
> +static const struct of_device_id altr_sysmgr_of_match[] = {
> + { .compatible = "altr,sys-mgr" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, altr_sysmgr_of_match);
> +
> +static struct platform_driver altr_sysmgr_driver = {
> + .probe = sysmgr_probe,
> + .driver = {
> + .name = "altr,system_manager",
> + .of_match_table = altr_sysmgr_of_match,
> + },
> +};
> +
> +static int __init altr_sysmgr_init(void)
> +{
> + return platform_driver_register(&altr_sysmgr_driver);
> +}
> +core_initcall(altr_sysmgr_init);
> +
> +static void __exit altr_sysmgr_exit(void)
> +{
> + platform_driver_unregister(&altr_sysmgr_driver);
> +}
> +module_exit(altr_sysmgr_exit);
> +
> +MODULE_AUTHOR("Thor Thayer <>");
> +MODULE_DESCRIPTION("SOCFPGA System Manager driver");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/mfd/altera-sysmgr.h b/include/linux/mfd/altera-sysmgr.h
> new file mode 100644
> index 000000000000..b82116706319
> --- /dev/null
> +++ b/include/linux/mfd/altera-sysmgr.h
> @@ -0,0 +1,113 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2018 Intel Corporation
> + * Copyright (C) 2012 Freescale Semiconductor, Inc.
> + * Copyright (C) 2012 Linaro Ltd.
> + */
> +
> +#ifndef __LINUX_MFD_ALTERA_SYSMGR_H__
> +#define __LINUX_MFD_ALTERA_SYSMGR_H__
> +
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +
> +struct device_node;
> +
> +#ifdef CONFIG_MFD_ALTERA_SYSMGR
> +struct regmap *altr_sysmgr_node_to_regmap(struct device_node *np);
> +struct regmap *altr_sysmgr_regmap_lookup_by_compatible(const char *s);
> +struct regmap *altr_sysmgr_regmap_lookup_by_pdevname(const char *s);
> +struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
> + const char *property);
> +
> +/*
> + * Functions specified by ARM SMC Calling convention:
> + *
> + * FAST call executes atomic operations, returns when the requested operation
> + * has completed.
> + * STD call starts a operation which can be preempted by a non-secure
> + * interrupt.
> + *
> + * a0..a7 is used as register names in the descriptions below, on arm32
> + * that translates to r0..r7 and on arm64 to w0..w7.
> + */
> +
> +#define INTEL_SIP_SMC_STD_CALL_VAL(func_num) \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_64, \
> + ARM_SMCCC_OWNER_SIP, (func_num))
> +
> +#define INTEL_SIP_SMC_FAST_CALL_VAL(func_num) \
> + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
> + ARM_SMCCC_OWNER_SIP, (func_num))
> +
> +#define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF
> +#define INTEL_SIP_SMC_STATUS_OK 0x0
> +#define INTEL_SIP_SMC_REG_ERROR 0x5
> +
> +/*
> + * Request INTEL_SIP_SMC_REG_READ
> + *
> + * Read a protected register using SMCCC
> + *
> + * Call register usage:
> + * a0: INTEL_SIP_SMC_REG_READ.
> + * a1: register address.
> + * a2-7: not used.
> + *
> + * Return status:
> + * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_REG_ERROR, or
> + * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION
> + * a1: Value in the register
> + * a2-3: not used.
> + */
> +#define INTEL_SIP_SMC_FUNCID_REG_READ 7
> +#define INTEL_SIP_SMC_REG_READ \
> + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_READ)
> +
> +/*
> + * Request INTEL_SIP_SMC_REG_WRITE
> + *
> + * Write a protected register using SMCCC
> + *
> + * Call register usage:
> + * a0: INTEL_SIP_SMC_REG_WRITE.
> + * a1: register address
> + * a2: value to program into register.
> + * a3-7: not used.
> + *
> + * Return status:
> + * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_REG_ERROR, or
> + * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION
> + * a1-3: not used.
> + */
> +#define INTEL_SIP_SMC_FUNCID_REG_WRITE 8
> +#define INTEL_SIP_SMC_REG_WRITE \
> + INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_WRITE)
> +
> +#else
> +static inline struct regmap *altr_sysmgr_node_to_regmap(struct device_node *np)
> +{
> + return ERR_PTR(-ENOTSUPP);
> +}
> +
> +static inline struct regmap *
> +altr_sysmgr_regmap_lookup_by_compatible(const char *s)
> +{
> + return ERR_PTR(-ENOTSUPP);
> +}
> +
> +static inline struct regmap *
> +altr_sysmgr_regmap_lookup_by_pdevname(const char *s)
> +{
> + return ERR_PTR(-ENOTSUPP);
> +}
> +
> +static inline struct regmap *
> +altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
> + const char *property)
> +{
> + return ERR_PTR(-ENOTSUPP);
> +}
> +#endif
> +
> +#endif /* __LINUX_MFD_ALTERA_SYSMGR_H__ */
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* RE: [PATCH] bonding:avoid repeated display of same link status change
From: Manish Kumar Singh @ 2018-10-25 9:21 UTC (permalink / raw)
To: Michal Kubecek, Eric Dumazet
Cc: Mahesh Bandewar (महेश बंडेवार),
linux-netdev, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, linux-kernel
In-Reply-To: <20181023163825.GB22291@unicorn.suse.cz>
> -----Original Message-----
> From: Michal Kubecek [mailto:mkubecek@suse.cz]
> Sent: 23 अक्तूबर 2018 22:08
> To: Eric Dumazet
> Cc: Mahesh Bandewar (महेश बंडेवार); Manish Kumar Singh; linux-netdev; Jay
> Vosburgh; Veaceslav Falico; Andy Gospodarek; David S. Miller; linux-
> kernel@vger.kernel.org
> Subject: Re: [PATCH] bonding:avoid repeated display of same link status
> change
>
> On Tue, Oct 23, 2018 at 06:26:14PM +0200, Michal Kubecek wrote:
> > On Tue, Oct 23, 2018 at 09:10:44AM -0700, Eric Dumazet wrote:
> > >
> > >
> > > On 10/23/2018 08:54 AM, Mahesh Bandewar (महेश बंडेवार) wrote:
> > >
> > > > Atomic operations are expensive (on certain architectures) and miimon
> > > > runs quite frequently. Is the added cost of these atomic operations
> > > > even worth just to avoid *duplicate info* messages? This seems like a
> > > > overkill!
> > >
> > > atomic_read() is a simple read, no atomic operation involved.
> > >
> > > Same remark for atomic_set()
> >
> > Which makes me wonder if the patch really needs atomic_t.
>
> IMHO it does not. AFAICS multiple instances of bond_mii_monitor() cannot
> run simultaneously for the same bond so that there doesn't seem to be
> anything to collide with. (And if they could, we would need to test and
> set the flag atomically in bond_miimon_inspect().)
>
Yes, Michal, we are inline with your understanding.
when the -original- patch was posted to upstream there was no -synchronization- nor -racing- addressing code was in read/write of this added filed, as we -never- saw need for either.
-only- writer of the added field is bond_mii_monitor.
-only- reader of the added field is bond_miimon_inspect.
-this writer & reader -never- can run concurrently.
-writer invokes the reader.
hence, imo uint_8 rtnl_needed is all what is needed; with bond_mii_monitor doing rtnl_needed = 1; and bond_miimon_inspect doing if rtnl_needed.
here is the gravity of the situation with multiple customers whose names including machine names redacted:
4353 May 31 02:38:57 hostname kernel: ixgbe 0000:03:00.0: removed PHC on p2p1
4354 May 31 02:38:57 hostname kernel: public: link status down for active interface p2p1, disabling it in 100 ms
4355 May 31 02:38:57 hostname kernel: public: link status down for active interface p2p1, disabling it in 100 ms
4356 May 31 02:38:57 hostname kernel: public: link status definitely down for interface p2p1, disabling it
4357 May 31 02:38:57 hostname kernel: public: making interface p2p2 the new active one
4358 May 31 02:38:59 hostname kernel: ixgbe 0000:03:00.0: registered PHC device on p2p1
4359 May 31 02:39:00 hostname kernel: ixgbe 0000:03:00.0 p2p1: NIC Link is Up 10 Gbps, Flow Control: RX/TX
4360 May 31 02:39:00 hostname kernel: public: link status up for interface p2p1, enabling it in 200 ms
4361 May 31 02:39:00 hostname kernel: public: link status definitely up for interface p2p1, 10000 Mbps full duplex
4362 May 31 02:45:37 hostname journal: Missed 217723 kernel messages
4363 May 31 02:45:37 hostname kernel: public: link status down for active interface p2p2, disabling it in 100 ms
---------------------
11000+ APPROX SAME REPEATED MESSAGES in second
---------------------
15877 May 31 02:45:37 hostname kernel: public: link status down for active interface p2p2, disabling it in 100 ms
15878 May 31 02:45:37 hostname kernel: public: link status definitely down for interface p2p2, disabling it
15879 May 31 02:45:37 hostname kernel: public: making interface p2p1 the new active one
Thanks,
Manish
> Michal Kubecek
^ permalink raw reply
* Re: [PATCH] bonding:avoid repeated display of same link status change
From: Michal Kubecek @ 2018-10-25 9:29 UTC (permalink / raw)
To: Manish Kumar Singh
Cc: Eric Dumazet,
Mahesh Bandewar (महेश बंडेवार),
linux-netdev, Jay Vosburgh, Veaceslav Falico, Andy Gospodarek,
David S. Miller, linux-kernel
In-Reply-To: <bee18dd4-0012-44d0-9508-2987bfe521e5@default>
On Thu, Oct 25, 2018 at 02:21:05AM -0700, Manish Kumar Singh wrote:
> > From: Michal Kubecek [mailto:mkubecek@suse.cz]
> > IMHO it does not. AFAICS multiple instances of bond_mii_monitor() cannot
> > run simultaneously for the same bond so that there doesn't seem to be
> > anything to collide with. (And if they could, we would need to test and
> > set the flag atomically in bond_miimon_inspect().)
> >
> Yes, Michal, we are inline with your understanding.
> when the -original- patch was posted to upstream there was no
> -synchronization- nor -racing- addressing code was in read/write of this
> added filed, as we -never- saw need for either.
>
> -only- writer of the added field is bond_mii_monitor.
> -only- reader of the added field is bond_miimon_inspect.
> -this writer & reader -never- can run concurrently.
> -writer invokes the reader.
>
> hence, imo uint_8 rtnl_needed is all what is needed; with bond_mii_monitor doing rtnl_needed = 1; and bond_miimon_inspect doing if rtnl_needed.
>
> here is the gravity of the situation with multiple customers whose names including machine names redacted:
>
> 4353 May 31 02:38:57 hostname kernel: ixgbe 0000:03:00.0: removed PHC on p2p1
> 4354 May 31 02:38:57 hostname kernel: public: link status down for active interface p2p1, disabling it in 100 ms
> 4355 May 31 02:38:57 hostname kernel: public: link status down for active interface p2p1, disabling it in 100 ms
> 4356 May 31 02:38:57 hostname kernel: public: link status definitely down for interface p2p1, disabling it
> 4357 May 31 02:38:57 hostname kernel: public: making interface p2p2 the new active one
> 4358 May 31 02:38:59 hostname kernel: ixgbe 0000:03:00.0: registered PHC device on p2p1
> 4359 May 31 02:39:00 hostname kernel: ixgbe 0000:03:00.0 p2p1: NIC Link is Up 10 Gbps, Flow Control: RX/TX
> 4360 May 31 02:39:00 hostname kernel: public: link status up for interface p2p1, enabling it in 200 ms
> 4361 May 31 02:39:00 hostname kernel: public: link status definitely up for interface p2p1, 10000 Mbps full duplex
> 4362 May 31 02:45:37 hostname journal: Missed 217723 kernel messages
> 4363 May 31 02:45:37 hostname kernel: public: link status down for active interface p2p2, disabling it in 100 ms
> ---------------------
> 11000+ APPROX SAME REPEATED MESSAGES in second
> ---------------------
> 15877 May 31 02:45:37 hostname kernel: public: link status down for active interface p2p2, disabling it in 100 ms
> 15878 May 31 02:45:37 hostname kernel: public: link status definitely down for interface p2p2, disabling it
> 15879 May 31 02:45:37 hostname kernel: public: making interface p2p1 the new active one
When I was replying, I didn't know this was a v2 and I haven't seen the
v1 discussion. I have read it since and I think I understand Eric's
point now. The thing is that just adding e.g. u8 is OK as it is now.
However, someone could later add another u8 next to it which would also
be perfectly OK on its own but reads/writes to these two could collide
between each other.
And as pointed out by a colleague, even having atomic_t and u8 flag in
one 64-bit word could be a problem on architectures which cannot do an
atomic read/write from/to a 32-bit word (sparc seems to be one).
Michal Kubecek
^ permalink raw reply
* Re: Regression: kernel 4.14 an later very slow with many ipsec tunnels
From: Wolfgang Walter @ 2018-10-25 9:38 UTC (permalink / raw)
To: netdev
Cc: Florian Westphal, Steffen Klassert, David Miller, linux-kernel,
torvalds, christophe.gouault, Greg KH
In-Reply-To: <1729915.dWWxddREcQ@stwm.de>
Hello,
there is now a new 4.19 which still has the big performance regression when
many ipsec tunnels are configured (throughput and latency get worse by 10 to
50 times) which makes any kernel > 4.9 unusable for our routers.
I still don't understand why a revert of the flow cache removal at least for
the longterm kernels is that a bad option (maybe as a compile time option),
especially as there is no workaround available.
We use linux in that scenario since more than 10 years so I'm really rather
unhappy if not to say despaired that we will be stucked with 4.9 for an
unforeseeable future.
We would have detected and reported that performance regression much earlier
if not another bug in ipsec had prevented us from running 4.14 and later until
end of august 2018 (See kernels > v4.12 oops/crash with ipsec-traffic:
bisected to b838d5e1c5b6e57b10ec8af2268824041e3ea911: ipv4: mark DST_NOGC and
remove the operation of dst_free()).
Am Donnerstag, 4. Oktober 2018, 15:57:52 schrieb Wolfgang Walter:
> Am Dienstag, 2. Oktober 2018, 23:35:36 schrieb Florian Westphal:
[snip]
> > Well, I'm not going to send a revert of the flowcache removal.
> >
> >
> > I'm willing to experiment with alternatives to a full iteration of the
> > inexact list but thats it.
>
> If this brings performance back to pre-removal, I'm fine with that. I'm even
> fine if it is slower by a factor of 2.
>
> I think it is a serious regression, and there is no workaround, and therefor
> it cannot stay like that.
>
> So I still hope that reverting is an option if no acceptable solution can be
> found.
>
> > > correctly done, as it still would have to obey the original order of the
> > > rules (their priority).
> >
> > Except that neither the priority or the order in which it was added
> > matters in case the selector doesn't match.
>
> To match a packet one has to find all matching rules and chose that one with
> the lowest priority.
>
> "indexing" by dst will not help much if you have a ruleset where a lot of
> rules sharing a dst. You also have to replicate rules with dsts that have a
> prefix oft another dst as they may habe a higher priority even if they are
> less specific.
>
> Every such entry may again have such an "indexing" by dst. Only then this
> would be efficient.
>
[snip]
>
> I wonder why there is no such thing for netfilter or the rules list in
> routing. nf does not have such a thing, either. This is the reason why I
> think that this is not that easy and for longterm kernel 4.14 the best
> solution will be a revert anyway.
>
> Regards,
Regards,
--
Wolfgang Walter
Studentenwerk München
Anstalt des öffentlichen Rechts
^ permalink raw reply
* [PATCH] octeontx2-af: Use GFP_ATOMIC under spin lock
From: Wei Yongjun @ 2018-10-25 1:42 UTC (permalink / raw)
To: Sunil Goutham, Linu Cherian, Geetha sowjanya, Jerin Jacob
Cc: Wei Yongjun, netdev, kernel-janitors
The function nix_update_mce_list() is called from
nix_update_bcast_mce_list(), and a spin lock is held
here, so we should use GFP_ATOMIC instead.
Fixes: 4b05528ebf0c ("octeontx2-af: Update bcast list upon NIXLF alloc/free")
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
---
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 8890c95..a618e48 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -1294,7 +1294,7 @@ static int nix_update_mce_list(struct nix_mce_list *mce_list,
return 0;
/* Add a new one to the list, at the tail */
- mce = kzalloc(sizeof(*mce), GFP_KERNEL);
+ mce = kzalloc(sizeof(*mce), GFP_ATOMIC);
if (!mce)
return -ENOMEM;
mce->idx = idx;
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox