Commit | Line | Data |
---|---|---|
aaec0fab JO |
1 | /* |
2 | * Network device driver for Cell Processor-Based Blade | |
3 | * | |
4 | * (C) Copyright IBM Corp. 2005 | |
5 | * | |
6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | |
7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; either version 2, or (at your option) | |
12 | * any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 | */ | |
23 | ||
24 | #include <linux/netdevice.h> | |
25 | #include <linux/ethtool.h> | |
26 | #include <linux/pci.h> | |
27 | ||
28 | #include "spider_net.h" | |
29 | ||
9b6b0b81 JL |
30 | |
31 | #define SPIDER_NET_NUM_STATS 13 | |
32 | ||
33 | static struct { | |
34 | const char str[ETH_GSTRING_LEN]; | |
35 | } ethtool_stats_keys[] = { | |
36 | { "tx_packets" }, | |
37 | { "tx_bytes" }, | |
38 | { "rx_packets" }, | |
39 | { "rx_bytes" }, | |
40 | { "tx_errors" }, | |
41 | { "tx_dropped" }, | |
42 | { "rx_dropped" }, | |
43 | { "rx_descriptor_error" }, | |
44 | { "tx_timeouts" }, | |
45 | { "alloc_rx_skb_error" }, | |
46 | { "rx_iommu_map_error" }, | |
47 | { "tx_iommu_map_error" }, | |
48 | { "rx_desc_unk_state" }, | |
49 | }; | |
50 | ||
054034db JO |
51 | static int |
52 | spider_net_ethtool_get_settings(struct net_device *netdev, | |
53 | struct ethtool_cmd *cmd) | |
54 | { | |
55 | struct spider_net_card *card; | |
56 | card = netdev_priv(netdev); | |
57 | ||
58 | cmd->supported = (SUPPORTED_1000baseT_Full | | |
59 | SUPPORTED_FIBRE); | |
60 | cmd->advertising = (ADVERTISED_1000baseT_Full | | |
61 | ADVERTISED_FIBRE); | |
62 | cmd->port = PORT_FIBRE; | |
63 | cmd->speed = card->phy.speed; | |
64 | cmd->duplex = DUPLEX_FULL; | |
65 | ||
66 | return 0; | |
67 | } | |
68 | ||
aaec0fab JO |
69 | static void |
70 | spider_net_ethtool_get_drvinfo(struct net_device *netdev, | |
71 | struct ethtool_drvinfo *drvinfo) | |
72 | { | |
73 | struct spider_net_card *card; | |
74 | card = netdev_priv(netdev); | |
75 | ||
76 | /* clear and fill out info */ | |
77 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); | |
78 | strncpy(drvinfo->driver, spider_net_driver_name, 32); | |
90f10841 | 79 | strncpy(drvinfo->version, VERSION, 32); |
aaec0fab JO |
80 | strcpy(drvinfo->fw_version, "no information"); |
81 | strncpy(drvinfo->bus_info, pci_name(card->pdev), 32); | |
82 | } | |
83 | ||
84 | static void | |
85 | spider_net_ethtool_get_wol(struct net_device *netdev, | |
86 | struct ethtool_wolinfo *wolinfo) | |
87 | { | |
88 | /* no support for wol */ | |
89 | wolinfo->supported = 0; | |
90 | wolinfo->wolopts = 0; | |
91 | } | |
92 | ||
93 | static u32 | |
94 | spider_net_ethtool_get_msglevel(struct net_device *netdev) | |
95 | { | |
96 | struct spider_net_card *card; | |
97 | card = netdev_priv(netdev); | |
98 | return card->msg_enable; | |
99 | } | |
100 | ||
101 | static void | |
102 | spider_net_ethtool_set_msglevel(struct net_device *netdev, | |
103 | u32 level) | |
104 | { | |
105 | struct spider_net_card *card; | |
106 | card = netdev_priv(netdev); | |
107 | card->msg_enable = level; | |
108 | } | |
109 | ||
110 | static int | |
111 | spider_net_ethtool_nway_reset(struct net_device *netdev) | |
112 | { | |
113 | if (netif_running(netdev)) { | |
114 | spider_net_stop(netdev); | |
115 | spider_net_open(netdev); | |
116 | } | |
117 | return 0; | |
118 | } | |
119 | ||
120 | static u32 | |
121 | spider_net_ethtool_get_rx_csum(struct net_device *netdev) | |
122 | { | |
123 | struct spider_net_card *card = netdev->priv; | |
124 | ||
125 | return card->options.rx_csum; | |
126 | } | |
127 | ||
128 | static int | |
129 | spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n) | |
130 | { | |
131 | struct spider_net_card *card = netdev->priv; | |
132 | ||
133 | card->options.rx_csum = n; | |
134 | return 0; | |
135 | } | |
136 | ||
11f1a52b AB |
137 | static uint32_t |
138 | spider_net_ethtool_get_tx_csum(struct net_device *netdev) | |
139 | { | |
140 | return (netdev->features & NETIF_F_HW_CSUM) != 0; | |
141 | } | |
142 | ||
143 | static int | |
144 | spider_net_ethtool_set_tx_csum(struct net_device *netdev, uint32_t data) | |
145 | { | |
146 | if (data) | |
147 | netdev->features |= NETIF_F_HW_CSUM; | |
148 | else | |
149 | netdev->features &= ~NETIF_F_HW_CSUM; | |
150 | ||
151 | return 0; | |
152 | } | |
153 | ||
b68a60e5 JL |
154 | static void |
155 | spider_net_ethtool_get_ringparam(struct net_device *netdev, | |
156 | struct ethtool_ringparam *ering) | |
157 | { | |
158 | struct spider_net_card *card = netdev->priv; | |
159 | ||
160 | ering->tx_max_pending = SPIDER_NET_TX_DESCRIPTORS_MAX; | |
66c09716 | 161 | ering->tx_pending = card->num_tx_desc; |
b68a60e5 | 162 | ering->rx_max_pending = SPIDER_NET_RX_DESCRIPTORS_MAX; |
66c09716 | 163 | ering->rx_pending = card->num_rx_desc; |
b68a60e5 JL |
164 | } |
165 | ||
9b6b0b81 JL |
166 | static int spider_net_get_stats_count(struct net_device *netdev) |
167 | { | |
168 | return SPIDER_NET_NUM_STATS; | |
169 | } | |
170 | ||
171 | static void spider_net_get_ethtool_stats(struct net_device *netdev, | |
172 | struct ethtool_stats *stats, u64 *data) | |
173 | { | |
174 | struct spider_net_card *card = netdev->priv; | |
175 | ||
176 | data[0] = card->netdev_stats.tx_packets; | |
177 | data[1] = card->netdev_stats.tx_bytes; | |
178 | data[2] = card->netdev_stats.rx_packets; | |
179 | data[3] = card->netdev_stats.rx_bytes; | |
180 | data[4] = card->netdev_stats.tx_errors; | |
181 | data[5] = card->netdev_stats.tx_dropped; | |
182 | data[6] = card->netdev_stats.rx_dropped; | |
183 | data[7] = card->spider_stats.rx_desc_error; | |
184 | data[8] = card->spider_stats.tx_timeouts; | |
185 | data[9] = card->spider_stats.alloc_rx_skb_error; | |
186 | data[10] = card->spider_stats.rx_iommu_map_error; | |
187 | data[11] = card->spider_stats.tx_iommu_map_error; | |
188 | data[12] = card->spider_stats.rx_desc_unk_state; | |
189 | } | |
190 | ||
191 | static void spider_net_get_strings(struct net_device *netdev, u32 stringset, | |
192 | u8 *data) | |
193 | { | |
194 | memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); | |
195 | } | |
196 | ||
7282d491 | 197 | const struct ethtool_ops spider_net_ethtool_ops = { |
054034db | 198 | .get_settings = spider_net_ethtool_get_settings, |
aaec0fab JO |
199 | .get_drvinfo = spider_net_ethtool_get_drvinfo, |
200 | .get_wol = spider_net_ethtool_get_wol, | |
201 | .get_msglevel = spider_net_ethtool_get_msglevel, | |
202 | .set_msglevel = spider_net_ethtool_set_msglevel, | |
203 | .nway_reset = spider_net_ethtool_nway_reset, | |
204 | .get_rx_csum = spider_net_ethtool_get_rx_csum, | |
205 | .set_rx_csum = spider_net_ethtool_set_rx_csum, | |
11f1a52b AB |
206 | .get_tx_csum = spider_net_ethtool_get_tx_csum, |
207 | .set_tx_csum = spider_net_ethtool_set_tx_csum, | |
b68a60e5 | 208 | .get_ringparam = spider_net_ethtool_get_ringparam, |
9b6b0b81 JL |
209 | .get_strings = spider_net_get_strings, |
210 | .get_stats_count = spider_net_get_stats_count, | |
211 | .get_ethtool_stats = spider_net_get_ethtool_stats, | |
aaec0fab JO |
212 | }; |
213 |