aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSathya Perla <sathya.perla@emulex.com>2013-08-27 07:27:35 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-27 15:57:05 -0400
commit68d7bdcb4c00ec799ad949f4b4c50985539710e2 (patch)
tree773f22351be2b8b9460e1593d104737c2b48b5bc /drivers/net
parent7707133ceb38f590729d0165099555928630af1c (diff)
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: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h17
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c25
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c94
3 files changed, 104 insertions, 32 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 8b416355879f..ace5050dba38 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -99,16 +99,17 @@ static inline char *nic_name(struct pci_dev *pdev)
99#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */ 99#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
100#define MCC_CQ_LEN 256 100#define MCC_CQ_LEN 256
101 101
102#define BE3_MAX_RSS_QS 8
103#define BE2_MAX_RSS_QS 4 102#define BE2_MAX_RSS_QS 4
104#define BE3_MAX_TX_QS 8 103#define BE3_MAX_RSS_QS 16
105#define MAX_RSS_QS BE3_MAX_RSS_QS 104#define BE3_MAX_TX_QS 16
106#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ 105#define BE3_MAX_EVT_QS 16
107#define MAX_EVT_QS MAX_RSS_QS 106
107#define MAX_RX_QS 32
108#define MAX_EVT_QS 32
109#define MAX_TX_QS 32
108 110
109#define MAX_TX_QS 8
110#define MAX_ROCE_EQS 5 111#define MAX_ROCE_EQS 5
111#define MAX_MSIX_VECTORS (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */ 112#define MAX_MSIX_VECTORS 32
112#define MIN_MSIX_VECTORS 1 113#define MIN_MSIX_VECTORS 1
113#define BE_TX_BUDGET 256 114#define BE_TX_BUDGET 256
114#define BE_NAPI_WEIGHT 64 115#define BE_NAPI_WEIGHT 64
@@ -701,6 +702,8 @@ extern int be_load_fw(struct be_adapter *adapter, u8 *func);
701extern bool be_is_wol_supported(struct be_adapter *adapter); 702extern bool be_is_wol_supported(struct be_adapter *adapter);
702extern bool be_pause_supported(struct be_adapter *adapter); 703extern bool be_pause_supported(struct be_adapter *adapter);
703extern u32 be_get_fw_log_level(struct be_adapter *adapter); 704extern u32 be_get_fw_log_level(struct be_adapter *adapter);
705int be_update_queues(struct be_adapter *adapter);
706int be_poll(struct napi_struct *napi, int budget);
704 707
705/* 708/*
706 * internal function to initialize-cleanup roce device. 709 * internal function to initialize-cleanup roce device.
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 4f8c941217cc..b440a1fac77b 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -1119,6 +1119,29 @@ static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
1119 return status; 1119 return status;
1120} 1120}
1121 1121
1122static void be_get_channels(struct net_device *netdev,
1123 struct ethtool_channels *ch)
1124{
1125 struct be_adapter *adapter = netdev_priv(netdev);
1126
1127 ch->combined_count = adapter->num_evt_qs;
1128 ch->max_combined = be_max_qs(adapter);
1129}
1130
1131static int be_set_channels(struct net_device *netdev,
1132 struct ethtool_channels *ch)
1133{
1134 struct be_adapter *adapter = netdev_priv(netdev);
1135
1136 if (ch->rx_count || ch->tx_count || ch->other_count ||
1137 !ch->combined_count || ch->combined_count > be_max_qs(adapter))
1138 return -EINVAL;
1139
1140 adapter->cfg_num_qs = ch->combined_count;
1141
1142 return be_update_queues(adapter);
1143}
1144
1122const struct ethtool_ops be_ethtool_ops = { 1145const struct ethtool_ops be_ethtool_ops = {
1123 .get_settings = be_get_settings, 1146 .get_settings = be_get_settings,
1124 .get_drvinfo = be_get_drvinfo, 1147 .get_drvinfo = be_get_drvinfo,
@@ -1145,4 +1168,6 @@ const struct ethtool_ops be_ethtool_ops = {
1145 .self_test = be_self_test, 1168 .self_test = be_self_test,
1146 .get_rxnfc = be_get_rxnfc, 1169 .get_rxnfc = be_get_rxnfc,
1147 .set_rxnfc = be_set_rxnfc, 1170 .set_rxnfc = be_set_rxnfc,
1171 .get_channels = be_get_channels,
1172 .set_channels = be_set_channels
1148}; 1173};
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index b08459d268b4..50116f8ed576 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1913,6 +1913,7 @@ static void be_evt_queues_destroy(struct be_adapter *adapter)
1913 if (eqo->q.created) { 1913 if (eqo->q.created) {
1914 be_eq_clean(eqo); 1914 be_eq_clean(eqo);
1915 be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ); 1915 be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
1916 netif_napi_del(&eqo->napi);
1916 } 1917 }
1917 be_queue_free(adapter, &eqo->q); 1918 be_queue_free(adapter, &eqo->q);
1918 } 1919 }
@@ -1928,6 +1929,8 @@ static int be_evt_queues_create(struct be_adapter *adapter)
1928 adapter->cfg_num_qs); 1929 adapter->cfg_num_qs);
1929 1930
1930 for_all_evt_queues(adapter, eqo, i) { 1931 for_all_evt_queues(adapter, eqo, i) {
1932 netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
1933 BE_NAPI_WEIGHT);
1931 eqo->adapter = adapter; 1934 eqo->adapter = adapter;
1932 eqo->tx_budget = BE_TX_BUDGET; 1935 eqo->tx_budget = BE_TX_BUDGET;
1933 eqo->idx = i; 1936 eqo->idx = i;
@@ -2021,12 +2024,6 @@ static int be_tx_qs_create(struct be_adapter *adapter)
2021 int status, i; 2024 int status, i;
2022 2025
2023 adapter->num_tx_qs = min(adapter->num_evt_qs, be_max_txqs(adapter)); 2026 adapter->num_tx_qs = min(adapter->num_evt_qs, be_max_txqs(adapter));
2024 if (adapter->num_tx_qs != MAX_TX_QS) {
2025 rtnl_lock();
2026 netif_set_real_num_tx_queues(adapter->netdev,
2027 adapter->num_tx_qs);
2028 rtnl_unlock();
2029 }
2030 2027
2031 for_all_tx_queues(adapter, txo, i) { 2028 for_all_tx_queues(adapter, txo, i) {
2032 cq = &txo->cq; 2029 cq = &txo->cq;
@@ -2087,13 +2084,6 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
2087 if (adapter->num_rx_qs > 1) 2084 if (adapter->num_rx_qs > 1)
2088 adapter->num_rx_qs++; 2085 adapter->num_rx_qs++;
2089 2086
2090 if (adapter->num_rx_qs != MAX_RX_QS) {
2091 rtnl_lock();
2092 netif_set_real_num_rx_queues(adapter->netdev,
2093 adapter->num_rx_qs);
2094 rtnl_unlock();
2095 }
2096
2097 adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; 2087 adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
2098 for_all_rx_queues(adapter, rxo, i) { 2088 for_all_rx_queues(adapter, rxo, i) {
2099 rxo->adapter = adapter; 2089 rxo->adapter = adapter;
@@ -2244,7 +2234,7 @@ static bool be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
2244 return (work_done < budget); /* Done */ 2234 return (work_done < budget); /* Done */
2245} 2235}
2246 2236
2247static int be_poll(struct napi_struct *napi, int budget) 2237int be_poll(struct napi_struct *napi, int budget)
2248{ 2238{
2249 struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi); 2239 struct be_eq_obj *eqo = container_of(napi, struct be_eq_obj, napi);
2250 struct be_adapter *adapter = eqo->adapter; 2240 struct be_adapter *adapter = eqo->adapter;
@@ -2356,6 +2346,7 @@ static void be_msix_disable(struct be_adapter *adapter)
2356 if (msix_enabled(adapter)) { 2346 if (msix_enabled(adapter)) {
2357 pci_disable_msix(adapter->pdev); 2347 pci_disable_msix(adapter->pdev);
2358 adapter->num_msix_vec = 0; 2348 adapter->num_msix_vec = 0;
2349 adapter->num_msix_roce_vec = 0;
2359 } 2350 }
2360} 2351}
2361 2352
@@ -2771,14 +2762,19 @@ static void be_clear_queues(struct be_adapter *adapter)
2771 be_evt_queues_destroy(adapter); 2762 be_evt_queues_destroy(adapter);
2772} 2763}
2773 2764
2774static int be_clear(struct be_adapter *adapter) 2765static void be_cancel_worker(struct be_adapter *adapter)
2775{ 2766{
2776 int i;
2777
2778 if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) { 2767 if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
2779 cancel_delayed_work_sync(&adapter->work); 2768 cancel_delayed_work_sync(&adapter->work);
2780 adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED; 2769 adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
2781 } 2770 }
2771}
2772
2773static int be_clear(struct be_adapter *adapter)
2774{
2775 int i;
2776
2777 be_cancel_worker(adapter);
2782 2778
2783 if (sriov_enabled(adapter)) 2779 if (sriov_enabled(adapter))
2784 be_vf_clear(adapter); 2780 be_vf_clear(adapter);
@@ -2982,7 +2978,7 @@ static void BEx_get_resources(struct be_adapter *adapter,
2982 BE3_MAX_RSS_QS : BE2_MAX_RSS_QS; 2978 BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
2983 res->max_rx_qs = res->max_rss_qs + 1; 2979 res->max_rx_qs = res->max_rss_qs + 1;
2984 2980
2985 res->max_evt_qs = be_physfn(adapter) ? MAX_EVT_QS : 1; 2981 res->max_evt_qs = be_physfn(adapter) ? BE3_MAX_EVT_QS : 1;
2986 2982
2987 res->if_cap_flags = BE_IF_CAP_FLAGS_WANT; 2983 res->if_cap_flags = BE_IF_CAP_FLAGS_WANT;
2988 if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS)) 2984 if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS))
@@ -3108,8 +3104,15 @@ static int be_mac_setup(struct be_adapter *adapter)
3108 return 0; 3104 return 0;
3109} 3105}
3110 3106
3107static void be_schedule_worker(struct be_adapter *adapter)
3108{
3109 schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
3110 adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
3111}
3112
3111static int be_setup_queues(struct be_adapter *adapter) 3113static int be_setup_queues(struct be_adapter *adapter)
3112{ 3114{
3115 struct net_device *netdev = adapter->netdev;
3113 int status; 3116 int status;
3114 3117
3115 status = be_evt_queues_create(adapter); 3118 status = be_evt_queues_create(adapter);
@@ -3128,12 +3131,56 @@ static int be_setup_queues(struct be_adapter *adapter)
3128 if (status) 3131 if (status)
3129 goto err; 3132 goto err;
3130 3133
3134 status = netif_set_real_num_rx_queues(netdev, adapter->num_rx_qs);
3135 if (status)
3136 goto err;
3137
3138 status = netif_set_real_num_tx_queues(netdev, adapter->num_tx_qs);
3139 if (status)
3140 goto err;
3141
3131 return 0; 3142 return 0;
3132err: 3143err:
3133 dev_err(&adapter->pdev->dev, "queue_setup failed\n"); 3144 dev_err(&adapter->pdev->dev, "queue_setup failed\n");
3134 return status; 3145 return status;
3135} 3146}
3136 3147
3148int be_update_queues(struct be_adapter *adapter)
3149{
3150 struct net_device *netdev = adapter->netdev;
3151 int status;
3152
3153 if (netif_running(netdev))
3154 be_close(netdev);
3155
3156 be_cancel_worker(adapter);
3157
3158 /* If any vectors have been shared with RoCE we cannot re-program
3159 * the MSIx table.
3160 */
3161 if (!adapter->num_msix_roce_vec)
3162 be_msix_disable(adapter);
3163
3164 be_clear_queues(adapter);
3165
3166 if (!msix_enabled(adapter)) {
3167 status = be_msix_enable(adapter);
3168 if (status)
3169 return status;
3170 }
3171
3172 status = be_setup_queues(adapter);
3173 if (status)
3174 return status;
3175
3176 be_schedule_worker(adapter);
3177
3178 if (netif_running(netdev))
3179 status = be_open(netdev);
3180
3181 return status;
3182}
3183
3137static int be_setup(struct be_adapter *adapter) 3184static int be_setup(struct be_adapter *adapter)
3138{ 3185{
3139 struct device *dev = &adapter->pdev->dev; 3186 struct device *dev = &adapter->pdev->dev;
@@ -3163,7 +3210,10 @@ static int be_setup(struct be_adapter *adapter)
3163 if (status) 3210 if (status)
3164 goto err; 3211 goto err;
3165 3212
3213 /* Updating real_num_tx/rx_queues() requires rtnl_lock() */
3214 rtnl_lock();
3166 status = be_setup_queues(adapter); 3215 status = be_setup_queues(adapter);
3216 rtnl_unlock();
3167 if (status) 3217 if (status)
3168 goto err; 3218 goto err;
3169 3219
@@ -3202,8 +3252,7 @@ static int be_setup(struct be_adapter *adapter)
3202 if (!status && be_pause_supported(adapter)) 3252 if (!status && be_pause_supported(adapter))
3203 adapter->phy.fc_autoneg = 1; 3253 adapter->phy.fc_autoneg = 1;
3204 3254
3205 schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); 3255 be_schedule_worker(adapter);
3206 adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
3207 return 0; 3256 return 0;
3208err: 3257err:
3209 be_clear(adapter); 3258 be_clear(adapter);
@@ -3769,8 +3818,6 @@ static const struct net_device_ops be_netdev_ops = {
3769static void be_netdev_init(struct net_device *netdev) 3818static void be_netdev_init(struct net_device *netdev)
3770{ 3819{
3771 struct be_adapter *adapter = netdev_priv(netdev); 3820 struct be_adapter *adapter = netdev_priv(netdev);
3772 struct be_eq_obj *eqo;
3773 int i;
3774 3821
3775 netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | 3822 netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
3776 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | 3823 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 netdev->netdev_ops = &be_netdev_ops; 3840 netdev->netdev_ops = &be_netdev_ops;
3794 3841
3795 SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); 3842 SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
3796
3797 for_all_evt_queues(adapter, eqo, i)
3798 netif_napi_add(netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT);
3799} 3843}
3800 3844
3801static void be_unmap_pci_bars(struct be_adapter *adapter) 3845static void be_unmap_pci_bars(struct be_adapter *adapter)