Commit 01413176 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-fixes'

Huazhong Tan says:

====================
net: hns3: fixes for -net

This patchset includes some bugfixes for the HNS3 ethernet driver.

[patch 1] removes flag WQ_MEM_RECLAIM flag when allocating WE,
since it will cause a warning when the reset task flushes a IB's WQ.

[patch 2] adds a new DESC_TYPE_FRAGLIST_SKB type to handle the
linear data of the fraglist SKB, since it is different with the frag
data.

[patch 3] adds different handings for RSS configuration when load
or reset.

[patch 4] fixes a link ksetting issue.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cf673ed0 a9775bb6
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
enum hns_desc_type { enum hns_desc_type {
DESC_TYPE_SKB, DESC_TYPE_SKB,
DESC_TYPE_FRAGLIST_SKB,
DESC_TYPE_PAGE, DESC_TYPE_PAGE,
}; };
......
...@@ -1106,6 +1106,10 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, ...@@ -1106,6 +1106,10 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
if (unlikely(ret < 0)) if (unlikely(ret < 0))
return ret; return ret;
dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE);
} else if (type == DESC_TYPE_FRAGLIST_SKB) {
struct sk_buff *skb = (struct sk_buff *)priv;
dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE); dma = dma_map_single(dev, skb->data, size, DMA_TO_DEVICE);
} else { } else {
frag = (skb_frag_t *)priv; frag = (skb_frag_t *)priv;
...@@ -1144,8 +1148,9 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv, ...@@ -1144,8 +1148,9 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
/* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */ /* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */
desc_cb->priv = priv; desc_cb->priv = priv;
desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k; desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k;
desc_cb->type = (type == DESC_TYPE_SKB && !k) ? desc_cb->type = ((type == DESC_TYPE_FRAGLIST_SKB ||
DESC_TYPE_SKB : DESC_TYPE_PAGE; type == DESC_TYPE_SKB) && !k) ?
type : DESC_TYPE_PAGE;
/* now, fill the descriptor */ /* now, fill the descriptor */
desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k); desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k);
...@@ -1354,7 +1359,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig) ...@@ -1354,7 +1359,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
ring_ptr_move_bw(ring, next_to_use); ring_ptr_move_bw(ring, next_to_use);
/* unmap the descriptor dma address */ /* unmap the descriptor dma address */
if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB) if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB ||
ring->desc_cb[ring->next_to_use].type ==
DESC_TYPE_FRAGLIST_SKB)
dma_unmap_single(dev, dma_unmap_single(dev,
ring->desc_cb[ring->next_to_use].dma, ring->desc_cb[ring->next_to_use].dma,
ring->desc_cb[ring->next_to_use].length, ring->desc_cb[ring->next_to_use].length,
...@@ -1447,7 +1454,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1447,7 +1454,8 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
goto out; goto out;
skb_walk_frags(skb, frag_skb) { skb_walk_frags(skb, frag_skb) {
ret = hns3_fill_skb_to_desc(ring, frag_skb, DESC_TYPE_PAGE); ret = hns3_fill_skb_to_desc(ring, frag_skb,
DESC_TYPE_FRAGLIST_SKB);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
goto fill_err; goto fill_err;
...@@ -2356,7 +2364,7 @@ static int hns3_map_buffer(struct hns3_enet_ring *ring, struct hns3_desc_cb *cb) ...@@ -2356,7 +2364,7 @@ static int hns3_map_buffer(struct hns3_enet_ring *ring, struct hns3_desc_cb *cb)
static void hns3_unmap_buffer(struct hns3_enet_ring *ring, static void hns3_unmap_buffer(struct hns3_enet_ring *ring,
struct hns3_desc_cb *cb) struct hns3_desc_cb *cb)
{ {
if (cb->type == DESC_TYPE_SKB) if (cb->type == DESC_TYPE_SKB || cb->type == DESC_TYPE_FRAGLIST_SKB)
dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length, dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length,
ring_to_dma_dir(ring)); ring_to_dma_dir(ring));
else if (cb->length) else if (cb->length)
......
...@@ -6765,7 +6765,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable) ...@@ -6765,7 +6765,7 @@ static void hclge_set_timer_task(struct hnae3_handle *handle, bool enable)
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
if (enable) { if (enable) {
hclge_task_schedule(hdev, round_jiffies_relative(HZ)); hclge_task_schedule(hdev, 0);
} else { } else {
/* Set the DOWN flag here to disable link updating */ /* Set the DOWN flag here to disable link updating */
set_bit(HCLGE_STATE_DOWN, &hdev->state); set_bit(HCLGE_STATE_DOWN, &hdev->state);
...@@ -8979,6 +8979,12 @@ static void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type, ...@@ -8979,6 +8979,12 @@ static void hclge_get_media_type(struct hnae3_handle *handle, u8 *media_type,
struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_vport *vport = hclge_get_vport(handle);
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
/* When nic is down, the service task is not running, doesn't update
* the port information per second. Query the port information before
* return the media type, ensure getting the correct media information.
*/
hclge_update_port_info(hdev);
if (media_type) if (media_type)
*media_type = hdev->hw.mac.media_type; *media_type = hdev->hw.mac.media_type;
...@@ -10666,7 +10672,7 @@ static int hclge_init(void) ...@@ -10666,7 +10672,7 @@ static int hclge_init(void)
{ {
pr_info("%s is initializing\n", HCLGE_NAME); pr_info("%s is initializing\n", HCLGE_NAME);
hclge_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, HCLGE_NAME); hclge_wq = alloc_workqueue("%s", 0, 0, HCLGE_NAME);
if (!hclge_wq) { if (!hclge_wq) {
pr_err("%s: failed to create workqueue\n", HCLGE_NAME); pr_err("%s: failed to create workqueue\n", HCLGE_NAME);
return -ENOMEM; return -ENOMEM;
......
...@@ -2124,50 +2124,51 @@ static int hclgevf_config_gro(struct hclgevf_dev *hdev, bool en) ...@@ -2124,50 +2124,51 @@ static int hclgevf_config_gro(struct hclgevf_dev *hdev, bool en)
return ret; return ret;
} }
static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) static void hclgevf_rss_init_cfg(struct hclgevf_dev *hdev)
{ {
struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg; struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
int ret; struct hclgevf_rss_tuple_cfg *tuple_sets;
u32 i; u32 i;
rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_TOEPLITZ;
rss_cfg->rss_size = hdev->nic.kinfo.rss_size; rss_cfg->rss_size = hdev->nic.kinfo.rss_size;
tuple_sets = &rss_cfg->rss_tuple_sets;
if (hdev->pdev->revision >= 0x21) { if (hdev->pdev->revision >= 0x21) {
rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_SIMPLE; rss_cfg->hash_algo = HCLGEVF_RSS_HASH_ALGO_SIMPLE;
memcpy(rss_cfg->rss_hash_key, hclgevf_hash_key, memcpy(rss_cfg->rss_hash_key, hclgevf_hash_key,
HCLGEVF_RSS_KEY_SIZE); HCLGEVF_RSS_KEY_SIZE);
tuple_sets->ipv4_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
tuple_sets->ipv4_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
tuple_sets->ipv4_sctp_en = HCLGEVF_RSS_INPUT_TUPLE_SCTP;
tuple_sets->ipv4_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
tuple_sets->ipv6_tcp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
tuple_sets->ipv6_udp_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
tuple_sets->ipv6_sctp_en = HCLGEVF_RSS_INPUT_TUPLE_SCTP;
tuple_sets->ipv6_fragment_en = HCLGEVF_RSS_INPUT_TUPLE_OTHER;
}
/* Initialize RSS indirect table */
for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size;
}
static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev)
{
struct hclgevf_rss_cfg *rss_cfg = &hdev->rss_cfg;
int ret;
if (hdev->pdev->revision >= 0x21) {
ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo, ret = hclgevf_set_rss_algo_key(hdev, rss_cfg->hash_algo,
rss_cfg->rss_hash_key); rss_cfg->rss_hash_key);
if (ret) if (ret)
return ret; return ret;
rss_cfg->rss_tuple_sets.ipv4_tcp_en =
HCLGEVF_RSS_INPUT_TUPLE_OTHER;
rss_cfg->rss_tuple_sets.ipv4_udp_en =
HCLGEVF_RSS_INPUT_TUPLE_OTHER;
rss_cfg->rss_tuple_sets.ipv4_sctp_en =
HCLGEVF_RSS_INPUT_TUPLE_SCTP;
rss_cfg->rss_tuple_sets.ipv4_fragment_en =
HCLGEVF_RSS_INPUT_TUPLE_OTHER;
rss_cfg->rss_tuple_sets.ipv6_tcp_en =
HCLGEVF_RSS_INPUT_TUPLE_OTHER;
rss_cfg->rss_tuple_sets.ipv6_udp_en =
HCLGEVF_RSS_INPUT_TUPLE_OTHER;
rss_cfg->rss_tuple_sets.ipv6_sctp_en =
HCLGEVF_RSS_INPUT_TUPLE_SCTP;
rss_cfg->rss_tuple_sets.ipv6_fragment_en =
HCLGEVF_RSS_INPUT_TUPLE_OTHER;
ret = hclgevf_set_rss_input_tuple(hdev, rss_cfg); ret = hclgevf_set_rss_input_tuple(hdev, rss_cfg);
if (ret) if (ret)
return ret; return ret;
} }
/* Initialize RSS indirect table */
for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size;
ret = hclgevf_set_rss_indir_table(hdev); ret = hclgevf_set_rss_indir_table(hdev);
if (ret) if (ret)
return ret; return ret;
...@@ -2764,6 +2765,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) ...@@ -2764,6 +2765,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
goto err_config; goto err_config;
/* Initialize RSS for this VF */ /* Initialize RSS for this VF */
hclgevf_rss_init_cfg(hdev);
ret = hclgevf_rss_init_hw(hdev); ret = hclgevf_rss_init_hw(hdev);
if (ret) { if (ret) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
...@@ -2936,6 +2938,8 @@ static int hclgevf_set_channels(struct hnae3_handle *handle, u32 new_tqps_num, ...@@ -2936,6 +2938,8 @@ static int hclgevf_set_channels(struct hnae3_handle *handle, u32 new_tqps_num,
for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++) for (i = 0; i < HCLGEVF_RSS_IND_TBL_SIZE; i++)
rss_indir[i] = i % kinfo->rss_size; rss_indir[i] = i % kinfo->rss_size;
hdev->rss_cfg.rss_size = kinfo->rss_size;
ret = hclgevf_set_rss(handle, rss_indir, NULL, 0); ret = hclgevf_set_rss(handle, rss_indir, NULL, 0);
if (ret) if (ret)
dev_err(&hdev->pdev->dev, "set rss indir table fail, ret=%d\n", dev_err(&hdev->pdev->dev, "set rss indir table fail, ret=%d\n",
...@@ -3188,7 +3192,7 @@ static int hclgevf_init(void) ...@@ -3188,7 +3192,7 @@ static int hclgevf_init(void)
{ {
pr_info("%s is initializing\n", HCLGEVF_NAME); pr_info("%s is initializing\n", HCLGEVF_NAME);
hclgevf_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, HCLGEVF_NAME); hclgevf_wq = alloc_workqueue("%s", 0, 0, HCLGEVF_NAME);
if (!hclgevf_wq) { if (!hclgevf_wq) {
pr_err("%s: failed to create workqueue\n", HCLGEVF_NAME); pr_err("%s: failed to create workqueue\n", HCLGEVF_NAME);
return -ENOMEM; return -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment