switchdev.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * switchdev.c
  4. *
  5. * Authors:
  6. * Hans J. Schultz <netdev@kapio-technology.com>
  7. *
  8. */
  9. #include <net/switchdev.h>
  10. #include "chip.h"
  11. #include "global1.h"
  12. #include "switchdev.h"
  13. struct mv88e6xxx_fid_search_ctx {
  14. u16 fid_search;
  15. u16 vid_found;
  16. };
  17. static int __mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip,
  18. const struct mv88e6xxx_vtu_entry *entry,
  19. void *priv)
  20. {
  21. struct mv88e6xxx_fid_search_ctx *ctx = priv;
  22. if (ctx->fid_search == entry->fid) {
  23. ctx->vid_found = entry->vid;
  24. return 1;
  25. }
  26. return 0;
  27. }
  28. static int mv88e6xxx_find_vid(struct mv88e6xxx_chip *chip, u16 fid, u16 *vid)
  29. {
  30. struct mv88e6xxx_fid_search_ctx ctx;
  31. int err;
  32. ctx.fid_search = fid;
  33. mv88e6xxx_reg_lock(chip);
  34. err = mv88e6xxx_vtu_walk(chip, __mv88e6xxx_find_vid, &ctx);
  35. mv88e6xxx_reg_unlock(chip);
  36. if (err < 0)
  37. return err;
  38. if (err == 1)
  39. *vid = ctx.vid_found;
  40. else
  41. return -ENOENT;
  42. return 0;
  43. }
  44. int mv88e6xxx_handle_miss_violation(struct mv88e6xxx_chip *chip, int port,
  45. struct mv88e6xxx_atu_entry *entry, u16 fid)
  46. {
  47. struct switchdev_notifier_fdb_info info = {
  48. .addr = entry->mac,
  49. .locked = true,
  50. };
  51. struct net_device *brport;
  52. struct dsa_port *dp;
  53. u16 vid;
  54. int err;
  55. err = mv88e6xxx_find_vid(chip, fid, &vid);
  56. if (err)
  57. return err;
  58. info.vid = vid;
  59. dp = dsa_to_port(chip->ds, port);
  60. rtnl_lock();
  61. brport = dsa_port_to_bridge_port(dp);
  62. if (!brport) {
  63. rtnl_unlock();
  64. return -ENODEV;
  65. }
  66. err = call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE,
  67. brport, &info.info, NULL);
  68. rtnl_unlock();
  69. return err;
  70. }