mac80211: clean up channel type config
[linux-2.6/libata-dev.git] / drivers / staging / benet / be_ethtool.c
blob027af85707aa21934be37af9e6ced570490bbef2
1 /*
2 * Copyright (C) 2005 - 2008 ServerEngines
3 * All rights reserved.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
10 * Contact Information:
11 * linux-drivers@serverengines.com
13 * ServerEngines
14 * 209 N. Fair Oaks Ave
15 * Sunnyvale, CA 94085
18 * be_ethtool.c
20 * This file contains various functions that ethtool can use
21 * to talk to the driver and the BE H/W.
24 #include "benet.h"
26 #include <linux/ethtool.h>
28 static const char benet_gstrings_stats[][ETH_GSTRING_LEN] = {
29 /* net_device_stats */
30 "rx_packets",
31 "tx_packets",
32 "rx_bytes",
33 "tx_bytes",
34 "rx_errors",
35 "tx_errors",
36 "rx_dropped",
37 "tx_dropped",
38 "multicast",
39 "collisions",
40 "rx_length_errors",
41 "rx_over_errors",
42 "rx_crc_errors",
43 "rx_frame_errors",
44 "rx_fifo_errors",
45 "rx_missed_errors",
46 "tx_aborted_errors",
47 "tx_carrier_errors",
48 "tx_fifo_errors",
49 "tx_heartbeat_errors",
50 "tx_window_errors",
51 "rx_compressed",
52 "tc_compressed",
53 /* BE driver Stats */
54 "bes_tx_reqs",
55 "bes_tx_fails",
56 "bes_fwd_reqs",
57 "bes_tx_wrbs",
58 "bes_interrupts",
59 "bes_events",
60 "bes_tx_events",
61 "bes_rx_events",
62 "bes_tx_compl",
63 "bes_rx_compl",
64 "bes_ethrx_post_fail",
65 "bes_802_3_dropped_frames",
66 "bes_802_3_malformed_frames",
67 "bes_rx_misc_pkts",
68 "bes_eth_tx_rate",
69 "bes_eth_rx_rate",
70 "Num Packets collected",
71 "Num Times Flushed",
74 #define NET_DEV_STATS_LEN \
75 (sizeof(struct net_device_stats)/sizeof(unsigned long))
77 #define BENET_STATS_LEN ARRAY_SIZE(benet_gstrings_stats)
79 static void
80 be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
82 struct be_net_object *pnob = netdev_priv(netdev);
83 struct be_adapter *adapter = pnob->adapter;
85 strncpy(drvinfo->driver, be_driver_name, 32);
86 strncpy(drvinfo->version, be_drvr_ver, 32);
87 strncpy(drvinfo->fw_version, be_fw_ver, 32);
88 strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
89 drvinfo->testinfo_len = 0;
90 drvinfo->regdump_len = 0;
91 drvinfo->eedump_len = 0;
94 static int
95 be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
97 struct be_net_object *pnob = netdev_priv(netdev);
98 struct be_adapter *adapter = pnob->adapter;
100 coalesce->rx_max_coalesced_frames = adapter->max_rx_coal;
102 coalesce->rx_coalesce_usecs = adapter->cur_eqd;
103 coalesce->rx_coalesce_usecs_high = adapter->max_eqd;
104 coalesce->rx_coalesce_usecs_low = adapter->min_eqd;
106 coalesce->tx_coalesce_usecs = adapter->cur_eqd;
107 coalesce->tx_coalesce_usecs_high = adapter->max_eqd;
108 coalesce->tx_coalesce_usecs_low = adapter->min_eqd;
110 coalesce->use_adaptive_rx_coalesce = adapter->enable_aic;
111 coalesce->use_adaptive_tx_coalesce = adapter->enable_aic;
113 return 0;
117 * This routine is used to set interrup coalescing delay *as well as*
118 * the number of pkts to coalesce for LRO.
120 static int
121 be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
123 struct be_net_object *pnob = netdev_priv(netdev);
124 struct be_adapter *adapter = pnob->adapter;
125 struct be_eq_object *eq_objectp;
126 u32 max, min, cur;
127 int status;
129 adapter->max_rx_coal = coalesce->rx_max_coalesced_frames;
130 if (adapter->max_rx_coal >= BE_LRO_MAX_PKTS)
131 adapter->max_rx_coal = BE_LRO_MAX_PKTS;
133 if (adapter->enable_aic == 0 &&
134 coalesce->use_adaptive_rx_coalesce == 1) {
135 /* if AIC is being turned on now, start with an EQD of 0 */
136 adapter->cur_eqd = 0;
138 adapter->enable_aic = coalesce->use_adaptive_rx_coalesce;
140 /* round off to nearest multiple of 8 */
141 max = (((coalesce->rx_coalesce_usecs_high + 4) >> 3) << 3);
142 min = (((coalesce->rx_coalesce_usecs_low + 4) >> 3) << 3);
143 cur = (((coalesce->rx_coalesce_usecs + 4) >> 3) << 3);
145 if (adapter->enable_aic) {
146 /* accept low and high if AIC is enabled */
147 if (max > MAX_EQD)
148 max = MAX_EQD;
149 if (min > max)
150 min = max;
151 adapter->max_eqd = max;
152 adapter->min_eqd = min;
153 if (adapter->cur_eqd > max)
154 adapter->cur_eqd = max;
155 if (adapter->cur_eqd < min)
156 adapter->cur_eqd = min;
157 } else {
158 /* accept specified coalesce_usecs only if AIC is disabled */
159 if (cur > MAX_EQD)
160 cur = MAX_EQD;
161 eq_objectp = &pnob->event_q_obj;
162 status =
163 be_eq_modify_delay(&pnob->fn_obj, 1, &eq_objectp, &cur,
164 NULL, NULL, NULL);
165 if (status == BE_SUCCESS)
166 adapter->cur_eqd = cur;
168 return 0;
171 static u32 be_get_rx_csum(struct net_device *netdev)
173 struct be_net_object *pnob = netdev_priv(netdev);
174 struct be_adapter *adapter = pnob->adapter;
175 return adapter->rx_csum;
178 static int be_set_rx_csum(struct net_device *netdev, uint32_t data)
180 struct be_net_object *pnob = netdev_priv(netdev);
181 struct be_adapter *adapter = pnob->adapter;
183 if (data)
184 adapter->rx_csum = 1;
185 else
186 adapter->rx_csum = 0;
188 return 0;
191 static void
192 be_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
194 switch (stringset) {
195 case ETH_SS_STATS:
196 memcpy(data, *benet_gstrings_stats,
197 sizeof(benet_gstrings_stats));
198 break;
202 static int be_get_stats_count(struct net_device *netdev)
204 return BENET_STATS_LEN;
207 static void
208 be_get_ethtool_stats(struct net_device *netdev,
209 struct ethtool_stats *stats, uint64_t *data)
211 struct be_net_object *pnob = netdev_priv(netdev);
212 struct be_adapter *adapter = pnob->adapter;
213 int i;
215 benet_get_stats(netdev);
217 for (i = 0; i <= NET_DEV_STATS_LEN; i++)
218 data[i] = ((unsigned long *)&adapter->benet_stats)[i];
220 data[i] = adapter->be_stat.bes_tx_reqs;
221 data[i++] = adapter->be_stat.bes_tx_fails;
222 data[i++] = adapter->be_stat.bes_fwd_reqs;
223 data[i++] = adapter->be_stat.bes_tx_wrbs;
225 data[i++] = adapter->be_stat.bes_ints;
226 data[i++] = adapter->be_stat.bes_events;
227 data[i++] = adapter->be_stat.bes_tx_events;
228 data[i++] = adapter->be_stat.bes_rx_events;
229 data[i++] = adapter->be_stat.bes_tx_compl;
230 data[i++] = adapter->be_stat.bes_rx_compl;
231 data[i++] = adapter->be_stat.bes_ethrx_post_fail;
232 data[i++] = adapter->be_stat.bes_802_3_dropped_frames;
233 data[i++] = adapter->be_stat.bes_802_3_malformed_frames;
234 data[i++] = adapter->be_stat.bes_rx_misc_pkts;
235 data[i++] = adapter->be_stat.bes_eth_tx_rate;
236 data[i++] = adapter->be_stat.bes_eth_rx_rate;
237 data[i++] = adapter->be_stat.bes_rx_coal;
238 data[i++] = adapter->be_stat.bes_rx_flush;
242 static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
244 ecmd->speed = SPEED_10000;
245 ecmd->duplex = DUPLEX_FULL;
246 ecmd->autoneg = AUTONEG_DISABLE;
247 return 0;
250 /* Get the Ring parameters from the pnob */
251 static void
252 be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
254 struct be_net_object *pnob = netdev_priv(netdev);
256 /* Pre Set Maxims */
257 ring->rx_max_pending = pnob->rx_q_len;
258 ring->rx_mini_max_pending = ring->rx_mini_max_pending;
259 ring->rx_jumbo_max_pending = ring->rx_jumbo_max_pending;
260 ring->tx_max_pending = pnob->tx_q_len;
262 /* Current hardware Settings */
263 ring->rx_pending = atomic_read(&pnob->rx_q_posted);
264 ring->rx_mini_pending = ring->rx_mini_pending;
265 ring->rx_jumbo_pending = ring->rx_jumbo_pending;
266 ring->tx_pending = atomic_read(&pnob->tx_q_used);
270 static void
271 be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
273 struct be_net_object *pnob = netdev_priv(netdev);
274 bool rxfc, txfc;
275 int status;
277 status = be_eth_get_flow_control(&pnob->fn_obj, &txfc, &rxfc);
278 if (status != BE_SUCCESS) {
279 dev_info(&netdev->dev, "Unable to get pause frame settings\n");
280 /* return defaults */
281 ecmd->rx_pause = 1;
282 ecmd->tx_pause = 0;
283 ecmd->autoneg = AUTONEG_ENABLE;
284 return;
287 if (txfc == true)
288 ecmd->tx_pause = 1;
289 else
290 ecmd->tx_pause = 0;
292 if (rxfc == true)
293 ecmd->rx_pause = 1;
294 else
295 ecmd->rx_pause = 0;
297 ecmd->autoneg = AUTONEG_ENABLE;
300 static int
301 be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
303 struct be_net_object *pnob = netdev_priv(netdev);
304 bool txfc, rxfc;
305 int status;
307 if (ecmd->autoneg != AUTONEG_ENABLE)
308 return -EINVAL;
310 if (ecmd->tx_pause)
311 txfc = true;
312 else
313 txfc = false;
315 if (ecmd->rx_pause)
316 rxfc = true;
317 else
318 rxfc = false;
320 status = be_eth_set_flow_control(&pnob->fn_obj, txfc, rxfc);
321 if (status != BE_SUCCESS) {
322 dev_info(&netdev->dev, "Unable to set pause frame settings\n");
323 return -1;
325 return 0;
328 struct ethtool_ops be_ethtool_ops = {
329 .get_settings = be_get_settings,
330 .get_drvinfo = be_get_drvinfo,
331 .get_link = ethtool_op_get_link,
332 .get_coalesce = be_get_coalesce,
333 .set_coalesce = be_set_coalesce,
334 .get_ringparam = be_get_ringparam,
335 .get_pauseparam = be_get_pauseparam,
336 .set_pauseparam = be_set_pauseparam,
337 .get_rx_csum = be_get_rx_csum,
338 .set_rx_csum = be_set_rx_csum,
339 .get_tx_csum = ethtool_op_get_tx_csum,
340 .set_tx_csum = ethtool_op_set_tx_csum,
341 .get_sg = ethtool_op_get_sg,
342 .set_sg = ethtool_op_set_sg,
343 .get_tso = ethtool_op_get_tso,
344 .set_tso = ethtool_op_set_tso,
345 .get_strings = be_get_strings,
346 .get_stats_count = be_get_stats_count,
347 .get_ethtool_stats = be_get_ethtool_stats,