.. | .. |
---|
18 | 18 | struct mvpp2 *priv; |
---|
19 | 19 | }; |
---|
20 | 20 | |
---|
| 21 | +struct mvpp2_dbgfs_c2_entry { |
---|
| 22 | + int id; |
---|
| 23 | + struct mvpp2 *priv; |
---|
| 24 | +}; |
---|
| 25 | + |
---|
21 | 26 | struct mvpp2_dbgfs_flow_entry { |
---|
22 | 27 | int flow; |
---|
| 28 | + struct mvpp2 *priv; |
---|
| 29 | +}; |
---|
| 30 | + |
---|
| 31 | +struct mvpp2_dbgfs_flow_tbl_entry { |
---|
| 32 | + int id; |
---|
23 | 33 | struct mvpp2 *priv; |
---|
24 | 34 | }; |
---|
25 | 35 | |
---|
.. | .. |
---|
28 | 38 | struct mvpp2_dbgfs_flow_entry *dbg_fe; |
---|
29 | 39 | }; |
---|
30 | 40 | |
---|
| 41 | +struct mvpp2_dbgfs_entries { |
---|
| 42 | + /* Entries for Header Parser debug info */ |
---|
| 43 | + struct mvpp2_dbgfs_prs_entry prs_entries[MVPP2_PRS_TCAM_SRAM_SIZE]; |
---|
| 44 | + |
---|
| 45 | + /* Entries for Classifier C2 engine debug info */ |
---|
| 46 | + struct mvpp2_dbgfs_c2_entry c2_entries[MVPP22_CLS_C2_N_ENTRIES]; |
---|
| 47 | + |
---|
| 48 | + /* Entries for Classifier Flow Table debug info */ |
---|
| 49 | + struct mvpp2_dbgfs_flow_tbl_entry flt_entries[MVPP2_CLS_FLOWS_TBL_SIZE]; |
---|
| 50 | + |
---|
| 51 | + /* Entries for Classifier flows debug info */ |
---|
| 52 | + struct mvpp2_dbgfs_flow_entry flow_entries[MVPP2_N_PRS_FLOWS]; |
---|
| 53 | + |
---|
| 54 | + /* Entries for per-port flows debug info */ |
---|
| 55 | + struct mvpp2_dbgfs_port_flow_entry port_flow_entries[MVPP2_MAX_PORTS]; |
---|
| 56 | +}; |
---|
| 57 | + |
---|
31 | 58 | static int mvpp2_dbgfs_flow_flt_hits_show(struct seq_file *s, void *unused) |
---|
32 | 59 | { |
---|
33 | | - struct mvpp2_dbgfs_flow_entry *entry = s->private; |
---|
34 | | - int id = MVPP2_FLOW_C2_ENTRY(entry->flow); |
---|
| 60 | + struct mvpp2_dbgfs_flow_tbl_entry *entry = s->private; |
---|
35 | 61 | |
---|
36 | | - u32 hits = mvpp2_cls_flow_hits(entry->priv, id); |
---|
| 62 | + u32 hits = mvpp2_cls_flow_hits(entry->priv, entry->id); |
---|
37 | 63 | |
---|
38 | 64 | seq_printf(s, "%u\n", hits); |
---|
39 | 65 | |
---|
.. | .. |
---|
58 | 84 | static int mvpp2_dbgfs_flow_type_show(struct seq_file *s, void *unused) |
---|
59 | 85 | { |
---|
60 | 86 | struct mvpp2_dbgfs_flow_entry *entry = s->private; |
---|
61 | | - struct mvpp2_cls_flow *f; |
---|
| 87 | + const struct mvpp2_cls_flow *f; |
---|
62 | 88 | const char *flow_name; |
---|
63 | 89 | |
---|
64 | 90 | f = mvpp2_cls_flow_get(entry->flow); |
---|
.. | .. |
---|
93 | 119 | return 0; |
---|
94 | 120 | } |
---|
95 | 121 | |
---|
96 | | -static int mvpp2_dbgfs_flow_type_open(struct inode *inode, struct file *file) |
---|
97 | | -{ |
---|
98 | | - return single_open(file, mvpp2_dbgfs_flow_type_show, inode->i_private); |
---|
99 | | -} |
---|
100 | | - |
---|
101 | | -static int mvpp2_dbgfs_flow_type_release(struct inode *inode, struct file *file) |
---|
102 | | -{ |
---|
103 | | - struct seq_file *seq = file->private_data; |
---|
104 | | - struct mvpp2_dbgfs_flow_entry *flow_entry = seq->private; |
---|
105 | | - |
---|
106 | | - kfree(flow_entry); |
---|
107 | | - return single_release(inode, file); |
---|
108 | | -} |
---|
109 | | - |
---|
110 | | -static const struct file_operations mvpp2_dbgfs_flow_type_fops = { |
---|
111 | | - .open = mvpp2_dbgfs_flow_type_open, |
---|
112 | | - .read = seq_read, |
---|
113 | | - .release = mvpp2_dbgfs_flow_type_release, |
---|
114 | | -}; |
---|
| 122 | +DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_type); |
---|
115 | 123 | |
---|
116 | 124 | static int mvpp2_dbgfs_flow_id_show(struct seq_file *s, void *unused) |
---|
117 | 125 | { |
---|
118 | | - struct mvpp2_dbgfs_flow_entry *entry = s->private; |
---|
119 | | - struct mvpp2_cls_flow *f; |
---|
| 126 | + const struct mvpp2_dbgfs_flow_entry *entry = s->private; |
---|
| 127 | + const struct mvpp2_cls_flow *f; |
---|
120 | 128 | |
---|
121 | 129 | f = mvpp2_cls_flow_get(entry->flow); |
---|
122 | 130 | if (!f) |
---|
.. | .. |
---|
134 | 142 | struct mvpp2_dbgfs_port_flow_entry *entry = s->private; |
---|
135 | 143 | struct mvpp2_port *port = entry->port; |
---|
136 | 144 | struct mvpp2_cls_flow_entry fe; |
---|
137 | | - struct mvpp2_cls_flow *f; |
---|
| 145 | + const struct mvpp2_cls_flow *f; |
---|
138 | 146 | int flow_index; |
---|
139 | 147 | u16 hash_opts; |
---|
140 | 148 | |
---|
.. | .. |
---|
142 | 150 | if (!f) |
---|
143 | 151 | return -EINVAL; |
---|
144 | 152 | |
---|
145 | | - flow_index = MVPP2_PORT_FLOW_HASH_ENTRY(entry->port->id, f->flow_id); |
---|
| 153 | + flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id); |
---|
146 | 154 | |
---|
147 | 155 | mvpp2_cls_flow_read(port->priv, flow_index, &fe); |
---|
148 | 156 | |
---|
.. | .. |
---|
153 | 161 | return 0; |
---|
154 | 162 | } |
---|
155 | 163 | |
---|
156 | | -static int mvpp2_dbgfs_port_flow_hash_opt_open(struct inode *inode, |
---|
157 | | - struct file *file) |
---|
158 | | -{ |
---|
159 | | - return single_open(file, mvpp2_dbgfs_port_flow_hash_opt_show, |
---|
160 | | - inode->i_private); |
---|
161 | | -} |
---|
162 | | - |
---|
163 | | -static int mvpp2_dbgfs_port_flow_hash_opt_release(struct inode *inode, |
---|
164 | | - struct file *file) |
---|
165 | | -{ |
---|
166 | | - struct seq_file *seq = file->private_data; |
---|
167 | | - struct mvpp2_dbgfs_port_flow_entry *flow_entry = seq->private; |
---|
168 | | - |
---|
169 | | - kfree(flow_entry); |
---|
170 | | - return single_release(inode, file); |
---|
171 | | -} |
---|
172 | | - |
---|
173 | | -static const struct file_operations mvpp2_dbgfs_port_flow_hash_opt_fops = { |
---|
174 | | - .open = mvpp2_dbgfs_port_flow_hash_opt_open, |
---|
175 | | - .read = seq_read, |
---|
176 | | - .release = mvpp2_dbgfs_port_flow_hash_opt_release, |
---|
177 | | -}; |
---|
| 164 | +DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_hash_opt); |
---|
178 | 165 | |
---|
179 | 166 | static int mvpp2_dbgfs_port_flow_engine_show(struct seq_file *s, void *unused) |
---|
180 | 167 | { |
---|
181 | 168 | struct mvpp2_dbgfs_port_flow_entry *entry = s->private; |
---|
182 | 169 | struct mvpp2_port *port = entry->port; |
---|
183 | 170 | struct mvpp2_cls_flow_entry fe; |
---|
184 | | - struct mvpp2_cls_flow *f; |
---|
| 171 | + const struct mvpp2_cls_flow *f; |
---|
185 | 172 | int flow_index, engine; |
---|
186 | 173 | |
---|
187 | 174 | f = mvpp2_cls_flow_get(entry->dbg_fe->flow); |
---|
188 | 175 | if (!f) |
---|
189 | 176 | return -EINVAL; |
---|
190 | 177 | |
---|
191 | | - flow_index = MVPP2_PORT_FLOW_HASH_ENTRY(entry->port->id, f->flow_id); |
---|
| 178 | + flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id); |
---|
192 | 179 | |
---|
193 | 180 | mvpp2_cls_flow_read(port->priv, flow_index, &fe); |
---|
194 | 181 | |
---|
.. | .. |
---|
203 | 190 | |
---|
204 | 191 | static int mvpp2_dbgfs_flow_c2_hits_show(struct seq_file *s, void *unused) |
---|
205 | 192 | { |
---|
206 | | - struct mvpp2_port *port = s->private; |
---|
| 193 | + struct mvpp2_dbgfs_c2_entry *entry = s->private; |
---|
207 | 194 | u32 hits; |
---|
208 | 195 | |
---|
209 | | - hits = mvpp2_cls_c2_hit_count(port->priv, |
---|
210 | | - MVPP22_CLS_C2_RSS_ENTRY(port->id)); |
---|
| 196 | + hits = mvpp2_cls_c2_hit_count(entry->priv, entry->id); |
---|
211 | 197 | |
---|
212 | 198 | seq_printf(s, "%u\n", hits); |
---|
213 | 199 | |
---|
.. | .. |
---|
218 | 204 | |
---|
219 | 205 | static int mvpp2_dbgfs_flow_c2_rxq_show(struct seq_file *s, void *unused) |
---|
220 | 206 | { |
---|
221 | | - struct mvpp2_port *port = s->private; |
---|
| 207 | + struct mvpp2_dbgfs_c2_entry *entry = s->private; |
---|
222 | 208 | struct mvpp2_cls_c2_entry c2; |
---|
223 | 209 | u8 qh, ql; |
---|
224 | 210 | |
---|
225 | | - mvpp2_cls_c2_read(port->priv, MVPP22_CLS_C2_RSS_ENTRY(port->id), &c2); |
---|
| 211 | + mvpp2_cls_c2_read(entry->priv, entry->id, &c2); |
---|
226 | 212 | |
---|
227 | 213 | qh = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QHIGH_OFFS) & |
---|
228 | 214 | MVPP22_CLS_C2_ATTR0_QHIGH_MASK; |
---|
.. | .. |
---|
239 | 225 | |
---|
240 | 226 | static int mvpp2_dbgfs_flow_c2_enable_show(struct seq_file *s, void *unused) |
---|
241 | 227 | { |
---|
242 | | - struct mvpp2_port *port = s->private; |
---|
| 228 | + struct mvpp2_dbgfs_c2_entry *entry = s->private; |
---|
243 | 229 | struct mvpp2_cls_c2_entry c2; |
---|
244 | 230 | int enabled; |
---|
245 | 231 | |
---|
246 | | - mvpp2_cls_c2_read(port->priv, MVPP22_CLS_C2_RSS_ENTRY(port->id), &c2); |
---|
| 232 | + mvpp2_cls_c2_read(entry->priv, entry->id, &c2); |
---|
247 | 233 | |
---|
248 | 234 | enabled = !!(c2.attr[2] & MVPP22_CLS_C2_ATTR2_RSS_EN); |
---|
249 | 235 | |
---|
.. | .. |
---|
456 | 442 | return 0; |
---|
457 | 443 | } |
---|
458 | 444 | |
---|
459 | | -static int mvpp2_dbgfs_prs_valid_open(struct inode *inode, struct file *file) |
---|
460 | | -{ |
---|
461 | | - return single_open(file, mvpp2_dbgfs_prs_valid_show, inode->i_private); |
---|
462 | | -} |
---|
463 | | - |
---|
464 | | -static int mvpp2_dbgfs_prs_valid_release(struct inode *inode, struct file *file) |
---|
465 | | -{ |
---|
466 | | - struct seq_file *seq = file->private_data; |
---|
467 | | - struct mvpp2_dbgfs_prs_entry *entry = seq->private; |
---|
468 | | - |
---|
469 | | - kfree(entry); |
---|
470 | | - return single_release(inode, file); |
---|
471 | | -} |
---|
472 | | - |
---|
473 | | -static const struct file_operations mvpp2_dbgfs_prs_valid_fops = { |
---|
474 | | - .open = mvpp2_dbgfs_prs_valid_open, |
---|
475 | | - .read = seq_read, |
---|
476 | | - .release = mvpp2_dbgfs_prs_valid_release, |
---|
477 | | -}; |
---|
| 445 | +DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_valid); |
---|
478 | 446 | |
---|
479 | 447 | static int mvpp2_dbgfs_flow_port_init(struct dentry *parent, |
---|
480 | 448 | struct mvpp2_port *port, |
---|
.. | .. |
---|
484 | 452 | struct dentry *port_dir; |
---|
485 | 453 | |
---|
486 | 454 | port_dir = debugfs_create_dir(port->dev->name, parent); |
---|
487 | | - if (IS_ERR(port_dir)) |
---|
488 | | - return PTR_ERR(port_dir); |
---|
489 | 455 | |
---|
490 | | - /* This will be freed by 'hash_opts' release op */ |
---|
491 | | - port_entry = kmalloc(sizeof(*port_entry), GFP_KERNEL); |
---|
492 | | - if (!port_entry) |
---|
493 | | - return -ENOMEM; |
---|
| 456 | + port_entry = &port->priv->dbgfs_entries->port_flow_entries[port->id]; |
---|
494 | 457 | |
---|
495 | 458 | port_entry->port = port; |
---|
496 | 459 | port_entry->dbg_fe = entry; |
---|
.. | .. |
---|
515 | 478 | sprintf(flow_entry_name, "%02d", flow); |
---|
516 | 479 | |
---|
517 | 480 | flow_entry_dir = debugfs_create_dir(flow_entry_name, parent); |
---|
518 | | - if (!flow_entry_dir) |
---|
519 | | - return -ENOMEM; |
---|
520 | 481 | |
---|
521 | | - /* This will be freed by 'type' release op */ |
---|
522 | | - entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
---|
523 | | - if (!entry) |
---|
524 | | - return -ENOMEM; |
---|
| 482 | + entry = &priv->dbgfs_entries->flow_entries[flow]; |
---|
525 | 483 | |
---|
526 | 484 | entry->flow = flow; |
---|
527 | 485 | entry->priv = priv; |
---|
528 | | - |
---|
529 | | - debugfs_create_file("flow_hits", 0444, flow_entry_dir, entry, |
---|
530 | | - &mvpp2_dbgfs_flow_flt_hits_fops); |
---|
531 | 486 | |
---|
532 | 487 | debugfs_create_file("dec_hits", 0444, flow_entry_dir, entry, |
---|
533 | 488 | &mvpp2_dbgfs_flow_dec_hits_fops); |
---|
.. | .. |
---|
545 | 500 | if (ret) |
---|
546 | 501 | return ret; |
---|
547 | 502 | } |
---|
| 503 | + |
---|
548 | 504 | return 0; |
---|
549 | 505 | } |
---|
550 | 506 | |
---|
.. | .. |
---|
554 | 510 | int i, ret; |
---|
555 | 511 | |
---|
556 | 512 | flow_dir = debugfs_create_dir("flows", parent); |
---|
557 | | - if (!flow_dir) |
---|
558 | | - return -ENOMEM; |
---|
559 | 513 | |
---|
560 | | - for (i = 0; i < MVPP2_N_FLOWS; i++) { |
---|
| 514 | + for (i = 0; i < MVPP2_N_PRS_FLOWS; i++) { |
---|
561 | 515 | ret = mvpp2_dbgfs_flow_entry_init(flow_dir, priv, i); |
---|
562 | 516 | if (ret) |
---|
563 | 517 | return ret; |
---|
.. | .. |
---|
579 | 533 | sprintf(prs_entry_name, "%03d", tid); |
---|
580 | 534 | |
---|
581 | 535 | prs_entry_dir = debugfs_create_dir(prs_entry_name, parent); |
---|
582 | | - if (!prs_entry_dir) |
---|
583 | | - return -ENOMEM; |
---|
584 | 536 | |
---|
585 | | - /* The 'valid' entry's ops will free that */ |
---|
586 | | - entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
---|
587 | | - if (!entry) |
---|
588 | | - return -ENOMEM; |
---|
| 537 | + entry = &priv->dbgfs_entries->prs_entries[tid]; |
---|
589 | 538 | |
---|
590 | 539 | entry->tid = tid; |
---|
591 | 540 | entry->priv = priv; |
---|
.. | .. |
---|
609 | 558 | debugfs_create_file("hits", 0444, prs_entry_dir, entry, |
---|
610 | 559 | &mvpp2_dbgfs_prs_hits_fops); |
---|
611 | 560 | |
---|
| 561 | + debugfs_create_file("pmap", 0444, prs_entry_dir, entry, |
---|
| 562 | + &mvpp2_dbgfs_prs_pmap_fops); |
---|
| 563 | + |
---|
612 | 564 | return 0; |
---|
613 | 565 | } |
---|
614 | 566 | |
---|
.. | .. |
---|
618 | 570 | int i, ret; |
---|
619 | 571 | |
---|
620 | 572 | prs_dir = debugfs_create_dir("parser", parent); |
---|
621 | | - if (!prs_dir) |
---|
622 | | - return -ENOMEM; |
---|
623 | 573 | |
---|
624 | 574 | for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) { |
---|
625 | 575 | ret = mvpp2_dbgfs_prs_entry_init(prs_dir, priv, i); |
---|
| 576 | + if (ret) |
---|
| 577 | + return ret; |
---|
| 578 | + } |
---|
| 579 | + |
---|
| 580 | + return 0; |
---|
| 581 | +} |
---|
| 582 | + |
---|
| 583 | +static int mvpp2_dbgfs_c2_entry_init(struct dentry *parent, |
---|
| 584 | + struct mvpp2 *priv, int id) |
---|
| 585 | +{ |
---|
| 586 | + struct mvpp2_dbgfs_c2_entry *entry; |
---|
| 587 | + struct dentry *c2_entry_dir; |
---|
| 588 | + char c2_entry_name[10]; |
---|
| 589 | + |
---|
| 590 | + if (id >= MVPP22_CLS_C2_N_ENTRIES) |
---|
| 591 | + return -EINVAL; |
---|
| 592 | + |
---|
| 593 | + sprintf(c2_entry_name, "%03d", id); |
---|
| 594 | + |
---|
| 595 | + c2_entry_dir = debugfs_create_dir(c2_entry_name, parent); |
---|
| 596 | + if (!c2_entry_dir) |
---|
| 597 | + return -ENOMEM; |
---|
| 598 | + |
---|
| 599 | + entry = &priv->dbgfs_entries->c2_entries[id]; |
---|
| 600 | + |
---|
| 601 | + entry->id = id; |
---|
| 602 | + entry->priv = priv; |
---|
| 603 | + |
---|
| 604 | + debugfs_create_file("hits", 0444, c2_entry_dir, entry, |
---|
| 605 | + &mvpp2_dbgfs_flow_c2_hits_fops); |
---|
| 606 | + |
---|
| 607 | + debugfs_create_file("default_rxq", 0444, c2_entry_dir, entry, |
---|
| 608 | + &mvpp2_dbgfs_flow_c2_rxq_fops); |
---|
| 609 | + |
---|
| 610 | + debugfs_create_file("rss_enable", 0444, c2_entry_dir, entry, |
---|
| 611 | + &mvpp2_dbgfs_flow_c2_enable_fops); |
---|
| 612 | + |
---|
| 613 | + return 0; |
---|
| 614 | +} |
---|
| 615 | + |
---|
| 616 | +static int mvpp2_dbgfs_flow_tbl_entry_init(struct dentry *parent, |
---|
| 617 | + struct mvpp2 *priv, int id) |
---|
| 618 | +{ |
---|
| 619 | + struct mvpp2_dbgfs_flow_tbl_entry *entry; |
---|
| 620 | + struct dentry *flow_tbl_entry_dir; |
---|
| 621 | + char flow_tbl_entry_name[10]; |
---|
| 622 | + |
---|
| 623 | + if (id >= MVPP2_CLS_FLOWS_TBL_SIZE) |
---|
| 624 | + return -EINVAL; |
---|
| 625 | + |
---|
| 626 | + sprintf(flow_tbl_entry_name, "%03d", id); |
---|
| 627 | + |
---|
| 628 | + flow_tbl_entry_dir = debugfs_create_dir(flow_tbl_entry_name, parent); |
---|
| 629 | + if (!flow_tbl_entry_dir) |
---|
| 630 | + return -ENOMEM; |
---|
| 631 | + |
---|
| 632 | + entry = &priv->dbgfs_entries->flt_entries[id]; |
---|
| 633 | + |
---|
| 634 | + entry->id = id; |
---|
| 635 | + entry->priv = priv; |
---|
| 636 | + |
---|
| 637 | + debugfs_create_file("hits", 0444, flow_tbl_entry_dir, entry, |
---|
| 638 | + &mvpp2_dbgfs_flow_flt_hits_fops); |
---|
| 639 | + |
---|
| 640 | + return 0; |
---|
| 641 | +} |
---|
| 642 | + |
---|
| 643 | +static int mvpp2_dbgfs_cls_init(struct dentry *parent, struct mvpp2 *priv) |
---|
| 644 | +{ |
---|
| 645 | + struct dentry *cls_dir, *c2_dir, *flow_tbl_dir; |
---|
| 646 | + int i, ret; |
---|
| 647 | + |
---|
| 648 | + cls_dir = debugfs_create_dir("classifier", parent); |
---|
| 649 | + if (!cls_dir) |
---|
| 650 | + return -ENOMEM; |
---|
| 651 | + |
---|
| 652 | + c2_dir = debugfs_create_dir("c2", cls_dir); |
---|
| 653 | + if (!c2_dir) |
---|
| 654 | + return -ENOMEM; |
---|
| 655 | + |
---|
| 656 | + for (i = 0; i < MVPP22_CLS_C2_N_ENTRIES; i++) { |
---|
| 657 | + ret = mvpp2_dbgfs_c2_entry_init(c2_dir, priv, i); |
---|
| 658 | + if (ret) |
---|
| 659 | + return ret; |
---|
| 660 | + } |
---|
| 661 | + |
---|
| 662 | + flow_tbl_dir = debugfs_create_dir("flow_table", cls_dir); |
---|
| 663 | + if (!flow_tbl_dir) |
---|
| 664 | + return -ENOMEM; |
---|
| 665 | + |
---|
| 666 | + for (i = 0; i < MVPP2_CLS_FLOWS_TBL_SIZE; i++) { |
---|
| 667 | + ret = mvpp2_dbgfs_flow_tbl_entry_init(flow_tbl_dir, priv, i); |
---|
626 | 668 | if (ret) |
---|
627 | 669 | return ret; |
---|
628 | 670 | } |
---|
.. | .. |
---|
636 | 678 | struct dentry *port_dir; |
---|
637 | 679 | |
---|
638 | 680 | port_dir = debugfs_create_dir(port->dev->name, parent); |
---|
639 | | - if (IS_ERR(port_dir)) |
---|
640 | | - return PTR_ERR(port_dir); |
---|
641 | 681 | |
---|
642 | 682 | debugfs_create_file("parser_entries", 0444, port_dir, port, |
---|
643 | 683 | &mvpp2_dbgfs_port_parser_fops); |
---|
.. | .. |
---|
648 | 688 | debugfs_create_file("vid_filter", 0444, port_dir, port, |
---|
649 | 689 | &mvpp2_dbgfs_port_vid_fops); |
---|
650 | 690 | |
---|
651 | | - debugfs_create_file("c2_hits", 0444, port_dir, port, |
---|
652 | | - &mvpp2_dbgfs_flow_c2_hits_fops); |
---|
653 | | - |
---|
654 | | - debugfs_create_file("default_rxq", 0444, port_dir, port, |
---|
655 | | - &mvpp2_dbgfs_flow_c2_rxq_fops); |
---|
656 | | - |
---|
657 | | - debugfs_create_file("rss_enable", 0444, port_dir, port, |
---|
658 | | - &mvpp2_dbgfs_flow_c2_enable_fops); |
---|
659 | | - |
---|
660 | 691 | return 0; |
---|
| 692 | +} |
---|
| 693 | + |
---|
| 694 | +static struct dentry *mvpp2_root; |
---|
| 695 | + |
---|
| 696 | +void mvpp2_dbgfs_exit(void) |
---|
| 697 | +{ |
---|
| 698 | + debugfs_remove(mvpp2_root); |
---|
661 | 699 | } |
---|
662 | 700 | |
---|
663 | 701 | void mvpp2_dbgfs_cleanup(struct mvpp2 *priv) |
---|
664 | 702 | { |
---|
665 | 703 | debugfs_remove_recursive(priv->dbgfs_dir); |
---|
| 704 | + |
---|
| 705 | + kfree(priv->dbgfs_entries); |
---|
666 | 706 | } |
---|
667 | 707 | |
---|
668 | 708 | void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name) |
---|
669 | 709 | { |
---|
670 | | - struct dentry *mvpp2_dir, *mvpp2_root; |
---|
| 710 | + struct dentry *mvpp2_dir; |
---|
671 | 711 | int ret, i; |
---|
672 | 712 | |
---|
673 | | - mvpp2_root = debugfs_lookup(MVPP2_DRIVER_NAME, NULL); |
---|
674 | | - if (!mvpp2_root) { |
---|
| 713 | + if (!mvpp2_root) |
---|
675 | 714 | mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL); |
---|
676 | | - if (IS_ERR(mvpp2_root)) |
---|
677 | | - return; |
---|
678 | | - } |
---|
679 | 715 | |
---|
680 | 716 | mvpp2_dir = debugfs_create_dir(name, mvpp2_root); |
---|
681 | | - if (IS_ERR(mvpp2_dir)) |
---|
682 | | - return; |
---|
683 | 717 | |
---|
684 | 718 | priv->dbgfs_dir = mvpp2_dir; |
---|
| 719 | + priv->dbgfs_entries = kzalloc(sizeof(*priv->dbgfs_entries), GFP_KERNEL); |
---|
| 720 | + if (!priv->dbgfs_entries) |
---|
| 721 | + goto err; |
---|
685 | 722 | |
---|
686 | 723 | ret = mvpp2_dbgfs_prs_init(mvpp2_dir, priv); |
---|
687 | 724 | if (ret) |
---|
688 | 725 | goto err; |
---|
689 | 726 | |
---|
| 727 | + ret = mvpp2_dbgfs_cls_init(mvpp2_dir, priv); |
---|
| 728 | + if (ret) |
---|
| 729 | + goto err; |
---|
| 730 | + |
---|
690 | 731 | for (i = 0; i < priv->port_count; i++) { |
---|
691 | 732 | ret = mvpp2_dbgfs_port_init(mvpp2_dir, priv->port_list[i]); |
---|
692 | 733 | if (ret) |
---|