diff options
author | Jesse Brandeburg <jesse.brandeburg@intel.com> | 2013-09-11 04:40:17 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-09-11 05:19:11 -0400 |
commit | 02e9c290814cc143ceccecb14eac3e7a05da745e (patch) | |
tree | a4269631298bf7558961b4927d0742d2401e2404 | |
parent | 56a62fc8689509fb86bcb20768d575b81d9c311e (diff) |
i40e: debugfs interface
This driver includes a debugfs interface for developers to get more hardware
information in real-time.
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
CC: PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
CC: e1000-devel@lists.sourceforge.net
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 2076 |
1 files changed, 2076 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c new file mode 100644 index 000000000000..8dbd91f64b74 --- /dev/null +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c | |||
@@ -0,0 +1,2076 @@ | |||
1 | /******************************************************************************* | ||
2 | * | ||
3 | * Intel Ethernet Controller XL710 Family Linux Driver | ||
4 | * Copyright(c) 2013 Intel Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | * | ||
19 | * The full GNU General Public License is included in this distribution in | ||
20 | * the file called "COPYING". | ||
21 | * | ||
22 | * Contact Information: | ||
23 | * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | ||
24 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
25 | * | ||
26 | ******************************************************************************/ | ||
27 | |||
28 | #ifdef CONFIG_DEBUG_FS | ||
29 | |||
30 | #include <linux/fs.h> | ||
31 | #include <linux/debugfs.h> | ||
32 | |||
33 | #include "i40e.h" | ||
34 | |||
35 | static struct dentry *i40e_dbg_root; | ||
36 | |||
37 | /** | ||
38 | * i40e_dbg_find_vsi - searches for the vsi with the given seid | ||
39 | * @pf - the pf structure to search for the vsi | ||
40 | * @seid - seid of the vsi it is searching for | ||
41 | **/ | ||
42 | static struct i40e_vsi *i40e_dbg_find_vsi(struct i40e_pf *pf, int seid) | ||
43 | { | ||
44 | int i; | ||
45 | |||
46 | if (seid < 0) | ||
47 | dev_info(&pf->pdev->dev, "%d: bad seid\n", seid); | ||
48 | else | ||
49 | for (i = 0; i < pf->hw.func_caps.num_vsis; i++) | ||
50 | if (pf->vsi[i] && (pf->vsi[i]->seid == seid)) | ||
51 | return pf->vsi[i]; | ||
52 | |||
53 | return NULL; | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * i40e_dbg_find_veb - searches for the veb with the given seid | ||
58 | * @pf - the pf structure to search for the veb | ||
59 | * @seid - seid of the veb it is searching for | ||
60 | **/ | ||
61 | static struct i40e_veb *i40e_dbg_find_veb(struct i40e_pf *pf, int seid) | ||
62 | { | ||
63 | int i; | ||
64 | |||
65 | if ((seid < I40E_BASE_VEB_SEID) || | ||
66 | (seid > (I40E_BASE_VEB_SEID + I40E_MAX_VEB))) | ||
67 | dev_info(&pf->pdev->dev, "%d: bad seid\n", seid); | ||
68 | else | ||
69 | for (i = 0; i < I40E_MAX_VEB; i++) | ||
70 | if (pf->veb[i] && pf->veb[i]->seid == seid) | ||
71 | return pf->veb[i]; | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
75 | /************************************************************** | ||
76 | * dump | ||
77 | * The dump entry in debugfs is for getting a data snapshow of | ||
78 | * the driver's current configuration and runtime details. | ||
79 | * When the filesystem entry is written, a snapshot is taken. | ||
80 | * When the entry is read, the most recent snapshot data is dumped. | ||
81 | **************************************************************/ | ||
82 | static char *i40e_dbg_dump_buf; | ||
83 | static ssize_t i40e_dbg_dump_data_len; | ||
84 | static ssize_t i40e_dbg_dump_buffer_len; | ||
85 | |||
86 | /** | ||
87 | * i40e_dbg_dump_read - read the dump data | ||
88 | * @filp: the opened file | ||
89 | * @buffer: where to write the data for the user to read | ||
90 | * @count: the size of the user's buffer | ||
91 | * @ppos: file position offset | ||
92 | **/ | ||
93 | static ssize_t i40e_dbg_dump_read(struct file *filp, char __user *buffer, | ||
94 | size_t count, loff_t *ppos) | ||
95 | { | ||
96 | int bytes_not_copied; | ||
97 | int len; | ||
98 | |||
99 | /* is *ppos bigger than the available data? */ | ||
100 | if (*ppos >= i40e_dbg_dump_data_len || !i40e_dbg_dump_buf) | ||
101 | return 0; | ||
102 | |||
103 | /* be sure to not read beyond the end of available data */ | ||
104 | len = min_t(int, count, (i40e_dbg_dump_data_len - *ppos)); | ||
105 | |||
106 | bytes_not_copied = copy_to_user(buffer, &i40e_dbg_dump_buf[*ppos], len); | ||
107 | if (bytes_not_copied < 0) | ||
108 | return bytes_not_copied; | ||
109 | |||
110 | *ppos += len; | ||
111 | return len; | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * i40e_dbg_prep_dump_buf | ||
116 | * @pf: the pf we're working with | ||
117 | * @buflen: the desired buffer length | ||
118 | * | ||
119 | * Return positive if success, 0 if failed | ||
120 | **/ | ||
121 | static int i40e_dbg_prep_dump_buf(struct i40e_pf *pf, int buflen) | ||
122 | { | ||
123 | /* if not already big enough, prep for re alloc */ | ||
124 | if (i40e_dbg_dump_buffer_len && i40e_dbg_dump_buffer_len < buflen) { | ||
125 | kfree(i40e_dbg_dump_buf); | ||
126 | i40e_dbg_dump_buffer_len = 0; | ||
127 | i40e_dbg_dump_buf = NULL; | ||
128 | } | ||
129 | |||
130 | /* get a new buffer if needed */ | ||
131 | if (!i40e_dbg_dump_buf) { | ||
132 | i40e_dbg_dump_buf = kzalloc(buflen, GFP_KERNEL); | ||
133 | if (i40e_dbg_dump_buf != NULL) | ||
134 | i40e_dbg_dump_buffer_len = buflen; | ||
135 | } | ||
136 | |||
137 | return i40e_dbg_dump_buffer_len; | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * i40e_dbg_dump_write - trigger a datadump snapshot | ||
142 | * @filp: the opened file | ||
143 | * @buffer: where to find the user's data | ||
144 | * @count: the length of the user's data | ||
145 | * @ppos: file position offset | ||
146 | * | ||
147 | * Any write clears the stats | ||
148 | **/ | ||
149 | static ssize_t i40e_dbg_dump_write(struct file *filp, | ||
150 | const char __user *buffer, | ||
151 | size_t count, loff_t *ppos) | ||
152 | { | ||
153 | struct i40e_pf *pf = filp->private_data; | ||
154 | char dump_request_buf[16]; | ||
155 | bool seid_found = false; | ||
156 | int bytes_not_copied; | ||
157 | long seid = -1; | ||
158 | int buflen = 0; | ||
159 | int i, ret; | ||
160 | int len; | ||
161 | u8 *p; | ||
162 | |||
163 | /* don't allow partial writes */ | ||
164 | if (*ppos != 0) | ||
165 | return 0; | ||
166 | if (count >= sizeof(dump_request_buf)) | ||
167 | return -ENOSPC; | ||
168 | |||
169 | bytes_not_copied = copy_from_user(dump_request_buf, buffer, count); | ||
170 | if (bytes_not_copied < 0) | ||
171 | return bytes_not_copied; | ||
172 | if (bytes_not_copied > 0) | ||
173 | count -= bytes_not_copied; | ||
174 | dump_request_buf[count] = '\0'; | ||
175 | |||
176 | /* decode the SEID given to be dumped */ | ||
177 | ret = kstrtol(dump_request_buf, 0, &seid); | ||
178 | if (ret < 0) { | ||
179 | dev_info(&pf->pdev->dev, "bad seid value '%s'\n", | ||
180 | dump_request_buf); | ||
181 | } else if (seid == 0) { | ||
182 | seid_found = true; | ||
183 | |||
184 | kfree(i40e_dbg_dump_buf); | ||
185 | i40e_dbg_dump_buffer_len = 0; | ||
186 | i40e_dbg_dump_data_len = 0; | ||
187 | i40e_dbg_dump_buf = NULL; | ||
188 | dev_info(&pf->pdev->dev, "debug buffer freed\n"); | ||
189 | |||
190 | } else if (seid == pf->pf_seid || seid == 1) { | ||
191 | seid_found = true; | ||
192 | |||
193 | buflen = sizeof(struct i40e_pf); | ||
194 | buflen += (sizeof(struct i40e_aq_desc) | ||
195 | * (pf->hw.aq.num_arq_entries + pf->hw.aq.num_asq_entries)); | ||
196 | |||
197 | if (i40e_dbg_prep_dump_buf(pf, buflen)) { | ||
198 | p = i40e_dbg_dump_buf; | ||
199 | |||
200 | len = sizeof(struct i40e_pf); | ||
201 | memcpy(p, pf, len); | ||
202 | p += len; | ||
203 | |||
204 | len = (sizeof(struct i40e_aq_desc) | ||
205 | * pf->hw.aq.num_asq_entries); | ||
206 | memcpy(p, pf->hw.aq.asq.desc, len); | ||
207 | p += len; | ||
208 | |||
209 | len = (sizeof(struct i40e_aq_desc) | ||
210 | * pf->hw.aq.num_arq_entries); | ||
211 | memcpy(p, pf->hw.aq.arq.desc, len); | ||
212 | p += len; | ||
213 | |||
214 | i40e_dbg_dump_data_len = buflen; | ||
215 | dev_info(&pf->pdev->dev, | ||
216 | "PF seid %ld dumped %d bytes\n", | ||
217 | seid, (int)i40e_dbg_dump_data_len); | ||
218 | } | ||
219 | } else if (seid >= I40E_BASE_VSI_SEID) { | ||
220 | struct i40e_vsi *vsi = NULL; | ||
221 | struct i40e_mac_filter *f; | ||
222 | int filter_count = 0; | ||
223 | |||
224 | mutex_lock(&pf->switch_mutex); | ||
225 | vsi = i40e_dbg_find_vsi(pf, seid); | ||
226 | if (!vsi) { | ||
227 | mutex_unlock(&pf->switch_mutex); | ||
228 | goto write_exit; | ||
229 | } | ||
230 | |||
231 | buflen = sizeof(struct i40e_vsi); | ||
232 | buflen += sizeof(struct i40e_q_vector) * vsi->num_q_vectors; | ||
233 | buflen += sizeof(struct i40e_ring) * 2 * vsi->num_queue_pairs; | ||
234 | buflen += sizeof(struct i40e_tx_buffer) * vsi->num_queue_pairs; | ||
235 | buflen += sizeof(struct i40e_rx_buffer) * vsi->num_queue_pairs; | ||
236 | list_for_each_entry(f, &vsi->mac_filter_list, list) | ||
237 | filter_count++; | ||
238 | buflen += sizeof(struct i40e_mac_filter) * filter_count; | ||
239 | |||
240 | if (i40e_dbg_prep_dump_buf(pf, buflen)) { | ||
241 | p = i40e_dbg_dump_buf; | ||
242 | seid_found = true; | ||
243 | |||
244 | len = sizeof(struct i40e_vsi); | ||
245 | memcpy(p, vsi, len); | ||
246 | p += len; | ||
247 | |||
248 | len = (sizeof(struct i40e_q_vector) | ||
249 | * vsi->num_q_vectors); | ||
250 | memcpy(p, vsi->q_vectors, len); | ||
251 | p += len; | ||
252 | |||
253 | len = (sizeof(struct i40e_ring) * vsi->num_queue_pairs); | ||
254 | memcpy(p, vsi->tx_rings, len); | ||
255 | p += len; | ||
256 | memcpy(p, vsi->rx_rings, len); | ||
257 | p += len; | ||
258 | |||
259 | for (i = 0; i < vsi->num_queue_pairs; i++) { | ||
260 | len = sizeof(struct i40e_tx_buffer); | ||
261 | memcpy(p, vsi->tx_rings[i].tx_bi, len); | ||
262 | p += len; | ||
263 | } | ||
264 | for (i = 0; i < vsi->num_queue_pairs; i++) { | ||
265 | len = sizeof(struct i40e_rx_buffer); | ||
266 | memcpy(p, vsi->rx_rings[i].rx_bi, len); | ||
267 | p += len; | ||
268 | } | ||
269 | |||
270 | /* macvlan filter list */ | ||
271 | len = sizeof(struct i40e_mac_filter); | ||
272 | list_for_each_entry(f, &vsi->mac_filter_list, list) { | ||
273 | memcpy(p, f, len); | ||
274 | p += len; | ||
275 | } | ||
276 | |||
277 | i40e_dbg_dump_data_len = buflen; | ||
278 | dev_info(&pf->pdev->dev, | ||
279 | "VSI seid %ld dumped %d bytes\n", | ||
280 | seid, (int)i40e_dbg_dump_data_len); | ||
281 | } | ||
282 | mutex_unlock(&pf->switch_mutex); | ||
283 | } else if (seid >= I40E_BASE_VEB_SEID) { | ||
284 | struct i40e_veb *veb = NULL; | ||
285 | |||
286 | mutex_lock(&pf->switch_mutex); | ||
287 | veb = i40e_dbg_find_veb(pf, seid); | ||
288 | if (!veb) { | ||
289 | mutex_unlock(&pf->switch_mutex); | ||
290 | goto write_exit; | ||
291 | } | ||
292 | |||
293 | buflen = sizeof(struct i40e_veb); | ||
294 | if (i40e_dbg_prep_dump_buf(pf, buflen)) { | ||
295 | seid_found = true; | ||
296 | memcpy(i40e_dbg_dump_buf, veb, buflen); | ||
297 | i40e_dbg_dump_data_len = buflen; | ||
298 | dev_info(&pf->pdev->dev, | ||
299 | "VEB seid %ld dumped %d bytes\n", | ||
300 | seid, (int)i40e_dbg_dump_data_len); | ||
301 | } | ||
302 | mutex_unlock(&pf->switch_mutex); | ||
303 | } | ||
304 | |||
305 | write_exit: | ||
306 | if (!seid_found) | ||
307 | dev_info(&pf->pdev->dev, "unknown seid %ld\n", seid); | ||
308 | |||
309 | return count; | ||
310 | } | ||
311 | |||
312 | static const struct file_operations i40e_dbg_dump_fops = { | ||
313 | .owner = THIS_MODULE, | ||
314 | .open = simple_open, | ||
315 | .read = i40e_dbg_dump_read, | ||
316 | .write = i40e_dbg_dump_write, | ||
317 | }; | ||
318 | |||
319 | /************************************************************** | ||
320 | * command | ||
321 | * The command entry in debugfs is for giving the driver commands | ||
322 | * to be executed - these may be for changing the internal switch | ||
323 | * setup, adding or removing filters, or other things. Many of | ||
324 | * these will be useful for some forms of unit testing. | ||
325 | **************************************************************/ | ||
326 | static char i40e_dbg_command_buf[256] = "hello world"; | ||
327 | |||
328 | /** | ||
329 | * i40e_dbg_command_read - read for command datum | ||
330 | * @filp: the opened file | ||
331 | * @buffer: where to write the data for the user to read | ||
332 | * @count: the size of the user's buffer | ||
333 | * @ppos: file position offset | ||
334 | **/ | ||
335 | static ssize_t i40e_dbg_command_read(struct file *filp, char __user *buffer, | ||
336 | size_t count, loff_t *ppos) | ||
337 | { | ||
338 | struct i40e_pf *pf = filp->private_data; | ||
339 | int bytes_not_copied; | ||
340 | int buf_size = 256; | ||
341 | char *buf; | ||
342 | int len; | ||
343 | |||
344 | /* don't allow partial reads */ | ||
345 | if (*ppos != 0) | ||
346 | return 0; | ||
347 | if (count < buf_size) | ||
348 | return -ENOSPC; | ||
349 | |||
350 | buf = kzalloc(buf_size, GFP_KERNEL); | ||
351 | if (!buf) | ||
352 | return -ENOSPC; | ||
353 | |||
354 | len = snprintf(buf, buf_size, "%s: %s\n", | ||
355 | pf->vsi[pf->lan_vsi]->netdev->name, | ||
356 | i40e_dbg_command_buf); | ||
357 | |||
358 | bytes_not_copied = copy_to_user(buffer, buf, len); | ||
359 | kfree(buf); | ||
360 | |||
361 | if (bytes_not_copied < 0) | ||
362 | return bytes_not_copied; | ||
363 | |||
364 | *ppos = len; | ||
365 | return len; | ||
366 | } | ||
367 | |||
368 | /** | ||
369 | * i40e_dbg_dump_vsi_seid - handles dump vsi seid write into pokem datum | ||
370 | * @pf: the i40e_pf created in command write | ||
371 | * @seid: the seid the user put in | ||
372 | **/ | ||
373 | static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid) | ||
374 | { | ||
375 | struct rtnl_link_stats64 *nstat; | ||
376 | struct i40e_mac_filter *f; | ||
377 | struct i40e_vsi *vsi; | ||
378 | int i; | ||
379 | |||
380 | vsi = i40e_dbg_find_vsi(pf, seid); | ||
381 | if (!vsi) { | ||
382 | dev_info(&pf->pdev->dev, | ||
383 | "dump %d: seid not found\n", seid); | ||
384 | return; | ||
385 | } | ||
386 | dev_info(&pf->pdev->dev, "vsi seid %d\n", seid); | ||
387 | if (vsi->netdev) | ||
388 | dev_info(&pf->pdev->dev, | ||
389 | " netdev: name = %s\n", | ||
390 | vsi->netdev->name); | ||
391 | if (vsi->active_vlans) | ||
392 | dev_info(&pf->pdev->dev, | ||
393 | " vlgrp: & = %p\n", vsi->active_vlans); | ||
394 | dev_info(&pf->pdev->dev, | ||
395 | " netdev_registered = %i, current_netdev_flags = 0x%04x, state = %li flags = 0x%08lx\n", | ||
396 | vsi->netdev_registered, | ||
397 | vsi->current_netdev_flags, vsi->state, vsi->flags); | ||
398 | list_for_each_entry(f, &vsi->mac_filter_list, list) { | ||
399 | dev_info(&pf->pdev->dev, | ||
400 | " mac_filter_list: %pM vid=%d, is_netdev=%d is_vf=%d counter=%d\n", | ||
401 | f->macaddr, f->vlan, f->is_netdev, f->is_vf, | ||
402 | f->counter); | ||
403 | } | ||
404 | nstat = i40e_get_vsi_stats_struct(vsi); | ||
405 | dev_info(&pf->pdev->dev, | ||
406 | " net_stats: rx_packets = %lu, rx_bytes = %lu, rx_errors = %lu, rx_dropped = %lu\n", | ||
407 | (long unsigned int)nstat->rx_packets, | ||
408 | (long unsigned int)nstat->rx_bytes, | ||
409 | (long unsigned int)nstat->rx_errors, | ||
410 | (long unsigned int)nstat->rx_dropped); | ||
411 | dev_info(&pf->pdev->dev, | ||
412 | " net_stats: tx_packets = %lu, tx_bytes = %lu, tx_errors = %lu, tx_dropped = %lu\n", | ||
413 | (long unsigned int)nstat->tx_packets, | ||
414 | (long unsigned int)nstat->tx_bytes, | ||
415 | (long unsigned int)nstat->tx_errors, | ||
416 | (long unsigned int)nstat->tx_dropped); | ||
417 | dev_info(&pf->pdev->dev, | ||
418 | " net_stats: multicast = %lu, collisions = %lu\n", | ||
419 | (long unsigned int)nstat->multicast, | ||
420 | (long unsigned int)nstat->collisions); | ||
421 | dev_info(&pf->pdev->dev, | ||
422 | " net_stats: rx_length_errors = %lu, rx_over_errors = %lu, rx_crc_errors = %lu\n", | ||
423 | (long unsigned int)nstat->rx_length_errors, | ||
424 | (long unsigned int)nstat->rx_over_errors, | ||
425 | (long unsigned int)nstat->rx_crc_errors); | ||
426 | dev_info(&pf->pdev->dev, | ||
427 | " net_stats: rx_frame_errors = %lu, rx_fifo_errors = %lu, rx_missed_errors = %lu\n", | ||
428 | (long unsigned int)nstat->rx_frame_errors, | ||
429 | (long unsigned int)nstat->rx_fifo_errors, | ||
430 | (long unsigned int)nstat->rx_missed_errors); | ||
431 | dev_info(&pf->pdev->dev, | ||
432 | " net_stats: tx_aborted_errors = %lu, tx_carrier_errors = %lu, tx_fifo_errors = %lu\n", | ||
433 | (long unsigned int)nstat->tx_aborted_errors, | ||
434 | (long unsigned int)nstat->tx_carrier_errors, | ||
435 | (long unsigned int)nstat->tx_fifo_errors); | ||
436 | dev_info(&pf->pdev->dev, | ||
437 | " net_stats: tx_heartbeat_errors = %lu, tx_window_errors = %lu\n", | ||
438 | (long unsigned int)nstat->tx_heartbeat_errors, | ||
439 | (long unsigned int)nstat->tx_window_errors); | ||
440 | dev_info(&pf->pdev->dev, | ||
441 | " net_stats: rx_compressed = %lu, tx_compressed = %lu\n", | ||
442 | (long unsigned int)nstat->rx_compressed, | ||
443 | (long unsigned int)nstat->tx_compressed); | ||
444 | dev_info(&pf->pdev->dev, | ||
445 | " net_stats_offsets: rx_packets = %lu, rx_bytes = %lu, rx_errors = %lu, rx_dropped = %lu\n", | ||
446 | (long unsigned int)vsi->net_stats_offsets.rx_packets, | ||
447 | (long unsigned int)vsi->net_stats_offsets.rx_bytes, | ||
448 | (long unsigned int)vsi->net_stats_offsets.rx_errors, | ||
449 | (long unsigned int)vsi->net_stats_offsets.rx_dropped); | ||
450 | dev_info(&pf->pdev->dev, | ||
451 | " net_stats_offsets: tx_packets = %lu, tx_bytes = %lu, tx_errors = %lu, tx_dropped = %lu\n", | ||
452 | (long unsigned int)vsi->net_stats_offsets.tx_packets, | ||
453 | (long unsigned int)vsi->net_stats_offsets.tx_bytes, | ||
454 | (long unsigned int)vsi->net_stats_offsets.tx_errors, | ||
455 | (long unsigned int)vsi->net_stats_offsets.tx_dropped); | ||
456 | dev_info(&pf->pdev->dev, | ||
457 | " net_stats_offsets: multicast = %lu, collisions = %lu\n", | ||
458 | (long unsigned int)vsi->net_stats_offsets.multicast, | ||
459 | (long unsigned int)vsi->net_stats_offsets.collisions); | ||
460 | dev_info(&pf->pdev->dev, | ||
461 | " net_stats_offsets: rx_length_errors = %lu, rx_over_errors = %lu, rx_crc_errors = %lu\n", | ||
462 | (long unsigned int)vsi->net_stats_offsets.rx_length_errors, | ||
463 | (long unsigned int)vsi->net_stats_offsets.rx_over_errors, | ||
464 | (long unsigned int)vsi->net_stats_offsets.rx_crc_errors); | ||
465 | dev_info(&pf->pdev->dev, | ||
466 | " net_stats_offsets: rx_frame_errors = %lu, rx_fifo_errors = %lu, rx_missed_errors = %lu\n", | ||
467 | (long unsigned int)vsi->net_stats_offsets.rx_frame_errors, | ||
468 | (long unsigned int)vsi->net_stats_offsets.rx_fifo_errors, | ||
469 | (long unsigned int)vsi->net_stats_offsets.rx_missed_errors); | ||
470 | dev_info(&pf->pdev->dev, | ||
471 | " net_stats_offsets: tx_aborted_errors = %lu, tx_carrier_errors = %lu, tx_fifo_errors = %lu\n", | ||
472 | (long unsigned int)vsi->net_stats_offsets.tx_aborted_errors, | ||
473 | (long unsigned int)vsi->net_stats_offsets.tx_carrier_errors, | ||
474 | (long unsigned int)vsi->net_stats_offsets.tx_fifo_errors); | ||
475 | dev_info(&pf->pdev->dev, | ||
476 | " net_stats_offsets: tx_heartbeat_errors = %lu, tx_window_errors = %lu\n", | ||
477 | (long unsigned int)vsi->net_stats_offsets.tx_heartbeat_errors, | ||
478 | (long unsigned int)vsi->net_stats_offsets.tx_window_errors); | ||
479 | dev_info(&pf->pdev->dev, | ||
480 | " net_stats_offsets: rx_compressed = %lu, tx_compressed = %lu\n", | ||
481 | (long unsigned int)vsi->net_stats_offsets.rx_compressed, | ||
482 | (long unsigned int)vsi->net_stats_offsets.tx_compressed); | ||
483 | dev_info(&pf->pdev->dev, | ||
484 | " tx_restart = %d, tx_busy = %d, rx_buf_failed = %d, rx_page_failed = %d\n", | ||
485 | vsi->tx_restart, vsi->tx_busy, | ||
486 | vsi->rx_buf_failed, vsi->rx_page_failed); | ||
487 | if (vsi->rx_rings) { | ||
488 | for (i = 0; i < vsi->num_queue_pairs; i++) { | ||
489 | dev_info(&pf->pdev->dev, | ||
490 | " rx_rings[%i]: desc = %p\n", | ||
491 | i, vsi->rx_rings[i].desc); | ||
492 | dev_info(&pf->pdev->dev, | ||
493 | " rx_rings[%i]: dev = %p, netdev = %p, rx_bi = %p\n", | ||
494 | i, vsi->rx_rings[i].dev, | ||
495 | vsi->rx_rings[i].netdev, | ||
496 | vsi->rx_rings[i].rx_bi); | ||
497 | dev_info(&pf->pdev->dev, | ||
498 | " rx_rings[%i]: state = %li, queue_index = %d, reg_idx = %d\n", | ||
499 | i, vsi->rx_rings[i].state, | ||
500 | vsi->rx_rings[i].queue_index, | ||
501 | vsi->rx_rings[i].reg_idx); | ||
502 | dev_info(&pf->pdev->dev, | ||
503 | " rx_rings[%i]: rx_hdr_len = %d, rx_buf_len = %d, dtype = %d\n", | ||
504 | i, vsi->rx_rings[i].rx_hdr_len, | ||
505 | vsi->rx_rings[i].rx_buf_len, | ||
506 | vsi->rx_rings[i].dtype); | ||
507 | dev_info(&pf->pdev->dev, | ||
508 | " rx_rings[%i]: hsplit = %d, next_to_use = %d, next_to_clean = %d, ring_active = %i\n", | ||
509 | i, vsi->rx_rings[i].hsplit, | ||
510 | vsi->rx_rings[i].next_to_use, | ||
511 | vsi->rx_rings[i].next_to_clean, | ||
512 | vsi->rx_rings[i].ring_active); | ||
513 | dev_info(&pf->pdev->dev, | ||
514 | " rx_rings[%i]: rx_stats: packets = %lld, bytes = %lld, non_eop_descs = %lld\n", | ||
515 | i, vsi->rx_rings[i].rx_stats.packets, | ||
516 | vsi->rx_rings[i].rx_stats.bytes, | ||
517 | vsi->rx_rings[i].rx_stats.non_eop_descs); | ||
518 | dev_info(&pf->pdev->dev, | ||
519 | " rx_rings[%i]: rx_stats: alloc_rx_page_failed = %lld, alloc_rx_buff_failed = %lld\n", | ||
520 | i, | ||
521 | vsi->rx_rings[i].rx_stats.alloc_rx_page_failed, | ||
522 | vsi->rx_rings[i].rx_stats.alloc_rx_buff_failed); | ||
523 | dev_info(&pf->pdev->dev, | ||
524 | " rx_rings[%i]: size = %i, dma = 0x%08lx\n", | ||
525 | i, vsi->rx_rings[i].size, | ||
526 | (long unsigned int)vsi->rx_rings[i].dma); | ||
527 | dev_info(&pf->pdev->dev, | ||
528 | " rx_rings[%i]: vsi = %p, q_vector = %p\n", | ||
529 | i, vsi->rx_rings[i].vsi, | ||
530 | vsi->rx_rings[i].q_vector); | ||
531 | } | ||
532 | } | ||
533 | if (vsi->tx_rings) { | ||
534 | for (i = 0; i < vsi->num_queue_pairs; i++) { | ||
535 | dev_info(&pf->pdev->dev, | ||
536 | " tx_rings[%i]: desc = %p\n", | ||
537 | i, vsi->tx_rings[i].desc); | ||
538 | dev_info(&pf->pdev->dev, | ||
539 | " tx_rings[%i]: dev = %p, netdev = %p, tx_bi = %p\n", | ||
540 | i, vsi->tx_rings[i].dev, | ||
541 | vsi->tx_rings[i].netdev, | ||
542 | vsi->tx_rings[i].tx_bi); | ||
543 | dev_info(&pf->pdev->dev, | ||
544 | " tx_rings[%i]: state = %li, queue_index = %d, reg_idx = %d\n", | ||
545 | i, vsi->tx_rings[i].state, | ||
546 | vsi->tx_rings[i].queue_index, | ||
547 | vsi->tx_rings[i].reg_idx); | ||
548 | dev_info(&pf->pdev->dev, | ||
549 | " tx_rings[%i]: dtype = %d\n", | ||
550 | i, vsi->tx_rings[i].dtype); | ||
551 | dev_info(&pf->pdev->dev, | ||
552 | " tx_rings[%i]: hsplit = %d, next_to_use = %d, next_to_clean = %d, ring_active = %i\n", | ||
553 | i, vsi->tx_rings[i].hsplit, | ||
554 | vsi->tx_rings[i].next_to_use, | ||
555 | vsi->tx_rings[i].next_to_clean, | ||
556 | vsi->tx_rings[i].ring_active); | ||
557 | dev_info(&pf->pdev->dev, | ||
558 | " tx_rings[%i]: tx_stats: packets = %lld, bytes = %lld, restart_queue = %lld\n", | ||
559 | i, vsi->tx_rings[i].tx_stats.packets, | ||
560 | vsi->tx_rings[i].tx_stats.bytes, | ||
561 | vsi->tx_rings[i].tx_stats.restart_queue); | ||
562 | dev_info(&pf->pdev->dev, | ||
563 | " tx_rings[%i]: tx_stats: tx_busy = %lld, completed = %lld, tx_done_old = %lld\n", | ||
564 | i, | ||
565 | vsi->tx_rings[i].tx_stats.tx_busy, | ||
566 | vsi->tx_rings[i].tx_stats.completed, | ||
567 | vsi->tx_rings[i].tx_stats.tx_done_old); | ||
568 | dev_info(&pf->pdev->dev, | ||
569 | " tx_rings[%i]: size = %i, dma = 0x%08lx\n", | ||
570 | i, vsi->tx_rings[i].size, | ||
571 | (long unsigned int)vsi->tx_rings[i].dma); | ||
572 | dev_info(&pf->pdev->dev, | ||
573 | " tx_rings[%i]: vsi = %p, q_vector = %p\n", | ||
574 | i, vsi->tx_rings[i].vsi, | ||
575 | vsi->tx_rings[i].q_vector); | ||
576 | dev_info(&pf->pdev->dev, | ||
577 | " tx_rings[%i]: DCB tc = %d\n", | ||
578 | i, vsi->tx_rings[i].dcb_tc); | ||
579 | } | ||
580 | } | ||
581 | dev_info(&pf->pdev->dev, | ||
582 | " work_limit = %d, rx_itr_setting = %d (%s), tx_itr_setting = %d (%s)\n", | ||
583 | vsi->work_limit, vsi->rx_itr_setting, | ||
584 | ITR_IS_DYNAMIC(vsi->rx_itr_setting) ? "dynamic" : "fixed", | ||
585 | vsi->tx_itr_setting, | ||
586 | ITR_IS_DYNAMIC(vsi->tx_itr_setting) ? "dynamic" : "fixed"); | ||
587 | dev_info(&pf->pdev->dev, | ||
588 | " max_frame = %d, rx_hdr_len = %d, rx_buf_len = %d dtype = %d\n", | ||
589 | vsi->max_frame, vsi->rx_hdr_len, vsi->rx_buf_len, vsi->dtype); | ||
590 | if (vsi->q_vectors) { | ||
591 | for (i = 0; i < vsi->num_q_vectors; i++) { | ||
592 | dev_info(&pf->pdev->dev, | ||
593 | " q_vectors[%i]: base index = %ld\n", | ||
594 | i, ((long int)*vsi->q_vectors[i].rx.ring- | ||
595 | (long int)*vsi->q_vectors[0].rx.ring)/ | ||
596 | sizeof(struct i40e_ring)); | ||
597 | } | ||
598 | } | ||
599 | dev_info(&pf->pdev->dev, | ||
600 | " num_q_vectors = %i, base_vector = %i\n", | ||
601 | vsi->num_q_vectors, vsi->base_vector); | ||
602 | dev_info(&pf->pdev->dev, | ||
603 | " seid = %d, id = %d, uplink_seid = %d\n", | ||
604 | vsi->seid, vsi->id, vsi->uplink_seid); | ||
605 | dev_info(&pf->pdev->dev, | ||
606 | " base_queue = %d, num_queue_pairs = %d, num_desc = %d\n", | ||
607 | vsi->base_queue, vsi->num_queue_pairs, vsi->num_desc); | ||
608 | dev_info(&pf->pdev->dev, " type = %i\n", vsi->type); | ||
609 | dev_info(&pf->pdev->dev, | ||
610 | " info: valid_sections = 0x%04x, switch_id = 0x%04x\n", | ||
611 | vsi->info.valid_sections, vsi->info.switch_id); | ||
612 | dev_info(&pf->pdev->dev, | ||
613 | " info: sw_reserved[] = 0x%02x 0x%02x\n", | ||
614 | vsi->info.sw_reserved[0], vsi->info.sw_reserved[1]); | ||
615 | dev_info(&pf->pdev->dev, | ||
616 | " info: sec_flags = 0x%02x, sec_reserved = 0x%02x\n", | ||
617 | vsi->info.sec_flags, vsi->info.sec_reserved); | ||
618 | dev_info(&pf->pdev->dev, | ||
619 | " info: pvid = 0x%04x, fcoe_pvid = 0x%04x, port_vlan_flags = 0x%02x\n", | ||
620 | vsi->info.pvid, vsi->info.fcoe_pvid, | ||
621 | vsi->info.port_vlan_flags); | ||
622 | dev_info(&pf->pdev->dev, | ||
623 | " info: pvlan_reserved[] = 0x%02x 0x%02x 0x%02x\n", | ||
624 | vsi->info.pvlan_reserved[0], vsi->info.pvlan_reserved[1], | ||
625 | vsi->info.pvlan_reserved[2]); | ||
626 | dev_info(&pf->pdev->dev, | ||
627 | " info: ingress_table = 0x%08x, egress_table = 0x%08x\n", | ||
628 | vsi->info.ingress_table, vsi->info.egress_table); | ||
629 | dev_info(&pf->pdev->dev, | ||
630 | " info: cas_pv_stag = 0x%04x, cas_pv_flags= 0x%02x, cas_pv_reserved = 0x%02x\n", | ||
631 | vsi->info.cas_pv_tag, vsi->info.cas_pv_flags, | ||
632 | vsi->info.cas_pv_reserved); | ||
633 | dev_info(&pf->pdev->dev, | ||
634 | " info: queue_mapping[0..7 ] = 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", | ||
635 | vsi->info.queue_mapping[0], vsi->info.queue_mapping[1], | ||
636 | vsi->info.queue_mapping[2], vsi->info.queue_mapping[3], | ||
637 | vsi->info.queue_mapping[4], vsi->info.queue_mapping[5], | ||
638 | vsi->info.queue_mapping[6], vsi->info.queue_mapping[7]); | ||
639 | dev_info(&pf->pdev->dev, | ||
640 | " info: queue_mapping[8..15] = 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", | ||
641 | vsi->info.queue_mapping[8], vsi->info.queue_mapping[9], | ||
642 | vsi->info.queue_mapping[10], vsi->info.queue_mapping[11], | ||
643 | vsi->info.queue_mapping[12], vsi->info.queue_mapping[13], | ||
644 | vsi->info.queue_mapping[14], vsi->info.queue_mapping[15]); | ||
645 | dev_info(&pf->pdev->dev, | ||
646 | " info: tc_mapping[] = 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", | ||
647 | vsi->info.tc_mapping[0], vsi->info.tc_mapping[1], | ||
648 | vsi->info.tc_mapping[2], vsi->info.tc_mapping[3], | ||
649 | vsi->info.tc_mapping[4], vsi->info.tc_mapping[5], | ||
650 | vsi->info.tc_mapping[6], vsi->info.tc_mapping[7]); | ||
651 | dev_info(&pf->pdev->dev, | ||
652 | " info: queueing_opt_flags = 0x%02x queueing_opt_reserved[0..2] = 0x%02x 0x%02x 0x%02x\n", | ||
653 | vsi->info.queueing_opt_flags, | ||
654 | vsi->info.queueing_opt_reserved[0], | ||
655 | vsi->info.queueing_opt_reserved[1], | ||
656 | vsi->info.queueing_opt_reserved[2]); | ||
657 | dev_info(&pf->pdev->dev, | ||
658 | " info: up_enable_bits = 0x%02x\n", | ||
659 | vsi->info.up_enable_bits); | ||
660 | dev_info(&pf->pdev->dev, | ||
661 | " info: sched_reserved = 0x%02x, outer_up_table = 0x%04x\n", | ||
662 | vsi->info.sched_reserved, vsi->info.outer_up_table); | ||
663 | dev_info(&pf->pdev->dev, | ||
664 | " info: cmd_reserved[] = 0x%02x 0x%02x 0x%02x 0x0%02x 0x%02x 0x%02x 0x%02x 0x0%02x\n", | ||
665 | vsi->info.cmd_reserved[0], vsi->info.cmd_reserved[1], | ||
666 | vsi->info.cmd_reserved[2], vsi->info.cmd_reserved[3], | ||
667 | vsi->info.cmd_reserved[4], vsi->info.cmd_reserved[5], | ||
668 | vsi->info.cmd_reserved[6], vsi->info.cmd_reserved[7]); | ||
669 | dev_info(&pf->pdev->dev, | ||
670 | " info: qs_handle[] = 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x 0x%04x\n", | ||
671 | vsi->info.qs_handle[0], vsi->info.qs_handle[1], | ||
672 | vsi->info.qs_handle[2], vsi->info.qs_handle[3], | ||
673 | vsi->info.qs_handle[4], vsi->info.qs_handle[5], | ||
674 | vsi->info.qs_handle[6], vsi->info.qs_handle[7]); | ||
675 | dev_info(&pf->pdev->dev, | ||
676 | " info: stat_counter_idx = 0x%04x, sched_id = 0x%04x\n", | ||
677 | vsi->info.stat_counter_idx, vsi->info.sched_id); | ||
678 | dev_info(&pf->pdev->dev, | ||
679 | " info: resp_reserved[] = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
680 | vsi->info.resp_reserved[0], vsi->info.resp_reserved[1], | ||
681 | vsi->info.resp_reserved[2], vsi->info.resp_reserved[3], | ||
682 | vsi->info.resp_reserved[4], vsi->info.resp_reserved[5], | ||
683 | vsi->info.resp_reserved[6], vsi->info.resp_reserved[7], | ||
684 | vsi->info.resp_reserved[8], vsi->info.resp_reserved[9], | ||
685 | vsi->info.resp_reserved[10], vsi->info.resp_reserved[11]); | ||
686 | if (vsi->back) | ||
687 | dev_info(&pf->pdev->dev, " pf = %p\n", vsi->back); | ||
688 | dev_info(&pf->pdev->dev, " idx = %d\n", vsi->idx); | ||
689 | dev_info(&pf->pdev->dev, | ||
690 | " tc_config: numtc = %d, enabled_tc = 0x%x\n", | ||
691 | vsi->tc_config.numtc, vsi->tc_config.enabled_tc); | ||
692 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { | ||
693 | dev_info(&pf->pdev->dev, | ||
694 | " tc_config: tc = %d, qoffset = %d, qcount = %d, netdev_tc = %d\n", | ||
695 | i, vsi->tc_config.tc_info[i].qoffset, | ||
696 | vsi->tc_config.tc_info[i].qcount, | ||
697 | vsi->tc_config.tc_info[i].netdev_tc); | ||
698 | } | ||
699 | dev_info(&pf->pdev->dev, | ||
700 | " bw: bw_limit = %d, bw_max_quanta = %d\n", | ||
701 | vsi->bw_limit, vsi->bw_max_quanta); | ||
702 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { | ||
703 | dev_info(&pf->pdev->dev, | ||
704 | " bw[%d]: ets_share_credits = %d, ets_limit_credits = %d, max_quanta = %d\n", | ||
705 | i, vsi->bw_ets_share_credits[i], | ||
706 | vsi->bw_ets_limit_credits[i], | ||
707 | vsi->bw_ets_max_quanta[i]); | ||
708 | } | ||
709 | } | ||
710 | |||
711 | /** | ||
712 | * i40e_dbg_dump_aq_desc - handles dump aq_desc write into command datum | ||
713 | * @pf: the i40e_pf created in command write | ||
714 | **/ | ||
715 | static void i40e_dbg_dump_aq_desc(struct i40e_pf *pf) | ||
716 | { | ||
717 | struct i40e_adminq_ring *ring; | ||
718 | struct i40e_hw *hw = &pf->hw; | ||
719 | int i; | ||
720 | |||
721 | /* first the send (command) ring, then the receive (event) ring */ | ||
722 | dev_info(&pf->pdev->dev, "AdminQ Tx Ring\n"); | ||
723 | ring = &(hw->aq.asq); | ||
724 | for (i = 0; i < ring->count; i++) { | ||
725 | struct i40e_aq_desc *d = I40E_ADMINQ_DESC(*ring, i); | ||
726 | dev_info(&pf->pdev->dev, | ||
727 | " at[%02d] flags=0x%04x op=0x%04x dlen=0x%04x ret=0x%04x cookie_h=0x%08x cookie_l=0x%08x\n", | ||
728 | i, d->flags, d->opcode, d->datalen, d->retval, | ||
729 | d->cookie_high, d->cookie_low); | ||
730 | dev_info(&pf->pdev->dev, | ||
731 | " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
732 | d->params.raw[0], d->params.raw[1], d->params.raw[2], | ||
733 | d->params.raw[3], d->params.raw[4], d->params.raw[5], | ||
734 | d->params.raw[6], d->params.raw[7], d->params.raw[8], | ||
735 | d->params.raw[9], d->params.raw[10], d->params.raw[11], | ||
736 | d->params.raw[12], d->params.raw[13], | ||
737 | d->params.raw[14], d->params.raw[15]); | ||
738 | } | ||
739 | |||
740 | dev_info(&pf->pdev->dev, "AdminQ Rx Ring\n"); | ||
741 | ring = &(hw->aq.arq); | ||
742 | for (i = 0; i < ring->count; i++) { | ||
743 | struct i40e_aq_desc *d = I40E_ADMINQ_DESC(*ring, i); | ||
744 | dev_info(&pf->pdev->dev, | ||
745 | " ar[%02d] flags=0x%04x op=0x%04x dlen=0x%04x ret=0x%04x cookie_h=0x%08x cookie_l=0x%08x\n", | ||
746 | i, d->flags, d->opcode, d->datalen, d->retval, | ||
747 | d->cookie_high, d->cookie_low); | ||
748 | dev_info(&pf->pdev->dev, | ||
749 | " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
750 | d->params.raw[0], d->params.raw[1], d->params.raw[2], | ||
751 | d->params.raw[3], d->params.raw[4], d->params.raw[5], | ||
752 | d->params.raw[6], d->params.raw[7], d->params.raw[8], | ||
753 | d->params.raw[9], d->params.raw[10], d->params.raw[11], | ||
754 | d->params.raw[12], d->params.raw[13], | ||
755 | d->params.raw[14], d->params.raw[15]); | ||
756 | } | ||
757 | } | ||
758 | |||
759 | /** | ||
760 | * i40e_dbg_dump_desc - handles dump desc write into command datum | ||
761 | * @cnt: number of arguments that the user supplied | ||
762 | * @vsi_seid: vsi id entered by user | ||
763 | * @ring_id: ring id entered by user | ||
764 | * @desc_n: descriptor number entered by user | ||
765 | * @pf: the i40e_pf created in command write | ||
766 | * @is_rx_ring: true if rx, false if tx | ||
767 | **/ | ||
768 | static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n, | ||
769 | struct i40e_pf *pf, bool is_rx_ring) | ||
770 | { | ||
771 | union i40e_rx_desc *ds; | ||
772 | struct i40e_ring ring; | ||
773 | struct i40e_vsi *vsi; | ||
774 | int i; | ||
775 | |||
776 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
777 | if (!vsi) { | ||
778 | dev_info(&pf->pdev->dev, | ||
779 | "vsi %d not found\n", vsi_seid); | ||
780 | if (is_rx_ring) | ||
781 | dev_info(&pf->pdev->dev, "dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
782 | else | ||
783 | dev_info(&pf->pdev->dev, "dump desc tx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
784 | return; | ||
785 | } | ||
786 | if (ring_id >= vsi->num_queue_pairs || ring_id < 0) { | ||
787 | dev_info(&pf->pdev->dev, "ring %d not found\n", ring_id); | ||
788 | if (is_rx_ring) | ||
789 | dev_info(&pf->pdev->dev, "dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
790 | else | ||
791 | dev_info(&pf->pdev->dev, "dump desc tx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
792 | return; | ||
793 | } | ||
794 | if (is_rx_ring) | ||
795 | ring = vsi->rx_rings[ring_id]; | ||
796 | else | ||
797 | ring = vsi->tx_rings[ring_id]; | ||
798 | if (cnt == 2) { | ||
799 | dev_info(&pf->pdev->dev, "vsi = %02i %s ring = %02i\n", | ||
800 | vsi_seid, is_rx_ring ? "rx" : "tx", ring_id); | ||
801 | for (i = 0; i < ring.count; i++) { | ||
802 | if (is_rx_ring) | ||
803 | ds = I40E_RX_DESC(&ring, i); | ||
804 | else | ||
805 | ds = (union i40e_rx_desc *) | ||
806 | I40E_TX_DESC(&ring, i); | ||
807 | if ((sizeof(union i40e_rx_desc) == | ||
808 | sizeof(union i40e_16byte_rx_desc)) || (!is_rx_ring)) | ||
809 | dev_info(&pf->pdev->dev, | ||
810 | " d[%03i] = 0x%016llx 0x%016llx\n", i, | ||
811 | ds->read.pkt_addr, ds->read.hdr_addr); | ||
812 | else | ||
813 | dev_info(&pf->pdev->dev, | ||
814 | " d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n", | ||
815 | i, ds->read.pkt_addr, | ||
816 | ds->read.hdr_addr, | ||
817 | ds->read.rsvd1, ds->read.rsvd2); | ||
818 | } | ||
819 | } else if (cnt == 3) { | ||
820 | if (desc_n >= ring.count || desc_n < 0) { | ||
821 | dev_info(&pf->pdev->dev, | ||
822 | "descriptor %d not found\n", desc_n); | ||
823 | return; | ||
824 | } | ||
825 | if (is_rx_ring) | ||
826 | ds = I40E_RX_DESC(&ring, desc_n); | ||
827 | else | ||
828 | ds = (union i40e_rx_desc *)I40E_TX_DESC(&ring, desc_n); | ||
829 | if ((sizeof(union i40e_rx_desc) == | ||
830 | sizeof(union i40e_16byte_rx_desc)) || (!is_rx_ring)) | ||
831 | dev_info(&pf->pdev->dev, | ||
832 | "vsi = %02i %s ring = %02i d[%03i] = 0x%016llx 0x%016llx\n", | ||
833 | vsi_seid, is_rx_ring ? "rx" : "tx", ring_id, | ||
834 | desc_n, ds->read.pkt_addr, ds->read.hdr_addr); | ||
835 | else | ||
836 | dev_info(&pf->pdev->dev, | ||
837 | "vsi = %02i rx ring = %02i d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n", | ||
838 | vsi_seid, ring_id, | ||
839 | desc_n, ds->read.pkt_addr, ds->read.hdr_addr, | ||
840 | ds->read.rsvd1, ds->read.rsvd2); | ||
841 | } else { | ||
842 | if (is_rx_ring) | ||
843 | dev_info(&pf->pdev->dev, "dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
844 | else | ||
845 | dev_info(&pf->pdev->dev, "dump desc tx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
846 | } | ||
847 | } | ||
848 | |||
849 | /** | ||
850 | * i40e_dbg_dump_vsi_no_seid - handles dump vsi write into command datum | ||
851 | * @pf: the i40e_pf created in command write | ||
852 | **/ | ||
853 | static void i40e_dbg_dump_vsi_no_seid(struct i40e_pf *pf) | ||
854 | { | ||
855 | int i; | ||
856 | |||
857 | for (i = 0; i < pf->hw.func_caps.num_vsis; i++) | ||
858 | if (pf->vsi[i]) | ||
859 | dev_info(&pf->pdev->dev, "dump vsi[%d]: %d\n", | ||
860 | i, pf->vsi[i]->seid); | ||
861 | } | ||
862 | |||
863 | /** | ||
864 | * i40e_dbg_dump_stats - handles dump stats write into command datum | ||
865 | * @pf: the i40e_pf created in command write | ||
866 | * @estats: the eth stats structure to be dumped | ||
867 | **/ | ||
868 | static void i40e_dbg_dump_eth_stats(struct i40e_pf *pf, | ||
869 | struct i40e_eth_stats *estats) | ||
870 | { | ||
871 | dev_info(&pf->pdev->dev, " ethstats:\n"); | ||
872 | dev_info(&pf->pdev->dev, | ||
873 | " rx_bytes = \t%lld \trx_unicast = \t\t%lld \trx_multicast = \t%lld\n", | ||
874 | estats->rx_bytes, estats->rx_unicast, estats->rx_multicast); | ||
875 | dev_info(&pf->pdev->dev, | ||
876 | " rx_broadcast = \t%lld \trx_discards = \t\t%lld \trx_errors = \t%lld\n", | ||
877 | estats->rx_broadcast, estats->rx_discards, estats->rx_errors); | ||
878 | dev_info(&pf->pdev->dev, | ||
879 | " rx_missed = \t%lld \trx_unknown_protocol = \t%lld \ttx_bytes = \t%lld\n", | ||
880 | estats->rx_missed, estats->rx_unknown_protocol, | ||
881 | estats->tx_bytes); | ||
882 | dev_info(&pf->pdev->dev, | ||
883 | " tx_unicast = \t%lld \ttx_multicast = \t\t%lld \ttx_broadcast = \t%lld\n", | ||
884 | estats->tx_unicast, estats->tx_multicast, estats->tx_broadcast); | ||
885 | dev_info(&pf->pdev->dev, | ||
886 | " tx_discards = \t%lld \ttx_errors = \t\t%lld\n", | ||
887 | estats->tx_discards, estats->tx_errors); | ||
888 | } | ||
889 | |||
890 | /** | ||
891 | * i40e_dbg_dump_stats - handles dump stats write into command datum | ||
892 | * @pf: the i40e_pf created in command write | ||
893 | * @stats: the stats structure to be dumped | ||
894 | **/ | ||
895 | static void i40e_dbg_dump_stats(struct i40e_pf *pf, | ||
896 | struct i40e_hw_port_stats *stats) | ||
897 | { | ||
898 | int i; | ||
899 | |||
900 | dev_info(&pf->pdev->dev, " stats:\n"); | ||
901 | dev_info(&pf->pdev->dev, | ||
902 | " crc_errors = \t\t%lld \tillegal_bytes = \t%lld \terror_bytes = \t\t%lld\n", | ||
903 | stats->crc_errors, stats->illegal_bytes, stats->error_bytes); | ||
904 | dev_info(&pf->pdev->dev, | ||
905 | " mac_local_faults = \t%lld \tmac_remote_faults = \t%lld \trx_length_errors = \t%lld\n", | ||
906 | stats->mac_local_faults, stats->mac_remote_faults, | ||
907 | stats->rx_length_errors); | ||
908 | dev_info(&pf->pdev->dev, | ||
909 | " link_xon_rx = \t\t%lld \tlink_xoff_rx = \t\t%lld \tlink_xon_tx = \t\t%lld\n", | ||
910 | stats->link_xon_rx, stats->link_xoff_rx, stats->link_xon_tx); | ||
911 | dev_info(&pf->pdev->dev, | ||
912 | " link_xoff_tx = \t\t%lld \trx_size_64 = \t\t%lld \trx_size_127 = \t\t%lld\n", | ||
913 | stats->link_xoff_tx, stats->rx_size_64, stats->rx_size_127); | ||
914 | dev_info(&pf->pdev->dev, | ||
915 | " rx_size_255 = \t\t%lld \trx_size_511 = \t\t%lld \trx_size_1023 = \t\t%lld\n", | ||
916 | stats->rx_size_255, stats->rx_size_511, stats->rx_size_1023); | ||
917 | dev_info(&pf->pdev->dev, | ||
918 | " rx_size_big = \t\t%lld \trx_undersize = \t\t%lld \trx_jabber = \t\t%lld\n", | ||
919 | stats->rx_size_big, stats->rx_undersize, stats->rx_jabber); | ||
920 | dev_info(&pf->pdev->dev, | ||
921 | " rx_fragments = \t\t%lld \trx_oversize = \t\t%lld \ttx_size_64 = \t\t%lld\n", | ||
922 | stats->rx_fragments, stats->rx_oversize, stats->tx_size_64); | ||
923 | dev_info(&pf->pdev->dev, | ||
924 | " tx_size_127 = \t\t%lld \ttx_size_255 = \t\t%lld \ttx_size_511 = \t\t%lld\n", | ||
925 | stats->tx_size_127, stats->tx_size_255, stats->tx_size_511); | ||
926 | dev_info(&pf->pdev->dev, | ||
927 | " tx_size_1023 = \t\t%lld \ttx_size_big = \t\t%lld \tmac_short_packet_dropped = \t%lld\n", | ||
928 | stats->tx_size_1023, stats->tx_size_big, | ||
929 | stats->mac_short_packet_dropped); | ||
930 | for (i = 0; i < 8; i += 4) { | ||
931 | dev_info(&pf->pdev->dev, | ||
932 | " priority_xon_rx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", | ||
933 | i, stats->priority_xon_rx[i], | ||
934 | i+1, stats->priority_xon_rx[i+1], | ||
935 | i+2, stats->priority_xon_rx[i+2], | ||
936 | i+3, stats->priority_xon_rx[i+3]); | ||
937 | } | ||
938 | for (i = 0; i < 8; i += 4) { | ||
939 | dev_info(&pf->pdev->dev, | ||
940 | " priority_xoff_rx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", | ||
941 | i, stats->priority_xoff_rx[i], | ||
942 | i+1, stats->priority_xoff_rx[i+1], | ||
943 | i+2, stats->priority_xoff_rx[i+2], | ||
944 | i+3, stats->priority_xoff_rx[i+3]); | ||
945 | } | ||
946 | for (i = 0; i < 8; i += 4) { | ||
947 | dev_info(&pf->pdev->dev, | ||
948 | " priority_xon_tx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", | ||
949 | i, stats->priority_xon_tx[i], | ||
950 | i+1, stats->priority_xon_tx[i+1], | ||
951 | i+2, stats->priority_xon_tx[i+2], | ||
952 | i+3, stats->priority_xon_rx[i+3]); | ||
953 | } | ||
954 | for (i = 0; i < 8; i += 4) { | ||
955 | dev_info(&pf->pdev->dev, | ||
956 | " priority_xoff_tx[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", | ||
957 | i, stats->priority_xoff_tx[i], | ||
958 | i+1, stats->priority_xoff_tx[i+1], | ||
959 | i+2, stats->priority_xoff_tx[i+2], | ||
960 | i+3, stats->priority_xoff_tx[i+3]); | ||
961 | } | ||
962 | for (i = 0; i < 8; i += 4) { | ||
963 | dev_info(&pf->pdev->dev, | ||
964 | " priority_xon_2_xoff[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld \t[%d] = \t%lld\n", | ||
965 | i, stats->priority_xon_2_xoff[i], | ||
966 | i+1, stats->priority_xon_2_xoff[i+1], | ||
967 | i+2, stats->priority_xon_2_xoff[i+2], | ||
968 | i+3, stats->priority_xon_2_xoff[i+3]); | ||
969 | } | ||
970 | |||
971 | i40e_dbg_dump_eth_stats(pf, &stats->eth); | ||
972 | } | ||
973 | |||
974 | /** | ||
975 | * i40e_dbg_dump_veb_seid - handles dump stats of a single given veb | ||
976 | * @pf: the i40e_pf created in command write | ||
977 | * @seid: the seid the user put in | ||
978 | **/ | ||
979 | static void i40e_dbg_dump_veb_seid(struct i40e_pf *pf, int seid) | ||
980 | { | ||
981 | struct i40e_veb *veb; | ||
982 | |||
983 | if ((seid < I40E_BASE_VEB_SEID) || | ||
984 | (seid >= (I40E_MAX_VEB + I40E_BASE_VEB_SEID))) { | ||
985 | dev_info(&pf->pdev->dev, "%d: bad seid\n", seid); | ||
986 | return; | ||
987 | } | ||
988 | |||
989 | veb = i40e_dbg_find_veb(pf, seid); | ||
990 | if (!veb) { | ||
991 | dev_info(&pf->pdev->dev, | ||
992 | "%d: can't find veb\n", seid); | ||
993 | return; | ||
994 | } | ||
995 | dev_info(&pf->pdev->dev, | ||
996 | "veb idx=%d,%d stats_ic=%d seid=%d uplink=%d\n", | ||
997 | veb->idx, veb->veb_idx, veb->stats_idx, veb->seid, | ||
998 | veb->uplink_seid); | ||
999 | i40e_dbg_dump_eth_stats(pf, &veb->stats); | ||
1000 | } | ||
1001 | |||
1002 | /** | ||
1003 | * i40e_dbg_dump_veb_all - dumps all known veb's stats | ||
1004 | * @pf: the i40e_pf created in command write | ||
1005 | **/ | ||
1006 | static void i40e_dbg_dump_veb_all(struct i40e_pf *pf) | ||
1007 | { | ||
1008 | struct i40e_veb *veb; | ||
1009 | int i; | ||
1010 | |||
1011 | for (i = 0; i < I40E_MAX_VEB; i++) { | ||
1012 | veb = pf->veb[i]; | ||
1013 | if (veb) | ||
1014 | i40e_dbg_dump_veb_seid(pf, veb->seid); | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | #define I40E_MAX_DEBUG_OUT_BUFFER (4096*4) | ||
1019 | /** | ||
1020 | * i40e_dbg_command_write - write into command datum | ||
1021 | * @filp: the opened file | ||
1022 | * @buffer: where to find the user's data | ||
1023 | * @count: the length of the user's data | ||
1024 | * @ppos: file position offset | ||
1025 | **/ | ||
1026 | static ssize_t i40e_dbg_command_write(struct file *filp, | ||
1027 | const char __user *buffer, | ||
1028 | size_t count, loff_t *ppos) | ||
1029 | { | ||
1030 | struct i40e_pf *pf = filp->private_data; | ||
1031 | int bytes_not_copied; | ||
1032 | struct i40e_vsi *vsi; | ||
1033 | u8 *print_buf_start; | ||
1034 | u8 *print_buf; | ||
1035 | char *cmd_buf; | ||
1036 | int vsi_seid; | ||
1037 | int veb_seid; | ||
1038 | int cnt; | ||
1039 | |||
1040 | /* don't allow partial writes */ | ||
1041 | if (*ppos != 0) | ||
1042 | return 0; | ||
1043 | |||
1044 | cmd_buf = kzalloc(count + 1, GFP_KERNEL); | ||
1045 | if (!cmd_buf) | ||
1046 | return count; | ||
1047 | bytes_not_copied = copy_from_user(cmd_buf, buffer, count); | ||
1048 | if (bytes_not_copied < 0) | ||
1049 | return bytes_not_copied; | ||
1050 | if (bytes_not_copied > 0) | ||
1051 | count -= bytes_not_copied; | ||
1052 | cmd_buf[count] = '\0'; | ||
1053 | |||
1054 | print_buf_start = kzalloc(I40E_MAX_DEBUG_OUT_BUFFER, GFP_KERNEL); | ||
1055 | if (!print_buf_start) | ||
1056 | goto command_write_done; | ||
1057 | print_buf = print_buf_start; | ||
1058 | |||
1059 | if (strncmp(cmd_buf, "add vsi", 7) == 0) { | ||
1060 | vsi_seid = -1; | ||
1061 | cnt = sscanf(&cmd_buf[7], "%i", &vsi_seid); | ||
1062 | if (cnt == 0) { | ||
1063 | /* default to PF VSI */ | ||
1064 | vsi_seid = pf->vsi[pf->lan_vsi]->seid; | ||
1065 | } else if (vsi_seid < 0) { | ||
1066 | dev_info(&pf->pdev->dev, "add VSI %d: bad vsi seid\n", | ||
1067 | vsi_seid); | ||
1068 | goto command_write_done; | ||
1069 | } | ||
1070 | |||
1071 | vsi = i40e_vsi_setup(pf, I40E_VSI_VMDQ2, vsi_seid, 0); | ||
1072 | if (vsi) | ||
1073 | dev_info(&pf->pdev->dev, "added VSI %d to relay %d\n", | ||
1074 | vsi->seid, vsi->uplink_seid); | ||
1075 | else | ||
1076 | dev_info(&pf->pdev->dev, "'%s' failed\n", cmd_buf); | ||
1077 | |||
1078 | } else if (strncmp(cmd_buf, "del vsi", 7) == 0) { | ||
1079 | sscanf(&cmd_buf[7], "%i", &vsi_seid); | ||
1080 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1081 | if (!vsi) { | ||
1082 | dev_info(&pf->pdev->dev, "del VSI %d: seid not found\n", | ||
1083 | vsi_seid); | ||
1084 | goto command_write_done; | ||
1085 | } | ||
1086 | |||
1087 | dev_info(&pf->pdev->dev, "deleting VSI %d\n", vsi_seid); | ||
1088 | i40e_vsi_release(vsi); | ||
1089 | |||
1090 | } else if (strncmp(cmd_buf, "add relay", 9) == 0) { | ||
1091 | struct i40e_veb *veb; | ||
1092 | int uplink_seid, i; | ||
1093 | |||
1094 | cnt = sscanf(&cmd_buf[9], "%i %i", &uplink_seid, &vsi_seid); | ||
1095 | if (cnt != 2) { | ||
1096 | dev_info(&pf->pdev->dev, | ||
1097 | "add relay: bad command string, cnt=%d\n", | ||
1098 | cnt); | ||
1099 | goto command_write_done; | ||
1100 | } else if (uplink_seid < 0) { | ||
1101 | dev_info(&pf->pdev->dev, | ||
1102 | "add relay %d: bad uplink seid\n", | ||
1103 | uplink_seid); | ||
1104 | goto command_write_done; | ||
1105 | } | ||
1106 | |||
1107 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1108 | if (!vsi) { | ||
1109 | dev_info(&pf->pdev->dev, | ||
1110 | "add relay: vsi VSI %d not found\n", vsi_seid); | ||
1111 | goto command_write_done; | ||
1112 | } | ||
1113 | |||
1114 | for (i = 0; i < I40E_MAX_VEB; i++) | ||
1115 | if (pf->veb[i] && pf->veb[i]->seid == uplink_seid) | ||
1116 | break; | ||
1117 | if (i >= I40E_MAX_VEB && uplink_seid != 0 && | ||
1118 | uplink_seid != pf->mac_seid) { | ||
1119 | dev_info(&pf->pdev->dev, | ||
1120 | "add relay: relay uplink %d not found\n", | ||
1121 | uplink_seid); | ||
1122 | goto command_write_done; | ||
1123 | } | ||
1124 | |||
1125 | veb = i40e_veb_setup(pf, 0, uplink_seid, vsi_seid, | ||
1126 | vsi->tc_config.enabled_tc); | ||
1127 | if (veb) | ||
1128 | dev_info(&pf->pdev->dev, "added relay %d\n", veb->seid); | ||
1129 | else | ||
1130 | dev_info(&pf->pdev->dev, "add relay failed\n"); | ||
1131 | |||
1132 | } else if (strncmp(cmd_buf, "del relay", 9) == 0) { | ||
1133 | int i; | ||
1134 | cnt = sscanf(&cmd_buf[9], "%i", &veb_seid); | ||
1135 | if (cnt != 1) { | ||
1136 | dev_info(&pf->pdev->dev, | ||
1137 | "del relay: bad command string, cnt=%d\n", | ||
1138 | cnt); | ||
1139 | goto command_write_done; | ||
1140 | } else if (veb_seid < 0) { | ||
1141 | dev_info(&pf->pdev->dev, | ||
1142 | "del relay %d: bad relay seid\n", veb_seid); | ||
1143 | goto command_write_done; | ||
1144 | } | ||
1145 | |||
1146 | /* find the veb */ | ||
1147 | for (i = 0; i < I40E_MAX_VEB; i++) | ||
1148 | if (pf->veb[i] && pf->veb[i]->seid == veb_seid) | ||
1149 | break; | ||
1150 | if (i >= I40E_MAX_VEB) { | ||
1151 | dev_info(&pf->pdev->dev, | ||
1152 | "del relay: relay %d not found\n", veb_seid); | ||
1153 | goto command_write_done; | ||
1154 | } | ||
1155 | |||
1156 | dev_info(&pf->pdev->dev, "deleting relay %d\n", veb_seid); | ||
1157 | i40e_veb_release(pf->veb[i]); | ||
1158 | |||
1159 | } else if (strncmp(cmd_buf, "add macaddr", 11) == 0) { | ||
1160 | u8 ma[6]; | ||
1161 | int vlan = 0; | ||
1162 | struct i40e_mac_filter *f; | ||
1163 | int ret; | ||
1164 | |||
1165 | cnt = sscanf(&cmd_buf[11], | ||
1166 | "%i %hhx:%hhx:%hhx:%hhx:%hhx:%hhx %i", | ||
1167 | &vsi_seid, | ||
1168 | &ma[0], &ma[1], &ma[2], &ma[3], &ma[4], &ma[5], | ||
1169 | &vlan); | ||
1170 | if (cnt == 7) { | ||
1171 | vlan = 0; | ||
1172 | } else if (cnt != 8) { | ||
1173 | dev_info(&pf->pdev->dev, | ||
1174 | "add macaddr: bad command string, cnt=%d\n", | ||
1175 | cnt); | ||
1176 | goto command_write_done; | ||
1177 | } | ||
1178 | |||
1179 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1180 | if (!vsi) { | ||
1181 | dev_info(&pf->pdev->dev, | ||
1182 | "add macaddr: VSI %d not found\n", vsi_seid); | ||
1183 | goto command_write_done; | ||
1184 | } | ||
1185 | |||
1186 | f = i40e_add_filter(vsi, ma, vlan, false, false); | ||
1187 | ret = i40e_sync_vsi_filters(vsi); | ||
1188 | if (f && !ret) | ||
1189 | dev_info(&pf->pdev->dev, | ||
1190 | "add macaddr: %pM vlan=%d added to VSI %d\n", | ||
1191 | ma, vlan, vsi_seid); | ||
1192 | else | ||
1193 | dev_info(&pf->pdev->dev, | ||
1194 | "add macaddr: %pM vlan=%d to VSI %d failed, f=%p ret=%d\n", | ||
1195 | ma, vlan, vsi_seid, f, ret); | ||
1196 | |||
1197 | } else if (strncmp(cmd_buf, "del macaddr", 11) == 0) { | ||
1198 | u8 ma[6]; | ||
1199 | int vlan = 0; | ||
1200 | int ret; | ||
1201 | |||
1202 | cnt = sscanf(&cmd_buf[11], | ||
1203 | "%i %hhx:%hhx:%hhx:%hhx:%hhx:%hhx %i", | ||
1204 | &vsi_seid, | ||
1205 | &ma[0], &ma[1], &ma[2], &ma[3], &ma[4], &ma[5], | ||
1206 | &vlan); | ||
1207 | if (cnt == 7) { | ||
1208 | vlan = 0; | ||
1209 | } else if (cnt != 8) { | ||
1210 | dev_info(&pf->pdev->dev, | ||
1211 | "del macaddr: bad command string, cnt=%d\n", | ||
1212 | cnt); | ||
1213 | goto command_write_done; | ||
1214 | } | ||
1215 | |||
1216 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1217 | if (!vsi) { | ||
1218 | dev_info(&pf->pdev->dev, | ||
1219 | "del macaddr: VSI %d not found\n", vsi_seid); | ||
1220 | goto command_write_done; | ||
1221 | } | ||
1222 | |||
1223 | i40e_del_filter(vsi, ma, vlan, false, false); | ||
1224 | ret = i40e_sync_vsi_filters(vsi); | ||
1225 | if (!ret) | ||
1226 | dev_info(&pf->pdev->dev, | ||
1227 | "del macaddr: %pM vlan=%d removed from VSI %d\n", | ||
1228 | ma, vlan, vsi_seid); | ||
1229 | else | ||
1230 | dev_info(&pf->pdev->dev, | ||
1231 | "del macaddr: %pM vlan=%d from VSI %d failed, ret=%d\n", | ||
1232 | ma, vlan, vsi_seid, ret); | ||
1233 | |||
1234 | } else if (strncmp(cmd_buf, "add pvid", 8) == 0) { | ||
1235 | int v; | ||
1236 | u16 vid; | ||
1237 | i40e_status ret; | ||
1238 | |||
1239 | cnt = sscanf(&cmd_buf[8], "%i %u", &vsi_seid, &v); | ||
1240 | if (cnt != 2) { | ||
1241 | dev_info(&pf->pdev->dev, | ||
1242 | "add pvid: bad command string, cnt=%d\n", cnt); | ||
1243 | goto command_write_done; | ||
1244 | } | ||
1245 | |||
1246 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1247 | if (!vsi) { | ||
1248 | dev_info(&pf->pdev->dev, "add pvid: VSI %d not found\n", | ||
1249 | vsi_seid); | ||
1250 | goto command_write_done; | ||
1251 | } | ||
1252 | |||
1253 | vid = (unsigned)v; | ||
1254 | ret = i40e_vsi_add_pvid(vsi, vid); | ||
1255 | if (!ret) | ||
1256 | dev_info(&pf->pdev->dev, | ||
1257 | "add pvid: %d added to VSI %d\n", | ||
1258 | vid, vsi_seid); | ||
1259 | else | ||
1260 | dev_info(&pf->pdev->dev, | ||
1261 | "add pvid: %d to VSI %d failed, ret=%d\n", | ||
1262 | vid, vsi_seid, ret); | ||
1263 | |||
1264 | } else if (strncmp(cmd_buf, "del pvid", 8) == 0) { | ||
1265 | |||
1266 | cnt = sscanf(&cmd_buf[8], "%i", &vsi_seid); | ||
1267 | if (cnt != 1) { | ||
1268 | dev_info(&pf->pdev->dev, | ||
1269 | "del pvid: bad command string, cnt=%d\n", | ||
1270 | cnt); | ||
1271 | goto command_write_done; | ||
1272 | } | ||
1273 | |||
1274 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1275 | if (!vsi) { | ||
1276 | dev_info(&pf->pdev->dev, | ||
1277 | "del pvid: VSI %d not found\n", vsi_seid); | ||
1278 | goto command_write_done; | ||
1279 | } | ||
1280 | |||
1281 | i40e_vsi_remove_pvid(vsi); | ||
1282 | dev_info(&pf->pdev->dev, | ||
1283 | "del pvid: removed from VSI %d\n", vsi_seid); | ||
1284 | |||
1285 | } else if (strncmp(cmd_buf, "dump", 4) == 0) { | ||
1286 | if (strncmp(&cmd_buf[5], "switch", 6) == 0) { | ||
1287 | i40e_fetch_switch_configuration(pf, true); | ||
1288 | } else if (strncmp(&cmd_buf[5], "vsi", 3) == 0) { | ||
1289 | cnt = sscanf(&cmd_buf[8], "%i", &vsi_seid); | ||
1290 | if (cnt > 0) | ||
1291 | i40e_dbg_dump_vsi_seid(pf, vsi_seid); | ||
1292 | else | ||
1293 | i40e_dbg_dump_vsi_no_seid(pf); | ||
1294 | } else if (strncmp(&cmd_buf[5], "veb", 3) == 0) { | ||
1295 | cnt = sscanf(&cmd_buf[8], "%i", &vsi_seid); | ||
1296 | if (cnt > 0) | ||
1297 | i40e_dbg_dump_veb_seid(pf, vsi_seid); | ||
1298 | else | ||
1299 | i40e_dbg_dump_veb_all(pf); | ||
1300 | } else if (strncmp(&cmd_buf[5], "desc", 4) == 0) { | ||
1301 | int ring_id, desc_n; | ||
1302 | if (strncmp(&cmd_buf[10], "rx", 2) == 0) { | ||
1303 | cnt = sscanf(&cmd_buf[12], "%i %i %i", | ||
1304 | &vsi_seid, &ring_id, &desc_n); | ||
1305 | i40e_dbg_dump_desc(cnt, vsi_seid, ring_id, | ||
1306 | desc_n, pf, true); | ||
1307 | } else if (strncmp(&cmd_buf[10], "tx", 2) | ||
1308 | == 0) { | ||
1309 | cnt = sscanf(&cmd_buf[12], "%i %i %i", | ||
1310 | &vsi_seid, &ring_id, &desc_n); | ||
1311 | i40e_dbg_dump_desc(cnt, vsi_seid, ring_id, | ||
1312 | desc_n, pf, false); | ||
1313 | } else if (strncmp(&cmd_buf[10], "aq", 2) == 0) { | ||
1314 | i40e_dbg_dump_aq_desc(pf); | ||
1315 | } else { | ||
1316 | dev_info(&pf->pdev->dev, | ||
1317 | "dump desc tx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
1318 | dev_info(&pf->pdev->dev, | ||
1319 | "dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
1320 | dev_info(&pf->pdev->dev, "dump desc aq\n"); | ||
1321 | } | ||
1322 | } else if (strncmp(&cmd_buf[5], "stats", 5) == 0) { | ||
1323 | dev_info(&pf->pdev->dev, "pf stats:\n"); | ||
1324 | i40e_dbg_dump_stats(pf, &pf->stats); | ||
1325 | dev_info(&pf->pdev->dev, "pf stats_offsets:\n"); | ||
1326 | i40e_dbg_dump_stats(pf, &pf->stats_offsets); | ||
1327 | } else if (strncmp(&cmd_buf[5], "reset stats", 11) == 0) { | ||
1328 | dev_info(&pf->pdev->dev, | ||
1329 | "core reset count: %d\n", pf->corer_count); | ||
1330 | dev_info(&pf->pdev->dev, | ||
1331 | "global reset count: %d\n", pf->globr_count); | ||
1332 | dev_info(&pf->pdev->dev, | ||
1333 | "emp reset count: %d\n", pf->empr_count); | ||
1334 | dev_info(&pf->pdev->dev, | ||
1335 | "pf reset count: %d\n", pf->pfr_count); | ||
1336 | } else if (strncmp(&cmd_buf[5], "port", 4) == 0) { | ||
1337 | struct i40e_aqc_query_port_ets_config_resp *bw_data; | ||
1338 | struct i40e_dcbx_config *cfg = | ||
1339 | &pf->hw.local_dcbx_config; | ||
1340 | struct i40e_dcbx_config *r_cfg = | ||
1341 | &pf->hw.remote_dcbx_config; | ||
1342 | int i, ret; | ||
1343 | |||
1344 | bw_data = kzalloc(sizeof( | ||
1345 | struct i40e_aqc_query_port_ets_config_resp), | ||
1346 | GFP_KERNEL); | ||
1347 | if (!bw_data) { | ||
1348 | ret = -ENOMEM; | ||
1349 | goto command_write_done; | ||
1350 | } | ||
1351 | |||
1352 | ret = i40e_aq_query_port_ets_config(&pf->hw, | ||
1353 | pf->mac_seid, | ||
1354 | bw_data, NULL); | ||
1355 | if (ret) { | ||
1356 | dev_info(&pf->pdev->dev, | ||
1357 | "Query Port ETS Config AQ command failed =0x%x\n", | ||
1358 | pf->hw.aq.asq_last_status); | ||
1359 | kfree(bw_data); | ||
1360 | bw_data = NULL; | ||
1361 | goto command_write_done; | ||
1362 | } | ||
1363 | dev_info(&pf->pdev->dev, | ||
1364 | "port bw: tc_valid=0x%x tc_strict_prio=0x%x, tc_bw_max=0x%04x,0x%04x\n", | ||
1365 | bw_data->tc_valid_bits, | ||
1366 | bw_data->tc_strict_priority_bits, | ||
1367 | le16_to_cpu(bw_data->tc_bw_max[0]), | ||
1368 | le16_to_cpu(bw_data->tc_bw_max[1])); | ||
1369 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { | ||
1370 | dev_info(&pf->pdev->dev, "port bw: tc_bw_share=%d tc_bw_limit=%d\n", | ||
1371 | bw_data->tc_bw_share_credits[i], | ||
1372 | le16_to_cpu(bw_data->tc_bw_limits[i])); | ||
1373 | } | ||
1374 | |||
1375 | kfree(bw_data); | ||
1376 | bw_data = NULL; | ||
1377 | |||
1378 | dev_info(&pf->pdev->dev, | ||
1379 | "port ets_cfg: willing=%d cbs=%d, maxtcs=%d\n", | ||
1380 | cfg->etscfg.willing, cfg->etscfg.cbs, | ||
1381 | cfg->etscfg.maxtcs); | ||
1382 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { | ||
1383 | dev_info(&pf->pdev->dev, "port ets_cfg: %d prio_tc=%d tcbw=%d tctsa=%d\n", | ||
1384 | i, cfg->etscfg.prioritytable[i], | ||
1385 | cfg->etscfg.tcbwtable[i], | ||
1386 | cfg->etscfg.tsatable[i]); | ||
1387 | } | ||
1388 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { | ||
1389 | dev_info(&pf->pdev->dev, "port ets_rec: %d prio_tc=%d tcbw=%d tctsa=%d\n", | ||
1390 | i, cfg->etsrec.prioritytable[i], | ||
1391 | cfg->etsrec.tcbwtable[i], | ||
1392 | cfg->etsrec.tsatable[i]); | ||
1393 | } | ||
1394 | dev_info(&pf->pdev->dev, | ||
1395 | "port pfc_cfg: willing=%d mbc=%d, pfccap=%d pfcenable=0x%x\n", | ||
1396 | cfg->pfc.willing, cfg->pfc.mbc, | ||
1397 | cfg->pfc.pfccap, cfg->pfc.pfcenable); | ||
1398 | dev_info(&pf->pdev->dev, | ||
1399 | "port app_table: num_apps=%d\n", cfg->numapps); | ||
1400 | for (i = 0; i < cfg->numapps; i++) { | ||
1401 | dev_info(&pf->pdev->dev, "port app_table: %d prio=%d selector=%d protocol=0x%x\n", | ||
1402 | i, cfg->app[i].priority, | ||
1403 | cfg->app[i].selector, | ||
1404 | cfg->app[i].protocolid); | ||
1405 | } | ||
1406 | /* Peer TLV DCBX data */ | ||
1407 | dev_info(&pf->pdev->dev, | ||
1408 | "remote port ets_cfg: willing=%d cbs=%d, maxtcs=%d\n", | ||
1409 | r_cfg->etscfg.willing, | ||
1410 | r_cfg->etscfg.cbs, r_cfg->etscfg.maxtcs); | ||
1411 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { | ||
1412 | dev_info(&pf->pdev->dev, "remote port ets_cfg: %d prio_tc=%d tcbw=%d tctsa=%d\n", | ||
1413 | i, r_cfg->etscfg.prioritytable[i], | ||
1414 | r_cfg->etscfg.tcbwtable[i], | ||
1415 | r_cfg->etscfg.tsatable[i]); | ||
1416 | } | ||
1417 | for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { | ||
1418 | dev_info(&pf->pdev->dev, "remote port ets_rec: %d prio_tc=%d tcbw=%d tctsa=%d\n", | ||
1419 | i, r_cfg->etsrec.prioritytable[i], | ||
1420 | r_cfg->etsrec.tcbwtable[i], | ||
1421 | r_cfg->etsrec.tsatable[i]); | ||
1422 | } | ||
1423 | dev_info(&pf->pdev->dev, | ||
1424 | "remote port pfc_cfg: willing=%d mbc=%d, pfccap=%d pfcenable=0x%x\n", | ||
1425 | r_cfg->pfc.willing, | ||
1426 | r_cfg->pfc.mbc, | ||
1427 | r_cfg->pfc.pfccap, | ||
1428 | r_cfg->pfc.pfcenable); | ||
1429 | dev_info(&pf->pdev->dev, | ||
1430 | "remote port app_table: num_apps=%d\n", | ||
1431 | r_cfg->numapps); | ||
1432 | for (i = 0; i < r_cfg->numapps; i++) { | ||
1433 | dev_info(&pf->pdev->dev, "remote port app_table: %d prio=%d selector=%d protocol=0x%x\n", | ||
1434 | i, r_cfg->app[i].priority, | ||
1435 | r_cfg->app[i].selector, | ||
1436 | r_cfg->app[i].protocolid); | ||
1437 | } | ||
1438 | } else { | ||
1439 | dev_info(&pf->pdev->dev, | ||
1440 | "dump desc tx <vsi_seid> <ring_id> [<desc_n>], dump desc rx <vsi_seid> <ring_id> [<desc_n>],\n"); | ||
1441 | dev_info(&pf->pdev->dev, "dump switch, dump vsi [seid] or\n"); | ||
1442 | dev_info(&pf->pdev->dev, "dump stats\n"); | ||
1443 | dev_info(&pf->pdev->dev, "dump reset stats\n"); | ||
1444 | dev_info(&pf->pdev->dev, "dump port\n"); | ||
1445 | dev_info(&pf->pdev->dev, | ||
1446 | "dump debug fwdata <cluster_id> <table_id> <index>\n"); | ||
1447 | } | ||
1448 | |||
1449 | } else if (strncmp(cmd_buf, "msg_enable", 10) == 0) { | ||
1450 | u32 level; | ||
1451 | cnt = sscanf(&cmd_buf[10], "%i", &level); | ||
1452 | if (cnt) { | ||
1453 | if (I40E_DEBUG_USER & level) { | ||
1454 | pf->hw.debug_mask = level; | ||
1455 | dev_info(&pf->pdev->dev, | ||
1456 | "set hw.debug_mask = 0x%08x\n", | ||
1457 | pf->hw.debug_mask); | ||
1458 | } | ||
1459 | pf->msg_enable = level; | ||
1460 | dev_info(&pf->pdev->dev, "set msg_enable = 0x%08x\n", | ||
1461 | pf->msg_enable); | ||
1462 | } else { | ||
1463 | dev_info(&pf->pdev->dev, "msg_enable = 0x%08x\n", | ||
1464 | pf->msg_enable); | ||
1465 | } | ||
1466 | } else if (strncmp(cmd_buf, "pfr", 3) == 0) { | ||
1467 | dev_info(&pf->pdev->dev, "forcing PFR\n"); | ||
1468 | i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED)); | ||
1469 | |||
1470 | } else if (strncmp(cmd_buf, "corer", 5) == 0) { | ||
1471 | dev_info(&pf->pdev->dev, "forcing CoreR\n"); | ||
1472 | i40e_do_reset(pf, (1 << __I40E_CORE_RESET_REQUESTED)); | ||
1473 | |||
1474 | } else if (strncmp(cmd_buf, "globr", 5) == 0) { | ||
1475 | dev_info(&pf->pdev->dev, "forcing GlobR\n"); | ||
1476 | i40e_do_reset(pf, (1 << __I40E_GLOBAL_RESET_REQUESTED)); | ||
1477 | |||
1478 | } else if (strncmp(cmd_buf, "read", 4) == 0) { | ||
1479 | u32 address; | ||
1480 | u32 value; | ||
1481 | cnt = sscanf(&cmd_buf[4], "%x", &address); | ||
1482 | if (cnt != 1) { | ||
1483 | dev_info(&pf->pdev->dev, "read <reg>\n"); | ||
1484 | goto command_write_done; | ||
1485 | } | ||
1486 | |||
1487 | /* check the range on address */ | ||
1488 | if (address >= I40E_MAX_REGISTER) { | ||
1489 | dev_info(&pf->pdev->dev, "read reg address 0x%08x too large\n", | ||
1490 | address); | ||
1491 | goto command_write_done; | ||
1492 | } | ||
1493 | |||
1494 | value = rd32(&pf->hw, address); | ||
1495 | dev_info(&pf->pdev->dev, "read: 0x%08x = 0x%08x\n", | ||
1496 | address, value); | ||
1497 | |||
1498 | } else if (strncmp(cmd_buf, "write", 5) == 0) { | ||
1499 | u32 address, value; | ||
1500 | cnt = sscanf(&cmd_buf[5], "%x %x", &address, &value); | ||
1501 | if (cnt != 2) { | ||
1502 | dev_info(&pf->pdev->dev, "write <reg> <value>\n"); | ||
1503 | goto command_write_done; | ||
1504 | } | ||
1505 | |||
1506 | /* check the range on address */ | ||
1507 | if (address >= I40E_MAX_REGISTER) { | ||
1508 | dev_info(&pf->pdev->dev, "write reg address 0x%08x too large\n", | ||
1509 | address); | ||
1510 | goto command_write_done; | ||
1511 | } | ||
1512 | wr32(&pf->hw, address, value); | ||
1513 | value = rd32(&pf->hw, address); | ||
1514 | dev_info(&pf->pdev->dev, "write: 0x%08x = 0x%08x\n", | ||
1515 | address, value); | ||
1516 | } else if (strncmp(cmd_buf, "clear_stats", 11) == 0) { | ||
1517 | if (strncmp(&cmd_buf[12], "vsi", 3) == 0) { | ||
1518 | cnt = sscanf(&cmd_buf[15], "%d", &vsi_seid); | ||
1519 | if (cnt == 0) { | ||
1520 | int i; | ||
1521 | for (i = 0; i < pf->hw.func_caps.num_vsis; i++) | ||
1522 | i40e_vsi_reset_stats(pf->vsi[i]); | ||
1523 | dev_info(&pf->pdev->dev, "vsi clear stats called for all vsi's\n"); | ||
1524 | } else if (cnt == 1) { | ||
1525 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1526 | if (!vsi) { | ||
1527 | dev_info(&pf->pdev->dev, | ||
1528 | "clear_stats vsi: bad vsi %d\n", | ||
1529 | vsi_seid); | ||
1530 | goto command_write_done; | ||
1531 | } | ||
1532 | i40e_vsi_reset_stats(vsi); | ||
1533 | dev_info(&pf->pdev->dev, | ||
1534 | "vsi clear stats called for vsi %d\n", | ||
1535 | vsi_seid); | ||
1536 | } else { | ||
1537 | dev_info(&pf->pdev->dev, "clear_stats vsi [seid]\n"); | ||
1538 | } | ||
1539 | } else if (strncmp(&cmd_buf[12], "pf", 2) == 0) { | ||
1540 | i40e_pf_reset_stats(pf); | ||
1541 | dev_info(&pf->pdev->dev, "pf clear stats called\n"); | ||
1542 | } else { | ||
1543 | dev_info(&pf->pdev->dev, "clear_stats vsi [seid] or clear_stats pf\n"); | ||
1544 | } | ||
1545 | } else if ((strncmp(cmd_buf, "add fd_filter", 13) == 0) || | ||
1546 | (strncmp(cmd_buf, "rem fd_filter", 13) == 0)) { | ||
1547 | struct i40e_fdir_data fd_data; | ||
1548 | int ret; | ||
1549 | u16 packet_len, i, j = 0; | ||
1550 | char *asc_packet; | ||
1551 | bool add = false; | ||
1552 | |||
1553 | asc_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_LOOKUP, | ||
1554 | GFP_KERNEL); | ||
1555 | if (!asc_packet) | ||
1556 | goto command_write_done; | ||
1557 | |||
1558 | fd_data.raw_packet = kzalloc(I40E_FDIR_MAX_RAW_PACKET_LOOKUP, | ||
1559 | GFP_KERNEL); | ||
1560 | |||
1561 | if (!fd_data.raw_packet) { | ||
1562 | kfree(asc_packet); | ||
1563 | asc_packet = NULL; | ||
1564 | goto command_write_done; | ||
1565 | } | ||
1566 | |||
1567 | if (strncmp(cmd_buf, "add", 3) == 0) | ||
1568 | add = true; | ||
1569 | cnt = sscanf(&cmd_buf[13], | ||
1570 | "%hx %2hhx %2hhx %hx %2hhx %2hhx %hx %x %hd %512s", | ||
1571 | &fd_data.q_index, | ||
1572 | &fd_data.flex_off, &fd_data.pctype, | ||
1573 | &fd_data.dest_vsi, &fd_data.dest_ctl, | ||
1574 | &fd_data.fd_status, &fd_data.cnt_index, | ||
1575 | &fd_data.fd_id, &packet_len, asc_packet); | ||
1576 | if (cnt != 10) { | ||
1577 | dev_info(&pf->pdev->dev, | ||
1578 | "program fd_filter: bad command string, cnt=%d\n", | ||
1579 | cnt); | ||
1580 | kfree(asc_packet); | ||
1581 | asc_packet = NULL; | ||
1582 | kfree(fd_data.raw_packet); | ||
1583 | goto command_write_done; | ||
1584 | } | ||
1585 | |||
1586 | /* fix packet length if user entered 0 */ | ||
1587 | if (packet_len == 0) | ||
1588 | packet_len = I40E_FDIR_MAX_RAW_PACKET_LOOKUP; | ||
1589 | |||
1590 | /* make sure to check the max as well */ | ||
1591 | packet_len = min_t(u16, | ||
1592 | packet_len, I40E_FDIR_MAX_RAW_PACKET_LOOKUP); | ||
1593 | |||
1594 | dev_info(&pf->pdev->dev, "FD raw packet:\n"); | ||
1595 | for (i = 0; i < packet_len; i++) { | ||
1596 | sscanf(&asc_packet[j], "%2hhx ", | ||
1597 | &fd_data.raw_packet[i]); | ||
1598 | j += 3; | ||
1599 | snprintf(print_buf, 3, "%02x ", fd_data.raw_packet[i]); | ||
1600 | print_buf += 3; | ||
1601 | if ((i % 16) == 15) { | ||
1602 | snprintf(print_buf, 1, "\n"); | ||
1603 | print_buf++; | ||
1604 | } | ||
1605 | } | ||
1606 | dev_info(&pf->pdev->dev, "%s\n", print_buf_start); | ||
1607 | ret = i40e_program_fdir_filter(&fd_data, pf, add); | ||
1608 | if (!ret) { | ||
1609 | dev_info(&pf->pdev->dev, "Filter command send Status : Success\n"); | ||
1610 | } else { | ||
1611 | dev_info(&pf->pdev->dev, | ||
1612 | "Filter command send failed %d\n", ret); | ||
1613 | } | ||
1614 | kfree(fd_data.raw_packet); | ||
1615 | fd_data.raw_packet = NULL; | ||
1616 | kfree(asc_packet); | ||
1617 | asc_packet = NULL; | ||
1618 | } else if (strncmp(cmd_buf, "lldp", 4) == 0) { | ||
1619 | if (strncmp(&cmd_buf[5], "stop", 4) == 0) { | ||
1620 | int ret; | ||
1621 | ret = i40e_aq_stop_lldp(&pf->hw, false, NULL); | ||
1622 | if (ret) { | ||
1623 | dev_info(&pf->pdev->dev, | ||
1624 | "Stop LLDP AQ command failed =0x%x\n", | ||
1625 | pf->hw.aq.asq_last_status); | ||
1626 | goto command_write_done; | ||
1627 | } | ||
1628 | } else if (strncmp(&cmd_buf[5], "start", 5) == 0) { | ||
1629 | int ret; | ||
1630 | ret = i40e_aq_start_lldp(&pf->hw, NULL); | ||
1631 | if (ret) { | ||
1632 | dev_info(&pf->pdev->dev, | ||
1633 | "Start LLDP AQ command failed =0x%x\n", | ||
1634 | pf->hw.aq.asq_last_status); | ||
1635 | goto command_write_done; | ||
1636 | } | ||
1637 | } else if (strncmp(&cmd_buf[5], | ||
1638 | "get local", 9) == 0) { | ||
1639 | int ret, i; | ||
1640 | u8 *buff; | ||
1641 | u16 llen, rlen; | ||
1642 | buff = kzalloc(I40E_LLDPDU_SIZE, GFP_KERNEL); | ||
1643 | if (!buff) | ||
1644 | goto command_write_done; | ||
1645 | |||
1646 | ret = i40e_aq_get_lldp_mib(&pf->hw, 0, | ||
1647 | I40E_AQ_LLDP_MIB_LOCAL, | ||
1648 | buff, I40E_LLDPDU_SIZE, | ||
1649 | &llen, &rlen, NULL); | ||
1650 | if (ret) { | ||
1651 | dev_info(&pf->pdev->dev, | ||
1652 | "Get LLDP MIB (local) AQ command failed =0x%x\n", | ||
1653 | pf->hw.aq.asq_last_status); | ||
1654 | kfree(buff); | ||
1655 | buff = NULL; | ||
1656 | goto command_write_done; | ||
1657 | } | ||
1658 | dev_info(&pf->pdev->dev, | ||
1659 | "Get LLDP MIB (local) AQ buffer written back:\n"); | ||
1660 | for (i = 0; i < I40E_LLDPDU_SIZE; i++) { | ||
1661 | snprintf(print_buf, 3, "%02x ", buff[i]); | ||
1662 | print_buf += 3; | ||
1663 | if ((i % 16) == 15) { | ||
1664 | snprintf(print_buf, 1, "\n"); | ||
1665 | print_buf++; | ||
1666 | } | ||
1667 | } | ||
1668 | dev_info(&pf->pdev->dev, "%s\n", print_buf_start); | ||
1669 | kfree(buff); | ||
1670 | buff = NULL; | ||
1671 | } else if (strncmp(&cmd_buf[5], "get remote", 10) == 0) { | ||
1672 | int ret, i; | ||
1673 | u8 *buff; | ||
1674 | u16 llen, rlen; | ||
1675 | buff = kzalloc(I40E_LLDPDU_SIZE, GFP_KERNEL); | ||
1676 | if (!buff) | ||
1677 | goto command_write_done; | ||
1678 | |||
1679 | ret = i40e_aq_get_lldp_mib(&pf->hw, | ||
1680 | I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE, | ||
1681 | I40E_AQ_LLDP_MIB_LOCAL, | ||
1682 | buff, I40E_LLDPDU_SIZE, | ||
1683 | &llen, &rlen, NULL); | ||
1684 | if (ret) { | ||
1685 | dev_info(&pf->pdev->dev, | ||
1686 | "Get LLDP MIB (remote) AQ command failed =0x%x\n", | ||
1687 | pf->hw.aq.asq_last_status); | ||
1688 | kfree(buff); | ||
1689 | buff = NULL; | ||
1690 | goto command_write_done; | ||
1691 | } | ||
1692 | dev_info(&pf->pdev->dev, | ||
1693 | "Get LLDP MIB (remote) AQ buffer written back:\n"); | ||
1694 | for (i = 0; i < I40E_LLDPDU_SIZE; i++) { | ||
1695 | snprintf(print_buf, 3, "%02x ", buff[i]); | ||
1696 | print_buf += 3; | ||
1697 | if ((i % 16) == 15) { | ||
1698 | snprintf(print_buf, 1, "\n"); | ||
1699 | print_buf++; | ||
1700 | } | ||
1701 | } | ||
1702 | dev_info(&pf->pdev->dev, "%s\n", print_buf_start); | ||
1703 | kfree(buff); | ||
1704 | buff = NULL; | ||
1705 | } else if (strncmp(&cmd_buf[5], "event on", 8) == 0) { | ||
1706 | int ret; | ||
1707 | ret = i40e_aq_cfg_lldp_mib_change_event(&pf->hw, | ||
1708 | true, NULL); | ||
1709 | if (ret) { | ||
1710 | dev_info(&pf->pdev->dev, | ||
1711 | "Config LLDP MIB Change Event (on) AQ command failed =0x%x\n", | ||
1712 | pf->hw.aq.asq_last_status); | ||
1713 | goto command_write_done; | ||
1714 | } | ||
1715 | } else if (strncmp(&cmd_buf[5], "event off", 9) == 0) { | ||
1716 | int ret; | ||
1717 | ret = i40e_aq_cfg_lldp_mib_change_event(&pf->hw, | ||
1718 | false, NULL); | ||
1719 | if (ret) { | ||
1720 | dev_info(&pf->pdev->dev, | ||
1721 | "Config LLDP MIB Change Event (off) AQ command failed =0x%x\n", | ||
1722 | pf->hw.aq.asq_last_status); | ||
1723 | goto command_write_done; | ||
1724 | } | ||
1725 | } | ||
1726 | } else if (strncmp(cmd_buf, "nvm read", 8) == 0) { | ||
1727 | u16 buffer_len, i, bytes; | ||
1728 | u16 module; | ||
1729 | u32 offset; | ||
1730 | u16 *buff; | ||
1731 | int ret; | ||
1732 | |||
1733 | cnt = sscanf(&cmd_buf[8], "%hx %x %hx", | ||
1734 | &module, &offset, &buffer_len); | ||
1735 | if (cnt == 0) { | ||
1736 | module = 0; | ||
1737 | offset = 0; | ||
1738 | buffer_len = 0; | ||
1739 | } else if (cnt == 1) { | ||
1740 | offset = 0; | ||
1741 | buffer_len = 0; | ||
1742 | } else if (cnt == 2) { | ||
1743 | buffer_len = 0; | ||
1744 | } else if (cnt > 3) { | ||
1745 | dev_info(&pf->pdev->dev, | ||
1746 | "nvm read: bad command string, cnt=%d\n", cnt); | ||
1747 | goto command_write_done; | ||
1748 | } | ||
1749 | |||
1750 | /* Read at least 512 words */ | ||
1751 | if (buffer_len == 0) | ||
1752 | buffer_len = 512; | ||
1753 | |||
1754 | bytes = 2 * buffer_len; | ||
1755 | buff = kzalloc(bytes, GFP_KERNEL); | ||
1756 | if (!buff) | ||
1757 | goto command_write_done; | ||
1758 | |||
1759 | ret = i40e_acquire_nvm(&pf->hw, I40E_RESOURCE_READ); | ||
1760 | if (ret) { | ||
1761 | dev_info(&pf->pdev->dev, | ||
1762 | "Failed Acquiring NVM resource for read err=%d status=0x%x\n", | ||
1763 | ret, pf->hw.aq.asq_last_status); | ||
1764 | kfree(buff); | ||
1765 | goto command_write_done; | ||
1766 | } | ||
1767 | |||
1768 | ret = i40e_aq_read_nvm(&pf->hw, module, (2 * offset), | ||
1769 | bytes, (u8 *)buff, true, NULL); | ||
1770 | i40e_release_nvm(&pf->hw); | ||
1771 | if (ret) { | ||
1772 | dev_info(&pf->pdev->dev, | ||
1773 | "Read NVM AQ failed err=%d status=0x%x\n", | ||
1774 | ret, pf->hw.aq.asq_last_status); | ||
1775 | } else { | ||
1776 | dev_info(&pf->pdev->dev, | ||
1777 | "Read NVM module=0x%x offset=0x%x words=%d\n", | ||
1778 | module, offset, buffer_len); | ||
1779 | for (i = 0; i < buffer_len; i++) { | ||
1780 | if ((i % 16) == 0) { | ||
1781 | snprintf(print_buf, 11, "\n0x%08x: ", | ||
1782 | offset + i); | ||
1783 | print_buf += 11; | ||
1784 | } | ||
1785 | snprintf(print_buf, 5, "%04x ", buff[i]); | ||
1786 | print_buf += 5; | ||
1787 | } | ||
1788 | dev_info(&pf->pdev->dev, "%s\n", print_buf_start); | ||
1789 | } | ||
1790 | kfree(buff); | ||
1791 | buff = NULL; | ||
1792 | } else { | ||
1793 | dev_info(&pf->pdev->dev, "unknown command '%s'\n", cmd_buf); | ||
1794 | dev_info(&pf->pdev->dev, "available commands\n"); | ||
1795 | dev_info(&pf->pdev->dev, " add vsi [relay_seid]\n"); | ||
1796 | dev_info(&pf->pdev->dev, " del vsi [vsi_seid]\n"); | ||
1797 | dev_info(&pf->pdev->dev, " add relay <uplink_seid> <vsi_seid>\n"); | ||
1798 | dev_info(&pf->pdev->dev, " del relay <relay_seid>\n"); | ||
1799 | dev_info(&pf->pdev->dev, " add macaddr <vsi_seid> <aa:bb:cc:dd:ee:ff> [vlan]\n"); | ||
1800 | dev_info(&pf->pdev->dev, " del macaddr <vsi_seid> <aa:bb:cc:dd:ee:ff> [vlan]\n"); | ||
1801 | dev_info(&pf->pdev->dev, " add pvid <vsi_seid> <vid>\n"); | ||
1802 | dev_info(&pf->pdev->dev, " del pvid <vsi_seid>\n"); | ||
1803 | dev_info(&pf->pdev->dev, " dump switch\n"); | ||
1804 | dev_info(&pf->pdev->dev, " dump vsi [seid]\n"); | ||
1805 | dev_info(&pf->pdev->dev, " dump desc tx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
1806 | dev_info(&pf->pdev->dev, " dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n"); | ||
1807 | dev_info(&pf->pdev->dev, " dump desc aq\n"); | ||
1808 | dev_info(&pf->pdev->dev, " dump stats\n"); | ||
1809 | dev_info(&pf->pdev->dev, " dump reset stats\n"); | ||
1810 | dev_info(&pf->pdev->dev, " msg_enable [level]\n"); | ||
1811 | dev_info(&pf->pdev->dev, " read <reg>\n"); | ||
1812 | dev_info(&pf->pdev->dev, " write <reg> <value>\n"); | ||
1813 | dev_info(&pf->pdev->dev, " clear_stats vsi [seid]\n"); | ||
1814 | dev_info(&pf->pdev->dev, " clear_stats pf\n"); | ||
1815 | dev_info(&pf->pdev->dev, " pfr\n"); | ||
1816 | dev_info(&pf->pdev->dev, " corer\n"); | ||
1817 | dev_info(&pf->pdev->dev, " globr\n"); | ||
1818 | dev_info(&pf->pdev->dev, " add fd_filter <dest q_index> <flex_off> <pctype> <dest_vsi> <dest_ctl> <fd_status> <cnt_index> <fd_id> <packet_len> <packet>\n"); | ||
1819 | dev_info(&pf->pdev->dev, " rem fd_filter <dest q_index> <flex_off> <pctype> <dest_vsi> <dest_ctl> <fd_status> <cnt_index> <fd_id> <packet_len> <packet>\n"); | ||
1820 | dev_info(&pf->pdev->dev, " lldp start\n"); | ||
1821 | dev_info(&pf->pdev->dev, " lldp stop\n"); | ||
1822 | dev_info(&pf->pdev->dev, " lldp get local\n"); | ||
1823 | dev_info(&pf->pdev->dev, " lldp get remote\n"); | ||
1824 | dev_info(&pf->pdev->dev, " lldp event on\n"); | ||
1825 | dev_info(&pf->pdev->dev, " lldp event off\n"); | ||
1826 | dev_info(&pf->pdev->dev, " nvm read [module] [word_offset] [word_count]\n"); | ||
1827 | } | ||
1828 | |||
1829 | command_write_done: | ||
1830 | kfree(cmd_buf); | ||
1831 | cmd_buf = NULL; | ||
1832 | kfree(print_buf_start); | ||
1833 | print_buf = NULL; | ||
1834 | print_buf_start = NULL; | ||
1835 | return count; | ||
1836 | } | ||
1837 | |||
1838 | static const struct file_operations i40e_dbg_command_fops = { | ||
1839 | .owner = THIS_MODULE, | ||
1840 | .open = simple_open, | ||
1841 | .read = i40e_dbg_command_read, | ||
1842 | .write = i40e_dbg_command_write, | ||
1843 | }; | ||
1844 | |||
1845 | /************************************************************** | ||
1846 | * netdev_ops | ||
1847 | * The netdev_ops entry in debugfs is for giving the driver commands | ||
1848 | * to be executed from the netdev operations. | ||
1849 | **************************************************************/ | ||
1850 | static char i40e_dbg_netdev_ops_buf[256] = "hello world"; | ||
1851 | |||
1852 | /** | ||
1853 | * i40e_dbg_netdev_ops - read for netdev_ops datum | ||
1854 | * @filp: the opened file | ||
1855 | * @buffer: where to write the data for the user to read | ||
1856 | * @count: the size of the user's buffer | ||
1857 | * @ppos: file position offset | ||
1858 | **/ | ||
1859 | static ssize_t i40e_dbg_netdev_ops_read(struct file *filp, char __user *buffer, | ||
1860 | size_t count, loff_t *ppos) | ||
1861 | { | ||
1862 | struct i40e_pf *pf = filp->private_data; | ||
1863 | int bytes_not_copied; | ||
1864 | int buf_size = 256; | ||
1865 | char *buf; | ||
1866 | int len; | ||
1867 | |||
1868 | /* don't allow partal reads */ | ||
1869 | if (*ppos != 0) | ||
1870 | return 0; | ||
1871 | if (count < buf_size) | ||
1872 | return -ENOSPC; | ||
1873 | |||
1874 | buf = kzalloc(buf_size, GFP_KERNEL); | ||
1875 | if (!buf) | ||
1876 | return -ENOSPC; | ||
1877 | |||
1878 | len = snprintf(buf, buf_size, "%s: %s\n", | ||
1879 | pf->vsi[pf->lan_vsi]->netdev->name, | ||
1880 | i40e_dbg_netdev_ops_buf); | ||
1881 | |||
1882 | bytes_not_copied = copy_to_user(buffer, buf, len); | ||
1883 | kfree(buf); | ||
1884 | |||
1885 | if (bytes_not_copied < 0) | ||
1886 | return bytes_not_copied; | ||
1887 | |||
1888 | *ppos = len; | ||
1889 | return len; | ||
1890 | } | ||
1891 | |||
1892 | /** | ||
1893 | * i40e_dbg_netdev_ops_write - write into netdev_ops datum | ||
1894 | * @filp: the opened file | ||
1895 | * @buffer: where to find the user's data | ||
1896 | * @count: the length of the user's data | ||
1897 | * @ppos: file position offset | ||
1898 | **/ | ||
1899 | static ssize_t i40e_dbg_netdev_ops_write(struct file *filp, | ||
1900 | const char __user *buffer, | ||
1901 | size_t count, loff_t *ppos) | ||
1902 | { | ||
1903 | struct i40e_pf *pf = filp->private_data; | ||
1904 | int bytes_not_copied; | ||
1905 | struct i40e_vsi *vsi; | ||
1906 | int vsi_seid; | ||
1907 | int i, cnt; | ||
1908 | |||
1909 | /* don't allow partial writes */ | ||
1910 | if (*ppos != 0) | ||
1911 | return 0; | ||
1912 | if (count >= sizeof(i40e_dbg_netdev_ops_buf)) | ||
1913 | return -ENOSPC; | ||
1914 | |||
1915 | memset(i40e_dbg_netdev_ops_buf, 0, sizeof(i40e_dbg_netdev_ops_buf)); | ||
1916 | bytes_not_copied = copy_from_user(i40e_dbg_netdev_ops_buf, | ||
1917 | buffer, count); | ||
1918 | if (bytes_not_copied < 0) | ||
1919 | return bytes_not_copied; | ||
1920 | else if (bytes_not_copied > 0) | ||
1921 | count -= bytes_not_copied; | ||
1922 | i40e_dbg_netdev_ops_buf[count] = '\0'; | ||
1923 | |||
1924 | if (strncmp(i40e_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) { | ||
1925 | cnt = sscanf(&i40e_dbg_netdev_ops_buf[11], "%i", &vsi_seid); | ||
1926 | if (cnt != 1) { | ||
1927 | dev_info(&pf->pdev->dev, "tx_timeout <vsi_seid>\n"); | ||
1928 | goto netdev_ops_write_done; | ||
1929 | } | ||
1930 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1931 | if (!vsi) { | ||
1932 | dev_info(&pf->pdev->dev, | ||
1933 | "tx_timeout: VSI %d not found\n", vsi_seid); | ||
1934 | goto netdev_ops_write_done; | ||
1935 | } | ||
1936 | if (rtnl_trylock()) { | ||
1937 | vsi->netdev->netdev_ops->ndo_tx_timeout(vsi->netdev); | ||
1938 | rtnl_unlock(); | ||
1939 | dev_info(&pf->pdev->dev, "tx_timeout called\n"); | ||
1940 | } else { | ||
1941 | dev_info(&pf->pdev->dev, "Could not acquire RTNL - please try again\n"); | ||
1942 | } | ||
1943 | } else if (strncmp(i40e_dbg_netdev_ops_buf, "change_mtu", 10) == 0) { | ||
1944 | int mtu; | ||
1945 | cnt = sscanf(&i40e_dbg_netdev_ops_buf[11], "%i %i", | ||
1946 | &vsi_seid, &mtu); | ||
1947 | if (cnt != 2) { | ||
1948 | dev_info(&pf->pdev->dev, "change_mtu <vsi_seid> <mtu>\n"); | ||
1949 | goto netdev_ops_write_done; | ||
1950 | } | ||
1951 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1952 | if (!vsi) { | ||
1953 | dev_info(&pf->pdev->dev, | ||
1954 | "change_mtu: VSI %d not found\n", vsi_seid); | ||
1955 | goto netdev_ops_write_done; | ||
1956 | } | ||
1957 | if (rtnl_trylock()) { | ||
1958 | vsi->netdev->netdev_ops->ndo_change_mtu(vsi->netdev, | ||
1959 | mtu); | ||
1960 | rtnl_unlock(); | ||
1961 | dev_info(&pf->pdev->dev, "change_mtu called\n"); | ||
1962 | } else { | ||
1963 | dev_info(&pf->pdev->dev, "Could not acquire RTNL - please try again\n"); | ||
1964 | } | ||
1965 | |||
1966 | } else if (strncmp(i40e_dbg_netdev_ops_buf, "set_rx_mode", 11) == 0) { | ||
1967 | cnt = sscanf(&i40e_dbg_netdev_ops_buf[11], "%i", &vsi_seid); | ||
1968 | if (cnt != 1) { | ||
1969 | dev_info(&pf->pdev->dev, "set_rx_mode <vsi_seid>\n"); | ||
1970 | goto netdev_ops_write_done; | ||
1971 | } | ||
1972 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1973 | if (!vsi) { | ||
1974 | dev_info(&pf->pdev->dev, | ||
1975 | "set_rx_mode: VSI %d not found\n", vsi_seid); | ||
1976 | goto netdev_ops_write_done; | ||
1977 | } | ||
1978 | if (rtnl_trylock()) { | ||
1979 | vsi->netdev->netdev_ops->ndo_set_rx_mode(vsi->netdev); | ||
1980 | rtnl_unlock(); | ||
1981 | dev_info(&pf->pdev->dev, "set_rx_mode called\n"); | ||
1982 | } else { | ||
1983 | dev_info(&pf->pdev->dev, "Could not acquire RTNL - please try again\n"); | ||
1984 | } | ||
1985 | |||
1986 | } else if (strncmp(i40e_dbg_netdev_ops_buf, "napi", 4) == 0) { | ||
1987 | cnt = sscanf(&i40e_dbg_netdev_ops_buf[4], "%i", &vsi_seid); | ||
1988 | if (cnt != 1) { | ||
1989 | dev_info(&pf->pdev->dev, "napi <vsi_seid>\n"); | ||
1990 | goto netdev_ops_write_done; | ||
1991 | } | ||
1992 | vsi = i40e_dbg_find_vsi(pf, vsi_seid); | ||
1993 | if (!vsi) { | ||
1994 | dev_info(&pf->pdev->dev, "napi: VSI %d not found\n", | ||
1995 | vsi_seid); | ||
1996 | goto netdev_ops_write_done; | ||
1997 | } | ||
1998 | for (i = 0; i < vsi->num_q_vectors; i++) | ||
1999 | napi_schedule(&vsi->q_vectors[i].napi); | ||
2000 | dev_info(&pf->pdev->dev, "napi called\n"); | ||
2001 | } else { | ||
2002 | dev_info(&pf->pdev->dev, "unknown command '%s'\n", | ||
2003 | i40e_dbg_netdev_ops_buf); | ||
2004 | dev_info(&pf->pdev->dev, "available commands\n"); | ||
2005 | dev_info(&pf->pdev->dev, " tx_timeout <vsi_seid>\n"); | ||
2006 | dev_info(&pf->pdev->dev, " change_mtu <vsi_seid> <mtu>\n"); | ||
2007 | dev_info(&pf->pdev->dev, " set_rx_mode <vsi_seid>\n"); | ||
2008 | dev_info(&pf->pdev->dev, " napi <vsi_seid>\n"); | ||
2009 | } | ||
2010 | netdev_ops_write_done: | ||
2011 | return count; | ||
2012 | } | ||
2013 | |||
2014 | static const struct file_operations i40e_dbg_netdev_ops_fops = { | ||
2015 | .owner = THIS_MODULE, | ||
2016 | .open = simple_open, | ||
2017 | .read = i40e_dbg_netdev_ops_read, | ||
2018 | .write = i40e_dbg_netdev_ops_write, | ||
2019 | }; | ||
2020 | |||
2021 | /** | ||
2022 | * i40e_dbg_pf_init - setup the debugfs directory for the pf | ||
2023 | * @pf: the pf that is starting up | ||
2024 | **/ | ||
2025 | void i40e_dbg_pf_init(struct i40e_pf *pf) | ||
2026 | { | ||
2027 | struct dentry *pfile __attribute__((unused)); | ||
2028 | const char *name = pci_name(pf->pdev); | ||
2029 | |||
2030 | pf->i40e_dbg_pf = debugfs_create_dir(name, i40e_dbg_root); | ||
2031 | if (pf->i40e_dbg_pf) { | ||
2032 | pfile = debugfs_create_file("command", 0600, pf->i40e_dbg_pf, | ||
2033 | pf, &i40e_dbg_command_fops); | ||
2034 | pfile = debugfs_create_file("dump", 0600, pf->i40e_dbg_pf, pf, | ||
2035 | &i40e_dbg_dump_fops); | ||
2036 | pfile = debugfs_create_file("netdev_ops", 0600, pf->i40e_dbg_pf, | ||
2037 | pf, &i40e_dbg_netdev_ops_fops); | ||
2038 | } else { | ||
2039 | dev_info(&pf->pdev->dev, | ||
2040 | "debugfs entry for %s failed\n", name); | ||
2041 | } | ||
2042 | } | ||
2043 | |||
2044 | /** | ||
2045 | * i40e_dbg_pf_exit - clear out the pf's debugfs entries | ||
2046 | * @pf: the pf that is stopping | ||
2047 | **/ | ||
2048 | void i40e_dbg_pf_exit(struct i40e_pf *pf) | ||
2049 | { | ||
2050 | debugfs_remove_recursive(pf->i40e_dbg_pf); | ||
2051 | pf->i40e_dbg_pf = NULL; | ||
2052 | |||
2053 | kfree(i40e_dbg_dump_buf); | ||
2054 | i40e_dbg_dump_buf = NULL; | ||
2055 | } | ||
2056 | |||
2057 | /** | ||
2058 | * i40e_dbg_init - start up debugfs for the driver | ||
2059 | **/ | ||
2060 | void i40e_dbg_init(void) | ||
2061 | { | ||
2062 | i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL); | ||
2063 | if (!i40e_dbg_root) | ||
2064 | pr_info("init of debugfs failed\n"); | ||
2065 | } | ||
2066 | |||
2067 | /** | ||
2068 | * i40e_dbg_exit - clean out the driver's debugfs entries | ||
2069 | **/ | ||
2070 | void i40e_dbg_exit(void) | ||
2071 | { | ||
2072 | debugfs_remove_recursive(i40e_dbg_root); | ||
2073 | i40e_dbg_root = NULL; | ||
2074 | } | ||
2075 | |||
2076 | #endif /* CONFIG_DEBUG_FS */ | ||