root/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mvpp2_dbgfs_flow_flt_hits_show
  2. mvpp2_dbgfs_flow_dec_hits_show
  3. mvpp2_dbgfs_flow_type_show
  4. mvpp2_dbgfs_flow_id_show
  5. mvpp2_dbgfs_port_flow_hash_opt_show
  6. mvpp2_dbgfs_port_flow_engine_show
  7. mvpp2_dbgfs_flow_c2_hits_show
  8. mvpp2_dbgfs_flow_c2_rxq_show
  9. mvpp2_dbgfs_flow_c2_enable_show
  10. mvpp2_dbgfs_port_vid_show
  11. mvpp2_dbgfs_port_parser_show
  12. mvpp2_dbgfs_filter_show
  13. mvpp2_dbgfs_prs_lu_show
  14. mvpp2_dbgfs_prs_pmap_show
  15. mvpp2_dbgfs_prs_ai_show
  16. mvpp2_dbgfs_prs_hdata_show
  17. mvpp2_dbgfs_prs_sram_show
  18. mvpp2_dbgfs_prs_hits_show
  19. mvpp2_dbgfs_prs_valid_show
  20. mvpp2_dbgfs_flow_port_init
  21. mvpp2_dbgfs_flow_entry_init
  22. mvpp2_dbgfs_flow_init
  23. mvpp2_dbgfs_prs_entry_init
  24. mvpp2_dbgfs_prs_init
  25. mvpp2_dbgfs_c2_entry_init
  26. mvpp2_dbgfs_flow_tbl_entry_init
  27. mvpp2_dbgfs_cls_init
  28. mvpp2_dbgfs_port_init
  29. mvpp2_dbgfs_cleanup
  30. mvpp2_dbgfs_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Driver for Marvell PPv2 network controller for Armada 375 SoC.
   4  *
   5  * Copyright (C) 2018 Marvell
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/slab.h>
  10 #include <linux/debugfs.h>
  11 
  12 #include "mvpp2.h"
  13 #include "mvpp2_prs.h"
  14 #include "mvpp2_cls.h"
  15 
  16 struct mvpp2_dbgfs_prs_entry {
  17         int tid;
  18         struct mvpp2 *priv;
  19 };
  20 
  21 struct mvpp2_dbgfs_c2_entry {
  22         int id;
  23         struct mvpp2 *priv;
  24 };
  25 
  26 struct mvpp2_dbgfs_flow_entry {
  27         int flow;
  28         struct mvpp2 *priv;
  29 };
  30 
  31 struct mvpp2_dbgfs_flow_tbl_entry {
  32         int id;
  33         struct mvpp2 *priv;
  34 };
  35 
  36 struct mvpp2_dbgfs_port_flow_entry {
  37         struct mvpp2_port *port;
  38         struct mvpp2_dbgfs_flow_entry *dbg_fe;
  39 };
  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 
  58 static int mvpp2_dbgfs_flow_flt_hits_show(struct seq_file *s, void *unused)
  59 {
  60         struct mvpp2_dbgfs_flow_tbl_entry *entry = s->private;
  61 
  62         u32 hits = mvpp2_cls_flow_hits(entry->priv, entry->id);
  63 
  64         seq_printf(s, "%u\n", hits);
  65 
  66         return 0;
  67 }
  68 
  69 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_flt_hits);
  70 
  71 static int mvpp2_dbgfs_flow_dec_hits_show(struct seq_file *s, void *unused)
  72 {
  73         struct mvpp2_dbgfs_flow_entry *entry = s->private;
  74 
  75         u32 hits = mvpp2_cls_lookup_hits(entry->priv, entry->flow);
  76 
  77         seq_printf(s, "%u\n", hits);
  78 
  79         return 0;
  80 }
  81 
  82 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_dec_hits);
  83 
  84 static int mvpp2_dbgfs_flow_type_show(struct seq_file *s, void *unused)
  85 {
  86         struct mvpp2_dbgfs_flow_entry *entry = s->private;
  87         const struct mvpp2_cls_flow *f;
  88         const char *flow_name;
  89 
  90         f = mvpp2_cls_flow_get(entry->flow);
  91         if (!f)
  92                 return -EINVAL;
  93 
  94         switch (f->flow_type) {
  95         case IPV4_FLOW:
  96                 flow_name = "ipv4";
  97                 break;
  98         case IPV6_FLOW:
  99                 flow_name = "ipv6";
 100                 break;
 101         case TCP_V4_FLOW:
 102                 flow_name = "tcp4";
 103                 break;
 104         case TCP_V6_FLOW:
 105                 flow_name = "tcp6";
 106                 break;
 107         case UDP_V4_FLOW:
 108                 flow_name = "udp4";
 109                 break;
 110         case UDP_V6_FLOW:
 111                 flow_name = "udp6";
 112                 break;
 113         default:
 114                 flow_name = "other";
 115         }
 116 
 117         seq_printf(s, "%s\n", flow_name);
 118 
 119         return 0;
 120 }
 121 
 122 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_type);
 123 
 124 static int mvpp2_dbgfs_flow_id_show(struct seq_file *s, void *unused)
 125 {
 126         const struct mvpp2_dbgfs_flow_entry *entry = s->private;
 127         const struct mvpp2_cls_flow *f;
 128 
 129         f = mvpp2_cls_flow_get(entry->flow);
 130         if (!f)
 131                 return -EINVAL;
 132 
 133         seq_printf(s, "%d\n", f->flow_id);
 134 
 135         return 0;
 136 }
 137 
 138 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_id);
 139 
 140 static int mvpp2_dbgfs_port_flow_hash_opt_show(struct seq_file *s, void *unused)
 141 {
 142         struct mvpp2_dbgfs_port_flow_entry *entry = s->private;
 143         struct mvpp2_port *port = entry->port;
 144         struct mvpp2_cls_flow_entry fe;
 145         const struct mvpp2_cls_flow *f;
 146         int flow_index;
 147         u16 hash_opts;
 148 
 149         f = mvpp2_cls_flow_get(entry->dbg_fe->flow);
 150         if (!f)
 151                 return -EINVAL;
 152 
 153         flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);
 154 
 155         mvpp2_cls_flow_read(port->priv, flow_index, &fe);
 156 
 157         hash_opts = mvpp2_flow_get_hek_fields(&fe);
 158 
 159         seq_printf(s, "0x%04x\n", hash_opts);
 160 
 161         return 0;
 162 }
 163 
 164 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_hash_opt);
 165 
 166 static int mvpp2_dbgfs_port_flow_engine_show(struct seq_file *s, void *unused)
 167 {
 168         struct mvpp2_dbgfs_port_flow_entry *entry = s->private;
 169         struct mvpp2_port *port = entry->port;
 170         struct mvpp2_cls_flow_entry fe;
 171         const struct mvpp2_cls_flow *f;
 172         int flow_index, engine;
 173 
 174         f = mvpp2_cls_flow_get(entry->dbg_fe->flow);
 175         if (!f)
 176                 return -EINVAL;
 177 
 178         flow_index = MVPP2_CLS_FLT_HASH_ENTRY(entry->port->id, f->flow_id);
 179 
 180         mvpp2_cls_flow_read(port->priv, flow_index, &fe);
 181 
 182         engine = mvpp2_cls_flow_eng_get(&fe);
 183 
 184         seq_printf(s, "%d\n", engine);
 185 
 186         return 0;
 187 }
 188 
 189 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_flow_engine);
 190 
 191 static int mvpp2_dbgfs_flow_c2_hits_show(struct seq_file *s, void *unused)
 192 {
 193         struct mvpp2_dbgfs_c2_entry *entry = s->private;
 194         u32 hits;
 195 
 196         hits = mvpp2_cls_c2_hit_count(entry->priv, entry->id);
 197 
 198         seq_printf(s, "%u\n", hits);
 199 
 200         return 0;
 201 }
 202 
 203 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_hits);
 204 
 205 static int mvpp2_dbgfs_flow_c2_rxq_show(struct seq_file *s, void *unused)
 206 {
 207         struct mvpp2_dbgfs_c2_entry *entry = s->private;
 208         struct mvpp2_cls_c2_entry c2;
 209         u8 qh, ql;
 210 
 211         mvpp2_cls_c2_read(entry->priv, entry->id, &c2);
 212 
 213         qh = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QHIGH_OFFS) &
 214              MVPP22_CLS_C2_ATTR0_QHIGH_MASK;
 215 
 216         ql = (c2.attr[0] >> MVPP22_CLS_C2_ATTR0_QLOW_OFFS) &
 217              MVPP22_CLS_C2_ATTR0_QLOW_MASK;
 218 
 219         seq_printf(s, "%d\n", (qh << 3 | ql));
 220 
 221         return 0;
 222 }
 223 
 224 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_rxq);
 225 
 226 static int mvpp2_dbgfs_flow_c2_enable_show(struct seq_file *s, void *unused)
 227 {
 228         struct mvpp2_dbgfs_c2_entry *entry = s->private;
 229         struct mvpp2_cls_c2_entry c2;
 230         int enabled;
 231 
 232         mvpp2_cls_c2_read(entry->priv, entry->id, &c2);
 233 
 234         enabled = !!(c2.attr[2] & MVPP22_CLS_C2_ATTR2_RSS_EN);
 235 
 236         seq_printf(s, "%d\n", enabled);
 237 
 238         return 0;
 239 }
 240 
 241 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_flow_c2_enable);
 242 
 243 static int mvpp2_dbgfs_port_vid_show(struct seq_file *s, void *unused)
 244 {
 245         struct mvpp2_port *port = s->private;
 246         unsigned char byte[2], enable[2];
 247         struct mvpp2 *priv = port->priv;
 248         struct mvpp2_prs_entry pe;
 249         unsigned long pmap;
 250         u16 rvid;
 251         int tid;
 252 
 253         for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);
 254              tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {
 255                 mvpp2_prs_init_from_hw(priv, &pe, tid);
 256 
 257                 pmap = mvpp2_prs_tcam_port_map_get(&pe);
 258 
 259                 if (!priv->prs_shadow[tid].valid)
 260                         continue;
 261 
 262                 if (!test_bit(port->id, &pmap))
 263                         continue;
 264 
 265                 mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);
 266                 mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);
 267 
 268                 rvid = ((byte[0] & 0xf) << 8) + byte[1];
 269 
 270                 seq_printf(s, "%u\n", rvid);
 271         }
 272 
 273         return 0;
 274 }
 275 
 276 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_vid);
 277 
 278 static int mvpp2_dbgfs_port_parser_show(struct seq_file *s, void *unused)
 279 {
 280         struct mvpp2_port *port = s->private;
 281         struct mvpp2 *priv = port->priv;
 282         struct mvpp2_prs_entry pe;
 283         unsigned long pmap;
 284         int i;
 285 
 286         for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {
 287                 mvpp2_prs_init_from_hw(port->priv, &pe, i);
 288 
 289                 pmap = mvpp2_prs_tcam_port_map_get(&pe);
 290                 if (priv->prs_shadow[i].valid && test_bit(port->id, &pmap))
 291                         seq_printf(s, "%03d\n", i);
 292         }
 293 
 294         return 0;
 295 }
 296 
 297 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_port_parser);
 298 
 299 static int mvpp2_dbgfs_filter_show(struct seq_file *s, void *unused)
 300 {
 301         struct mvpp2_port *port = s->private;
 302         struct mvpp2 *priv = port->priv;
 303         struct mvpp2_prs_entry pe;
 304         unsigned long pmap;
 305         int index, tid;
 306 
 307         for (tid = MVPP2_PE_MAC_RANGE_START;
 308              tid <= MVPP2_PE_MAC_RANGE_END; tid++) {
 309                 unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];
 310 
 311                 if (!priv->prs_shadow[tid].valid ||
 312                     priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC ||
 313                     priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)
 314                         continue;
 315 
 316                 mvpp2_prs_init_from_hw(priv, &pe, tid);
 317 
 318                 pmap = mvpp2_prs_tcam_port_map_get(&pe);
 319 
 320                 /* We only want entries active on this port */
 321                 if (!test_bit(port->id, &pmap))
 322                         continue;
 323 
 324                 /* Read mac addr from entry */
 325                 for (index = 0; index < ETH_ALEN; index++)
 326                         mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index],
 327                                                      &da_mask[index]);
 328 
 329                 seq_printf(s, "%pM\n", da);
 330         }
 331 
 332         return 0;
 333 }
 334 
 335 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_filter);
 336 
 337 static int mvpp2_dbgfs_prs_lu_show(struct seq_file *s, void *unused)
 338 {
 339         struct mvpp2_dbgfs_prs_entry *entry = s->private;
 340         struct mvpp2 *priv = entry->priv;
 341 
 342         seq_printf(s, "%x\n", priv->prs_shadow[entry->tid].lu);
 343 
 344         return 0;
 345 }
 346 
 347 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_lu);
 348 
 349 static int mvpp2_dbgfs_prs_pmap_show(struct seq_file *s, void *unused)
 350 {
 351         struct mvpp2_dbgfs_prs_entry *entry = s->private;
 352         struct mvpp2_prs_entry pe;
 353         unsigned int pmap;
 354 
 355         mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
 356 
 357         pmap = mvpp2_prs_tcam_port_map_get(&pe);
 358         pmap &= MVPP2_PRS_PORT_MASK;
 359 
 360         seq_printf(s, "%02x\n", pmap);
 361 
 362         return 0;
 363 }
 364 
 365 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_pmap);
 366 
 367 static int mvpp2_dbgfs_prs_ai_show(struct seq_file *s, void *unused)
 368 {
 369         struct mvpp2_dbgfs_prs_entry *entry = s->private;
 370         struct mvpp2_prs_entry pe;
 371         unsigned char ai, ai_mask;
 372 
 373         mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
 374 
 375         ai = pe.tcam[MVPP2_PRS_TCAM_AI_WORD] & MVPP2_PRS_AI_MASK;
 376         ai_mask = (pe.tcam[MVPP2_PRS_TCAM_AI_WORD] >> 16) & MVPP2_PRS_AI_MASK;
 377 
 378         seq_printf(s, "%02x %02x\n", ai, ai_mask);
 379 
 380         return 0;
 381 }
 382 
 383 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_ai);
 384 
 385 static int mvpp2_dbgfs_prs_hdata_show(struct seq_file *s, void *unused)
 386 {
 387         struct mvpp2_dbgfs_prs_entry *entry = s->private;
 388         struct mvpp2_prs_entry pe;
 389         unsigned char data[8], mask[8];
 390         int i;
 391 
 392         mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
 393 
 394         for (i = 0; i < 8; i++)
 395                 mvpp2_prs_tcam_data_byte_get(&pe, i, &data[i], &mask[i]);
 396 
 397         seq_printf(s, "%*phN %*phN\n", 8, data, 8, mask);
 398 
 399         return 0;
 400 }
 401 
 402 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hdata);
 403 
 404 static int mvpp2_dbgfs_prs_sram_show(struct seq_file *s, void *unused)
 405 {
 406         struct mvpp2_dbgfs_prs_entry *entry = s->private;
 407         struct mvpp2_prs_entry pe;
 408 
 409         mvpp2_prs_init_from_hw(entry->priv, &pe, entry->tid);
 410 
 411         seq_printf(s, "%*phN\n", 14, pe.sram);
 412 
 413         return 0;
 414 }
 415 
 416 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_sram);
 417 
 418 static int mvpp2_dbgfs_prs_hits_show(struct seq_file *s, void *unused)
 419 {
 420         struct mvpp2_dbgfs_prs_entry *entry = s->private;
 421         int val;
 422 
 423         val = mvpp2_prs_hits(entry->priv, entry->tid);
 424         if (val < 0)
 425                 return val;
 426 
 427         seq_printf(s, "%d\n", val);
 428 
 429         return 0;
 430 }
 431 
 432 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_hits);
 433 
 434 static int mvpp2_dbgfs_prs_valid_show(struct seq_file *s, void *unused)
 435 {
 436         struct mvpp2_dbgfs_prs_entry *entry = s->private;
 437         struct mvpp2 *priv = entry->priv;
 438         int tid = entry->tid;
 439 
 440         seq_printf(s, "%d\n", priv->prs_shadow[tid].valid ? 1 : 0);
 441 
 442         return 0;
 443 }
 444 
 445 DEFINE_SHOW_ATTRIBUTE(mvpp2_dbgfs_prs_valid);
 446 
 447 static int mvpp2_dbgfs_flow_port_init(struct dentry *parent,
 448                                       struct mvpp2_port *port,
 449                                       struct mvpp2_dbgfs_flow_entry *entry)
 450 {
 451         struct mvpp2_dbgfs_port_flow_entry *port_entry;
 452         struct dentry *port_dir;
 453 
 454         port_dir = debugfs_create_dir(port->dev->name, parent);
 455 
 456         port_entry = &port->priv->dbgfs_entries->port_flow_entries[port->id];
 457 
 458         port_entry->port = port;
 459         port_entry->dbg_fe = entry;
 460 
 461         debugfs_create_file("hash_opts", 0444, port_dir, port_entry,
 462                             &mvpp2_dbgfs_port_flow_hash_opt_fops);
 463 
 464         debugfs_create_file("engine", 0444, port_dir, port_entry,
 465                             &mvpp2_dbgfs_port_flow_engine_fops);
 466 
 467         return 0;
 468 }
 469 
 470 static int mvpp2_dbgfs_flow_entry_init(struct dentry *parent,
 471                                        struct mvpp2 *priv, int flow)
 472 {
 473         struct mvpp2_dbgfs_flow_entry *entry;
 474         struct dentry *flow_entry_dir;
 475         char flow_entry_name[10];
 476         int i, ret;
 477 
 478         sprintf(flow_entry_name, "%02d", flow);
 479 
 480         flow_entry_dir = debugfs_create_dir(flow_entry_name, parent);
 481 
 482         entry = &priv->dbgfs_entries->flow_entries[flow];
 483 
 484         entry->flow = flow;
 485         entry->priv = priv;
 486 
 487         debugfs_create_file("dec_hits", 0444, flow_entry_dir, entry,
 488                             &mvpp2_dbgfs_flow_dec_hits_fops);
 489 
 490         debugfs_create_file("type", 0444, flow_entry_dir, entry,
 491                             &mvpp2_dbgfs_flow_type_fops);
 492 
 493         debugfs_create_file("id", 0444, flow_entry_dir, entry,
 494                             &mvpp2_dbgfs_flow_id_fops);
 495 
 496         /* Create entry for each port */
 497         for (i = 0; i < priv->port_count; i++) {
 498                 ret = mvpp2_dbgfs_flow_port_init(flow_entry_dir,
 499                                                  priv->port_list[i], entry);
 500                 if (ret)
 501                         return ret;
 502         }
 503 
 504         return 0;
 505 }
 506 
 507 static int mvpp2_dbgfs_flow_init(struct dentry *parent, struct mvpp2 *priv)
 508 {
 509         struct dentry *flow_dir;
 510         int i, ret;
 511 
 512         flow_dir = debugfs_create_dir("flows", parent);
 513 
 514         for (i = 0; i < MVPP2_N_PRS_FLOWS; i++) {
 515                 ret = mvpp2_dbgfs_flow_entry_init(flow_dir, priv, i);
 516                 if (ret)
 517                         return ret;
 518         }
 519 
 520         return 0;
 521 }
 522 
 523 static int mvpp2_dbgfs_prs_entry_init(struct dentry *parent,
 524                                       struct mvpp2 *priv, int tid)
 525 {
 526         struct mvpp2_dbgfs_prs_entry *entry;
 527         struct dentry *prs_entry_dir;
 528         char prs_entry_name[10];
 529 
 530         if (tid >= MVPP2_PRS_TCAM_SRAM_SIZE)
 531                 return -EINVAL;
 532 
 533         sprintf(prs_entry_name, "%03d", tid);
 534 
 535         prs_entry_dir = debugfs_create_dir(prs_entry_name, parent);
 536 
 537         entry = &priv->dbgfs_entries->prs_entries[tid];
 538 
 539         entry->tid = tid;
 540         entry->priv = priv;
 541 
 542         /* Create each attr */
 543         debugfs_create_file("sram", 0444, prs_entry_dir, entry,
 544                             &mvpp2_dbgfs_prs_sram_fops);
 545 
 546         debugfs_create_file("valid", 0644, prs_entry_dir, entry,
 547                             &mvpp2_dbgfs_prs_valid_fops);
 548 
 549         debugfs_create_file("lookup_id", 0644, prs_entry_dir, entry,
 550                             &mvpp2_dbgfs_prs_lu_fops);
 551 
 552         debugfs_create_file("ai", 0644, prs_entry_dir, entry,
 553                             &mvpp2_dbgfs_prs_ai_fops);
 554 
 555         debugfs_create_file("header_data", 0644, prs_entry_dir, entry,
 556                             &mvpp2_dbgfs_prs_hdata_fops);
 557 
 558         debugfs_create_file("hits", 0444, prs_entry_dir, entry,
 559                             &mvpp2_dbgfs_prs_hits_fops);
 560 
 561         debugfs_create_file("pmap", 0444, prs_entry_dir, entry,
 562                              &mvpp2_dbgfs_prs_pmap_fops);
 563 
 564         return 0;
 565 }
 566 
 567 static int mvpp2_dbgfs_prs_init(struct dentry *parent, struct mvpp2 *priv)
 568 {
 569         struct dentry *prs_dir;
 570         int i, ret;
 571 
 572         prs_dir = debugfs_create_dir("parser", parent);
 573 
 574         for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) {
 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);
 668                 if (ret)
 669                         return ret;
 670         }
 671 
 672         return 0;
 673 }
 674 
 675 static int mvpp2_dbgfs_port_init(struct dentry *parent,
 676                                  struct mvpp2_port *port)
 677 {
 678         struct dentry *port_dir;
 679 
 680         port_dir = debugfs_create_dir(port->dev->name, parent);
 681 
 682         debugfs_create_file("parser_entries", 0444, port_dir, port,
 683                             &mvpp2_dbgfs_port_parser_fops);
 684 
 685         debugfs_create_file("mac_filter", 0444, port_dir, port,
 686                             &mvpp2_dbgfs_filter_fops);
 687 
 688         debugfs_create_file("vid_filter", 0444, port_dir, port,
 689                             &mvpp2_dbgfs_port_vid_fops);
 690 
 691         return 0;
 692 }
 693 
 694 void mvpp2_dbgfs_cleanup(struct mvpp2 *priv)
 695 {
 696         debugfs_remove_recursive(priv->dbgfs_dir);
 697 
 698         kfree(priv->dbgfs_entries);
 699 }
 700 
 701 void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name)
 702 {
 703         struct dentry *mvpp2_dir, *mvpp2_root;
 704         int ret, i;
 705 
 706         mvpp2_root = debugfs_lookup(MVPP2_DRIVER_NAME, NULL);
 707         if (!mvpp2_root)
 708                 mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL);
 709 
 710         mvpp2_dir = debugfs_create_dir(name, mvpp2_root);
 711 
 712         priv->dbgfs_dir = mvpp2_dir;
 713         priv->dbgfs_entries = kzalloc(sizeof(*priv->dbgfs_entries), GFP_KERNEL);
 714         if (!priv->dbgfs_entries)
 715                 goto err;
 716 
 717         ret = mvpp2_dbgfs_prs_init(mvpp2_dir, priv);
 718         if (ret)
 719                 goto err;
 720 
 721         ret = mvpp2_dbgfs_cls_init(mvpp2_dir, priv);
 722         if (ret)
 723                 goto err;
 724 
 725         for (i = 0; i < priv->port_count; i++) {
 726                 ret = mvpp2_dbgfs_port_init(mvpp2_dir, priv->port_list[i]);
 727                 if (ret)
 728                         goto err;
 729         }
 730 
 731         ret = mvpp2_dbgfs_flow_init(mvpp2_dir, priv);
 732         if (ret)
 733                 goto err;
 734 
 735         return;
 736 err:
 737         mvpp2_dbgfs_cleanup(priv);
 738 }

/* [<][>][^][v][top][bottom][index][help] */