| .. | .. |
|---|
| 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) |
|---|