Commit 323e9a95 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-fixes'



Guangbin Huang says:

====================
net: hns3: add some fixes for -net

This series adds some fixes for the HNS3 ethernet driver.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 55161e67 0dd8a25f
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -10,6 +10,27 @@ static LIST_HEAD(hnae3_ae_algo_list);
static LIST_HEAD(hnae3_client_list);
static LIST_HEAD(hnae3_ae_dev_list);

void hnae3_unregister_ae_algo_prepare(struct hnae3_ae_algo *ae_algo)
{
	const struct pci_device_id *pci_id;
	struct hnae3_ae_dev *ae_dev;

	if (!ae_algo)
		return;

	list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
		if (!hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B))
			continue;

		pci_id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
		if (!pci_id)
			continue;
		if (IS_ENABLED(CONFIG_PCI_IOV))
			pci_disable_sriov(ae_dev->pdev);
	}
}
EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare);

/* we are keeping things simple and using single lock for all the
 * list. This is a non-critical code so other updations, if happen
 * in parallel, can wait.
+1 −0
Original line number Diff line number Diff line
@@ -853,6 +853,7 @@ struct hnae3_handle {
int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev);
void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev);

void hnae3_unregister_ae_algo_prepare(struct hnae3_ae_algo *ae_algo);
void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo);
void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo);

+22 −15
Original line number Diff line number Diff line
@@ -1847,7 +1847,6 @@ void hns3_shinfo_pack(struct skb_shared_info *shinfo, __u32 *size)

static int hns3_skb_linearize(struct hns3_enet_ring *ring,
			      struct sk_buff *skb,
			      u8 max_non_tso_bd_num,
			      unsigned int bd_num)
{
	/* 'bd_num == UINT_MAX' means the skb' fraglist has a
@@ -1864,8 +1863,7 @@ static int hns3_skb_linearize(struct hns3_enet_ring *ring,
	 * will not help.
	 */
	if (skb->len > HNS3_MAX_TSO_SIZE ||
	    (!skb_is_gso(skb) && skb->len >
	     HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num))) {
	    (!skb_is_gso(skb) && skb->len > HNS3_MAX_NON_TSO_SIZE)) {
		u64_stats_update_begin(&ring->syncp);
		ring->stats.hw_limitation++;
		u64_stats_update_end(&ring->syncp);
@@ -1900,8 +1898,7 @@ static int hns3_nic_maybe_stop_tx(struct hns3_enet_ring *ring,
			goto out;
		}

		if (hns3_skb_linearize(ring, skb, max_non_tso_bd_num,
				       bd_num))
		if (hns3_skb_linearize(ring, skb, bd_num))
			return -ENOMEM;

		bd_num = hns3_tx_bd_count(skb->len);
@@ -3258,6 +3255,7 @@ static void hns3_buffer_detach(struct hns3_enet_ring *ring, int i)
{
	hns3_unmap_buffer(ring, &ring->desc_cb[i]);
	ring->desc[i].addr = 0;
	ring->desc_cb[i].refill = 0;
}

static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i,
@@ -3336,6 +3334,7 @@ static int hns3_alloc_and_attach_buffer(struct hns3_enet_ring *ring, int i)

	ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
					 ring->desc_cb[i].page_offset);
	ring->desc_cb[i].refill = 1;

	return 0;
}
@@ -3365,6 +3364,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,
{
	hns3_unmap_buffer(ring, &ring->desc_cb[i]);
	ring->desc_cb[i] = *res_cb;
	ring->desc_cb[i].refill = 1;
	ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
					 ring->desc_cb[i].page_offset);
	ring->desc[i].rx.bd_base_info = 0;
@@ -3373,6 +3373,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,
static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i)
{
	ring->desc_cb[i].reuse_flag = 0;
	ring->desc_cb[i].refill = 1;
	ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
					 ring->desc_cb[i].page_offset);
	ring->desc[i].rx.bd_base_info = 0;
@@ -3479,10 +3480,14 @@ static int hns3_desc_unused(struct hns3_enet_ring *ring)
	int ntc = ring->next_to_clean;
	int ntu = ring->next_to_use;

	if (unlikely(ntc == ntu && !ring->desc_cb[ntc].refill))
		return ring->desc_num;

	return ((ntc >= ntu) ? 0 : ring->desc_num) + ntc - ntu;
}

static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,
/* Return true if there is any allocation failure */
static bool hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,
				      int cleand_count)
{
	struct hns3_desc_cb *desc_cb;
@@ -3507,7 +3512,10 @@ static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,
				hns3_rl_err(ring_to_netdev(ring),
					    "alloc rx buffer failed: %d\n",
					    ret);
				break;

				writel(i, ring->tqp->io_base +
				       HNS3_RING_RX_RING_HEAD_REG);
				return true;
			}
			hns3_replace_buffer(ring, ring->next_to_use, &res_cbs);

@@ -3520,6 +3528,7 @@ static void hns3_nic_alloc_rx_buffers(struct hns3_enet_ring *ring,
	}

	writel(i, ring->tqp->io_base + HNS3_RING_RX_RING_HEAD_REG);
	return false;
}

static bool hns3_can_reuse_page(struct hns3_desc_cb *cb)
@@ -3824,6 +3833,7 @@ static void hns3_rx_ring_move_fw(struct hns3_enet_ring *ring)
{
	ring->desc[ring->next_to_clean].rx.bd_base_info &=
		cpu_to_le32(~BIT(HNS3_RXD_VLD_B));
	ring->desc_cb[ring->next_to_clean].refill = 0;
	ring->next_to_clean += 1;

	if (unlikely(ring->next_to_clean == ring->desc_num))
@@ -4170,6 +4180,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
{
#define RCB_NOF_ALLOC_RX_BUFF_ONCE 16
	int unused_count = hns3_desc_unused(ring);
	bool failure = false;
	int recv_pkts = 0;
	int err;

@@ -4178,9 +4189,9 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
	while (recv_pkts < budget) {
		/* Reuse or realloc buffers */
		if (unused_count >= RCB_NOF_ALLOC_RX_BUFF_ONCE) {
			failure = failure ||
				hns3_nic_alloc_rx_buffers(ring, unused_count);
			unused_count = hns3_desc_unused(ring) -
					ring->pending_buf;
			unused_count = 0;
		}

		/* Poll one pkt */
@@ -4199,11 +4210,7 @@ int hns3_clean_rx_ring(struct hns3_enet_ring *ring, int budget,
	}

out:
	/* Make all data has been write before submit */
	if (unused_count > 0)
		hns3_nic_alloc_rx_buffers(ring, unused_count);

	return recv_pkts;
	return failure ? budget : recv_pkts;
}

static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector *tqp_vector)
+3 −4
Original line number Diff line number Diff line
@@ -186,11 +186,9 @@ enum hns3_nic_state {

#define HNS3_MAX_BD_SIZE			65535
#define HNS3_MAX_TSO_BD_NUM			63U
#define HNS3_MAX_TSO_SIZE \
	(HNS3_MAX_BD_SIZE * HNS3_MAX_TSO_BD_NUM)
#define HNS3_MAX_TSO_SIZE			1048576U
#define HNS3_MAX_NON_TSO_SIZE			9728U

#define HNS3_MAX_NON_TSO_SIZE(max_non_tso_bd_num) \
	(HNS3_MAX_BD_SIZE * (max_non_tso_bd_num))

#define HNS3_VECTOR_GL0_OFFSET			0x100
#define HNS3_VECTOR_GL1_OFFSET			0x200
@@ -332,6 +330,7 @@ struct hns3_desc_cb {
	u32 length;     /* length of the buffer */

	u16 reuse_flag;
	u16 refill;

	/* desc type, used by the ring user to mark the type of the priv data */
	u16 type;
+9 −0
Original line number Diff line number Diff line
@@ -137,6 +137,15 @@ static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev,
				*changed = true;
			break;
		case IEEE_8021QAZ_TSA_ETS:
			/* The hardware will switch to sp mode if bandwidth is
			 * 0, so limit ets bandwidth must be greater than 0.
			 */
			if (!ets->tc_tx_bw[i]) {
				dev_err(&hdev->pdev->dev,
					"tc%u ets bw cannot be 0\n", i);
				return -EINVAL;
			}

			if (hdev->tm_info.tc_info[i].tc_sch_mode !=
				HCLGE_SCH_MODE_DWRR)
				*changed = true;
Loading