@@ -18,6 +18,18 @@
#include "lan743x_main.h"
#include "lan743x_ethtool.h"
+static bool is_pcia0x1_chip(struct lan743x_adapter *adapter)
+{
+ struct lan743x_csr *csr = &adapter->csr;
+ u32 id_rev = csr->id_rev;
+
+ if (((id_rev & 0xFFFF0000) == ID_REV_ID_PCIA011_) ||
+ ((id_rev & 0xFFFF0000) == ID_REV_ID_PCIA041_)) {
+ return true;
+ }
+ return false;
+}
+
static void lan743x_pci_cleanup(struct lan743x_adapter *adapter)
{
pci_release_selected_regions(adapter->pdev,
@@ -250,7 +262,7 @@ static void lan743x_intr_shared_isr(void *context, u32 int_sts, u32 flags)
}
}
if (int_sts & INT_BIT_ALL_TX_) {
- for (channel = 0; channel < LAN743X_USED_TX_CHANNELS;
+ for (channel = 0; channel < adapter->max_used_tx_channels;
channel++) {
u32 int_bit = INT_BIT_DMA_TX_(channel);
@@ -447,6 +459,7 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
{
struct msix_entry msix_entries[LAN743X_MAX_VECTOR_COUNT];
struct lan743x_intr *intr = &adapter->intr;
+ unsigned int max_used_tx_channels;
u32 int_vec_en_auto_clr = 0;
u32 int_vec_map0 = 0;
u32 int_vec_map1 = 0;
@@ -461,9 +474,10 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
sizeof(struct msix_entry) * LAN743X_MAX_VECTOR_COUNT);
for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++)
msix_entries[index].entry = index;
+ max_used_tx_channels = adapter->max_used_tx_channels;
ret = pci_enable_msix_range(adapter->pdev,
msix_entries, 1,
- 1 + LAN743X_USED_TX_CHANNELS +
+ 1 + max_used_tx_channels +
LAN743X_USED_RX_CHANNELS);
if (ret > 0) {
@@ -570,8 +584,8 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
if (intr->number_of_vectors > 1) {
int number_of_tx_vectors = intr->number_of_vectors - 1;
- if (number_of_tx_vectors > LAN743X_USED_TX_CHANNELS)
- number_of_tx_vectors = LAN743X_USED_TX_CHANNELS;
+ if (number_of_tx_vectors > max_used_tx_channels)
+ number_of_tx_vectors = max_used_tx_channels;
flags = LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ |
LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C |
LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK |
@@ -609,9 +623,9 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
INT_VEC_EN_(vector));
}
}
- if ((intr->number_of_vectors - LAN743X_USED_TX_CHANNELS) > 1) {
+ if ((intr->number_of_vectors - max_used_tx_channels) > 1) {
int number_of_rx_vectors = intr->number_of_vectors -
- LAN743X_USED_TX_CHANNELS - 1;
+ max_used_tx_channels - 1;
if (number_of_rx_vectors > LAN743X_USED_RX_CHANNELS)
number_of_rx_vectors = LAN743X_USED_RX_CHANNELS;
@@ -2489,9 +2503,12 @@ static int lan743x_rx_open(struct lan743x_rx *rx)
static int lan743x_netdev_close(struct net_device *netdev)
{
struct lan743x_adapter *adapter = netdev_priv(netdev);
+ unsigned int max_used_tx_channels;
int index;
- lan743x_tx_close(&adapter->tx[0]);
+ max_used_tx_channels = adapter->max_used_tx_channels;
+ for (index = 0; index < max_used_tx_channels; index++)
+ lan743x_tx_close(&adapter->tx[index]);
for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++)
lan743x_rx_close(&adapter->rx[index]);
@@ -2537,12 +2554,19 @@ static int lan743x_netdev_open(struct net_device *netdev)
goto close_rx;
}
- ret = lan743x_tx_open(&adapter->tx[0]);
- if (ret)
- goto close_rx;
-
+ for (index = 0; index < adapter->max_used_tx_channels; index++) {
+ ret = lan743x_tx_open(&adapter->tx[index]);
+ if (ret)
+ goto close_tx;
+ }
return 0;
+close_tx:
+ for (index = 0; index < adapter->max_used_tx_channels; index++) {
+ if (adapter->tx[index].ring_cpu_ptr)
+ lan743x_tx_close(&adapter->tx[index]);
+ }
+
close_rx:
for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) {
if (adapter->rx[index].ring_cpu_ptr)
@@ -2569,8 +2593,12 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb,
struct net_device *netdev)
{
struct lan743x_adapter *adapter = netdev_priv(netdev);
+ u8 ch = 0;
+
+ if (adapter->is_pcia0x1)
+ ch = skb->queue_mapping % PCIA0X1_MAX_TX_CHANNELS;
- return lan743x_tx_xmit_frame(&adapter->tx[0], skb);
+ return lan743x_tx_xmit_frame(&adapter->tx[ch], skb);
}
static int lan743x_netdev_ioctl(struct net_device *netdev,
@@ -2701,6 +2729,15 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
int index;
int ret;
+ adapter->is_pcia0x1 = is_pcia0x1_chip(adapter);
+ if (adapter->is_pcia0x1) {
+ adapter->max_tx_channels = PCIA0X1_MAX_TX_CHANNELS;
+ adapter->max_used_tx_channels = PCIA0X1_USED_TX_CHANNELS;
+ } else {
+ adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS;
+ adapter->max_used_tx_channels = LAN743X_USED_TX_CHANNELS;
+ }
+
adapter->intr.irq = adapter->pdev->irq;
lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF);
@@ -2731,10 +2768,13 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
adapter->rx[index].channel_number = index;
}
- tx = &adapter->tx[0];
- tx->adapter = adapter;
- tx->channel_number = 0;
- spin_lock_init(&tx->ring_lock);
+ for (index = 0; index < adapter->max_used_tx_channels; index++) {
+ tx = &adapter->tx[index];
+ tx->adapter = adapter;
+ tx->channel_number = index;
+ spin_lock_init(&tx->ring_lock);
+ }
+
return 0;
}
@@ -2790,8 +2830,17 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
struct net_device *netdev = NULL;
int ret = -ENODEV;
- netdev = devm_alloc_etherdev(&pdev->dev,
- sizeof(struct lan743x_adapter));
+ if ((id->device == (ID_REV_ID_PCIA011_ >> 16)) ||
+ (id->device == (ID_REV_ID_PCIA041_ >> 16))) {
+ netdev = devm_alloc_etherdev_mqs(&pdev->dev,
+ sizeof(struct lan743x_adapter),
+ PCIA0X1_MAX_TX_CHANNELS,
+ LAN743X_MAX_RX_CHANNELS);
+ } else {
+ netdev = devm_alloc_etherdev(&pdev->dev,
+ sizeof(struct lan743x_adapter));
+ }
+
if (!netdev)
goto return_error;
@@ -545,10 +545,12 @@
#define LAN743X_MAX_RX_CHANNELS (4)
#define LAN743X_MAX_TX_CHANNELS (1)
+#define PCIA0X1_MAX_TX_CHANNELS (4)
struct lan743x_adapter;
#define LAN743X_USED_RX_CHANNELS (4)
#define LAN743X_USED_TX_CHANNELS (1)
+#define PCIA0X1_USED_TX_CHANNELS (4)
#define LAN743X_INT_MOD (400)
#if (LAN743X_USED_RX_CHANNELS > LAN743X_MAX_RX_CHANNELS)
@@ -557,6 +559,9 @@ struct lan743x_adapter;
#if (LAN743X_USED_TX_CHANNELS > LAN743X_MAX_TX_CHANNELS)
#error Invalid LAN743X_USED_TX_CHANNELS
#endif
+#if (PCIA0X1_USED_TX_CHANNELS > PCIA0X1_MAX_TX_CHANNELS)
+#error Invalid PCIA0X1_USED_TX_CHANNELS
+#endif
/* PCI */
/* SMSC acquired EFAR late 1990's, MCHP acquired SMSC 2012 */
@@ -727,8 +732,11 @@ struct lan743x_adapter {
u8 mac_address[ETH_ALEN];
struct lan743x_phy phy;
- struct lan743x_tx tx[LAN743X_MAX_TX_CHANNELS];
+ struct lan743x_tx tx[PCIA0X1_MAX_TX_CHANNELS];
struct lan743x_rx rx[LAN743X_MAX_RX_CHANNELS];
+ bool is_pcia0x1;
+ u8 max_tx_channels;
+ u8 max_used_tx_channels;
#define LAN743X_ADAPTER_FLAG_OTP BIT(0)
u32 flags;
@@ -1307,21 +1307,21 @@ int lan743x_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
switch (config.tx_type) {
case HWTSTAMP_TX_OFF:
- for (index = 0; index < LAN743X_MAX_TX_CHANNELS;
- index++)
+ for (index = 0; index < adapter->max_tx_channels;
+ index++)
lan743x_tx_set_timestamping_mode(&adapter->tx[index],
false, false);
lan743x_ptp_set_sync_ts_insert(adapter, false);
break;
case HWTSTAMP_TX_ON:
- for (index = 0; index < LAN743X_MAX_TX_CHANNELS;
+ for (index = 0; index < adapter->max_tx_channels;
index++)
lan743x_tx_set_timestamping_mode(&adapter->tx[index],
true, false);
lan743x_ptp_set_sync_ts_insert(adapter, false);
break;
case HWTSTAMP_TX_ONESTEP_SYNC:
- for (index = 0; index < LAN743X_MAX_TX_CHANNELS;
+ for (index = 0; index < adapter->max_tx_channels;
index++)
lan743x_tx_set_timestamping_mode(&adapter->tx[index],
true, true);
PCI1A011/PCI1A041 chip support the 4 Tx Queues Signed-off-by: Raju Lakkaraju <Raju.Lakkaraju@microchip.com> --- drivers/net/ethernet/microchip/lan743x_main.c | 85 +++++++++++++++---- drivers/net/ethernet/microchip/lan743x_main.h | 10 ++- drivers/net/ethernet/microchip/lan743x_ptp.c | 8 +- 3 files changed, 80 insertions(+), 23 deletions(-)