Skip to content

Commit

Permalink
Merge branch 'hns3-fixes'
Browse files Browse the repository at this point in the history
Huazhong Tan says:

====================
Bugfix for the HNS3 driver

This patch series include bugfix for the HNS3 ethernet
controller driver.

Change log:
V4->V5:
	Fixes comments from Joe Perches & Sergei Shtylyov
V3->V4:
	Fixes comments from Sergei Shtylyov
V2->V3:
	Fixes comments from Sergei Shtylyov
V1->V2:
	Fixes the compilation break reported by kbuild test robot
	http://patchwork.ozlabs.org/patch/989818/
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 31, 2018
2 parents d48051c + 29118ab commit c4d63c7
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 77 deletions.
6 changes: 3 additions & 3 deletions drivers/net/ethernet/hisilicon/hns3/hnae3.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
117 changes: 85 additions & 32 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2727,7 +2733,7 @@ static int hns3_get_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector,
chain = devm_kzalloc(&pdev->dev, sizeof(*chain),
GFP_KERNEL);
if (!chain)
return -ENOMEM;
goto err_free_chain;

cur_chain->next = chain;
chain->tqp_index = tx_ring->tqp->tqp_index;
Expand Down Expand Up @@ -2757,7 +2763,7 @@ static int hns3_get_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector,
while (rx_ring) {
chain = devm_kzalloc(&pdev->dev, sizeof(*chain), GFP_KERNEL);
if (!chain)
return -ENOMEM;
goto err_free_chain;

cur_chain->next = chain;
chain->tqp_index = rx_ring->tqp->tqp_index;
Expand All @@ -2772,6 +2778,16 @@ static int hns3_get_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector,
}

return 0;

err_free_chain:
cur_chain = head->next;
while (cur_chain) {
chain = cur_chain->next;
devm_kfree(&pdev->dev, chain);
cur_chain = chain;
}

return -ENOMEM;
}

static void hns3_free_vector_ring_chain(struct hns3_enet_tqp_vector *tqp_vector,
Expand Down Expand Up @@ -2821,7 +2837,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;

hns3_nic_set_cpumask(priv);

Expand Down Expand Up @@ -2868,13 +2884,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:
while (i--)
netif_napi_del(&priv->tqp_vector[i].napi);

return ret;
}

static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
Expand Down Expand Up @@ -3031,8 +3053,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;
}
Expand All @@ -3059,6 +3083,12 @@ static int hns3_get_ring_config(struct hns3_nic_priv *priv)

return 0;
err:
while (i--) {
devm_kfree(priv->dev, priv->ring_data[i].ring);
devm_kfree(priv->dev,
priv->ring_data[i + h->kinfo.num_tqps].ring);
}

devm_kfree(&pdev->dev, priv->ring_data);
return ret;
}
Expand Down Expand Up @@ -3226,21 +3256,19 @@ 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);
}
return 0;
}

/* 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);
Expand All @@ -3255,8 +3283,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)
Expand Down Expand Up @@ -3469,20 +3498,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)
Expand Down Expand Up @@ -3609,7 +3647,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
Expand Down Expand Up @@ -3701,18 +3742,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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
26 changes: 16 additions & 10 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -304,6 +304,10 @@ int hclge_cmd_queue_init(struct hclge_dev *hdev)
{
int ret;

/* Setup the lock for command queue */
spin_lock_init(&hdev->hw.cmq.csq.lock);
spin_lock_init(&hdev->hw.cmq.crq.lock);

/* Setup the queue entries for use cmd queue */
hdev->hw.cmq.csq.desc_num = HCLGE_NIC_CMQ_DESC_NUM;
hdev->hw.cmq.crq.desc_num = HCLGE_NIC_CMQ_DESC_NUM;
Expand Down Expand Up @@ -337,18 +341,20 @@ int hclge_cmd_init(struct hclge_dev *hdev)
u32 version;
int ret;

spin_lock_bh(&hdev->hw.cmq.csq.lock);
spin_lock_bh(&hdev->hw.cmq.crq.lock);

hdev->hw.cmq.csq.next_to_clean = 0;
hdev->hw.cmq.csq.next_to_use = 0;
hdev->hw.cmq.crq.next_to_clean = 0;
hdev->hw.cmq.crq.next_to_use = 0;

/* Setup the lock for command queue */
spin_lock_init(&hdev->hw.cmq.csq.lock);
spin_lock_init(&hdev->hw.cmq.crq.lock);

hclge_cmd_init_regs(&hdev->hw);
clear_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state);

spin_unlock_bh(&hdev->hw.cmq.crq.lock);
spin_unlock_bh(&hdev->hw.cmq.csq.lock);

ret = hclge_cmd_query_firmware_version(&hdev->hw, &version);
if (ret) {
dev_err(&hdev->pdev->dev,
Expand Down
Loading

0 comments on commit c4d63c7

Please sign in to comment.