Unverified Commit e57d23fd authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!6774 [OLK-6.6] merge upstream 4 wangxun related patches to fix i2c bug

Merge Pull Request from: @duanqiangwen 
 
backport upstream 4 wangxun related patches from mainline to fix i2c_designware bugs.

issue:https://gitee.com/openeuler/kernel/issues/I9IP8F

patch1: commit 99f4570cfba1e60daafde737cb7e395006d719e6
patch2: commit 907ee6681788556b9ade3ad0a1f6f4aea192399c
patch3: commit edd2d250fb3bb5d70419ae82c1f9dbb9684dffd3
patch4: commit 8d6bf83f6740ba52a59e25dad360e1e87ef47666 
 
Link:https://gitee.com/openeuler/kernel/pulls/6774

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 27467fc2 1e8f1504
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ void clkdev_add_table(struct clk_lookup *cl, size_t num)
	mutex_unlock(&clocks_mutex);
}

#define MAX_DEV_ID	20
#define MAX_DEV_ID	24
#define MAX_CON_ID	16

struct clk_lookup_alloc {
+56 −0
Original line number Diff line number Diff line
@@ -364,3 +364,59 @@ void wx_set_msglevel(struct net_device *netdev, u32 data)
	wx->msg_enable = data;
}
EXPORT_SYMBOL(wx_set_msglevel);
static unsigned int wx_max_channels(struct wx *wx)
{
	unsigned int max_combined;

	if (!wx->msix_q_entries) {
		/* We only support one q_vector without MSI-X */
		max_combined = 1;
	} else {
		/* support up to max allowed queues with RSS */
		if (wx->mac.type == wx_mac_sp)
			max_combined = 63;
		else
			max_combined = 8;
	}

	return max_combined;
}

void wx_get_channels(struct net_device *dev,
		     struct ethtool_channels *ch)
{
	struct wx *wx = netdev_priv(dev);

	/* report maximum channels */
	ch->max_combined = wx_max_channels(wx);

	/* report info for other vector */
	if (wx->msix_q_entries) {
		ch->max_other = 1;
		ch->other_count = 1;
	}

	/* record RSS queues */
	ch->combined_count = wx->ring_feature[RING_F_RSS].indices;
}
EXPORT_SYMBOL(wx_get_channels);

int wx_set_channels(struct net_device *dev,
		    struct ethtool_channels *ch)
{
	unsigned int count = ch->combined_count;
	struct wx *wx = netdev_priv(dev);

	/* verify other_count has not changed */
	if (ch->other_count != 1)
		return -EINVAL;

	/* verify the number of channels does not exceed hardware limits */
	if (count > wx_max_channels(wx))
		return -EINVAL;

	wx->ring_feature[RING_F_RSS].limit = count;

	return 0;
}
EXPORT_SYMBOL(wx_set_channels);
+4 −0
Original line number Diff line number Diff line
@@ -36,4 +36,8 @@ int wx_set_coalesce(struct net_device *netdev,
		    struct netlink_ext_ack *extack);
u32 wx_get_msglevel(struct net_device *netdev);
void wx_set_msglevel(struct net_device *netdev, u32 data);
void wx_get_channels(struct net_device *dev,
		     struct ethtool_channels *ch);
int wx_set_channels(struct net_device *dev,
		    struct ethtool_channels *ch);
#endif /* _WX_ETHTOOL_H_ */
+101 −2
Original line number Diff line number Diff line
@@ -149,9 +149,9 @@ void wx_irq_disable(struct wx *wx)
		int vector;

		for (vector = 0; vector < wx->num_q_vectors; vector++)
			synchronize_irq(wx->msix_entries[vector].vector);
			synchronize_irq(wx->msix_q_entries[vector].vector);

		synchronize_irq(wx->msix_entries[vector].vector);
		synchronize_irq(wx->msix_entry->vector);
	} else {
		synchronize_irq(pdev->irq);
	}
@@ -1597,6 +1597,72 @@ static void wx_restore_vlan(struct wx *wx)
		wx_vlan_rx_add_vid(wx->netdev, htons(ETH_P_8021Q), vid);
}

static void wx_store_reta(struct wx *wx)
{
	u8 *indir_tbl = wx->rss_indir_tbl;
	u32 reta = 0;
	u32 i;

	/* Fill out the redirection table as follows:
	 *  - 8 bit wide entries containing 4 bit RSS index
	 */
	for (i = 0; i < WX_MAX_RETA_ENTRIES; i++) {
		reta |= indir_tbl[i] << (i & 0x3) * 8;
		if ((i & 3) == 3) {
			wr32(wx, WX_RDB_RSSTBL(i >> 2), reta);
			reta = 0;
		}
	}
}

static void wx_setup_reta(struct wx *wx)
{
	u16 rss_i = wx->ring_feature[RING_F_RSS].indices;
	u32 random_key_size = WX_RSS_KEY_SIZE / 4;
	u32 i, j;

	/* Fill out hash function seeds */
	for (i = 0; i < random_key_size; i++)
		wr32(wx, WX_RDB_RSSRK(i), wx->rss_key[i]);

	/* Fill out redirection table */
	memset(wx->rss_indir_tbl, 0, sizeof(wx->rss_indir_tbl));

	for (i = 0, j = 0; i < WX_MAX_RETA_ENTRIES; i++, j++) {
		if (j == rss_i)
			j = 0;

		wx->rss_indir_tbl[i] = j;
	}

	wx_store_reta(wx);
}

static void wx_setup_mrqc(struct wx *wx)
{
	u32 rss_field = 0;

	/* Disable indicating checksum in descriptor, enables RSS hash */
	wr32m(wx, WX_PSR_CTL, WX_PSR_CTL_PCSD, WX_PSR_CTL_PCSD);

	/* Perform hash on these packet types */
	rss_field = WX_RDB_RA_CTL_RSS_IPV4 |
		    WX_RDB_RA_CTL_RSS_IPV4_TCP |
		    WX_RDB_RA_CTL_RSS_IPV4_UDP |
		    WX_RDB_RA_CTL_RSS_IPV6 |
		    WX_RDB_RA_CTL_RSS_IPV6_TCP |
		    WX_RDB_RA_CTL_RSS_IPV6_UDP;

	netdev_rss_key_fill(wx->rss_key, sizeof(wx->rss_key));

	wx_setup_reta(wx);

	if (wx->rss_enabled)
		rss_field |= WX_RDB_RA_CTL_RSS_EN;

	wr32(wx, WX_RDB_RA_CTL, rss_field);
}

/**
 * wx_configure_rx - Configure Receive Unit after Reset
 * @wx: pointer to private structure
@@ -1629,6 +1695,8 @@ void wx_configure_rx(struct wx *wx)
		wr32(wx, WX_PSR_CTL, psrctl);
	}

	wx_setup_mrqc(wx);

	/* set_rx_buffer_len must be called before ring initialization */
	wx_set_rx_buffer_len(wx);

@@ -1826,6 +1894,28 @@ int wx_get_pcie_msix_counts(struct wx *wx, u16 *msix_count, u16 max_msix_count)
}
EXPORT_SYMBOL(wx_get_pcie_msix_counts);

/**
 * wx_init_rss_key - Initialize wx RSS key
 * @wx: device handle
 *
 * Allocates and initializes the RSS key if it is not allocated.
 **/
static int wx_init_rss_key(struct wx *wx)
{
	u32 *rss_key;

	if (!wx->rss_key) {
		rss_key = kzalloc(WX_RSS_KEY_SIZE, GFP_KERNEL);
		if (unlikely(!rss_key))
			return -ENOMEM;

		netdev_rss_key_fill(rss_key, WX_RSS_KEY_SIZE);
		wx->rss_key = rss_key;
	}

	return 0;
}

int wx_sw_init(struct wx *wx)
{
	struct pci_dev *pdev = wx->pdev;
@@ -1853,14 +1943,23 @@ int wx_sw_init(struct wx *wx)
		wx->subsystem_device_id = swab16((u16)ssid);
	}

	err = wx_init_rss_key(wx);
	if (err < 0) {
		wx_err(wx, "rss key allocation failed\n");
		return err;
	}

	wx->mac_table = kcalloc(wx->mac.num_rar_entries,
				sizeof(struct wx_mac_addr),
				GFP_KERNEL);
	if (!wx->mac_table) {
		wx_err(wx, "mac_table allocation failed\n");
		kfree(wx->rss_key);
		return -ENOMEM;
	}

	wx->msix_in_use = false;

	return 0;
}
EXPORT_SYMBOL(wx_sw_init);
+59 −27
Original line number Diff line number Diff line
@@ -1568,8 +1568,14 @@ EXPORT_SYMBOL(wx_napi_disable_all);
 **/
static void wx_set_rss_queues(struct wx *wx)
{
	wx->num_rx_queues = wx->mac.max_rx_queues;
	wx->num_tx_queues = wx->mac.max_tx_queues;
	struct wx_ring_feature *f;

	/* set mask for 16 queue limit of RSS */
	f = &wx->ring_feature[RING_F_RSS];
	f->indices = f->limit;

	wx->num_rx_queues = f->limit;
	wx->num_tx_queues = f->limit;
}

static void wx_set_num_queues(struct wx *wx)
@@ -1595,35 +1601,51 @@ static int wx_acquire_msix_vectors(struct wx *wx)
	struct irq_affinity affd = { .pre_vectors = 1 };
	int nvecs, i;

	nvecs = min_t(int, num_online_cpus(), wx->mac.max_msix_vectors);
	/* We start by asking for one vector per queue pair */
	nvecs = max(wx->num_rx_queues, wx->num_tx_queues);
	nvecs = min_t(int, nvecs, num_online_cpus());
	nvecs = min_t(int, nvecs, wx->mac.max_msix_vectors);

	wx->msix_entries = kcalloc(nvecs,
				   sizeof(struct msix_entry),
	wx->msix_q_entries = kcalloc(nvecs, sizeof(struct msix_entry),
				     GFP_KERNEL);
	if (!wx->msix_entries)
	if (!wx->msix_q_entries)
		return -ENOMEM;

	/* One for non-queue interrupts */
	nvecs += 1;

	if (!wx->msix_in_use) {
		wx->msix_entry = kcalloc(1, sizeof(struct msix_entry),
					 GFP_KERNEL);
		if (!wx->msix_entry) {
			kfree(wx->msix_q_entries);
			wx->msix_q_entries = NULL;
			return -ENOMEM;
		}
	}

	nvecs = pci_alloc_irq_vectors_affinity(wx->pdev, nvecs,
					       nvecs,
					       PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
					       &affd);
	if (nvecs < 0) {
		wx_err(wx, "Failed to allocate MSI-X interrupts. Err: %d\n", nvecs);
		kfree(wx->msix_entries);
		wx->msix_entries = NULL;
		kfree(wx->msix_q_entries);
		wx->msix_q_entries = NULL;
		kfree(wx->msix_entry);
		wx->msix_entry = NULL;
		return nvecs;
	}

	wx->msix_entry->entry = 0;
	wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0);
	nvecs -= 1;
	for (i = 0; i < nvecs; i++) {
		wx->msix_entries[i].entry = i;
		wx->msix_entries[i].vector = pci_irq_vector(wx->pdev, i);
		wx->msix_q_entries[i].entry = i;
		wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i + 1);
	}

	/* one for msix_other */
	nvecs -= 1;
	wx->num_q_vectors = nvecs;
	wx->num_rx_queues = nvecs;
	wx->num_tx_queues = nvecs;

	return 0;
}
@@ -1645,9 +1667,11 @@ static int wx_set_interrupt_capability(struct wx *wx)
	if (ret == 0 || (ret == -ENOMEM))
		return ret;

	wx->num_rx_queues = 1;
	wx->num_tx_queues = 1;
	wx->num_q_vectors = 1;
	/* Disable RSS */
	dev_warn(&wx->pdev->dev, "Disabling RSS support\n");
	wx->ring_feature[RING_F_RSS].limit = 1;

	wx_set_num_queues(wx);

	/* minmum one for queue, one for misc*/
	nvecs = 1;
@@ -1905,8 +1929,12 @@ void wx_reset_interrupt_capability(struct wx *wx)
		return;

	if (pdev->msix_enabled) {
		kfree(wx->msix_entries);
		wx->msix_entries = NULL;
		kfree(wx->msix_q_entries);
		wx->msix_q_entries = NULL;
		if (!wx->msix_in_use) {
			kfree(wx->msix_entry);
			wx->msix_entry = NULL;
		}
	}
	pci_free_irq_vectors(wx->pdev);
}
@@ -1978,7 +2006,7 @@ void wx_free_irq(struct wx *wx)

	for (vector = 0; vector < wx->num_q_vectors; vector++) {
		struct wx_q_vector *q_vector = wx->q_vector[vector];
		struct msix_entry *entry = &wx->msix_entries[vector];
		struct msix_entry *entry = &wx->msix_q_entries[vector];

		/* free only the irqs that were actually requested */
		if (!q_vector->rx.ring && !q_vector->tx.ring)
@@ -1988,7 +2016,7 @@ void wx_free_irq(struct wx *wx)
	}

	if (wx->mac.type == wx_mac_em)
		free_irq(wx->msix_entries[vector].vector, wx);
		free_irq(wx->msix_entry->vector, wx);
}
EXPORT_SYMBOL(wx_free_irq);

@@ -2065,6 +2093,7 @@ static void wx_set_ivar(struct wx *wx, s8 direction,
		wr32(wx, WX_PX_MISC_IVAR, ivar);
	} else {
		/* tx or rx causes */
		msix_vector += 1; /* offset for queue vectors */
		msix_vector |= WX_PX_IVAR_ALLOC_VAL;
		index = ((16 * (queue & 1)) + (8 * direction));
		ivar = rd32(wx, WX_PX_IVAR(queue >> 1));
@@ -2095,7 +2124,7 @@ void wx_write_eitr(struct wx_q_vector *q_vector)

	itr_reg |= WX_PX_ITR_CNT_WDIS;

	wr32(wx, WX_PX_ITR(v_idx), itr_reg);
	wr32(wx, WX_PX_ITR(v_idx + 1), itr_reg);
}

/**
@@ -2141,9 +2170,9 @@ void wx_configure_vectors(struct wx *wx)
		wx_write_eitr(q_vector);
	}

	wx_set_ivar(wx, -1, 0, v_idx);
	wx_set_ivar(wx, -1, 0, 0);
	if (pdev->msix_enabled)
		wr32(wx, WX_PX_ITR(v_idx), 1950);
		wr32(wx, WX_PX_ITR(0), 1950);
}
EXPORT_SYMBOL(wx_configure_vectors);

@@ -2656,11 +2685,14 @@ int wx_set_features(struct net_device *netdev, netdev_features_t features)
	netdev_features_t changed = netdev->features ^ features;
	struct wx *wx = netdev_priv(netdev);

	if (changed & NETIF_F_RXHASH)
	if (features & NETIF_F_RXHASH) {
		wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN,
		      WX_RDB_RA_CTL_RSS_EN);
	else
		wx->rss_enabled = true;
	} else {
		wr32m(wx, WX_RDB_RA_CTL, WX_RDB_RA_CTL_RSS_EN, 0);
		wx->rss_enabled = false;
	}

	if (changed &
	    (NETIF_F_HW_VLAN_CTAG_RX |
Loading