aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/ethtool.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <marcelo@kvack.org>2007-02-10 09:25:27 -0500
committerJeff Garzik <jeff@garzik.org>2007-04-28 11:00:54 -0400
commit876c9d3aeb989cf1961f2c228d309ba5dcfb1172 (patch)
tree239e9db92d13abc799c1ffc5304d8ec1503dbc61 /drivers/net/wireless/libertas/ethtool.c
parent35c3404efa7407811b706453f83d39b2539dcbd0 (diff)
[PATCH] Marvell Libertas 8388 802.11b/g USB driver
Add the Marvell Libertas 8388 802.11 USB driver. Signed-off-by: Marcelo Tosatti <marcelo@kvack.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/ethtool.c')
-rw-r--r--drivers/net/wireless/libertas/ethtool.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
new file mode 100644
index 000000000000..0064de542963
--- /dev/null
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -0,0 +1,184 @@
1
2#include <linux/netdevice.h>
3#include <linux/ethtool.h>
4#include <linux/delay.h>
5
6#include "host.h"
7#include "sbi.h"
8#include "decl.h"
9#include "defs.h"
10#include "dev.h"
11#include "join.h"
12#include "wext.h"
13static const char * mesh_stat_strings[]= {
14 "drop_duplicate_bcast",
15 "drop_ttl_zero",
16 "drop_no_fwd_route",
17 "drop_no_buffers",
18 "fwded_unicast_cnt",
19 "fwded_bcast_cnt",
20 "drop_blind_table"
21};
22
23static void libertas_ethtool_get_drvinfo(struct net_device *dev,
24 struct ethtool_drvinfo *info)
25{
26 wlan_private *priv = (wlan_private *) dev->priv;
27 char fwver[32];
28
29 libertas_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1);
30
31 strcpy(info->driver, "libertas");
32 strcpy(info->version, libertas_driver_version);
33 strcpy(info->fw_version, fwver);
34}
35
36/* All 8388 parts have 16KiB EEPROM size at the time of writing.
37 * In case that changes this needs fixing.
38 */
39#define LIBERTAS_EEPROM_LEN 16384
40
41static int libertas_ethtool_get_eeprom_len(struct net_device *dev)
42{
43 return LIBERTAS_EEPROM_LEN;
44}
45
46static int libertas_ethtool_get_eeprom(struct net_device *dev,
47 struct ethtool_eeprom *eeprom, u8 * bytes)
48{
49 wlan_private *priv = (wlan_private *) dev->priv;
50 wlan_adapter *adapter = priv->adapter;
51 struct wlan_ioctl_regrdwr regctrl;
52 char *ptr;
53 int ret;
54
55 regctrl.action = 0;
56 regctrl.offset = eeprom->offset;
57 regctrl.NOB = eeprom->len;
58
59 if (eeprom->offset + eeprom->len > LIBERTAS_EEPROM_LEN)
60 return -EINVAL;
61
62// mutex_lock(&priv->mutex);
63
64 adapter->prdeeprom =
65 (char *)kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
66 if (!adapter->prdeeprom)
67 return -ENOMEM;
68 memcpy(adapter->prdeeprom, &regctrl, sizeof(regctrl));
69
70 /* +14 is for action, offset, and NOB in
71 * response */
72 lbs_pr_debug(1, "action:%d offset: %x NOB: %02x\n",
73 regctrl.action, regctrl.offset, regctrl.NOB);
74
75 ret = libertas_prepare_and_send_command(priv,
76 cmd_802_11_eeprom_access,
77 regctrl.action,
78 cmd_option_waitforrsp, 0,
79 &regctrl);
80
81 if (ret) {
82 if (adapter->prdeeprom)
83 kfree(adapter->prdeeprom);
84 LEAVE();
85 return ret;
86 }
87
88 mdelay(10);
89
90 ptr = (char *)adapter->prdeeprom;
91
92 /* skip the command header, but include the "value" u32 variable */
93 ptr = ptr + sizeof(struct wlan_ioctl_regrdwr) - 4;
94
95 /*
96 * Return the result back to the user
97 */
98 memcpy(bytes, ptr, eeprom->len);
99
100 if (adapter->prdeeprom)
101 kfree(adapter->prdeeprom);
102// mutex_unlock(&priv->mutex);
103
104 return 0;
105}
106
107static void libertas_ethtool_get_stats(struct net_device * dev,
108 struct ethtool_stats * stats, u64 * data)
109{
110 wlan_private *priv = dev->priv;
111
112 ENTER();
113
114 stats->cmd = ETHTOOL_GSTATS;
115 BUG_ON(stats->n_stats != MESH_STATS_NUM);
116
117 data[0] = priv->mstats.fwd_drop_rbt;
118 data[1] = priv->mstats.fwd_drop_ttl;
119 data[2] = priv->mstats.fwd_drop_noroute;
120 data[3] = priv->mstats.fwd_drop_nobuf;
121 data[4] = priv->mstats.fwd_unicast_cnt;
122 data[5] = priv->mstats.fwd_bcast_cnt;
123 data[6] = priv->mstats.drop_blind;
124
125 LEAVE();
126}
127
128static int libertas_ethtool_get_stats_count(struct net_device * dev)
129{
130 int ret;
131 wlan_private *priv = dev->priv;
132 struct cmd_ds_mesh_access mesh_access;
133
134 ENTER();
135 /* Get Mesh Statistics */
136 ret = libertas_prepare_and_send_command(priv,
137 cmd_mesh_access, cmd_act_mesh_get_stats,
138 cmd_option_waitforrsp, 0, &mesh_access);
139
140 if (ret) {
141 LEAVE();
142 return 0;
143 }
144
145 priv->mstats.fwd_drop_rbt = mesh_access.data[0];
146 priv->mstats.fwd_drop_ttl = mesh_access.data[1];
147 priv->mstats.fwd_drop_noroute = mesh_access.data[2];
148 priv->mstats.fwd_drop_nobuf = mesh_access.data[3];
149 priv->mstats.fwd_unicast_cnt = mesh_access.data[4];
150 priv->mstats.fwd_bcast_cnt = mesh_access.data[5];
151 priv->mstats.drop_blind = mesh_access.data[6];
152
153 LEAVE();
154 return MESH_STATS_NUM;
155}
156
157static void libertas_ethtool_get_strings (struct net_device * dev,
158 u32 stringset,
159 u8 * s)
160{
161 int i;
162
163 ENTER();
164 switch (stringset) {
165 case ETH_SS_STATS:
166 for (i=0; i < MESH_STATS_NUM; i++) {
167 memcpy(s + i * ETH_GSTRING_LEN,
168 mesh_stat_strings[i],
169 ETH_GSTRING_LEN);
170 }
171 break;
172 }
173 LEAVE();
174}
175
176struct ethtool_ops libertas_ethtool_ops = {
177 .get_drvinfo = libertas_ethtool_get_drvinfo,
178 .get_eeprom = libertas_ethtool_get_eeprom,
179 .get_eeprom_len = libertas_ethtool_get_eeprom_len,
180 .get_stats_count = libertas_ethtool_get_stats_count,
181 .get_ethtool_stats = libertas_ethtool_get_stats,
182 .get_strings = libertas_ethtool_get_strings,
183};
184