Commit cf9aaea8 authored by Raju Lakkaraju's avatar Raju Lakkaraju Committed by David S. Miller

net: lan743x: Add support for 4 Tx queues

Add support for 4 Tx queues
Signed-off-by: default avatarRaju Lakkaraju <Raju.Lakkaraju@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bb4f6bff
...@@ -18,6 +18,18 @@ ...@@ -18,6 +18,18 @@
#include "lan743x_main.h" #include "lan743x_main.h"
#include "lan743x_ethtool.h" #include "lan743x_ethtool.h"
static bool is_pci11x1x_chip(struct lan743x_adapter *adapter)
{
struct lan743x_csr *csr = &adapter->csr;
u32 id_rev = csr->id_rev;
if (((id_rev & 0xFFFF0000) == ID_REV_ID_A011_) ||
((id_rev & 0xFFFF0000) == ID_REV_ID_A041_)) {
return true;
}
return false;
}
static void lan743x_pci_cleanup(struct lan743x_adapter *adapter) static void lan743x_pci_cleanup(struct lan743x_adapter *adapter)
{ {
pci_release_selected_regions(adapter->pdev, pci_release_selected_regions(adapter->pdev,
...@@ -250,7 +262,7 @@ static void lan743x_intr_shared_isr(void *context, u32 int_sts, u32 flags) ...@@ -250,7 +262,7 @@ static void lan743x_intr_shared_isr(void *context, u32 int_sts, u32 flags)
} }
} }
if (int_sts & INT_BIT_ALL_TX_) { if (int_sts & INT_BIT_ALL_TX_) {
for (channel = 0; channel < LAN743X_USED_TX_CHANNELS; for (channel = 0; channel < adapter->used_tx_channels;
channel++) { channel++) {
u32 int_bit = INT_BIT_DMA_TX_(channel); u32 int_bit = INT_BIT_DMA_TX_(channel);
...@@ -447,6 +459,7 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) ...@@ -447,6 +459,7 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
{ {
struct msix_entry msix_entries[LAN743X_MAX_VECTOR_COUNT]; struct msix_entry msix_entries[LAN743X_MAX_VECTOR_COUNT];
struct lan743x_intr *intr = &adapter->intr; struct lan743x_intr *intr = &adapter->intr;
unsigned int used_tx_channels;
u32 int_vec_en_auto_clr = 0; u32 int_vec_en_auto_clr = 0;
u32 int_vec_map0 = 0; u32 int_vec_map0 = 0;
u32 int_vec_map1 = 0; u32 int_vec_map1 = 0;
...@@ -461,9 +474,10 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) ...@@ -461,9 +474,10 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
sizeof(struct msix_entry) * LAN743X_MAX_VECTOR_COUNT); sizeof(struct msix_entry) * LAN743X_MAX_VECTOR_COUNT);
for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++) for (index = 0; index < LAN743X_MAX_VECTOR_COUNT; index++)
msix_entries[index].entry = index; msix_entries[index].entry = index;
used_tx_channels = adapter->used_tx_channels;
ret = pci_enable_msix_range(adapter->pdev, ret = pci_enable_msix_range(adapter->pdev,
msix_entries, 1, msix_entries, 1,
1 + LAN743X_USED_TX_CHANNELS + 1 + used_tx_channels +
LAN743X_USED_RX_CHANNELS); LAN743X_USED_RX_CHANNELS);
if (ret > 0) { if (ret > 0) {
...@@ -570,8 +584,8 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) ...@@ -570,8 +584,8 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
if (intr->number_of_vectors > 1) { if (intr->number_of_vectors > 1) {
int number_of_tx_vectors = intr->number_of_vectors - 1; int number_of_tx_vectors = intr->number_of_vectors - 1;
if (number_of_tx_vectors > LAN743X_USED_TX_CHANNELS) if (number_of_tx_vectors > used_tx_channels)
number_of_tx_vectors = LAN743X_USED_TX_CHANNELS; number_of_tx_vectors = used_tx_channels;
flags = LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ | flags = LAN743X_VECTOR_FLAG_SOURCE_STATUS_READ |
LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C | LAN743X_VECTOR_FLAG_SOURCE_STATUS_W2C |
LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK | LAN743X_VECTOR_FLAG_SOURCE_ENABLE_CHECK |
...@@ -609,9 +623,9 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter) ...@@ -609,9 +623,9 @@ static int lan743x_intr_open(struct lan743x_adapter *adapter)
INT_VEC_EN_(vector)); INT_VEC_EN_(vector));
} }
} }
if ((intr->number_of_vectors - LAN743X_USED_TX_CHANNELS) > 1) { if ((intr->number_of_vectors - used_tx_channels) > 1) {
int number_of_rx_vectors = intr->number_of_vectors - int number_of_rx_vectors = intr->number_of_vectors -
LAN743X_USED_TX_CHANNELS - 1; used_tx_channels - 1;
if (number_of_rx_vectors > LAN743X_USED_RX_CHANNELS) if (number_of_rx_vectors > LAN743X_USED_RX_CHANNELS)
number_of_rx_vectors = LAN743X_USED_RX_CHANNELS; number_of_rx_vectors = LAN743X_USED_RX_CHANNELS;
...@@ -2491,7 +2505,8 @@ static int lan743x_netdev_close(struct net_device *netdev) ...@@ -2491,7 +2505,8 @@ static int lan743x_netdev_close(struct net_device *netdev)
struct lan743x_adapter *adapter = netdev_priv(netdev); struct lan743x_adapter *adapter = netdev_priv(netdev);
int index; int index;
lan743x_tx_close(&adapter->tx[0]); for (index = 0; index < adapter->used_tx_channels; index++)
lan743x_tx_close(&adapter->tx[index]);
for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++)
lan743x_rx_close(&adapter->rx[index]); lan743x_rx_close(&adapter->rx[index]);
...@@ -2537,12 +2552,19 @@ static int lan743x_netdev_open(struct net_device *netdev) ...@@ -2537,12 +2552,19 @@ static int lan743x_netdev_open(struct net_device *netdev)
goto close_rx; goto close_rx;
} }
ret = lan743x_tx_open(&adapter->tx[0]); for (index = 0; index < adapter->used_tx_channels; index++) {
if (ret) ret = lan743x_tx_open(&adapter->tx[index]);
goto close_rx; if (ret)
goto close_tx;
}
return 0; return 0;
close_tx:
for (index = 0; index < adapter->used_tx_channels; index++) {
if (adapter->tx[index].ring_cpu_ptr)
lan743x_tx_close(&adapter->tx[index]);
}
close_rx: close_rx:
for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) { for (index = 0; index < LAN743X_USED_RX_CHANNELS; index++) {
if (adapter->rx[index].ring_cpu_ptr) if (adapter->rx[index].ring_cpu_ptr)
...@@ -2569,8 +2591,12 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb, ...@@ -2569,8 +2591,12 @@ static netdev_tx_t lan743x_netdev_xmit_frame(struct sk_buff *skb,
struct net_device *netdev) struct net_device *netdev)
{ {
struct lan743x_adapter *adapter = netdev_priv(netdev); struct lan743x_adapter *adapter = netdev_priv(netdev);
u8 ch = 0;
if (adapter->is_pci11x1x)
ch = skb->queue_mapping % PCI11X1X_USED_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, static int lan743x_netdev_ioctl(struct net_device *netdev,
...@@ -2701,6 +2727,15 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, ...@@ -2701,6 +2727,15 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
int index; int index;
int ret; int ret;
adapter->is_pci11x1x = is_pci11x1x_chip(adapter);
if (adapter->is_pci11x1x) {
adapter->max_tx_channels = PCI11X1X_MAX_TX_CHANNELS;
adapter->used_tx_channels = PCI11X1X_USED_TX_CHANNELS;
} else {
adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS;
adapter->used_tx_channels = LAN743X_USED_TX_CHANNELS;
}
adapter->intr.irq = adapter->pdev->irq; adapter->intr.irq = adapter->pdev->irq;
lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF); lan743x_csr_write(adapter, INT_EN_CLR, 0xFFFFFFFF);
...@@ -2731,10 +2766,13 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter, ...@@ -2731,10 +2766,13 @@ static int lan743x_hardware_init(struct lan743x_adapter *adapter,
adapter->rx[index].channel_number = index; adapter->rx[index].channel_number = index;
} }
tx = &adapter->tx[0]; for (index = 0; index < adapter->used_tx_channels; index++) {
tx->adapter = adapter; tx = &adapter->tx[index];
tx->channel_number = 0; tx->adapter = adapter;
spin_lock_init(&tx->ring_lock); tx->channel_number = index;
spin_lock_init(&tx->ring_lock);
}
return 0; return 0;
} }
...@@ -2786,8 +2824,17 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev, ...@@ -2786,8 +2824,17 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
struct net_device *netdev = NULL; struct net_device *netdev = NULL;
int ret = -ENODEV; int ret = -ENODEV;
netdev = devm_alloc_etherdev(&pdev->dev, if (id->device == PCI_DEVICE_ID_SMSC_A011 ||
sizeof(struct lan743x_adapter)); id->device == PCI_DEVICE_ID_SMSC_A041) {
netdev = devm_alloc_etherdev_mqs(&pdev->dev,
sizeof(struct lan743x_adapter),
PCI11X1X_USED_TX_CHANNELS,
LAN743X_USED_RX_CHANNELS);
} else {
netdev = devm_alloc_etherdev(&pdev->dev,
sizeof(struct lan743x_adapter));
}
if (!netdev) if (!netdev)
goto return_error; goto return_error;
......
...@@ -546,10 +546,12 @@ ...@@ -546,10 +546,12 @@
#define LAN743X_MAX_RX_CHANNELS (4) #define LAN743X_MAX_RX_CHANNELS (4)
#define LAN743X_MAX_TX_CHANNELS (1) #define LAN743X_MAX_TX_CHANNELS (1)
#define PCI11X1X_MAX_TX_CHANNELS (4)
struct lan743x_adapter; struct lan743x_adapter;
#define LAN743X_USED_RX_CHANNELS (4) #define LAN743X_USED_RX_CHANNELS (4)
#define LAN743X_USED_TX_CHANNELS (1) #define LAN743X_USED_TX_CHANNELS (1)
#define PCI11X1X_USED_TX_CHANNELS (4)
#define LAN743X_INT_MOD (400) #define LAN743X_INT_MOD (400)
#if (LAN743X_USED_RX_CHANNELS > LAN743X_MAX_RX_CHANNELS) #if (LAN743X_USED_RX_CHANNELS > LAN743X_MAX_RX_CHANNELS)
...@@ -558,6 +560,9 @@ struct lan743x_adapter; ...@@ -558,6 +560,9 @@ struct lan743x_adapter;
#if (LAN743X_USED_TX_CHANNELS > LAN743X_MAX_TX_CHANNELS) #if (LAN743X_USED_TX_CHANNELS > LAN743X_MAX_TX_CHANNELS)
#error Invalid LAN743X_USED_TX_CHANNELS #error Invalid LAN743X_USED_TX_CHANNELS
#endif #endif
#if (PCI11X1X_USED_TX_CHANNELS > PCI11X1X_MAX_TX_CHANNELS)
#error Invalid PCI11X1X_USED_TX_CHANNELS
#endif
/* PCI */ /* PCI */
/* SMSC acquired EFAR late 1990's, MCHP acquired SMSC 2012 */ /* SMSC acquired EFAR late 1990's, MCHP acquired SMSC 2012 */
...@@ -728,8 +733,11 @@ struct lan743x_adapter { ...@@ -728,8 +733,11 @@ struct lan743x_adapter {
u8 mac_address[ETH_ALEN]; u8 mac_address[ETH_ALEN];
struct lan743x_phy phy; struct lan743x_phy phy;
struct lan743x_tx tx[LAN743X_MAX_TX_CHANNELS]; struct lan743x_tx tx[PCI11X1X_USED_TX_CHANNELS];
struct lan743x_rx rx[LAN743X_MAX_RX_CHANNELS]; struct lan743x_rx rx[LAN743X_USED_RX_CHANNELS];
bool is_pci11x1x;
u8 max_tx_channels;
u8 used_tx_channels;
#define LAN743X_ADAPTER_FLAG_OTP BIT(0) #define LAN743X_ADAPTER_FLAG_OTP BIT(0)
u32 flags; u32 flags;
......
...@@ -1307,21 +1307,21 @@ int lan743x_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) ...@@ -1307,21 +1307,21 @@ int lan743x_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
switch (config.tx_type) { switch (config.tx_type) {
case HWTSTAMP_TX_OFF: case HWTSTAMP_TX_OFF:
for (index = 0; index < LAN743X_MAX_TX_CHANNELS; for (index = 0; index < adapter->used_tx_channels;
index++) index++)
lan743x_tx_set_timestamping_mode(&adapter->tx[index], lan743x_tx_set_timestamping_mode(&adapter->tx[index],
false, false); false, false);
lan743x_ptp_set_sync_ts_insert(adapter, false); lan743x_ptp_set_sync_ts_insert(adapter, false);
break; break;
case HWTSTAMP_TX_ON: case HWTSTAMP_TX_ON:
for (index = 0; index < LAN743X_MAX_TX_CHANNELS; for (index = 0; index < adapter->used_tx_channels;
index++) index++)
lan743x_tx_set_timestamping_mode(&adapter->tx[index], lan743x_tx_set_timestamping_mode(&adapter->tx[index],
true, false); true, false);
lan743x_ptp_set_sync_ts_insert(adapter, false); lan743x_ptp_set_sync_ts_insert(adapter, false);
break; break;
case HWTSTAMP_TX_ONESTEP_SYNC: case HWTSTAMP_TX_ONESTEP_SYNC:
for (index = 0; index < LAN743X_MAX_TX_CHANNELS; for (index = 0; index < adapter->used_tx_channels;
index++) index++)
lan743x_tx_set_timestamping_mode(&adapter->tx[index], lan743x_tx_set_timestamping_mode(&adapter->tx[index],
true, true); true, true);
......
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