Commit 68d7bdcb authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

be2net: implement ethtool set/get_channel hooks

Support is provided only for combined channels. When SR-IOV is not
enabled, BE3 supports upto 16 channels and Lancer-R/SH-R support upto
32 channels.
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7707133c
...@@ -99,16 +99,17 @@ static inline char *nic_name(struct pci_dev *pdev) ...@@ -99,16 +99,17 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */ #define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
#define MCC_CQ_LEN 256 #define MCC_CQ_LEN 256
#define BE3_MAX_RSS_QS 8
#define BE2_MAX_RSS_QS 4 #define BE2_MAX_RSS_QS 4
#define BE3_MAX_TX_QS 8 #define BE3_MAX_RSS_QS 16
#define MAX_RSS_QS BE3_MAX_RSS_QS #define BE3_MAX_TX_QS 16
#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ #define BE3_MAX_EVT_QS 16
#define MAX_EVT_QS MAX_RSS_QS
#define MAX_RX_QS 32
#define MAX_EVT_QS 32
#define MAX_TX_QS 32
#define MAX_TX_QS 8
#define MAX_ROCE_EQS 5 #define MAX_ROCE_EQS 5
#define MAX_MSIX_VECTORS (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */ #define MAX_MSIX_VECTORS 32
#define MIN_MSIX_VECTORS 1 #define MIN_MSIX_VECTORS 1
#define BE_TX_BUDGET 256 #define BE_TX_BUDGET 256
#define BE_NAPI_WEIGHT 64 #define BE_NAPI_WEIGHT 64
...@@ -701,6 +702,8 @@ extern int be_load_fw(struct be_adapter *adapter, u8 *func); ...@@ -701,6 +702,8 @@ extern int be_load_fw(struct be_adapter *adapter, u8 *func);
extern bool be_is_wol_supported(struct be_adapter *adapter); extern bool be_is_wol_supported(struct be_adapter *adapter);
extern bool be_pause_supported(struct be_adapter *adapter); extern bool be_pause_supported(struct be_adapter *adapter);
extern u32 be_get_fw_log_level(struct be_adapter *adapter); extern u32 be_get_fw_log_level(struct be_adapter *adapter);
int be_update_queues(struct be_adapter *adapter);
int be_poll(struct napi_struct *napi, int budget);
/* /*
* internal function to initialize-cleanup roce device. * internal function to initialize-cleanup roce device.
......
...@@ -1119,6 +1119,29 @@ static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) ...@@ -1119,6 +1119,29 @@ static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
return status; return status;
} }
static void be_get_channels(struct net_device *netdev,
struct ethtool_channels *ch)
{
struct be_adapter *adapter = netdev_priv(netdev);
ch->combined_count = adapter->num_evt_qs;
ch->max_combined = be_max_qs(adapter);
}
static int be_set_channels(struct net_device *netdev,
struct ethtool_channels *ch)
{
struct be_adapter *adapter = netdev_priv(netdev);
if (ch->rx_count || ch->tx_count || ch->other_count ||
!ch->combined_count || ch->combined_count > be_max_qs(adapter))
return -EINVAL;
adapter->cfg_num_qs = ch->combined_count;
return be_update_queues(adapter);
}
const struct ethtool_ops be_ethtool_ops = { const struct ethtool_ops be_ethtool_ops = {
.get_settings = be_get_settings, .get_settings = be_get_settings,
.get_drvinfo = be_get_drvinfo, .get_drvinfo = be_get_drvinfo,
...@@ -1145,4 +1168,6 @@ const struct ethtool_ops be_ethtool_ops = { ...@@ -1145,4 +1168,6 @@ const struct ethtool_ops be_ethtool_ops = {
.self_test = be_self_test, .self_test = be_self_test,
.get_rxnfc = be_get_rxnfc, .get_rxnfc = be_get_rxnfc,
.set_rxnfc = be_set_rxnfc, .set_rxnfc = be_set_rxnfc,
.get_channels = be_get_channels,
.set_channels = be_set_channels
}; };
...@@ -1913,6 +1913,7 @@ static void be_evt_queues_destroy(struct be_adapter *adapter) ...@@ -1913,6 +1913,7 @@ static void be_evt_queues_destroy(struct be_adapter *adapter)
if (eqo->q.created) { if (eqo->q.created) {
be_eq_clean(eqo); be_eq_clean(eqo);
be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ); be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
netif_napi_del(&eqo->napi);
} }
be_queue_free(adapter, &eqo->q); be_queue_free(adapter, &eqo->q);
} }
...@@ -1928,6 +1929,8 @@ static int be_evt_queues_create(struct be_adapter *adapter) ...@@ -1928,6 +1929,8 @@ static int be_evt_queues_create(struct be_adapter *adapter)
adapter->cfg_num_qs); adapter->cfg_num_qs);
for_all_evt_queues(adapter, eqo, i) { for_all_evt_queues(adapter, eqo, i) {
netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
BE_NAPI_WEIGHT);
eqo->adapter = adapter; eqo->adapter = adapter;
eqo->tx_budget = BE_TX_BUDGET; eqo->tx_budget = BE_TX_BUDGET;
eqo->idx = i; eqo->idx = i;
...@@ -2021,12 +2024,6 @@ static int be_tx_qs_create(struct be_adapter *adapter) ...@@ -2021,12 +2024,6 @@ static int be_tx_qs_create(struct be_adapter *adapter)
int status, i; int status, i;
adapter->num_tx_qs = min(adapter->num_evt_qs, be_max_txqs(adapter)); adapter->num_tx_qs = min(adapter->num_evt_qs, be_max_txqs(adapter));
if (adapter->num_tx_qs != MAX_TX_QS) {
rtnl_lock();
netif_set_real_num_tx_queues(adapter->netdev,
adapter->num_tx_qs);
rtnl_unlock();
}
for_all_tx_queues(adapter, txo, i) { for_all_tx_queues(adapter, txo, i) {
cq = &txo->cq; cq = &txo->cq;
...@@ -2087,13 +2084,6 @@ static int be_rx_cqs_create(struct be_adapter *adapter) ...@@ -2087,13 +2084,6 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
if (adapter->num_rx_qs > 1) if (adapter->num_rx_qs > 1)
adapter->num_rx_qs++; adapter->num_rx_qs++;
if (adapter->num_rx_qs != MAX_RX_QS) {
rtnl_lock();
netif_set_real_num_rx_queues(adapter->netdev,
adapter->num_rx_qs);
rtnl_unlock();
}
adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
for_all_rx_queues(adapter, rxo, i) { for_all_rx_queues(adapter, rxo, i) {
rxo->adapter = adapter; rxo->adapter = adapter;
...@@ -2244,7 +2234,7 @@ static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo, ...@@ -2244,7 +2234,7 @@ static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
return (work_done < budget); /* Done */ return (work_done < budget); /* Done */
} }
static int be_poll(struct napi_struct *napi, int budget) int be_poll(struct napi_struct *napi, int budget)
{ {
struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi); struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi);
struct be_adapter *adapter = eqo->adapter; struct be_adapter *adapter = eqo->adapter;
...@@ -2356,6 +2346,7 @@ static void be_msix_disable(struct be_adapter *adapter) ...@@ -2356,6 +2346,7 @@ static void be_msix_disable(struct be_adapter *adapter)
if (msix_enabled(adapter)) { if (msix_enabled(adapter)) {
pci_disable_msix(adapter->pdev); pci_disable_msix(adapter->pdev);
adapter->num_msix_vec = 0; adapter->num_msix_vec = 0;
adapter->num_msix_roce_vec = 0;
} }
} }
...@@ -2771,14 +2762,19 @@ static void be_clear_queues(struct be_adapter *adapter) ...@@ -2771,14 +2762,19 @@ static void be_clear_queues(struct be_adapter *adapter)
be_evt_queues_destroy(adapter); be_evt_queues_destroy(adapter);
} }
static int be_clear(struct be_adapter *adapter) static void be_cancel_worker(struct be_adapter *adapter)
{ {
int i;
if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) { if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
cancel_delayed_work_sync(&adapter->work); cancel_delayed_work_sync(&adapter->work);
adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED; adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
} }
}
static int be_clear(struct be_adapter *adapter)
{
int i;
be_cancel_worker(adapter);
if (sriov_enabled(adapter)) if (sriov_enabled(adapter))
be_vf_clear(adapter); be_vf_clear(adapter);
...@@ -2982,7 +2978,7 @@ static void BEx_get_resources(struct be_adapter *adapter, ...@@ -2982,7 +2978,7 @@ static void BEx_get_resources(struct be_adapter *adapter,
BE3_MAX_RSS_QS : BE2_MAX_RSS_QS; BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
res->max_rx_qs = res->max_rss_qs + 1; res->max_rx_qs = res->max_rss_qs + 1;
res->max_evt_qs = be_physfn(adapter) ? MAX_EVT_QS : 1; res->max_evt_qs = be_physfn(adapter) ? BE3_MAX_EVT_QS : 1;
res->if_cap_flags = BE_IF_CAP_FLAGS_WANT; res->if_cap_flags = BE_IF_CAP_FLAGS_WANT;
if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS)) if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS))
...@@ -3108,8 +3104,15 @@ static int be_mac_setup(struct be_adapter *adapter) ...@@ -3108,8 +3104,15 @@ static int be_mac_setup(struct be_adapter *adapter)
return 0; return 0;
} }
static void be_schedule_worker(struct be_adapter *adapter)
{
schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
}
static int be_setup_queues(struct be_adapter *adapter) static int be_setup_queues(struct be_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev;
int status; int status;
status = be_evt_queues_create(adapter); status = be_evt_queues_create(adapter);
...@@ -3128,12 +3131,56 @@ static int be_setup_queues(struct be_adapter *adapter) ...@@ -3128,12 +3131,56 @@ static int be_setup_queues(struct be_adapter *adapter)
if (status) if (status)
goto err; goto err;
status = netif_set_real_num_rx_queues(netdev, adapter->num_rx_qs);
if (status)
goto err;
status = netif_set_real_num_tx_queues(netdev, adapter->num_tx_qs);
if (status)
goto err;
return 0; return 0;
err: err:
dev_err(&adapter->pdev->dev, "queue_setup failed\n"); dev_err(&adapter->pdev->dev, "queue_setup failed\n");
return status; return status;
} }
int be_update_queues(struct be_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
int status;
if (netif_running(netdev))
be_close(netdev);
be_cancel_worker(adapter);
/* If any vectors have been shared with RoCE we cannot re-program
* the MSIx table.
*/
if (!adapter->num_msix_roce_vec)
be_msix_disable(adapter);
be_clear_queues(adapter);
if (!msix_enabled(adapter)) {
status = be_msix_enable(adapter);
if (status)
return status;
}
status = be_setup_queues(adapter);
if (status)
return status;
be_schedule_worker(adapter);
if (netif_running(netdev))
status = be_open(netdev);
return status;
}
static int be_setup(struct be_adapter *adapter) static int be_setup(struct be_adapter *adapter)
{ {
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
...@@ -3163,7 +3210,10 @@ static int be_setup(struct be_adapter *adapter) ...@@ -3163,7 +3210,10 @@ static int be_setup(struct be_adapter *adapter)
if (status) if (status)
goto err; goto err;
/* Updating real_num_tx/rx_queues() requires rtnl_lock() */
rtnl_lock();
status = be_setup_queues(adapter); status = be_setup_queues(adapter);
rtnl_unlock();
if (status) if (status)
goto err; goto err;
...@@ -3202,8 +3252,7 @@ static int be_setup(struct be_adapter *adapter) ...@@ -3202,8 +3252,7 @@ static int be_setup(struct be_adapter *adapter)
if (!status && be_pause_supported(adapter)) if (!status && be_pause_supported(adapter))
adapter->phy.fc_autoneg = 1; adapter->phy.fc_autoneg = 1;
schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); be_schedule_worker(adapter);
adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
return 0; return 0;
err: err:
be_clear(adapter); be_clear(adapter);
...@@ -3769,8 +3818,6 @@ static const struct net_device_ops be_netdev_ops = { ...@@ -3769,8 +3818,6 @@ static const struct net_device_ops be_netdev_ops = {
static void be_netdev_init(struct net_device *netdev) static void be_netdev_init(struct net_device *netdev)
{ {
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
struct be_eq_obj *eqo;
int i;
netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
...@@ -3793,9 +3840,6 @@ static void be_netdev_init(struct net_device *netdev) ...@@ -3793,9 +3840,6 @@ static void be_netdev_init(struct net_device *netdev)
netdev->netdev_ops = &be_netdev_ops; netdev->netdev_ops = &be_netdev_ops;
SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
for_all_evt_queues(adapter, eqo, i)
netif_napi_add(netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT);
} }
static void be_unmap_pci_bars(struct be_adapter *adapter) static void be_unmap_pci_bars(struct be_adapter *adapter)
......
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