Commit 3c8def97 authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

be2net: support multiple TX queues

This patch provides support for multiple TX queues.
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@conan.davemloft.net>
parent 15b4d93f
...@@ -87,6 +87,7 @@ static inline char *nic_name(struct pci_dev *pdev) ...@@ -87,6 +87,7 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */ #define MAX_RSS_QS 4 /* BE limit is 4 queues/port */
#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ #define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
#define MAX_TX_QS 8
#define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */ #define BE_MAX_MSIX_VECTORS (MAX_RX_QS + 1)/* RX + TX */
#define BE_NAPI_WEIGHT 64 #define BE_NAPI_WEIGHT 64
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
...@@ -170,7 +171,6 @@ struct be_tx_stats { ...@@ -170,7 +171,6 @@ struct be_tx_stats {
u32 be_tx_reqs; /* number of TX requests initiated */ u32 be_tx_reqs; /* number of TX requests initiated */
u32 be_tx_stops; /* number of times TX Q was stopped */ u32 be_tx_stops; /* number of times TX Q was stopped */
u32 be_tx_wrbs; /* number of tx WRBs used */ u32 be_tx_wrbs; /* number of tx WRBs used */
u32 be_tx_events; /* number of tx completion events */
u32 be_tx_compl; /* number of tx completion entries processed */ u32 be_tx_compl; /* number of tx completion entries processed */
ulong be_tx_jiffies; ulong be_tx_jiffies;
u64 be_tx_bytes; u64 be_tx_bytes;
...@@ -184,6 +184,7 @@ struct be_tx_obj { ...@@ -184,6 +184,7 @@ struct be_tx_obj {
struct be_queue_info cq; struct be_queue_info cq;
/* Remember the skbs that were transmitted */ /* Remember the skbs that were transmitted */
struct sk_buff *sent_skb_list[TX_Q_LEN]; struct sk_buff *sent_skb_list[TX_Q_LEN];
struct be_tx_stats stats;
}; };
/* Struct to remember the pages posted for rx frags */ /* Struct to remember the pages posted for rx frags */
...@@ -319,8 +320,8 @@ struct be_adapter { ...@@ -319,8 +320,8 @@ struct be_adapter {
/* TX Rings */ /* TX Rings */
struct be_eq_obj tx_eq; struct be_eq_obj tx_eq;
struct be_tx_obj tx_obj; struct be_tx_obj tx_obj[MAX_TX_QS];
struct be_tx_stats tx_stats; u8 num_tx_qs;
u32 cache_line_break[8]; u32 cache_line_break[8];
...@@ -391,7 +392,7 @@ struct be_adapter { ...@@ -391,7 +392,7 @@ struct be_adapter {
extern const struct ethtool_ops be_ethtool_ops; extern const struct ethtool_ops be_ethtool_ops;
#define msix_enabled(adapter) (adapter->num_msix_vec > 0) #define msix_enabled(adapter) (adapter->num_msix_vec > 0)
#define tx_stats(adapter) (&adapter->tx_stats) #define tx_stats(txo) (&txo->stats)
#define rx_stats(rxo) (&rxo->stats) #define rx_stats(rxo) (&rxo->stats)
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
...@@ -405,6 +406,10 @@ extern const struct ethtool_ops be_ethtool_ops; ...@@ -405,6 +406,10 @@ extern const struct ethtool_ops be_ethtool_ops;
for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\ for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\
i++, rxo++) i++, rxo++)
#define for_all_tx_queues(adapter, txo, i) \
for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs; \
i++, txo++)
#define PAGE_SHIFT_4K 12 #define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
......
...@@ -52,12 +52,7 @@ static const struct be_ethtool_stat et_stats[] = { ...@@ -52,12 +52,7 @@ static const struct be_ethtool_stat et_stats[] = {
{NETSTAT_INFO(tx_errors)}, {NETSTAT_INFO(tx_errors)},
{NETSTAT_INFO(rx_dropped)}, {NETSTAT_INFO(rx_dropped)},
{NETSTAT_INFO(tx_dropped)}, {NETSTAT_INFO(tx_dropped)},
{DRVSTAT_TX_INFO(be_tx_rate)}, {DRVSTAT_INFO(be_tx_events)},
{DRVSTAT_TX_INFO(be_tx_reqs)},
{DRVSTAT_TX_INFO(be_tx_wrbs)},
{DRVSTAT_TX_INFO(be_tx_stops)},
{DRVSTAT_TX_INFO(be_tx_events)},
{DRVSTAT_TX_INFO(be_tx_compl)},
{DRVSTAT_INFO(rx_crc_errors)}, {DRVSTAT_INFO(rx_crc_errors)},
{DRVSTAT_INFO(rx_alignment_symbol_errors)}, {DRVSTAT_INFO(rx_alignment_symbol_errors)},
{DRVSTAT_INFO(rx_pause_frames)}, {DRVSTAT_INFO(rx_pause_frames)},
...@@ -111,6 +106,16 @@ static const struct be_ethtool_stat et_rx_stats[] = { ...@@ -111,6 +106,16 @@ static const struct be_ethtool_stat et_rx_stats[] = {
}; };
#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats))
/* Stats related to multi TX queues */
static const struct be_ethtool_stat et_tx_stats[] = {
{DRVSTAT_TX_INFO(be_tx_rate)},
{DRVSTAT_TX_INFO(be_tx_reqs)},
{DRVSTAT_TX_INFO(be_tx_wrbs)},
{DRVSTAT_TX_INFO(be_tx_stops)},
{DRVSTAT_TX_INFO(be_tx_compl)}
};
#define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats))
static const char et_self_tests[][ETH_GSTRING_LEN] = { static const char et_self_tests[][ETH_GSTRING_LEN] = {
"MAC Loopback test", "MAC Loopback test",
"PHY Loopback test", "PHY Loopback test",
...@@ -253,17 +258,15 @@ be_get_ethtool_stats(struct net_device *netdev, ...@@ -253,17 +258,15 @@ be_get_ethtool_stats(struct net_device *netdev,
{ {
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
struct be_rx_obj *rxo; struct be_rx_obj *rxo;
struct be_tx_obj *txo;
void *p = NULL; void *p = NULL;
int i, j; int i, j, base;
for (i = 0; i < ETHTOOL_STATS_NUM; i++) { for (i = 0; i < ETHTOOL_STATS_NUM; i++) {
switch (et_stats[i].type) { switch (et_stats[i].type) {
case NETSTAT: case NETSTAT:
p = &netdev->stats; p = &netdev->stats;
break; break;
case DRVSTAT_TX:
p = &adapter->tx_stats;
break;
case DRVSTAT: case DRVSTAT:
p = &adapter->drv_stats; p = &adapter->drv_stats;
break; break;
...@@ -274,6 +277,7 @@ be_get_ethtool_stats(struct net_device *netdev, ...@@ -274,6 +277,7 @@ be_get_ethtool_stats(struct net_device *netdev,
*(u64 *)p: *(u32 *)p; *(u64 *)p: *(u32 *)p;
} }
base = ETHTOOL_STATS_NUM;
for_all_rx_queues(adapter, rxo, j) { for_all_rx_queues(adapter, rxo, j) {
for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) { for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) {
switch (et_rx_stats[i].type) { switch (et_rx_stats[i].type) {
...@@ -285,11 +289,21 @@ be_get_ethtool_stats(struct net_device *netdev, ...@@ -285,11 +289,21 @@ be_get_ethtool_stats(struct net_device *netdev,
rxo->q.id; rxo->q.id;
break; break;
} }
data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] = data[base + j * ETHTOOL_RXSTATS_NUM + i] =
(et_rx_stats[i].size == sizeof(u64)) ? (et_rx_stats[i].size == sizeof(u64)) ?
*(u64 *)p: *(u32 *)p; *(u64 *)p: *(u32 *)p;
} }
} }
base = ETHTOOL_STATS_NUM + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM;
for_all_tx_queues(adapter, txo, j) {
for (i = 0; i < ETHTOOL_TXSTATS_NUM; i++) {
p = (u8 *)&txo->stats + et_tx_stats[i].offset;
data[base + j * ETHTOOL_TXSTATS_NUM + i] =
(et_tx_stats[i].size == sizeof(u64)) ?
*(u64 *)p: *(u32 *)p;
}
}
} }
static void static void
...@@ -312,6 +326,13 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset, ...@@ -312,6 +326,13 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset,
data += ETH_GSTRING_LEN; data += ETH_GSTRING_LEN;
} }
} }
for (i = 0; i < adapter->num_tx_qs; i++) {
for (j = 0; j < ETHTOOL_TXSTATS_NUM; j++) {
sprintf(data, "txq%d: %s", i,
et_tx_stats[j].desc);
data += ETH_GSTRING_LEN;
}
}
break; break;
case ETH_SS_TEST: case ETH_SS_TEST:
for (i = 0; i < ETHTOOL_TESTS_NUM; i++) { for (i = 0; i < ETHTOOL_TESTS_NUM; i++) {
...@@ -331,7 +352,8 @@ static int be_get_sset_count(struct net_device *netdev, int stringset) ...@@ -331,7 +352,8 @@ static int be_get_sset_count(struct net_device *netdev, int stringset)
return ETHTOOL_TESTS_NUM; return ETHTOOL_TESTS_NUM;
case ETH_SS_STATS: case ETH_SS_STATS:
return ETHTOOL_STATS_NUM + return ETHTOOL_STATS_NUM +
adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM; adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM +
adapter->num_tx_qs * ETHTOOL_TXSTATS_NUM;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -457,10 +479,10 @@ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) ...@@ -457,10 +479,10 @@ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
ring->rx_max_pending = adapter->rx_obj[0].q.len; ring->rx_max_pending = adapter->rx_obj[0].q.len;
ring->tx_max_pending = adapter->tx_obj.q.len; ring->tx_max_pending = adapter->tx_obj[0].q.len;
ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used); ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used);
ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); ring->tx_pending = atomic_read(&adapter->tx_obj[0].q.used);
} }
static void static void
......
This diff is collapsed.
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