1 // SPDX-License-Identifier: GPL-2.0+ 2 /* Microchip VCAP API debug file system support 3 * 4 * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. 5 * 6 */ 7 8 #include "vcap_api_private.h" 9 #include "vcap_api_debugfs.h" 10 11 struct vcap_admin_debugfs_info { 12 struct vcap_control *vctrl; 13 struct vcap_admin *admin; 14 }; 15 16 struct vcap_port_debugfs_info { 17 struct vcap_control *vctrl; 18 struct net_device *ndev; 19 }; 20 21 static bool vcap_bitarray_zero(int width, u8 *value) 22 { 23 int bytes = DIV_ROUND_UP(width, BITS_PER_BYTE); 24 u8 total = 0, bmask = 0xff; 25 int rwidth = width; 26 int idx; 27 28 for (idx = 0; idx < bytes; ++idx, rwidth -= BITS_PER_BYTE) { 29 if (rwidth && rwidth < BITS_PER_BYTE) 30 bmask = (1 << rwidth) - 1; 31 total += value[idx] & bmask; 32 } 33 return total == 0; 34 } 35 36 static bool vcap_get_bit(u32 *stream, struct vcap_stream_iter *itr) 37 { 38 u32 mask = BIT(itr->reg_bitpos); 39 u32 *p = &stream[itr->reg_idx]; 40 41 return !!(*p & mask); 42 } 43 44 static void vcap_decode_field(u32 *stream, struct vcap_stream_iter *itr, 45 int width, u8 *value) 46 { 47 int idx; 48 49 /* Loop over the field value bits and get the field bits and 50 * set them in the output value byte array 51 */ 52 for (idx = 0; idx < width; idx++) { 53 u8 bidx = idx & 0x7; 54 55 /* Decode one field value bit */ 56 if (vcap_get_bit(stream, itr)) 57 *value |= 1 << bidx; 58 vcap_iter_next(itr); 59 if (bidx == 7) 60 value++; 61 } 62 } 63 64 /* Verify that the typegroup bits have the correct values */ 65 static int vcap_verify_typegroups(u32 *stream, int sw_width, 66 const struct vcap_typegroup *tgt, bool mask, 67 int sw_max) 68 { 69 struct vcap_stream_iter iter; 70 int sw_cnt, idx; 71 72 vcap_iter_set(&iter, sw_width, tgt, 0); 73 sw_cnt = 0; 74 while (iter.tg->width) { 75 u32 value = 0; 76 u32 tg_value = iter.tg->value; 77 78 if (mask) 79 tg_value = (1 << iter.tg->width) - 1; 80 /* Set position to current typegroup bit */ 81 iter.offset = iter.tg->offset; 82 vcap_iter_update(&iter); 83 for (idx = 0; idx < iter.tg->width; idx++) { 84 /* Decode one typegroup bit */ 85 if (vcap_get_bit(stream, &iter)) 86 value |= 1 << idx; 87 iter.offset++; 88 vcap_iter_update(&iter); 89 } 90 if (value != tg_value) 91 return -EINVAL; 92 iter.tg++; /* next typegroup */ 93 sw_cnt++; 94 /* Stop checking more typegroups */ 95 if (sw_max && sw_cnt >= sw_max) 96 break; 97 } 98 return 0; 99 } 100 101 /* Find the subword width of the key typegroup that matches the stream data */ 102 static int vcap_find_keystream_typegroup_sw(struct vcap_control *vctrl, 103 enum vcap_type vt, u32 *stream, 104 bool mask, int sw_max) 105 { 106 const struct vcap_typegroup **tgt; 107 int sw_idx, res; 108 109 tgt = vctrl->vcaps[vt].keyfield_set_typegroups; 110 /* Try the longest subword match first */ 111 for (sw_idx = vctrl->vcaps[vt].sw_count; sw_idx >= 0; sw_idx--) { 112 if (!tgt[sw_idx]) 113 continue; 114 115 res = vcap_verify_typegroups(stream, vctrl->vcaps[vt].sw_width, 116 tgt[sw_idx], mask, sw_max); 117 if (res == 0) 118 return sw_idx; 119 } 120 return -EINVAL; 121 } 122 123 /* Find the subword width of the action typegroup that matches the stream data 124 */ 125 static int vcap_find_actionstream_typegroup_sw(struct vcap_control *vctrl, 126 enum vcap_type vt, u32 *stream, 127 int sw_max) 128 { 129 const struct vcap_typegroup **tgt; 130 int sw_idx, res; 131 132 tgt = vctrl->vcaps[vt].actionfield_set_typegroups; 133 /* Try the longest subword match first */ 134 for (sw_idx = vctrl->vcaps[vt].sw_count; sw_idx >= 0; sw_idx--) { 135 if (!tgt[sw_idx]) 136 continue; 137 res = vcap_verify_typegroups(stream, vctrl->vcaps[vt].act_width, 138 tgt[sw_idx], false, sw_max); 139 if (res == 0) 140 return sw_idx; 141 } 142 return -EINVAL; 143 } 144 145 /* Verify that the type id in the stream matches the type id of the keyset */ 146 static bool vcap_verify_keystream_keyset(struct vcap_control *vctrl, 147 enum vcap_type vt, 148 u32 *keystream, 149 u32 *mskstream, 150 enum vcap_keyfield_set keyset) 151 { 152 const struct vcap_info *vcap = &vctrl->vcaps[vt]; 153 const struct vcap_field *typefld; 154 const struct vcap_typegroup *tgt; 155 const struct vcap_field *fields; 156 struct vcap_stream_iter iter; 157 const struct vcap_set *info; 158 u32 value = 0; 159 u32 mask = 0; 160 161 if (vcap_keyfield_count(vctrl, vt, keyset) == 0) 162 return false; 163 164 info = vcap_keyfieldset(vctrl, vt, keyset); 165 /* Check that the keyset is valid */ 166 if (!info) 167 return false; 168 169 /* a type_id of value -1 means that there is no type field */ 170 if (info->type_id == (u8)-1) 171 return true; 172 173 /* Get a valid typegroup for the specific keyset */ 174 tgt = vcap_keyfield_typegroup(vctrl, vt, keyset); 175 if (!tgt) 176 return false; 177 178 fields = vcap_keyfields(vctrl, vt, keyset); 179 if (!fields) 180 return false; 181 182 typefld = &fields[VCAP_KF_TYPE]; 183 vcap_iter_init(&iter, vcap->sw_width, tgt, typefld->offset); 184 vcap_decode_field(mskstream, &iter, typefld->width, (u8 *)&mask); 185 /* no type info if there are no mask bits */ 186 if (vcap_bitarray_zero(typefld->width, (u8 *)&mask)) 187 return false; 188 189 /* Get the value of the type field in the stream and compare to the 190 * one define in the vcap keyset 191 */ 192 vcap_iter_init(&iter, vcap->sw_width, tgt, typefld->offset); 193 vcap_decode_field(keystream, &iter, typefld->width, (u8 *)&value); 194 195 return (value == info->type_id); 196 } 197 198 /* Verify that the typegroup information, subword count, keyset and type id 199 * are in sync and correct, return the keyset 200 */ 201 static enum 202 vcap_keyfield_set vcap_find_keystream_keyset(struct vcap_control *vctrl, 203 enum vcap_type vt, 204 u32 *keystream, 205 u32 *mskstream, 206 bool mask, int sw_max) 207 { 208 const struct vcap_set *keyfield_set; 209 int sw_count, idx; 210 bool res; 211 212 sw_count = vcap_find_keystream_typegroup_sw(vctrl, vt, keystream, mask, 213 sw_max); 214 if (sw_count < 0) 215 return sw_count; 216 217 keyfield_set = vctrl->vcaps[vt].keyfield_set; 218 for (idx = 0; idx < vctrl->vcaps[vt].keyfield_set_size; ++idx) { 219 if (keyfield_set[idx].sw_per_item != sw_count) 220 continue; 221 222 res = vcap_verify_keystream_keyset(vctrl, vt, keystream, 223 mskstream, idx); 224 if (res) 225 return idx; 226 } 227 return -EINVAL; 228 } 229 230 /* Read key data from a VCAP address and discover if there is a rule keyset 231 * here 232 */ 233 static bool 234 vcap_verify_actionstream_actionset(struct vcap_control *vctrl, 235 enum vcap_type vt, 236 u32 *actionstream, 237 enum vcap_actionfield_set actionset) 238 { 239 const struct vcap_typegroup *tgt; 240 const struct vcap_field *fields; 241 const struct vcap_set *info; 242 243 if (vcap_actionfield_count(vctrl, vt, actionset) == 0) 244 return false; 245 246 info = vcap_actionfieldset(vctrl, vt, actionset); 247 /* Check that the actionset is valid */ 248 if (!info) 249 return false; 250 251 /* a type_id of value -1 means that there is no type field */ 252 if (info->type_id == (u8)-1) 253 return true; 254 255 /* Get a valid typegroup for the specific actionset */ 256 tgt = vcap_actionfield_typegroup(vctrl, vt, actionset); 257 if (!tgt) 258 return false; 259 260 fields = vcap_actionfields(vctrl, vt, actionset); 261 if (!fields) 262 return false; 263 264 /* Later this will be expanded with a check of the type id */ 265 return true; 266 } 267 268 /* Verify that the typegroup information, subword count, actionset and type id 269 * are in sync and correct, return the actionset 270 */ 271 static enum vcap_actionfield_set 272 vcap_find_actionstream_actionset(struct vcap_control *vctrl, 273 enum vcap_type vt, 274 u32 *stream, 275 int sw_max) 276 { 277 const struct vcap_set *actionfield_set; 278 int sw_count, idx; 279 bool res; 280 281 sw_count = vcap_find_actionstream_typegroup_sw(vctrl, vt, stream, 282 sw_max); 283 if (sw_count < 0) 284 return sw_count; 285 286 actionfield_set = vctrl->vcaps[vt].actionfield_set; 287 for (idx = 0; idx < vctrl->vcaps[vt].actionfield_set_size; ++idx) { 288 if (actionfield_set[idx].sw_per_item != sw_count) 289 continue; 290 291 res = vcap_verify_actionstream_actionset(vctrl, vt, 292 stream, idx); 293 if (res) 294 return idx; 295 } 296 return -EINVAL; 297 } 298 299 /* Read key data from a VCAP address and discover if there is a rule keyset 300 * here 301 */ 302 static int vcap_addr_keyset(struct vcap_control *vctrl, 303 struct net_device *ndev, 304 struct vcap_admin *admin, 305 int addr) 306 { 307 enum vcap_type vt = admin->vtype; 308 int keyset_sw_regs, idx; 309 u32 key = 0, mask = 0; 310 311 /* Read the cache at the specified address */ 312 keyset_sw_regs = DIV_ROUND_UP(vctrl->vcaps[vt].sw_width, 32); 313 vctrl->ops->update(ndev, admin, VCAP_CMD_READ, VCAP_SEL_ALL, addr); 314 vctrl->ops->cache_read(ndev, admin, VCAP_SEL_ENTRY, 0, 315 keyset_sw_regs); 316 /* Skip uninitialized key/mask entries */ 317 for (idx = 0; idx < keyset_sw_regs; ++idx) { 318 key |= ~admin->cache.keystream[idx]; 319 mask |= admin->cache.maskstream[idx]; 320 } 321 if (key == 0 && mask == 0) 322 return -EINVAL; 323 /* Decode and locate the keyset */ 324 return vcap_find_keystream_keyset(vctrl, vt, admin->cache.keystream, 325 admin->cache.maskstream, false, 0); 326 } 327 328 static int vcap_read_rule(struct vcap_rule_internal *ri) 329 { 330 struct vcap_admin *admin = ri->admin; 331 int sw_idx, ent_idx = 0, act_idx = 0; 332 u32 addr = ri->addr; 333 334 if (!ri->size || !ri->keyset_sw_regs || !ri->actionset_sw_regs) { 335 pr_err("%s:%d: rule is empty\n", __func__, __LINE__); 336 return -EINVAL; 337 } 338 vcap_erase_cache(ri); 339 /* Use the values in the streams to read the VCAP cache */ 340 for (sw_idx = 0; sw_idx < ri->size; sw_idx++, addr++) { 341 ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_READ, 342 VCAP_SEL_ALL, addr); 343 ri->vctrl->ops->cache_read(ri->ndev, admin, 344 VCAP_SEL_ENTRY, ent_idx, 345 ri->keyset_sw_regs); 346 ri->vctrl->ops->cache_read(ri->ndev, admin, 347 VCAP_SEL_ACTION, act_idx, 348 ri->actionset_sw_regs); 349 if (sw_idx == 0) 350 ri->vctrl->ops->cache_read(ri->ndev, admin, 351 VCAP_SEL_COUNTER, 352 ri->counter_id, 0); 353 ent_idx += ri->keyset_sw_regs; 354 act_idx += ri->actionset_sw_regs; 355 } 356 return 0; 357 } 358 359 /* Dump the keyfields value and mask values */ 360 static void vcap_debugfs_show_rule_keyfield(struct vcap_control *vctrl, 361 struct vcap_output_print *out, 362 enum vcap_key_field key, 363 const struct vcap_field *keyfield, 364 u8 *value, u8 *mask) 365 { 366 bool hex = false; 367 int idx, bytes; 368 369 out->prf(out->dst, " %s: W%d: ", vcap_keyfield_name(vctrl, key), 370 keyfield[key].width); 371 372 switch (keyfield[key].type) { 373 case VCAP_FIELD_BIT: 374 out->prf(out->dst, "%d/%d", value[0], mask[0]); 375 break; 376 case VCAP_FIELD_U32: 377 if (key == VCAP_KF_L3_IP4_SIP || key == VCAP_KF_L3_IP4_DIP) { 378 out->prf(out->dst, "%pI4h/%pI4h", value, mask); 379 } else if (key == VCAP_KF_ETYPE || 380 key == VCAP_KF_IF_IGR_PORT_MASK) { 381 hex = true; 382 } else { 383 u32 fmsk = (1 << keyfield[key].width) - 1; 384 u32 val = *(u32 *)value; 385 u32 msk = *(u32 *)mask; 386 387 out->prf(out->dst, "%u/%u", val & fmsk, msk & fmsk); 388 } 389 break; 390 case VCAP_FIELD_U48: 391 if (key == VCAP_KF_L2_SMAC || key == VCAP_KF_L2_DMAC) 392 out->prf(out->dst, "%pMR/%pMR", value, mask); 393 else 394 hex = true; 395 break; 396 case VCAP_FIELD_U56: 397 case VCAP_FIELD_U64: 398 case VCAP_FIELD_U72: 399 case VCAP_FIELD_U112: 400 hex = true; 401 break; 402 case VCAP_FIELD_U128: 403 if (key == VCAP_KF_L3_IP6_SIP || key == VCAP_KF_L3_IP6_DIP) { 404 u8 nvalue[16], nmask[16]; 405 406 vcap_netbytes_copy(nvalue, value, sizeof(nvalue)); 407 vcap_netbytes_copy(nmask, mask, sizeof(nmask)); 408 out->prf(out->dst, "%pI6/%pI6", nvalue, nmask); 409 } else { 410 hex = true; 411 } 412 break; 413 } 414 if (hex) { 415 bytes = DIV_ROUND_UP(keyfield[key].width, BITS_PER_BYTE); 416 out->prf(out->dst, "0x"); 417 for (idx = 0; idx < bytes; ++idx) 418 out->prf(out->dst, "%02x", value[bytes - idx - 1]); 419 out->prf(out->dst, "/0x"); 420 for (idx = 0; idx < bytes; ++idx) 421 out->prf(out->dst, "%02x", mask[bytes - idx - 1]); 422 } 423 out->prf(out->dst, "\n"); 424 } 425 426 static void 427 vcap_debugfs_show_rule_actionfield(struct vcap_control *vctrl, 428 struct vcap_output_print *out, 429 enum vcap_action_field action, 430 const struct vcap_field *actionfield, 431 u8 *value) 432 { 433 bool hex = false; 434 int idx, bytes; 435 u32 fmsk, val; 436 437 out->prf(out->dst, " %s: W%d: ", 438 vcap_actionfield_name(vctrl, action), 439 actionfield[action].width); 440 441 switch (actionfield[action].type) { 442 case VCAP_FIELD_BIT: 443 out->prf(out->dst, "%d", value[0]); 444 break; 445 case VCAP_FIELD_U32: 446 fmsk = (1 << actionfield[action].width) - 1; 447 val = *(u32 *)value; 448 out->prf(out->dst, "%u", val & fmsk); 449 break; 450 case VCAP_FIELD_U48: 451 case VCAP_FIELD_U56: 452 case VCAP_FIELD_U64: 453 case VCAP_FIELD_U72: 454 case VCAP_FIELD_U112: 455 case VCAP_FIELD_U128: 456 hex = true; 457 break; 458 } 459 if (hex) { 460 bytes = DIV_ROUND_UP(actionfield[action].width, BITS_PER_BYTE); 461 out->prf(out->dst, "0x"); 462 for (idx = 0; idx < bytes; ++idx) 463 out->prf(out->dst, "%02x", value[bytes - idx - 1]); 464 } 465 out->prf(out->dst, "\n"); 466 } 467 468 static int vcap_debugfs_show_rule_keyset(struct vcap_rule_internal *ri, 469 struct vcap_output_print *out) 470 { 471 struct vcap_control *vctrl = ri->vctrl; 472 struct vcap_stream_iter kiter, miter; 473 struct vcap_admin *admin = ri->admin; 474 const struct vcap_field *keyfield; 475 enum vcap_type vt = admin->vtype; 476 const struct vcap_typegroup *tgt; 477 enum vcap_keyfield_set keyset; 478 int idx, res, keyfield_count; 479 u32 *maskstream; 480 u32 *keystream; 481 u8 value[16]; 482 u8 mask[16]; 483 484 keystream = admin->cache.keystream; 485 maskstream = admin->cache.maskstream; 486 res = vcap_find_keystream_keyset(vctrl, vt, keystream, maskstream, 487 false, 0); 488 if (res < 0) { 489 pr_err("%s:%d: could not find valid keyset: %d\n", 490 __func__, __LINE__, res); 491 return -EINVAL; 492 } 493 keyset = res; 494 out->prf(out->dst, " keyset: %s\n", 495 vcap_keyset_name(vctrl, ri->data.keyset)); 496 out->prf(out->dst, " keyset_sw: %d\n", ri->keyset_sw); 497 out->prf(out->dst, " keyset_sw_regs: %d\n", ri->keyset_sw_regs); 498 keyfield_count = vcap_keyfield_count(vctrl, vt, keyset); 499 keyfield = vcap_keyfields(vctrl, vt, keyset); 500 tgt = vcap_keyfield_typegroup(vctrl, vt, keyset); 501 /* Start decoding the streams */ 502 for (idx = 0; idx < keyfield_count; ++idx) { 503 if (keyfield[idx].width <= 0) 504 continue; 505 /* First get the mask */ 506 memset(mask, 0, DIV_ROUND_UP(keyfield[idx].width, 8)); 507 vcap_iter_init(&miter, vctrl->vcaps[vt].sw_width, tgt, 508 keyfield[idx].offset); 509 vcap_decode_field(maskstream, &miter, keyfield[idx].width, 510 mask); 511 /* Skip if no mask bits are set */ 512 if (vcap_bitarray_zero(keyfield[idx].width, mask)) 513 continue; 514 /* Get the key */ 515 memset(value, 0, DIV_ROUND_UP(keyfield[idx].width, 8)); 516 vcap_iter_init(&kiter, vctrl->vcaps[vt].sw_width, tgt, 517 keyfield[idx].offset); 518 vcap_decode_field(keystream, &kiter, keyfield[idx].width, 519 value); 520 vcap_debugfs_show_rule_keyfield(vctrl, out, idx, keyfield, 521 value, mask); 522 } 523 return 0; 524 } 525 526 static int vcap_debugfs_show_rule_actionset(struct vcap_rule_internal *ri, 527 struct vcap_output_print *out) 528 { 529 struct vcap_control *vctrl = ri->vctrl; 530 struct vcap_admin *admin = ri->admin; 531 const struct vcap_field *actionfield; 532 enum vcap_actionfield_set actionset; 533 enum vcap_type vt = admin->vtype; 534 const struct vcap_typegroup *tgt; 535 struct vcap_stream_iter iter; 536 int idx, res, actfield_count; 537 u32 *actstream; 538 u8 value[16]; 539 bool no_bits; 540 541 actstream = admin->cache.actionstream; 542 res = vcap_find_actionstream_actionset(vctrl, vt, actstream, 0); 543 if (res < 0) { 544 pr_err("%s:%d: could not find valid actionset: %d\n", 545 __func__, __LINE__, res); 546 return -EINVAL; 547 } 548 actionset = res; 549 out->prf(out->dst, " actionset: %s\n", 550 vcap_actionset_name(vctrl, ri->data.actionset)); 551 out->prf(out->dst, " actionset_sw: %d\n", ri->actionset_sw); 552 out->prf(out->dst, " actionset_sw_regs: %d\n", ri->actionset_sw_regs); 553 actfield_count = vcap_actionfield_count(vctrl, vt, actionset); 554 actionfield = vcap_actionfields(vctrl, vt, actionset); 555 tgt = vcap_actionfield_typegroup(vctrl, vt, actionset); 556 /* Start decoding the stream */ 557 for (idx = 0; idx < actfield_count; ++idx) { 558 if (actionfield[idx].width <= 0) 559 continue; 560 /* Get the action */ 561 memset(value, 0, DIV_ROUND_UP(actionfield[idx].width, 8)); 562 vcap_iter_init(&iter, vctrl->vcaps[vt].act_width, tgt, 563 actionfield[idx].offset); 564 vcap_decode_field(actstream, &iter, actionfield[idx].width, 565 value); 566 /* Skip if no bits are set */ 567 no_bits = vcap_bitarray_zero(actionfield[idx].width, value); 568 if (no_bits) 569 continue; 570 /* Later the action id will also be checked */ 571 vcap_debugfs_show_rule_actionfield(vctrl, out, idx, actionfield, 572 value); 573 } 574 return 0; 575 } 576 577 static void vcap_show_admin_rule(struct vcap_control *vctrl, 578 struct vcap_admin *admin, 579 struct vcap_output_print *out, 580 struct vcap_rule_internal *ri) 581 { 582 ri->counter.value = admin->cache.counter; 583 ri->counter.sticky = admin->cache.sticky; 584 out->prf(out->dst, 585 "rule: %u, addr: [%d,%d], X%d, ctr[%d]: %d, hit: %d\n", 586 ri->data.id, ri->addr, ri->addr + ri->size - 1, ri->size, 587 ri->counter_id, ri->counter.value, ri->counter.sticky); 588 out->prf(out->dst, " chain_id: %d\n", ri->data.vcap_chain_id); 589 out->prf(out->dst, " user: %d\n", ri->data.user); 590 out->prf(out->dst, " priority: %d\n", ri->data.priority); 591 vcap_debugfs_show_rule_keyset(ri, out); 592 vcap_debugfs_show_rule_actionset(ri, out); 593 } 594 595 static void vcap_show_admin_info(struct vcap_control *vctrl, 596 struct vcap_admin *admin, 597 struct vcap_output_print *out) 598 { 599 const struct vcap_info *vcap = &vctrl->vcaps[admin->vtype]; 600 601 out->prf(out->dst, "name: %s\n", vcap->name); 602 out->prf(out->dst, "rows: %d\n", vcap->rows); 603 out->prf(out->dst, "sw_count: %d\n", vcap->sw_count); 604 out->prf(out->dst, "sw_width: %d\n", vcap->sw_width); 605 out->prf(out->dst, "sticky_width: %d\n", vcap->sticky_width); 606 out->prf(out->dst, "act_width: %d\n", vcap->act_width); 607 out->prf(out->dst, "default_cnt: %d\n", vcap->default_cnt); 608 out->prf(out->dst, "require_cnt_dis: %d\n", vcap->require_cnt_dis); 609 out->prf(out->dst, "version: %d\n", vcap->version); 610 out->prf(out->dst, "vtype: %d\n", admin->vtype); 611 out->prf(out->dst, "vinst: %d\n", admin->vinst); 612 out->prf(out->dst, "first_cid: %d\n", admin->first_cid); 613 out->prf(out->dst, "last_cid: %d\n", admin->last_cid); 614 out->prf(out->dst, "lookups: %d\n", admin->lookups); 615 out->prf(out->dst, "first_valid_addr: %d\n", admin->first_valid_addr); 616 out->prf(out->dst, "last_valid_addr: %d\n", admin->last_valid_addr); 617 out->prf(out->dst, "last_used_addr: %d\n", admin->last_used_addr); 618 } 619 620 static int vcap_show_admin(struct vcap_control *vctrl, 621 struct vcap_admin *admin, 622 struct vcap_output_print *out) 623 { 624 struct vcap_rule_internal *elem, *ri; 625 int ret = 0; 626 627 vcap_show_admin_info(vctrl, admin, out); 628 mutex_lock(&admin->lock); 629 list_for_each_entry(elem, &admin->rules, list) { 630 ri = vcap_dup_rule(elem); 631 if (IS_ERR(ri)) 632 goto free_rule; 633 /* Read data from VCAP */ 634 ret = vcap_read_rule(ri); 635 if (ret) 636 goto free_rule; 637 out->prf(out->dst, "\n"); 638 vcap_show_admin_rule(vctrl, admin, out, ri); 639 free_rule: 640 vcap_free_rule((struct vcap_rule *)ri); 641 } 642 mutex_unlock(&admin->lock); 643 return ret; 644 } 645 646 static int vcap_show_admin_raw(struct vcap_control *vctrl, 647 struct vcap_admin *admin, 648 struct vcap_output_print *out) 649 { 650 enum vcap_type vt = admin->vtype; 651 struct vcap_rule_internal *ri; 652 const struct vcap_set *info; 653 int keyset; 654 int addr; 655 int ret; 656 657 if (list_empty(&admin->rules)) 658 return 0; 659 660 ret = vcap_api_check(vctrl); 661 if (ret) 662 return ret; 663 664 ri = list_first_entry(&admin->rules, struct vcap_rule_internal, list); 665 666 /* Go from higher to lower addresses searching for a keyset */ 667 for (addr = admin->last_valid_addr; addr >= admin->first_valid_addr; 668 --addr) { 669 keyset = vcap_addr_keyset(vctrl, ri->ndev, admin, addr); 670 if (keyset < 0) 671 continue; 672 info = vcap_keyfieldset(vctrl, vt, keyset); 673 if (!info) 674 continue; 675 if (addr % info->sw_per_item) 676 pr_info("addr: %d X%d error rule, keyset: %s\n", 677 addr, 678 info->sw_per_item, 679 vcap_keyset_name(vctrl, keyset)); 680 else 681 out->prf(out->dst, " addr: %d, X%d rule, keyset: %s\n", 682 addr, 683 info->sw_per_item, 684 vcap_keyset_name(vctrl, keyset)); 685 } 686 return 0; 687 } 688 689 /* Show the port configuration and status */ 690 static int vcap_port_debugfs_show(struct seq_file *m, void *unused) 691 { 692 struct vcap_port_debugfs_info *info = m->private; 693 struct vcap_admin *admin; 694 struct vcap_output_print out = { 695 .prf = (void *)seq_printf, 696 .dst = m, 697 }; 698 699 list_for_each_entry(admin, &info->vctrl->list, list) { 700 if (admin->vinst) 701 continue; 702 info->vctrl->ops->port_info(info->ndev, admin, &out); 703 } 704 return 0; 705 } 706 DEFINE_SHOW_ATTRIBUTE(vcap_port_debugfs); 707 708 void vcap_port_debugfs(struct device *dev, struct dentry *parent, 709 struct vcap_control *vctrl, 710 struct net_device *ndev) 711 { 712 struct vcap_port_debugfs_info *info; 713 714 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 715 if (!info) 716 return; 717 718 info->vctrl = vctrl; 719 info->ndev = ndev; 720 debugfs_create_file(netdev_name(ndev), 0444, parent, info, 721 &vcap_port_debugfs_fops); 722 } 723 EXPORT_SYMBOL_GPL(vcap_port_debugfs); 724 725 /* Show the full VCAP instance data (rules with all fields) */ 726 static int vcap_debugfs_show(struct seq_file *m, void *unused) 727 { 728 struct vcap_admin_debugfs_info *info = m->private; 729 struct vcap_output_print out = { 730 .prf = (void *)seq_printf, 731 .dst = m, 732 }; 733 734 return vcap_show_admin(info->vctrl, info->admin, &out); 735 } 736 DEFINE_SHOW_ATTRIBUTE(vcap_debugfs); 737 738 /* Show the raw VCAP instance data (rules with address info) */ 739 static int vcap_raw_debugfs_show(struct seq_file *m, void *unused) 740 { 741 struct vcap_admin_debugfs_info *info = m->private; 742 struct vcap_output_print out = { 743 .prf = (void *)seq_printf, 744 .dst = m, 745 }; 746 747 return vcap_show_admin_raw(info->vctrl, info->admin, &out); 748 } 749 DEFINE_SHOW_ATTRIBUTE(vcap_raw_debugfs); 750 751 struct dentry *vcap_debugfs(struct device *dev, struct dentry *parent, 752 struct vcap_control *vctrl) 753 { 754 struct vcap_admin_debugfs_info *info; 755 struct vcap_admin *admin; 756 struct dentry *dir; 757 char name[50]; 758 759 dir = debugfs_create_dir("vcaps", parent); 760 if (PTR_ERR_OR_ZERO(dir)) 761 return NULL; 762 list_for_each_entry(admin, &vctrl->list, list) { 763 sprintf(name, "raw_%s_%d", vctrl->vcaps[admin->vtype].name, 764 admin->vinst); 765 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); 766 if (!info) 767 return NULL; 768 info->vctrl = vctrl; 769 info->admin = admin; 770 debugfs_create_file(name, 0444, dir, info, 771 &vcap_raw_debugfs_fops); 772 sprintf(name, "%s_%d", vctrl->vcaps[admin->vtype].name, 773 admin->vinst); 774 debugfs_create_file(name, 0444, dir, info, &vcap_debugfs_fops); 775 } 776 return dir; 777 } 778 EXPORT_SYMBOL_GPL(vcap_debugfs); 779 780 #ifdef CONFIG_VCAP_KUNIT_TEST 781 #include "vcap_api_debugfs_kunit.c" 782 #endif 783