* [Patch net 05/11] net: hns3: remove unnecessary queue reset in the hns3_uninit_all_ring()
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
It is not necessary to reset the queue in the hns3_uninit_all_ring(),
since the queue is stopped in the down operation, and will be resetted
in the up operaton. And the judgment of the HCLGE_STATE_RST_HANDLING
flag in the hclge_reset_tqp() is not correct, because we need to reset
tqp during pf reset, otherwise it may cause queue not be resetted to
working state problem.
Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 3 ---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 ---
2 files changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 6f0fd62..a80ecfb 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3240,9 +3240,6 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv)
int i;
for (i = 0; i < h->kinfo.num_tqps; i++) {
- if (h->ae_algo->ops->reset_queue)
- h->ae_algo->ops->reset_queue(h, i);
-
hns3_fini_ring(priv->ring_data[i].ring);
hns3_fini_ring(priv->ring_data[i + h->kinfo.num_tqps].ring);
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 2a63147..4dd0506 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -6116,9 +6116,6 @@ void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
u16 queue_gid;
int ret;
- if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
- return;
-
queue_gid = hclge_covert_handle_qid_global(handle, queue_id);
ret = hclge_tqp_enable(hdev, queue_id, 0, false);
--
2.7.4
^ permalink raw reply related
* [Patch net 06/11] net: hns3: bugfix for is_valid_csq_clean_head()
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
The HEAD pointer of the hardware command queue maybe equal to the command
queue's next_to_use the driver, so that does not belong to the invalid
HEAD pointer, since the hardware may not process the command in time,
causing the HEAD pointer to be too late to update. The variables' name
in this function is unreadable, so give them a more readable one.
Fixes: 3ff504908f95 ("net: hns3: fix a dead loop in hclge_cmd_csq_clean")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 68026a5..690f62e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -24,15 +24,15 @@ static int hclge_ring_space(struct hclge_cmq_ring *ring)
return ring->desc_num - used - 1;
}
-static int is_valid_csq_clean_head(struct hclge_cmq_ring *ring, int h)
+static int is_valid_csq_clean_head(struct hclge_cmq_ring *ring, int head)
{
- int u = ring->next_to_use;
- int c = ring->next_to_clean;
+ int ntu = ring->next_to_use;
+ int ntc = ring->next_to_clean;
- if (unlikely(h >= ring->desc_num))
- return 0;
+ if (ntu > ntc)
+ return head >= ntc && head <= ntu;
- return u > c ? (h > c && h <= u) : (h > c || h <= u);
+ return head >= ntc || head <= ntu;
}
static int hclge_alloc_cmd_desc(struct hclge_cmq_ring *ring)
--
2.7.4
^ permalink raw reply related
* [Patch net 01/11] net: hns3: add error handler for hns3_nic_init_vector_data()
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
When hns3_nic_init_vector_data() failed for mapping ring to vector,
it should cancel the netif_napi_add() that have been successfully done
and then exit.
Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 32f3aca8..d9066c5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2821,7 +2821,7 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
struct hnae3_handle *h = priv->ae_handle;
struct hns3_enet_tqp_vector *tqp_vector;
int ret = 0;
- u16 i;
+ int i, j;
hns3_nic_set_cpumask(priv);
@@ -2868,13 +2868,19 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain);
if (ret)
- return ret;
+ goto map_ring_fail;
netif_napi_add(priv->netdev, &tqp_vector->napi,
hns3_nic_common_poll, NAPI_POLL_WEIGHT);
}
return 0;
+
+map_ring_fail:
+ for (j = i - 1; j >= 0; j--)
+ netif_napi_del(&priv->tqp_vector[j].napi);
+
+ return ret;
}
static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
--
2.7.4
^ permalink raw reply related
* [Patch net 02/11] net: hns3: add error handler for hns3_get_ring_config/hns3_queue_to_ring
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
When hns3_get_ring_config()/hns3_queue_to_ring() failed during resetting,
the allocated memory has not been freed before hns3_get_ring_config() and
hns3_queue_to_ring() return. So this patch fixes the buffer not freeing
problem during resetting.
Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index d9066c5..6f0fd62 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3037,8 +3037,10 @@ static int hns3_queue_to_ring(struct hnae3_queue *tqp,
return ret;
ret = hns3_ring_get_cfg(tqp, priv, HNAE3_RING_TYPE_RX);
- if (ret)
+ if (ret) {
+ devm_kfree(priv->dev, priv->ring_data[tqp->tqp_index].ring);
return ret;
+ }
return 0;
}
@@ -3047,7 +3049,7 @@ static int hns3_get_ring_config(struct hns3_nic_priv *priv)
{
struct hnae3_handle *h = priv->ae_handle;
struct pci_dev *pdev = h->pdev;
- int i, ret;
+ int i, j, ret;
priv->ring_data = devm_kzalloc(&pdev->dev,
array3_size(h->kinfo.num_tqps,
@@ -3065,6 +3067,12 @@ static int hns3_get_ring_config(struct hns3_nic_priv *priv)
return 0;
err:
+ for (j = i - 1; j >= 0; j--) {
+ devm_kfree(priv->dev, priv->ring_data[j].ring);
+ devm_kfree(priv->dev,
+ priv->ring_data[j + h->kinfo.num_tqps].ring);
+ }
+
devm_kfree(&pdev->dev, priv->ring_data);
return ret;
}
--
2.7.4
^ permalink raw reply related
* [Patch net 10/11] net: hns3: bugfix for rtnl_lock's range in the hclge_reset()
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
Since hclge_reset_wait() is used to wait for the hardware to complete
the reset, it is not necessary to hold the rtnl_lock during
hclge_reset_wait(). So this patch release the lock for the duration
of hclge_reset_wait().
Fixes: 6d4fab39533f ("net: hns3: Reset net device with rtnl_lock")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index a0c2834..394f797 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2470,14 +2470,17 @@ static void hclge_reset(struct hclge_dev *hdev)
handle = &hdev->vport[0].nic;
rtnl_lock();
hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
+ rtnl_unlock();
if (!hclge_reset_wait(hdev)) {
+ rtnl_lock();
hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT);
hclge_reset_ae_dev(hdev->ae_dev);
hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
hclge_clear_reset_cause(hdev);
} else {
+ rtnl_lock();
/* schedule again to check pending resets later */
set_bit(hdev->reset_type, &hdev->reset_pending);
hclge_reset_task_schedule(hdev);
--
2.7.4
^ permalink raw reply related
* [Patch net 11/11] net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset()
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
Since hclgevf_reset_wait() is used to wait for the hardware to complete
the reset, it is not necessary to hold the rtnl_lock during
hclgevf_reset_wait(). So this patch release the lock for the duration
of hclgevf_reset_wait().
Fixes: 6988eb2a9b77 ("net: hns3: Add support to reset the enet/ring mgmt layer")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index 552b708..fa6251e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -1170,6 +1170,8 @@ static int hclgevf_reset(struct hclgevf_dev *hdev)
/* bring down the nic to stop any ongoing TX/RX */
hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT);
+ rtnl_unlock();
+
/* check if VF could successfully fetch the hardware reset completion
* status from the hardware
*/
@@ -1187,6 +1189,8 @@ static int hclgevf_reset(struct hclgevf_dev *hdev)
return ret;
}
+ rtnl_lock();
+
/* now, re-initialize the nic client and ae device*/
ret = hclgevf_reset_stack(hdev);
if (ret)
--
2.7.4
^ permalink raw reply related
* [Patch net 09/11] net: hns3: bugfix for handling mailbox while the command queue reinitialized
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
In a multi-core machine, the mailbox service and reset service
will be executed at the same time. The reset server will re-initialize
the commond queue, before that, the mailbox handler can only get some
invalid messages.
The HCLGE_STATE_CMD_DISABLE flag means that the command queue is not
available and needs to be reinitialized. Therefore, when the mailbox
hanlder recognizes this flag, it should not process the command.
Fixes: dde1a86e93ca ("net: hns3: Add mailbox support to PF driver")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
index 04462a3..6ac2fab 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
@@ -400,6 +400,12 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
/* handle all the mailbox requests in the queue */
while (!hclge_cmd_crq_empty(&hdev->hw)) {
+ if (test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state)) {
+ dev_warn(&hdev->pdev->dev,
+ "command queue need re-initialize\n");
+ return;
+ }
+
desc = &crq->desc[crq->next_to_use];
req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data;
--
2.7.4
^ permalink raw reply related
* [Patch net 08/11] net: hns3: fix incorrect return value/type of some functions
From: Huazhong Tan @ 2018-10-27 2:41 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
Huazhong Tan
In-Reply-To: <1540608118-27449-1-git-send-email-tanhuazhong@huawei.com>
There are some functions that, when they fail to execute a send command,
need to return the corresponding error value to its caller.
Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
Fixes: 681ec3999b3d ("net: hns3: fix for vlan table lost problem when resetting")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 6 +-
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 81 +++++++++++++++-------
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 32 +++++----
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 +-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 8 +--
6 files changed, 83 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index e82e4ca..055b406 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -316,8 +316,8 @@ struct hnae3_ae_ops {
int (*set_loopback)(struct hnae3_handle *handle,
enum hnae3_loop loop_mode, bool en);
- void (*set_promisc_mode)(struct hnae3_handle *handle, bool en_uc_pmc,
- bool en_mc_pmc);
+ int (*set_promisc_mode)(struct hnae3_handle *handle, bool en_uc_pmc,
+ bool en_mc_pmc);
int (*set_mtu)(struct hnae3_handle *handle, int new_mtu);
void (*get_pauseparam)(struct hnae3_handle *handle,
@@ -391,7 +391,7 @@ struct hnae3_ae_ops {
int vector_num,
struct hnae3_ring_chain_node *vr_chain);
- void (*reset_queue)(struct hnae3_handle *handle, u16 queue_id);
+ int (*reset_queue)(struct hnae3_handle *handle, u16 queue_id);
u32 (*get_fw_version)(struct hnae3_handle *handle);
void (*get_mdix_mode)(struct hnae3_handle *handle,
u8 *tp_mdix_ctrl, u8 *tp_mdix);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a80ecfb..d9c6889 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -509,16 +509,18 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev)
h->netdev_flags = new_flags;
}
-void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
+int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
if (h->ae_algo->ops->set_promisc_mode) {
- h->ae_algo->ops->set_promisc_mode(h,
- promisc_flags & HNAE3_UPE,
- promisc_flags & HNAE3_MPE);
+ return h->ae_algo->ops->set_promisc_mode(h,
+ promisc_flags & HNAE3_UPE,
+ promisc_flags & HNAE3_MPE);
}
+
+ return 0;
}
void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
@@ -1494,18 +1496,22 @@ static int hns3_vlan_rx_kill_vid(struct net_device *netdev,
return ret;
}
-static void hns3_restore_vlan(struct net_device *netdev)
+static int hns3_restore_vlan(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
u16 vid;
- int ret;
+ int ret = 0;
for_each_set_bit(vid, priv->active_vlans, VLAN_N_VID) {
ret = hns3_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
- if (ret)
- netdev_warn(netdev, "Restore vlan: %d filter, ret:%d\n",
- vid, ret);
+ if (ret) {
+ netdev_err(netdev, "Restore vlan: %d filter, ret:%d\n",
+ vid, ret);
+ return ret;
+ }
}
+
+ return ret;
}
static int hns3_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
@@ -3247,11 +3253,12 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv)
}
/* Set mac addr if it is configured. or leave it to the AE driver */
-static void hns3_init_mac_addr(struct net_device *netdev, bool init)
+static int hns3_init_mac_addr(struct net_device *netdev, bool init)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
u8 mac_addr_temp[ETH_ALEN];
+ int ret = 0;
if (h->ae_algo->ops->get_mac_addr && init) {
h->ae_algo->ops->get_mac_addr(h, mac_addr_temp);
@@ -3266,8 +3273,9 @@ static void hns3_init_mac_addr(struct net_device *netdev, bool init)
}
if (h->ae_algo->ops->set_mac_addr)
- h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr, true);
+ ret = h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr, true);
+ return ret;
}
static int hns3_restore_fd_rules(struct net_device *netdev)
@@ -3480,20 +3488,29 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
return ret;
}
-static void hns3_recover_hw_addr(struct net_device *ndev)
+static int hns3_recover_hw_addr(struct net_device *ndev)
{
struct netdev_hw_addr_list *list;
struct netdev_hw_addr *ha, *tmp;
+ int ret = 0;
/* go through and sync uc_addr entries to the device */
list = &ndev->uc;
- list_for_each_entry_safe(ha, tmp, &list->list, list)
- hns3_nic_uc_sync(ndev, ha->addr);
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ ret = hns3_nic_uc_sync(ndev, ha->addr);
+ if (ret)
+ return ret;
+ }
/* go through and sync mc_addr entries to the device */
list = &ndev->mc;
- list_for_each_entry_safe(ha, tmp, &list->list, list)
- hns3_nic_mc_sync(ndev, ha->addr);
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ ret = hns3_nic_mc_sync(ndev, ha->addr);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
}
static void hns3_remove_hw_addr(struct net_device *netdev)
@@ -3620,7 +3637,10 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h)
int ret;
for (i = 0; i < h->kinfo.num_tqps; i++) {
- h->ae_algo->ops->reset_queue(h, i);
+ ret = h->ae_algo->ops->reset_queue(h, i);
+ if (ret)
+ return ret;
+
hns3_init_ring_hw(priv->ring_data[i].ring);
/* We need to clear tx ring here because self test will
@@ -3712,18 +3732,31 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
bool vlan_filter_enable;
int ret;
- hns3_init_mac_addr(netdev, false);
- hns3_recover_hw_addr(netdev);
- hns3_update_promisc_mode(netdev, handle->netdev_flags);
+ ret = hns3_init_mac_addr(netdev, false);
+ if (ret)
+ return ret;
+
+ ret = hns3_recover_hw_addr(netdev);
+ if (ret)
+ return ret;
+
+ ret = hns3_update_promisc_mode(netdev, handle->netdev_flags);
+ if (ret)
+ return ret;
+
vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true;
hns3_enable_vlan_filter(netdev, vlan_filter_enable);
-
/* Hardware table is only clear when pf resets */
- if (!(handle->flags & HNAE3_SUPPORT_VF))
- hns3_restore_vlan(netdev);
+ if (!(handle->flags & HNAE3_SUPPORT_VF)) {
+ ret = hns3_restore_vlan(netdev);
+ return ret;
+ }
+
+ ret = hns3_restore_fd_rules(netdev);
+ if (ret)
+ return ret;
- hns3_restore_fd_rules(netdev);
/* Carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 71cfca1..d3636d0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -640,7 +640,7 @@ void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
u32 rl_value);
void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
-void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
+int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
#ifdef CONFIG_HNS3_DCB
void hns3_dcbnl_setup(struct hnae3_handle *handle);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 4dd0506..a0c2834 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3314,8 +3314,8 @@ void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
param->vf_id = vport_id;
}
-static void hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
- bool en_mc_pmc)
+static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
+ bool en_mc_pmc)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
@@ -3323,7 +3323,7 @@ static void hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
hclge_promisc_param_init(¶m, en_uc_pmc, en_mc_pmc, true,
vport->vport_id);
- hclge_cmd_set_promisc_mode(hdev, ¶m);
+ return hclge_cmd_set_promisc_mode(hdev, ¶m);
}
static int hclge_get_fd_mode(struct hclge_dev *hdev, u8 *fd_mode)
@@ -6107,28 +6107,28 @@ static u16 hclge_covert_handle_qid_global(struct hnae3_handle *handle,
return tqp->index;
}
-void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
+int hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
int reset_try_times = 0;
int reset_status;
u16 queue_gid;
- int ret;
+ int ret = 0;
queue_gid = hclge_covert_handle_qid_global(handle, queue_id);
ret = hclge_tqp_enable(hdev, queue_id, 0, false);
if (ret) {
- dev_warn(&hdev->pdev->dev, "Disable tqp fail, ret = %d\n", ret);
- return;
+ dev_err(&hdev->pdev->dev, "Disable tqp fail, ret = %d\n", ret);
+ return ret;
}
ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, true);
if (ret) {
- dev_warn(&hdev->pdev->dev,
- "Send reset tqp cmd fail, ret = %d\n", ret);
- return;
+ dev_err(&hdev->pdev->dev,
+ "Send reset tqp cmd fail, ret = %d\n", ret);
+ return ret;
}
reset_try_times = 0;
@@ -6141,16 +6141,18 @@ void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
}
if (reset_try_times >= HCLGE_TQP_RESET_TRY_TIMES) {
- dev_warn(&hdev->pdev->dev, "Reset TQP fail\n");
- return;
+ dev_err(&hdev->pdev->dev, "Reset TQP fail\n");
+ return ret;
}
ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, false);
if (ret) {
- dev_warn(&hdev->pdev->dev,
- "Deassert the soft reset fail, ret = %d\n", ret);
- return;
+ dev_err(&hdev->pdev->dev,
+ "Deassert the soft reset fail, ret = %d\n", ret);
+ return ret;
}
+
+ return ret;
}
void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index e3dfd65..0d92154 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -778,7 +778,7 @@ int hclge_rss_init_hw(struct hclge_dev *hdev);
void hclge_rss_indir_init_cfg(struct hclge_dev *hdev);
void hclge_mbx_handler(struct hclge_dev *hdev);
-void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
+int hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id);
int hclge_cfg_flowctrl(struct hclge_dev *hdev);
int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index e0a86a5..552b708 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -1080,7 +1080,7 @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
1, false, NULL, 0);
}
-static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
+static int hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
u8 msg_data[2];
@@ -1091,10 +1091,10 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
/* disable vf queue before send queue reset msg to PF */
ret = hclgevf_tqp_enable(hdev, queue_id, 0, false);
if (ret)
- return;
+ return ret;
- hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data,
- 2, true, NULL, 0);
+ return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data,
+ 2, true, NULL, 0);
}
static int hclgevf_notify_client(struct hclgevf_dev *hdev,
--
2.7.4
^ permalink raw reply related
* Re: [Patch net 08/11] net: hns3: fix incorrect return value/type of some functions
From: kbuild test robot @ 2018-10-27 4:10 UTC (permalink / raw)
To: Huazhong Tan
Cc: kbuild-all, davem, netdev, linuxarm, salil.mehta, yisen.zhuang,
lipeng321, Huazhong Tan
In-Reply-To: <1540608118-27449-9-git-send-email-tanhuazhong@huawei.com>
[-- Attachment #1: Type: text/plain, Size: 5095 bytes --]
Hi Huazhong,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on net/master]
url: https://github.com/0day-ci/linux/commits/Huazhong-Tan/Bugfix-for-the-HNS3-driver/20181027-105711
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=8.1.0 make.cross ARCH=xtensa
All errors (new ones prefixed by >>):
>> drivers/net/ethernet//hisilicon/hns3/hns3vf/hclgevf_main.c:2169:22: error: initialization of 'int (*)(struct hnae3_handle *, bool, bool)' {aka 'int (*)(struct hnae3_handle *, _Bool, _Bool)'} from incompatible pointer type 'void (*)(struct hnae3_handle *, bool, bool)' {aka 'void (*)(struct hnae3_handle *, _Bool, _Bool)'} [-Werror=incompatible-pointer-types]
.set_promisc_mode = hclgevf_set_promisc_mode,
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet//hisilicon/hns3/hns3vf/hclgevf_main.c:2169:22: note: (near initialization for 'hclgevf_ops.set_promisc_mode')
cc1: some warnings being treated as errors
vim +2169 drivers/net/ethernet//hisilicon/hns3/hns3vf/hclgevf_main.c
c136b8842 Peng Li 2018-09-21 2156
e2cb1dec9 Salil Mehta 2017-12-14 2157 static const struct hnae3_ae_ops hclgevf_ops = {
e2cb1dec9 Salil Mehta 2017-12-14 2158 .init_ae_dev = hclgevf_init_ae_dev,
e2cb1dec9 Salil Mehta 2017-12-14 2159 .uninit_ae_dev = hclgevf_uninit_ae_dev,
e718a93fe Peng Li 2018-06-28 2160 .init_client_instance = hclgevf_init_client_instance,
e718a93fe Peng Li 2018-06-28 2161 .uninit_client_instance = hclgevf_uninit_client_instance,
e2cb1dec9 Salil Mehta 2017-12-14 2162 .start = hclgevf_ae_start,
e2cb1dec9 Salil Mehta 2017-12-14 2163 .stop = hclgevf_ae_stop,
e2cb1dec9 Salil Mehta 2017-12-14 2164 .map_ring_to_vector = hclgevf_map_ring_to_vector,
e2cb1dec9 Salil Mehta 2017-12-14 2165 .unmap_ring_from_vector = hclgevf_unmap_ring_from_vector,
e2cb1dec9 Salil Mehta 2017-12-14 2166 .get_vector = hclgevf_get_vector,
0d3e6631d Yunsheng Lin 2018-03-09 2167 .put_vector = hclgevf_put_vector,
e2cb1dec9 Salil Mehta 2017-12-14 2168 .reset_queue = hclgevf_reset_tqp,
e2cb1dec9 Salil Mehta 2017-12-14 @2169 .set_promisc_mode = hclgevf_set_promisc_mode,
e2cb1dec9 Salil Mehta 2017-12-14 2170 .get_mac_addr = hclgevf_get_mac_addr,
e2cb1dec9 Salil Mehta 2017-12-14 2171 .set_mac_addr = hclgevf_set_mac_addr,
e2cb1dec9 Salil Mehta 2017-12-14 2172 .add_uc_addr = hclgevf_add_uc_addr,
e2cb1dec9 Salil Mehta 2017-12-14 2173 .rm_uc_addr = hclgevf_rm_uc_addr,
e2cb1dec9 Salil Mehta 2017-12-14 2174 .add_mc_addr = hclgevf_add_mc_addr,
e2cb1dec9 Salil Mehta 2017-12-14 2175 .rm_mc_addr = hclgevf_rm_mc_addr,
e2cb1dec9 Salil Mehta 2017-12-14 2176 .get_stats = hclgevf_get_stats,
e2cb1dec9 Salil Mehta 2017-12-14 2177 .update_stats = hclgevf_update_stats,
e2cb1dec9 Salil Mehta 2017-12-14 2178 .get_strings = hclgevf_get_strings,
e2cb1dec9 Salil Mehta 2017-12-14 2179 .get_sset_count = hclgevf_get_sset_count,
e2cb1dec9 Salil Mehta 2017-12-14 2180 .get_rss_key_size = hclgevf_get_rss_key_size,
e2cb1dec9 Salil Mehta 2017-12-14 2181 .get_rss_indir_size = hclgevf_get_rss_indir_size,
e2cb1dec9 Salil Mehta 2017-12-14 2182 .get_rss = hclgevf_get_rss,
e2cb1dec9 Salil Mehta 2017-12-14 2183 .set_rss = hclgevf_set_rss,
d97b30721 Jian Shen 2018-10-10 2184 .get_rss_tuple = hclgevf_get_rss_tuple,
d97b30721 Jian Shen 2018-10-10 2185 .set_rss_tuple = hclgevf_set_rss_tuple,
e2cb1dec9 Salil Mehta 2017-12-14 2186 .get_tc_size = hclgevf_get_tc_size,
e2cb1dec9 Salil Mehta 2017-12-14 2187 .get_fw_version = hclgevf_get_fw_version,
e2cb1dec9 Salil Mehta 2017-12-14 2188 .set_vlan_filter = hclgevf_set_vlan_filter,
b2641e2ad Yunsheng Lin 2018-05-03 2189 .enable_hw_strip_rxvtag = hclgevf_en_hw_strip_rxvtag,
6d4c3981a Salil Mehta 2018-03-22 2190 .reset_event = hclgevf_reset_event,
849e46077 Peng Li 2018-01-12 2191 .get_channels = hclgevf_get_channels,
cc719218e Peng Li 2018-03-08 2192 .get_tqps_and_rss_info = hclgevf_get_tqps_and_rss_info,
175ec96b4 Fuyun Liang 2018-03-21 2193 .get_status = hclgevf_get_status,
4a152de95 Fuyun Liang 2018-03-21 2194 .get_ksettings_an_result = hclgevf_get_ksettings_an_result,
c136b8842 Peng Li 2018-09-21 2195 .get_media_type = hclgevf_get_media_type,
e2cb1dec9 Salil Mehta 2017-12-14 2196 };
e2cb1dec9 Salil Mehta 2017-12-14 2197
:::::: The code at line 2169 was first introduced by commit
:::::: e2cb1dec9779ba2d89302a653eb0abaeb8682196 net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support
:::::: TO: Salil Mehta <salil.mehta@huawei.com>
:::::: CC: David S. Miller <davem@davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 55368 bytes --]
^ permalink raw reply
* Re: [PATCH] ptp: drop redundant kasprintf() to create worker name
From: Richard Cochran @ 2018-10-27 13:04 UTC (permalink / raw)
To: Rasmus Villemoes; +Cc: Kees Cook, netdev, linux-kernel
In-Reply-To: <20181026212300.5827-1-linux@rasmusvillemoes.dk>
On Fri, Oct 26, 2018 at 11:22:59PM +0200, Rasmus Villemoes wrote:
> Building with -Wformat-nonliteral, gcc complains
>
> drivers/ptp/ptp_clock.c: In function ‘ptp_clock_register’:
> drivers/ptp/ptp_clock.c:239:26: warning: format not a string literal and no format arguments [-Wformat-nonliteral]
> worker_name : info->name);
>
> kthread_create_worker takes fmt+varargs to set the name of the
> worker, and that happens with a vsnprintf() to a stack buffer (that is
> then copied into task_comm). So there's no reason not to just pass
> "ptp%d", ptp->index to kthread_create_worker() and avoid the
> intermediate worker_name variable.
Acked-by: Richard Cochran <richardcochran@gmail.com>
^ permalink raw reply
* Re: pull-request: bpf 2018-10-27
From: David Miller @ 2018-10-27 4:43 UTC (permalink / raw)
To: daniel; +Cc: ast, netdev
In-Reply-To: <20181027000748.15464-1-daniel@iogearbox.net>
From: Daniel Borkmann <daniel@iogearbox.net>
Date: Sat, 27 Oct 2018 02:07:48 +0200
> The following pull-request contains BPF updates for your *net* tree.
>
> The main changes are:
>
> 1) Fix toctou race in BTF header validation, from Martin and Wenwen.
>
> 2) Fix devmap interface comparison in notifier call which was
> neglecting netns, from Taehee.
>
> 3) Several fixes in various places, for example, correcting direct
> packet access and helper function availability, from Daniel.
>
> 4) Fix BPF kselftest config fragment to include af_xdp and sockmap,
> from Naresh.
>
> Please consider pulling these changes from:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
Pulled, thanks Daniel.
^ permalink raw reply
* Re: CAKE and r8169 cause panic on upload in v4.19
From: Heiner Kallweit @ 2018-10-27 13:43 UTC (permalink / raw)
To: Oleksandr Natalenko, Dave Taht, David S. Miller
Cc: Toke Høiland-Jørgensen, Jamal Hadi Salim, Cong Wang,
Jiří Pírko, Linux Kernel Network Developers,
linux-kernel
In-Reply-To: <b80e6819da8ea74f18b6ec0aaf9128fa@natalenko.name>
On 26.10.2018 22:54, Oleksandr Natalenko wrote:
> Hi.
>
> On 26.10.2018 22:25, Dave Taht wrote:
>> Can you repeat your test, disabling gro splitting in cake?
>>
>> the option is "no-split-gso"
>
> Still panics. Takes a couple of rounds, but panics.
>
> Moreover, I've stressed my HTB setup like this too for a longer time, and it panics as well. So, at least, now I have a proof this is not a CAKE-specific thing.
>
> Also, I've stressed it even with noqueue, and the panic is still there. So, this thing is not even sch-specific.
>
> Next, I've seen GRO bits in the call trace and decided to disable GRO on this NIC. So far, I cannot trigger a panic with GRO disabled even after 20 rounds of speedtest.
>
> So, must be some generic thing indeed.
>
In net-next there's the following patch which mentions in the
description that it "eliminates spurious list pointer poisoning":
992cba7e276d ("net: Add and use skb_list_del_init().")
And spurious list pointer poisoning is what we see here (IMO).
As an idea this patch and a8305bff6852 ("net: Add and use skb_mark_not_on_list().")
from net-next could be applied on top of 4.19. Would be curious
whether it fixes the issue.
^ permalink raw reply
* Re: [RFC PATCH 1/3] can: m_can: Create m_can core to leverage common code
From: Wolfgang Grandegger @ 2018-10-27 14:19 UTC (permalink / raw)
To: Dan Murphy, mkl, davem; +Cc: linux-can, netdev, linux-kernel
In-Reply-To: <20181010142055.25271-2-dmurphy@ti.com>
Hello Dan,
for the RFC, could you please just do the necessary changes to the
existing code. We can discuss about better names, etc. later. For
the review if the common code I quickly did:
mv m_can.c m_can_platform.c
mv m_can_core.c m_can.c
The file names are similar to what we have for the C_CAN driver.
s/classdev/priv/
variable name s/m_can_dev/priv/
Then your patch 1/3 looks as shown below. I'm going to comment on that
one. The comments start with "***"....
>From 9966873dc261b2703e0545718222874ba1b88638 Mon Sep 17 00:00:00 2001
From: Dan Murphy <dmurphy@ti.com>
Date: Wed, 10 Oct 2018 09:20:53 -0500
Subject: [PATCH] can: m_can: Create m_can core to leverage common code
Create a common code base that can be leveraged by other
devices that use the Bosch MCAN IP.
The common code manages the MCAN IP as well as registering
the CAN device.
Signed-off-by: Dan Murphy <dmurphy@ti.com>
---
drivers/net/can/m_can/Kconfig | 12 +
drivers/net/can/m_can/Makefile | 3 +-
drivers/net/can/m_can/m_can.c | 385 +++++++++++++++------------------
drivers/net/can/m_can/m_can_core.h | 100 +++++++++
drivers/net/can/m_can/m_can_platform.c | 168 ++++++++++++++
5 files changed, 461 insertions(+), 207 deletions(-)
create mode 100644 drivers/net/can/m_can/m_can_core.h
create mode 100644 drivers/net/can/m_can/m_can_platform.c
diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig
index 04f20dd..b1a9358 100644
--- a/drivers/net/can/m_can/Kconfig
+++ b/drivers/net/can/m_can/Kconfig
@@ -1,5 +1,17 @@
config CAN_M_CAN
+ tristate "Bosch M_CAN support"
+ ---help---
+ Say Y here if you want to support for Bosch M_CAN controller.
+
+config CAN_M_CAN_CORE
+ depends on CAN_M_CAN
+ tristate "Bosch M_CAN Core support"
+ ---help---
+ Say Y here if you want to support for Bosch M_CAN controller.
+
+config CAN_M_CAN_PLATFORM
depends on HAS_IOMEM
+ depends on CAN_M_CAN_CORE
tristate "Bosch M_CAN devices"
---help---
Say Y here if you want to support for Bosch M_CAN controller.
diff --git a/drivers/net/can/m_can/Makefile b/drivers/net/can/m_can/Makefile
index 8bbd7f2..e013d6f 100644
--- a/drivers/net/can/m_can/Makefile
+++ b/drivers/net/can/m_can/Makefile
@@ -2,4 +2,5 @@
# Makefile for the Bosch M_CAN controller driver.
#
-obj-$(CONFIG_CAN_M_CAN) += m_can.o
+obj-$(CONFIG_CAN_M_CAN_CORE) += m_can_core.o
+obj-$(CONFIG_CAN_M_CAN_PLATFORM) += m_can.o
*** I haven't updated Kconfig and Makefile... it needs some adoptions anyway.
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index 9b44940..4fb4269 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -28,6 +28,8 @@
#include <linux/can/dev.h>
#include <linux/pinctrl/consumer.h>
+#include "m_can_core.h"
+
/* napi related */
#define M_CAN_NAPI_WEIGHT 64
@@ -86,28 +88,6 @@ enum m_can_reg {
M_CAN_TXEFA = 0xf8,
};
-/* m_can lec values */
-enum m_can_lec_type {
- LEC_NO_ERROR = 0,
- LEC_STUFF_ERROR,
- LEC_FORM_ERROR,
- LEC_ACK_ERROR,
- LEC_BIT1_ERROR,
- LEC_BIT0_ERROR,
- LEC_CRC_ERROR,
- LEC_UNUSED,
-};
-
-enum m_can_mram_cfg {
- MRAM_SIDF = 0,
- MRAM_XIDF,
- MRAM_RXF0,
- MRAM_RXF1,
- MRAM_RXB,
- MRAM_TXE,
- MRAM_TXB,
- MRAM_CFG_NUM,
-};
/* Core Release Register (CREL) */
#define CREL_REL_SHIFT 28
@@ -347,68 +327,100 @@ enum m_can_mram_cfg {
#define TX_EVENT_MM_SHIFT TX_BUF_MM_SHIFT
#define TX_EVENT_MM_MASK (0xff << TX_EVENT_MM_SHIFT)
-/* address offset and element number for each FIFO/Buffer in the Message RAM */
-struct mram_cfg {
- u16 off;
- u8 num;
-};
-
-/* m_can private data structure */
-struct m_can_priv {
- struct can_priv can; /* must be the first member */
- struct napi_struct napi;
- struct net_device *dev;
- struct device *device;
- struct clk *hclk;
- struct clk *cclk;
- void __iomem *base;
- u32 irqstatus;
- int version;
-
- /* message ram configuration */
- void __iomem *mram_base;
- struct mram_cfg mcfg[MRAM_CFG_NUM];
-};
-
static inline u32 m_can_read(const struct m_can_priv *priv, enum m_can_reg reg)
{
- return readl(priv->base + reg);
+ u32 ret;
+
+ if (priv->m_can_write)
+ ret = priv->m_can_read(priv, priv->reg_offset + reg);
+ else
+ ret = readl(priv->base + reg);
*** Why not just
return priv->m_can_read(priv, priv->reg_offset, reg);
for both cases. Do we need "reg_offset" here or is it only needed in
platform code?
+
+ return ret;
}
-static inline void m_can_write(const struct m_can_priv *priv,
+static inline int m_can_write(const struct m_can_priv *priv,
enum m_can_reg reg, u32 val)
{
- writel(val, priv->base + reg);
+ int ret = 0;
+
+ if (priv->m_can_write)
+ ret = priv->m_can_write(priv, priv->reg_offset + reg, val);
+ else
+ writel(val, priv->base + reg);
*** Ditto.
+
+ return ret;
}
static inline u32 m_can_fifo_read(const struct m_can_priv *priv,
u32 fgi, unsigned int offset)
{
- return readl(priv->mram_base + priv->mcfg[MRAM_RXF0].off +
- fgi * RXF0_ELEMENT_SIZE + offset);
+ u32 addr_offset = priv->mcfg[MRAM_RXF0].off + fgi * RXF0_ELEMENT_SIZE + offset;
+ u32 read_fifo_addr; /* need to take into account iomem cases */
+ u32 ret = 0;
+
+ if (priv->mram_start)
+ read_fifo_addr = priv->mram_start + addr_offset;
+ else
+ read_fifo_addr = priv->mram_base + addr_offset;
*** Why do we need two platform-specific variables here? Couldn't it
be hidden in platform-specific code?
+ if (priv->m_can_fifo_read)
+ ret = priv->m_can_read(priv, read_fifo_addr);
*** Shouldn't that use "priv->m_can_fifo_read"? Looking to "tcan4x5x.c",
the functions "m_can_read" and "m_can_fifo_read" are identical.
+ else
+ ret = readl(read_fifo_addr);
+
+ return ret;
}
static inline void m_can_fifo_write(const struct m_can_priv *priv,
u32 fpi, unsigned int offset, u32 val)
{
- writel(val, priv->mram_base + priv->mcfg[MRAM_TXB].off +
- fpi * TXB_ELEMENT_SIZE + offset);
+ u32 addr_offset = priv->mcfg[MRAM_TXB].off + fpi * TXB_ELEMENT_SIZE + offset;
+ u32 write_fifo_addr;
+ u32 ret;
+
+ if (priv->mram_start)
+ write_fifo_addr = priv->mram_start + addr_offset;
+ else
+ write_fifo_addr = priv->mram_base + addr_offset;
+
+ if (priv->m_can_write)
+ ret = priv->m_can_write(priv, write_fifo_addr, val);
+ else
+ writel(val, write_fifo_addr);
+
+ return ret;
}
static inline u32 m_can_txe_fifo_read(const struct m_can_priv *priv,
u32 fgi,
- u32 offset) {
- return readl(priv->mram_base + priv->mcfg[MRAM_TXE].off +
- fgi * TXE_ELEMENT_SIZE + offset);
+ u32 offset)
+{
+ u32 addr_offset = priv->mcfg[MRAM_TXE].off + fgi * TXE_ELEMENT_SIZE + offset;
+ u32 read_fifo_addr;
+ u32 ret = 0;
+
+printk("%s: Here\n", __func__);
+ if (priv->mram_start)
+ read_fifo_addr = priv->mram_start + addr_offset;
+ else
+ read_fifo_addr = priv->mram_base + addr_offset;
+
+ if (priv->m_can_fifo_read)
+ ret = priv->m_can_read(priv, read_fifo_addr);
+ else
+ ret = readl(read_fifo_addr);
+
+ return ret;
}
static inline bool m_can_tx_fifo_full(const struct m_can_priv *priv)
{
+printk("%s: Here\n", __func__);
return !!(m_can_read(priv, M_CAN_TXFQS) & TXFQS_TFQF);
}
-static inline void m_can_config_endisable(const struct m_can_priv *priv,
- bool enable)
+void m_can_config_endisable(const struct m_can_priv *priv, bool enable)
{
u32 cccr = m_can_read(priv, M_CAN_CCCR);
u32 timeout = 10;
@@ -430,7 +442,7 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv,
while ((m_can_read(priv, M_CAN_CCCR) & (CCCR_INIT | CCCR_CCE)) != val) {
if (timeout == 0) {
- netdev_warn(priv->dev, "Failed to init module\n");
+ netdev_warn(priv->net, "Failed to init module\n");
return;
}
timeout--;
@@ -457,7 +469,7 @@ static void m_can_read_fifo(struct net_device *dev, u32 rxfs)
struct sk_buff *skb;
u32 id, fgi, dlc;
int i;
-
+printk("%s: Here\n", __func__);
/* calculate the fifo get index for where to read data */
fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_SHIFT;
dlc = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
@@ -512,7 +524,7 @@ static int m_can_do_rx_poll(struct net_device *dev, int quota)
struct m_can_priv *priv = netdev_priv(dev);
u32 pkts = 0;
u32 rxfs;
-
+printk("%s: Here\n", __func__);
rxfs = m_can_read(priv, M_CAN_RXF0S);
if (!(rxfs & RXFS_FFL_MASK)) {
netdev_dbg(dev, "no messages in fifo0\n");
@@ -541,7 +553,7 @@ static int m_can_handle_lost_msg(struct net_device *dev)
struct net_device_stats *stats = &dev->stats;
struct sk_buff *skb;
struct can_frame *frame;
-
+printk("%s: Here\n", __func__);
netdev_err(dev, "msg lost in rxf0\n");
stats->rx_errors++;
@@ -566,7 +578,7 @@ static int m_can_handle_lec_err(struct net_device *dev,
struct net_device_stats *stats = &dev->stats;
struct can_frame *cf;
struct sk_buff *skb;
-
+printk("%s: Here\n", __func__);
priv->can.can_stats.bus_error++;
stats->rx_errors++;
@@ -633,9 +645,12 @@ static int m_can_clk_start(struct m_can_priv *priv)
{
int err;
- err = pm_runtime_get_sync(priv->device);
+ if (priv->pm_clock_support == 0)
+ return 0;
+
+ err = pm_runtime_get_sync(priv->dev);
if (err < 0) {
- pm_runtime_put_noidle(priv->device);
+ pm_runtime_put_noidle(priv->dev);
return err;
}
@@ -644,7 +659,8 @@ static int m_can_clk_start(struct m_can_priv *priv)
static void m_can_clk_stop(struct m_can_priv *priv)
{
- pm_runtime_put_sync(priv->device);
+ if (priv->pm_clock_support)
+ pm_runtime_put_sync(priv->dev);
}
static int m_can_get_berr_counter(const struct net_device *dev,
@@ -1150,17 +1166,17 @@ static void m_can_chip_config(struct net_device *dev)
/* route all interrupts to INT0 */
m_can_write(priv, M_CAN_ILS, ILS_ALL_INT0);
-
+printk("%s: Bit timing\n", __func__);
/* set bittiming params */
m_can_set_bittiming(dev);
-
+printk("%s: out\n", __func__);
m_can_config_endisable(priv, false);
}
static void m_can_start(struct net_device *dev)
{
struct m_can_priv *priv = netdev_priv(dev);
-
+printk("%s: Hear\n", __func__);
/* basic m_can configuration */
m_can_chip_config(dev);
@@ -1171,6 +1187,7 @@ static void m_can_start(struct net_device *dev)
static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
{
+printk("%s: Hear\n", __func__);
switch (mode) {
case CAN_MODE_START:
m_can_start(dev);
@@ -1188,20 +1205,17 @@ static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
* else it returns the release and step coded as:
* return value = 10 * <release> + 1 * <step>
*/
-static int m_can_check_core_release(void __iomem *m_can_base)
+static int m_can_check_core_release(struct m_can_priv *priv)
{
u32 crel_reg;
u8 rel;
u8 step;
int res;
- struct m_can_priv temp_priv = {
- .base = m_can_base
- };
/* Read Core Release Version and split into version number
* Example: Version 3.2.1 => rel = 3; step = 2; substep = 1;
*/
- crel_reg = m_can_read(&temp_priv, M_CAN_CREL);
+ crel_reg = m_can_read(priv, M_CAN_CREL);
rel = (u8)((crel_reg & CREL_REL_MASK) >> CREL_REL_SHIFT);
step = (u8)((crel_reg & CREL_STEP_MASK) >> CREL_STEP_SHIFT);
@@ -1222,47 +1236,45 @@ static int m_can_check_core_release(void __iomem *m_can_base)
static bool m_can_niso_supported(const struct m_can_priv *priv)
{
u32 cccr_reg, cccr_poll;
- int niso_timeout;
+ int niso_timeout = 0;
m_can_config_endisable(priv, true);
cccr_reg = m_can_read(priv, M_CAN_CCCR);
cccr_reg |= CCCR_NISO;
m_can_write(priv, M_CAN_CCCR, cccr_reg);
-
- niso_timeout = readl_poll_timeout((priv->base + M_CAN_CCCR), cccr_poll,
- (cccr_poll == cccr_reg), 0, 10);
+printk("%s: Fix readl poll timeout\n", __func__);
+/* niso_timeout = readl_poll_timeout((priv->base + M_CAN_CCCR), cccr_poll,
+ (cccr_poll == cccr_reg), 0, 10);*/
/* Clear NISO */
cccr_reg &= ~(CCCR_NISO);
m_can_write(priv, M_CAN_CCCR, cccr_reg);
m_can_config_endisable(priv, false);
-
+printk("%s: out\n", __func__);
/* return false if time out (-ETIMEDOUT), else return true */
return !niso_timeout;
}
-static int m_can_dev_setup(struct platform_device *pdev, struct net_device *dev,
- void __iomem *addr)
+static int m_can_dev_setup(struct net_device *dev)
{
struct m_can_priv *priv;
int m_can_version;
- m_can_version = m_can_check_core_release(addr);
+ priv = netdev_priv(dev);
+
+ m_can_version = m_can_check_core_release(priv);
/* return if unsupported version */
if (!m_can_version) {
- dev_err(&pdev->dev, "Unsupported version number: %2d",
+ dev_err(priv->dev, "Unsupported version number: %2d",
m_can_version);
return -EINVAL;
}
- priv = netdev_priv(dev);
netif_napi_add(dev, &priv->napi, m_can_poll, M_CAN_NAPI_WEIGHT);
/* Shared properties of all M_CAN versions */
priv->version = m_can_version;
- priv->dev = dev;
- priv->base = addr;
priv->can.do_set_mode = m_can_set_mode;
priv->can.do_get_berr_counter = m_can_get_berr_counter;
@@ -1297,7 +1309,7 @@ static int m_can_dev_setup(struct platform_device *pdev, struct net_device *dev,
: 0);
break;
default:
- dev_err(&pdev->dev, "Unsupported version number: %2d",
+ dev_err(priv->dev, "Unsupported version number: %2d",
priv->version);
return -EINVAL;
}
@@ -1515,20 +1527,6 @@ static int register_m_can_dev(struct net_device *dev)
return register_candev(dev);
}
-static void m_can_init_ram(struct m_can_priv *priv)
-{
- int end, i, start;
-
- /* initialize the entire Message RAM in use to avoid possible
- * ECC/parity checksum errors when reading an uninitialized buffer
- */
- start = priv->mcfg[MRAM_SIDF].off;
- end = priv->mcfg[MRAM_TXB].off +
- priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
- for (i = start; i < end; i += 4)
- writel(0x0, priv->mram_base + i);
-}
-
static void m_can_of_parse_mram(struct m_can_priv *priv,
const u32 *mram_config_vals)
{
@@ -1556,7 +1554,7 @@ static void m_can_of_parse_mram(struct m_can_priv *priv,
priv->mcfg[MRAM_TXB].num = mram_config_vals[7] &
(TXBC_NDTB_MASK >> TXBC_NDTB_SHIFT);
- dev_dbg(priv->device,
+ dev_dbg(priv->dev,
"mram_base %p sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n",
priv->mram_base,
priv->mcfg[MRAM_SIDF].off, priv->mcfg[MRAM_SIDF].num,
@@ -1566,63 +1564,57 @@ static void m_can_of_parse_mram(struct m_can_priv *priv,
priv->mcfg[MRAM_RXB].off, priv->mcfg[MRAM_RXB].num,
priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
-
- m_can_init_ram(priv);
}
-static int m_can_plat_probe(struct platform_device *pdev)
+void m_can_init_ram(struct m_can_priv *priv)
{
- struct net_device *dev;
- struct m_can_priv *priv;
- struct resource *res;
- void __iomem *addr;
- void __iomem *mram_addr;
- struct clk *hclk, *cclk;
- int irq, ret;
- struct device_node *np;
- u32 mram_config_vals[MRAM_CFG_LEN];
- u32 tx_fifo_size;
-
- np = pdev->dev.of_node;
+ int end, i, start;
- hclk = devm_clk_get(&pdev->dev, "hclk");
- cclk = devm_clk_get(&pdev->dev, "cclk");
+ /* initialize the entire Message RAM in use to avoid possible
+ * ECC/parity checksum errors when reading an uninitialized buffer
+ */
+ start = priv->mcfg[MRAM_SIDF].off;
+ end = priv->mcfg[MRAM_TXB].off +
+ priv->mcfg[MRAM_TXB].num * TXB_ELEMENT_SIZE;
- if (IS_ERR(hclk) || IS_ERR(cclk)) {
- dev_err(&pdev->dev, "no clock found\n");
- ret = -ENODEV;
- goto failed_ret;
+ for (i = start; i < end; i += 4) {
+ if (priv->mram_start)
+ m_can_write(priv, priv->mram_start + i, 0x0);
+ else
+ writel(0x0, priv->mram_base + i);
*** See my comments above.
}
+}
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m_can");
- addr = devm_ioremap_resource(&pdev->dev, res);
- irq = platform_get_irq_byname(pdev, "int0");
+int m_can_core_get_clocks(struct m_can_priv *priv)
+{
+ int ret = 0;
- if (IS_ERR(addr) || irq < 0) {
- ret = -EINVAL;
- goto failed_ret;
- }
+ priv->hclk = devm_clk_get(priv->dev, "hclk");
+ priv->cclk = devm_clk_get(priv->dev, "cclk");
- /* message ram could be shared */
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram");
- if (!res) {
+ if (IS_ERR(priv->cclk)) {
+ dev_err(priv->dev, "no clock found\n");
ret = -ENODEV;
- goto failed_ret;
}
- mram_addr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
- if (!mram_addr) {
- ret = -ENOMEM;
- goto failed_ret;
- }
+ return ret;
+}
- /* get message ram configuration */
- ret = of_property_read_u32_array(np, "bosch,mram-cfg",
- mram_config_vals,
- sizeof(mram_config_vals) / 4);
+struct m_can_priv *m_can_core_allocate_dev(struct device *dev)
+{
+ struct m_can_priv *class_dev = NULL;
+ u32 mram_config_vals[MRAM_CFG_LEN];
+ struct net_device *net_dev;
+ u32 tx_fifo_size;
+ int ret;
+
+ ret = fwnode_property_read_u32_array(dev_fwnode(dev),
+ "bosch,mram-cfg",
+ mram_config_vals,
+ sizeof(mram_config_vals) / 4);
if (ret) {
- dev_err(&pdev->dev, "Could not get Message RAM configuration.");
- goto failed_ret;
+ dev_err(dev, "Could not get Message RAM configuration.");
+ goto out;
}
/* Get TX FIFO size
@@ -1631,50 +1623,57 @@ static int m_can_plat_probe(struct platform_device *pdev)
tx_fifo_size = mram_config_vals[7];
/* allocate the m_can device */
- dev = alloc_candev(sizeof(*priv), tx_fifo_size);
- if (!dev) {
- ret = -ENOMEM;
- goto failed_ret;
+ net_dev = alloc_candev(sizeof(*class_dev), tx_fifo_size);
+ if (!net_dev) {
+ dev_err(dev, "Failed to allocate CAN device");
+ goto out;
}
- priv = netdev_priv(dev);
- dev->irq = irq;
- priv->device = &pdev->dev;
- priv->hclk = hclk;
- priv->cclk = cclk;
- priv->can.clock.freq = clk_get_rate(cclk);
- priv->mram_base = mram_addr;
-
- platform_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- /* Enable clocks. Necessary to read Core Release in order to determine
- * M_CAN version
- */
- pm_runtime_enable(&pdev->dev);
- ret = m_can_clk_start(priv);
- if (ret)
- goto pm_runtime_fail;
+ class_dev = netdev_priv(net_dev);
+ if (!class_dev) {
+ dev_err(dev, "Failed to init netdev private");
+ goto out;
+ }
+
+ class_dev->net = net_dev;
+ class_dev->dev = dev;
+ SET_NETDEV_DEV(net_dev, dev);
+
+ m_can_of_parse_mram(class_dev, mram_config_vals);
+out:
+ return class_dev;
+}
+
+int m_can_core_register(struct m_can_priv *priv)
+{
+ int ret;
- ret = m_can_dev_setup(pdev, dev, addr);
+ if (priv->pm_clock_support) {
+ pm_runtime_enable(priv->dev);
+ ret = m_can_clk_start(priv);
+ if (ret)
+ goto pm_runtime_fail;
+ }
+
+ ret = priv_setup(priv->net);
if (ret)
goto clk_disable;
- ret = register_m_can_dev(dev);
+ ret = register_priv(priv->net);
if (ret) {
- dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
- KBUILD_MODNAME, ret);
+ dev_err(priv->dev, "registering %s failed (err=%d)\n",
+ priv->net->name, ret);
goto clk_disable;
}
- m_can_of_parse_mram(priv, mram_config_vals);
+ devm_can_led_init(priv->net);
- devm_can_led_init(dev);
+ of_can_transceiver(priv->net);
- of_can_transceiver(dev);
+ dev_info(priv->dev, "%s device registered (irq=%d, version=%d)\n",
+ KBUILD_MODNAME, priv->net->irq, priv->version);
- dev_info(&pdev->dev, "%s device registered (irq=%d, version=%d)\n",
- KBUILD_MODNAME, dev->irq, priv->version);
+ m_can_set_bittiming(priv->net);
/* Probe finished
* Stop clocks. They will be reactivated once the M_CAN device is opened
@@ -1683,14 +1682,14 @@ static int m_can_plat_probe(struct platform_device *pdev)
m_can_clk_stop(priv);
pm_runtime_fail:
if (ret) {
- pm_runtime_disable(&pdev->dev);
- free_candev(dev);
+ pm_runtime_disable(priv->dev);
+ free_candev(priv->net);
}
-failed_ret:
+
return ret;
}
-static __maybe_unused int m_can_suspend(struct device *dev)
+int m_can_core_suspend(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct m_can_priv *priv = netdev_priv(ndev);
@@ -1709,7 +1708,7 @@ static __maybe_unused int m_can_suspend(struct device *dev)
return 0;
}
-static __maybe_unused int m_can_resume(struct device *dev)
+int m_can_core_resume(struct device *dev)
{
struct net_device *ndev = dev_get_drvdata(dev);
struct m_can_priv *priv = netdev_priv(ndev);
@@ -1747,8 +1746,6 @@ static int m_can_plat_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
-
free_candev(dev);
return 0;
@@ -1782,30 +1779,6 @@ static int __maybe_unused m_can_runtime_resume(struct device *dev)
return err;
}
-static const struct dev_pm_ops m_can_pmops = {
- SET_RUNTIME_PM_OPS(m_can_runtime_suspend,
- m_can_runtime_resume, NULL)
- SET_SYSTEM_SLEEP_PM_OPS(m_can_suspend, m_can_resume)
-};
-
-static const struct of_device_id m_can_of_table[] = {
- { .compatible = "bosch,m_can", .data = NULL },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, m_can_of_table);
-
-static struct platform_driver m_can_plat_driver = {
- .driver = {
- .name = KBUILD_MODNAME,
- .of_match_table = m_can_of_table,
- .pm = &m_can_pmops,
- },
- .probe = m_can_plat_probe,
- .remove = m_can_plat_remove,
-};
-
-module_platform_driver(m_can_plat_driver);
-
MODULE_AUTHOR("Dong Aisheng <b29396@freescale.com>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("CAN bus driver for Bosch M_CAN controller");
*** I didn't review the rest of the patch for now.
Looking to the generic code, you didn't really change the way
the driver is accessing the registers. Also the interrupt handling
and rx polling is as it was before. Does that work properly using
the SPI interface of the TCAN4x5x?
I was also thinking about optimized read/write functions handling
more than 4 bytes of data, e.g. for the CAN payload data. That
would speed-up SPI transfers, I think. But that could also be
introduced later-on.
Wolfgang.
^ permalink raw reply related
* [PATCH] xfrm: Fix error return code in xfrm_output_one()
From: Wei Yongjun @ 2018-10-27 6:12 UTC (permalink / raw)
To: Steffen Klassert, Herbert Xu; +Cc: Wei Yongjun, netdev, kernel-janitors
xfrm_output_one() does not return a error code when there is
no dst_entry attached to the skb, it is still possible crash
with a NULL pointer dereference in xfrm_output_resume(). Fix
it by return error code -EHOSTUNREACH.
Fixes: 9e1437937807 ("xfrm: Fix NULL pointer dereference when skb_dst_force clears the dst_entry.")
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
---
net/xfrm/xfrm_output.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 4ae87c5c..fef6b2d 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -102,6 +102,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
skb_dst_force(skb);
if (!skb_dst(skb)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
+ err = -EHOSTUNREACH;
goto error_nolock;
}
^ permalink raw reply related
* Re: CAKE and r8169 cause panic on upload in v4.19
From: Oleksandr Natalenko @ 2018-10-27 15:37 UTC (permalink / raw)
To: Heiner Kallweit
Cc: Dave Taht, David S. Miller, Toke Høiland-Jørgensen,
Jamal Hadi Salim, Cong Wang, Jiří Pírko,
Linux Kernel Network Developers, linux-kernel
In-Reply-To: <1beabdd3-dbac-de8a-07b0-d0788b1dbc38@gmail.com>
Hi.
On 27.10.2018 15:43, Heiner Kallweit wrote:
> In net-next there's the following patch which mentions in the
> description that it "eliminates spurious list pointer poisoning":
> 992cba7e276d ("net: Add and use skb_list_del_init().")
> And spurious list pointer poisoning is what we see here (IMO).
>
> As an idea this patch and a8305bff6852 ("net: Add and use
> skb_mark_not_on_list().")
> from net-next could be applied on top of 4.19. Would be curious
> whether it fixes the issue.
Applied both, still panics. %r12/%r15 are still poisoned too.
--
Oleksandr Natalenko (post-factum)
^ permalink raw reply
* Re: [net:master 17/19] net//bridge/br_multicast.c:1432:32: error: 'union <anonymous>' has no member named 'ip6'; did you mean 'ip4'?
From: Nikolay Aleksandrov @ 2018-10-27 7:10 UTC (permalink / raw)
To: kbuild test robot, Hangbin Liu; +Cc: kbuild-all, netdev
In-Reply-To: <201810270855.stkRNjNp%fengguang.wu@intel.com>
On 27/10/2018 03:50, kbuild test robot wrote:
> tree: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git master
> head: aab456dfa404f3a16d6f1780e62a6a8533c4d008
> commit: 5a2de63fd1a59c30c02526d427bc014b98adf508 [17/19] bridge: do not add port to router list when receives query with source 0.0.0.0
> config: powerpc-defconfig (attached as .config)
> compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> git checkout 5a2de63fd1a59c30c02526d427bc014b98adf508
> # save the attached .config to linux build tree
> GCC_VERSION=7.2.0 make.cross ARCH=powerpc
>
> All errors (new ones prefixed by >>):
>
> net//bridge/br_multicast.c: In function 'br_multicast_query_received':
>>> net//bridge/br_multicast.c:1432:32: error: 'union <anonymous>' has no member named 'ip6'; did you mean 'ip4'?
> !ipv6_addr_any(&saddr->u.ip6)))
> ^~~
> ip4
>
> vim +1432 net//bridge/br_multicast.c
>
> 1414
> 1415 static void br_multicast_query_received(struct net_bridge *br,
> 1416 struct net_bridge_port *port,
> 1417 struct bridge_mcast_other_query *query,
> 1418 struct br_ip *saddr,
> 1419 unsigned long max_delay)
> 1420 {
> 1421 if (!br_multicast_select_querier(br, port, saddr))
> 1422 return;
> 1423
> 1424 br_multicast_update_query_timer(br, query, max_delay);
> 1425
> 1426 /* Based on RFC4541, section 2.1.1 IGMP Forwarding Rules,
> 1427 * the arrival port for IGMP Queries where the source address
> 1428 * is 0.0.0.0 should not be added to router port list.
> 1429 */
> 1430 if ((saddr->proto == htons(ETH_P_IP) && saddr->u.ip4) ||
> 1431 (saddr->proto == htons(ETH_P_IPV6) &&
>> 1432 !ipv6_addr_any(&saddr->u.ip6)))
> 1433 br_multicast_mark_router(br, port);
> 1434 }
> 1435
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
>
Should've seen this one coming when reviewing the patch, ip6 is defined
only when IPv6 is configured.
I'll send a fix in a minute after running a few tests.
Thanks.
^ permalink raw reply
* [Patch V2 net 05/11] net: hns3: remove unnecessary queue reset in the hns3_uninit_all_ring()
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
It is not necessary to reset the queue in the hns3_uninit_all_ring(),
since the queue is stopped in the down operation, and will be resetted
in the up operaton. And the judgment of the HCLGE_STATE_RST_HANDLING
flag in the hclge_reset_tqp() is not correct, because we need to reset
tqp during pf reset, otherwise it may cause queue not be resetted to
working state problem.
Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 3 ---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 ---
2 files changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 6f0fd62..a80ecfb 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -3240,9 +3240,6 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv)
int i;
for (i = 0; i < h->kinfo.num_tqps; i++) {
- if (h->ae_algo->ops->reset_queue)
- h->ae_algo->ops->reset_queue(h, i);
-
hns3_fini_ring(priv->ring_data[i].ring);
hns3_fini_ring(priv->ring_data[i + h->kinfo.num_tqps].ring);
}
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 2a63147..4dd0506 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -6116,9 +6116,6 @@ void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
u16 queue_gid;
int ret;
- if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
- return;
-
queue_gid = hclge_covert_handle_qid_global(handle, queue_id);
ret = hclge_tqp_enable(hdev, queue_id, 0, false);
--
2.7.4
^ permalink raw reply related
* [Patch V2 net 03/11] net: hns3: bugfix for reporting unknown vector0 interrupt repeatly problem
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
The current driver supports handling two vector0 interrupts, reset and
mailbox. When the hardware reports an interrupt of another type of
interrupt source, if the driver does not process the interrupt and
enables the interrupt, the hardware will repeatedly report the unknown
interrupt.
Therefore, the driver enables the vector0 interrupt after clearing the
known type of interrupt source. Other conditions are not enabled.
Fixes: cd8c5c269b1d ("net: hns3: Fix for hclge_reset running repeatly problem")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 5234b53..2a63147 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2236,7 +2236,7 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data)
}
/* clear the source of interrupt if it is not cause by reset */
- if (event_cause != HCLGE_VECTOR0_EVENT_RST) {
+ if (event_cause == HCLGE_VECTOR0_EVENT_MBX) {
hclge_clear_event_cause(hdev, event_cause, clearval);
hclge_enable_vector(&hdev->misc_vector, true);
}
--
2.7.4
^ permalink raw reply related
* [Patch V2 net 07/11] net: hns3: bugfix for hclge_mdio_write and hclge_mdio_read
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
When there is a PHY, the driver needs to complete some operations through
MDIO during reset reinitialization, so HCLGE_STATE_CMD_DISABLE is more
suitable than HCLGE_STATE_RST_HANDLING to prevent the MDIO operation from
being sent during the hardware reset.
Fixes: b50ae26c57cb ("net: hns3: never send command queue message to IMP when reset)
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
index 24b1f2a..0301863 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
@@ -52,7 +52,7 @@ static int hclge_mdio_write(struct mii_bus *bus, int phyid, int regnum,
struct hclge_desc desc;
int ret;
- if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
+ if (test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state))
return 0;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MDIO_CONFIG, false);
@@ -90,7 +90,7 @@ static int hclge_mdio_read(struct mii_bus *bus, int phyid, int regnum)
struct hclge_desc desc;
int ret;
- if (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
+ if (test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state))
return 0;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MDIO_CONFIG, true);
--
2.7.4
^ permalink raw reply related
* [Patch V2 net 01/11] net: hns3: add error handler for hns3_nic_init_vector_data()
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
When hns3_nic_init_vector_data() failed for mapping ring to vector,
it should cancel the netif_napi_add() that have been successfully done
and then exit.
Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index 32f3aca8..d9066c5 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2821,7 +2821,7 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
struct hnae3_handle *h = priv->ae_handle;
struct hns3_enet_tqp_vector *tqp_vector;
int ret = 0;
- u16 i;
+ int i, j;
hns3_nic_set_cpumask(priv);
@@ -2868,13 +2868,19 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain);
if (ret)
- return ret;
+ goto map_ring_fail;
netif_napi_add(priv->netdev, &tqp_vector->napi,
hns3_nic_common_poll, NAPI_POLL_WEIGHT);
}
return 0;
+
+map_ring_fail:
+ for (j = i - 1; j >= 0; j--)
+ netif_napi_del(&priv->tqp_vector[j].napi);
+
+ return ret;
}
static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
--
2.7.4
^ permalink raw reply related
* [Patch V2 net 00/11] Bugfix for the HNS3 driver
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
This patch series include bugfix for the HNS3 ethernet
controller driver.
Change log:
V1->V2:
Fixes the compilation break reported by kbuild test robot
http://patchwork.ozlabs.org/patch/989818/
Huazhong Tan (11):
net: hns3: add error handler for hns3_nic_init_vector_data()
net: hns3: add error handler for
hns3_get_ring_config/hns3_queue_to_ring
net: hns3: bugfix for reporting unknown vector0 interrupt repeatly
problem
net: hns3: bugfix for the initialization of command queue's spin lock
net: hns3: remove unnecessary queue reset in the
hns3_uninit_all_ring()
net: hns3: bugfix for is_valid_csq_clean_head()
net: hns3: bugfix for hclge_mdio_write and hclge_mdio_read
net: hns3: fix incorrect return value/type of some functions
net: hns3: bugfix for handling mailbox while the command queue
reinitialized
net: hns3: bugfix for rtnl_lock's range in the hclge_reset()
net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset()
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 6 +-
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 105 +++++++++++++++------
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 26 +++--
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 42 ++++-----
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 +-
.../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 6 ++
.../ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 4 +-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 19 ++--
9 files changed, 136 insertions(+), 76 deletions(-)
--
2.7.4
^ permalink raw reply
* [Patch V2 net 08/11] net: hns3: fix incorrect return value/type of some functions
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
There are some functions that, when they fail to execute a send command,
need to return the corresponding error value to its caller.
Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
Fixes: 681ec3999b3d ("net: hns3: fix for vlan table lost problem when resetting")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
V2: Fix the compilation error reported by kbuild test robot
---
drivers/net/ethernet/hisilicon/hns3/hnae3.h | 6 +-
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 80 +++++++++++++++-------
drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 2 +-
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 34 ++++-----
.../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 +-
.../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 14 ++--
6 files changed, 85 insertions(+), 53 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index e82e4ca..055b406 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -316,8 +316,8 @@ struct hnae3_ae_ops {
int (*set_loopback)(struct hnae3_handle *handle,
enum hnae3_loop loop_mode, bool en);
- void (*set_promisc_mode)(struct hnae3_handle *handle, bool en_uc_pmc,
- bool en_mc_pmc);
+ int (*set_promisc_mode)(struct hnae3_handle *handle, bool en_uc_pmc,
+ bool en_mc_pmc);
int (*set_mtu)(struct hnae3_handle *handle, int new_mtu);
void (*get_pauseparam)(struct hnae3_handle *handle,
@@ -391,7 +391,7 @@ struct hnae3_ae_ops {
int vector_num,
struct hnae3_ring_chain_node *vr_chain);
- void (*reset_queue)(struct hnae3_handle *handle, u16 queue_id);
+ int (*reset_queue)(struct hnae3_handle *handle, u16 queue_id);
u32 (*get_fw_version)(struct hnae3_handle *handle);
void (*get_mdix_mode)(struct hnae3_handle *handle,
u8 *tp_mdix_ctrl, u8 *tp_mdix);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
index a80ecfb..4d919b8 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -509,16 +509,18 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev)
h->netdev_flags = new_flags;
}
-void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
+int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
if (h->ae_algo->ops->set_promisc_mode) {
- h->ae_algo->ops->set_promisc_mode(h,
- promisc_flags & HNAE3_UPE,
- promisc_flags & HNAE3_MPE);
+ return h->ae_algo->ops->set_promisc_mode(h,
+ promisc_flags & HNAE3_UPE,
+ promisc_flags & HNAE3_MPE);
}
+
+ return 0;
}
void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
@@ -1494,18 +1496,22 @@ static int hns3_vlan_rx_kill_vid(struct net_device *netdev,
return ret;
}
-static void hns3_restore_vlan(struct net_device *netdev)
+static int hns3_restore_vlan(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
+ int ret = 0;
u16 vid;
- int ret;
for_each_set_bit(vid, priv->active_vlans, VLAN_N_VID) {
ret = hns3_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
- if (ret)
- netdev_warn(netdev, "Restore vlan: %d filter, ret:%d\n",
- vid, ret);
+ if (ret) {
+ netdev_err(netdev, "Restore vlan: %d filter, ret:%d\n",
+ vid, ret);
+ return ret;
+ }
}
+
+ return ret;
}
static int hns3_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
@@ -3247,11 +3253,12 @@ int hns3_uninit_all_ring(struct hns3_nic_priv *priv)
}
/* Set mac addr if it is configured. or leave it to the AE driver */
-static void hns3_init_mac_addr(struct net_device *netdev, bool init)
+static int hns3_init_mac_addr(struct net_device *netdev, bool init)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
u8 mac_addr_temp[ETH_ALEN];
+ int ret = 0;
if (h->ae_algo->ops->get_mac_addr && init) {
h->ae_algo->ops->get_mac_addr(h, mac_addr_temp);
@@ -3266,8 +3273,9 @@ static void hns3_init_mac_addr(struct net_device *netdev, bool init)
}
if (h->ae_algo->ops->set_mac_addr)
- h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr, true);
+ ret = h->ae_algo->ops->set_mac_addr(h, netdev->dev_addr, true);
+ return ret;
}
static int hns3_restore_fd_rules(struct net_device *netdev)
@@ -3480,20 +3488,29 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
return ret;
}
-static void hns3_recover_hw_addr(struct net_device *ndev)
+static int hns3_recover_hw_addr(struct net_device *ndev)
{
struct netdev_hw_addr_list *list;
struct netdev_hw_addr *ha, *tmp;
+ int ret = 0;
/* go through and sync uc_addr entries to the device */
list = &ndev->uc;
- list_for_each_entry_safe(ha, tmp, &list->list, list)
- hns3_nic_uc_sync(ndev, ha->addr);
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ ret = hns3_nic_uc_sync(ndev, ha->addr);
+ if (ret)
+ return ret;
+ }
/* go through and sync mc_addr entries to the device */
list = &ndev->mc;
- list_for_each_entry_safe(ha, tmp, &list->list, list)
- hns3_nic_mc_sync(ndev, ha->addr);
+ list_for_each_entry_safe(ha, tmp, &list->list, list) {
+ ret = hns3_nic_mc_sync(ndev, ha->addr);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
}
static void hns3_remove_hw_addr(struct net_device *netdev)
@@ -3620,7 +3637,10 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h)
int ret;
for (i = 0; i < h->kinfo.num_tqps; i++) {
- h->ae_algo->ops->reset_queue(h, i);
+ ret = h->ae_algo->ops->reset_queue(h, i);
+ if (ret)
+ return ret;
+
hns3_init_ring_hw(priv->ring_data[i].ring);
/* We need to clear tx ring here because self test will
@@ -3712,18 +3732,30 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
bool vlan_filter_enable;
int ret;
- hns3_init_mac_addr(netdev, false);
- hns3_recover_hw_addr(netdev);
- hns3_update_promisc_mode(netdev, handle->netdev_flags);
+ ret = hns3_init_mac_addr(netdev, false);
+ if (ret)
+ return ret;
+
+ ret = hns3_recover_hw_addr(netdev);
+ if (ret)
+ return ret;
+
+ ret = hns3_update_promisc_mode(netdev, handle->netdev_flags);
+ if (ret)
+ return ret;
+
vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true;
hns3_enable_vlan_filter(netdev, vlan_filter_enable);
-
/* Hardware table is only clear when pf resets */
- if (!(handle->flags & HNAE3_SUPPORT_VF))
- hns3_restore_vlan(netdev);
+ if (!(handle->flags & HNAE3_SUPPORT_VF)) {
+ ret = hns3_restore_vlan(netdev);
+ return ret;
+ }
- hns3_restore_fd_rules(netdev);
+ ret = hns3_restore_fd_rules(netdev);
+ if (ret)
+ return ret;
/* Carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
index 71cfca1..d3636d0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -640,7 +640,7 @@ void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
u32 rl_value);
void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
-void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
+int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
#ifdef CONFIG_HNS3_DCB
void hns3_dcbnl_setup(struct hnae3_handle *handle);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index 4dd0506..f3212c9 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -3314,8 +3314,8 @@ void hclge_promisc_param_init(struct hclge_promisc_param *param, bool en_uc,
param->vf_id = vport_id;
}
-static void hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
- bool en_mc_pmc)
+static int hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
+ bool en_mc_pmc)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
@@ -3323,7 +3323,7 @@ static void hclge_set_promisc_mode(struct hnae3_handle *handle, bool en_uc_pmc,
hclge_promisc_param_init(¶m, en_uc_pmc, en_mc_pmc, true,
vport->vport_id);
- hclge_cmd_set_promisc_mode(hdev, ¶m);
+ return hclge_cmd_set_promisc_mode(hdev, ¶m);
}
static int hclge_get_fd_mode(struct hclge_dev *hdev, u8 *fd_mode)
@@ -6107,28 +6107,28 @@ static u16 hclge_covert_handle_qid_global(struct hnae3_handle *handle,
return tqp->index;
}
-void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
+int hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
{
struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back;
int reset_try_times = 0;
int reset_status;
u16 queue_gid;
- int ret;
+ int ret = 0;
queue_gid = hclge_covert_handle_qid_global(handle, queue_id);
ret = hclge_tqp_enable(hdev, queue_id, 0, false);
if (ret) {
- dev_warn(&hdev->pdev->dev, "Disable tqp fail, ret = %d\n", ret);
- return;
+ dev_err(&hdev->pdev->dev, "Disable tqp fail, ret = %d\n", ret);
+ return ret;
}
ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, true);
if (ret) {
- dev_warn(&hdev->pdev->dev,
- "Send reset tqp cmd fail, ret = %d\n", ret);
- return;
+ dev_err(&hdev->pdev->dev,
+ "Send reset tqp cmd fail, ret = %d\n", ret);
+ return ret;
}
reset_try_times = 0;
@@ -6141,16 +6141,16 @@ void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
}
if (reset_try_times >= HCLGE_TQP_RESET_TRY_TIMES) {
- dev_warn(&hdev->pdev->dev, "Reset TQP fail\n");
- return;
+ dev_err(&hdev->pdev->dev, "Reset TQP fail\n");
+ return ret;
}
ret = hclge_send_reset_tqp_cmd(hdev, queue_gid, false);
- if (ret) {
- dev_warn(&hdev->pdev->dev,
- "Deassert the soft reset fail, ret = %d\n", ret);
- return;
- }
+ if (ret)
+ dev_err(&hdev->pdev->dev,
+ "Deassert the soft reset fail, ret = %d\n", ret);
+
+ return ret;
}
void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
index e3dfd65..0d92154 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -778,7 +778,7 @@ int hclge_rss_init_hw(struct hclge_dev *hdev);
void hclge_rss_indir_init_cfg(struct hclge_dev *hdev);
void hclge_mbx_handler(struct hclge_dev *hdev);
-void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
+int hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id);
void hclge_reset_vf_queue(struct hclge_vport *vport, u16 queue_id);
int hclge_cfg_flowctrl(struct hclge_dev *hdev);
int hclge_func_reset_cmd(struct hclge_dev *hdev, int func_id);
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index e0a86a5..b224f6a 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -925,12 +925,12 @@ static int hclgevf_cmd_set_promisc_mode(struct hclgevf_dev *hdev,
return status;
}
-static void hclgevf_set_promisc_mode(struct hnae3_handle *handle,
- bool en_uc_pmc, bool en_mc_pmc)
+static int hclgevf_set_promisc_mode(struct hnae3_handle *handle,
+ bool en_uc_pmc, bool en_mc_pmc)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
- hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc);
+ return hclgevf_cmd_set_promisc_mode(hdev, en_uc_pmc, en_mc_pmc);
}
static int hclgevf_tqp_enable(struct hclgevf_dev *hdev, int tqp_id,
@@ -1080,7 +1080,7 @@ static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
1, false, NULL, 0);
}
-static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
+static int hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
u8 msg_data[2];
@@ -1091,10 +1091,10 @@ static void hclgevf_reset_tqp(struct hnae3_handle *handle, u16 queue_id)
/* disable vf queue before send queue reset msg to PF */
ret = hclgevf_tqp_enable(hdev, queue_id, 0, false);
if (ret)
- return;
+ return ret;
- hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data,
- 2, true, NULL, 0);
+ return hclgevf_send_mbx_msg(hdev, HCLGE_MBX_QUEUE_RESET, 0, msg_data,
+ 2, true, NULL, 0);
}
static int hclgevf_notify_client(struct hclgevf_dev *hdev,
--
2.7.4
^ permalink raw reply related
* [Patch V2 net 10/11] net: hns3: bugfix for rtnl_lock's range in the hclge_reset()
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
Since hclge_reset_wait() is used to wait for the hardware to complete
the reset, it is not necessary to hold the rtnl_lock during
hclge_reset_wait(). So this patch release the lock for the duration
of hclge_reset_wait().
Fixes: 6d4fab39533f ("net: hns3: Reset net device with rtnl_lock")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
index f3212c9..ffdd960 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -2470,14 +2470,17 @@ static void hclge_reset(struct hclge_dev *hdev)
handle = &hdev->vport[0].nic;
rtnl_lock();
hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
+ rtnl_unlock();
if (!hclge_reset_wait(hdev)) {
+ rtnl_lock();
hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT);
hclge_reset_ae_dev(hdev->ae_dev);
hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
hclge_clear_reset_cause(hdev);
} else {
+ rtnl_lock();
/* schedule again to check pending resets later */
set_bit(hdev->reset_type, &hdev->reset_pending);
hclge_reset_task_schedule(hdev);
--
2.7.4
^ permalink raw reply related
* [Patch V2 net 06/11] net: hns3: bugfix for is_valid_csq_clean_head()
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
The HEAD pointer of the hardware command queue maybe equal to the command
queue's next_to_use the driver, so that does not belong to the invalid
HEAD pointer, since the hardware may not process the command in time,
causing the HEAD pointer to be too late to update. The variables' name
in this function is unreadable, so give them a more readable one.
Fixes: 3ff504908f95 ("net: hns3: fix a dead loop in hclge_cmd_csq_clean")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
index 68026a5..690f62e 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
@@ -24,15 +24,15 @@ static int hclge_ring_space(struct hclge_cmq_ring *ring)
return ring->desc_num - used - 1;
}
-static int is_valid_csq_clean_head(struct hclge_cmq_ring *ring, int h)
+static int is_valid_csq_clean_head(struct hclge_cmq_ring *ring, int head)
{
- int u = ring->next_to_use;
- int c = ring->next_to_clean;
+ int ntu = ring->next_to_use;
+ int ntc = ring->next_to_clean;
- if (unlikely(h >= ring->desc_num))
- return 0;
+ if (ntu > ntc)
+ return head >= ntc && head <= ntu;
- return u > c ? (h > c && h <= u) : (h > c || h <= u);
+ return head >= ntc || head <= ntu;
}
static int hclge_alloc_cmd_desc(struct hclge_cmq_ring *ring)
--
2.7.4
^ permalink raw reply related
* [Patch V2 net 09/11] net: hns3: bugfix for handling mailbox while the command queue reinitialized
From: Huazhong Tan @ 2018-10-27 8:10 UTC (permalink / raw)
To: davem; +Cc: netdev, linuxarm, salil.mehta, yisen.zhuang, lipeng321,
linyunsheng
In-Reply-To: <1540627818-17635-1-git-send-email-tanhuazhong@huawei.com>
In a multi-core machine, the mailbox service and reset service
will be executed at the same time. The reset server will re-initialize
the commond queue, before that, the mailbox handler can only get some
invalid messages.
The HCLGE_STATE_CMD_DISABLE flag means that the command queue is not
available and needs to be reinitialized. Therefore, when the mailbox
hanlder recognizes this flag, it should not process the command.
Fixes: dde1a86e93ca ("net: hns3: Add mailbox support to PF driver")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
---
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
index 04462a3..6ac2fab 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
@@ -400,6 +400,12 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
/* handle all the mailbox requests in the queue */
while (!hclge_cmd_crq_empty(&hdev->hw)) {
+ if (test_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state)) {
+ dev_warn(&hdev->pdev->dev,
+ "command queue need re-initialize\n");
+ return;
+ }
+
desc = &crq->desc[crq->next_to_use];
req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data;
--
2.7.4
^ 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