diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 51 | ||||
-rw-r--r-- | drivers/net/plip/plip.c | 36 |
2 files changed, 65 insertions, 22 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index 614ef57ceefa..d64559e4aff7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -594,11 +594,10 @@ static enum mlxsw_reg_sfd_op mlxsw_sp_sfd_op(bool adding) MLXSW_REG_SFD_OP_WRITE_REMOVE; } -static int mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp_port *mlxsw_sp_port, +static int mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port, const char *mac, u16 fid, bool adding, bool dynamic) { - struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; char *sfd_pl; int err; @@ -609,7 +608,7 @@ static int mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp_port *mlxsw_sp_port, mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0); mlxsw_reg_sfd_uc_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic), mac, fid, MLXSW_REG_SFD_REC_ACTION_NOP, - mlxsw_sp_port->local_port); + local_port); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl); kfree(sfd_pl); @@ -659,7 +658,8 @@ mlxsw_sp_port_fdb_static_add(struct mlxsw_sp_port *mlxsw_sp_port, fid = mlxsw_sp_port->pvid; if (!mlxsw_sp_port->lagged) - return mlxsw_sp_port_fdb_uc_op(mlxsw_sp_port, + return mlxsw_sp_port_fdb_uc_op(mlxsw_sp_port->mlxsw_sp, + mlxsw_sp_port->local_port, fdb->addr, fid, true, false); else return mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp_port->mlxsw_sp, @@ -798,7 +798,8 @@ mlxsw_sp_port_fdb_static_del(struct mlxsw_sp_port *mlxsw_sp_port, } if (!mlxsw_sp_port->lagged) - return mlxsw_sp_port_fdb_uc_op(mlxsw_sp_port, + return mlxsw_sp_port_fdb_uc_op(mlxsw_sp_port->mlxsw_sp, + mlxsw_sp_port->local_port, fdb->addr, fid, false, false); else @@ -1029,13 +1030,14 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp, char mac[ETH_ALEN]; u8 local_port; u16 vid, fid; + bool do_notification = true; int err; mlxsw_reg_sfn_mac_unpack(sfn_pl, rec_index, mac, &fid, &local_port); mlxsw_sp_port = mlxsw_sp->ports[local_port]; if (!mlxsw_sp_port) { dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect local port in FDB notification\n"); - return; + goto just_remove; } if (mlxsw_sp_fid_is_vfid(fid)) { @@ -1046,9 +1048,8 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp, vfid); if (!mlxsw_sp_vport) { netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n"); - return; + goto just_remove; } - vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport); /* Override the physical port with the vPort. */ mlxsw_sp_port = mlxsw_sp_vport; @@ -1056,17 +1057,28 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp, vid = fid; } - err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp_port, mac, fid, - adding && mlxsw_sp_port->learning, true); + adding = adding && mlxsw_sp_port->learning; + +do_fdb_op: + err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, + adding, true); if (err) { if (net_ratelimit()) netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n"); return; } + if (!do_notification) + return; mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning, mlxsw_sp_port->learning_sync, adding, mac, vid, mlxsw_sp_port->dev); + return; + +just_remove: + adding = false; + do_notification = false; + goto do_fdb_op; } static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp, @@ -1078,13 +1090,14 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp, u16 lag_vid = 0; u16 lag_id; u16 vid, fid; + bool do_notification = true; int err; mlxsw_reg_sfn_mac_lag_unpack(sfn_pl, rec_index, mac, &fid, &lag_id); mlxsw_sp_port = mlxsw_sp_lag_rep_port(mlxsw_sp, lag_id); if (!mlxsw_sp_port) { dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Cannot find port representor for LAG\n"); - return; + goto just_remove; } if (mlxsw_sp_fid_is_vfid(fid)) { @@ -1095,7 +1108,7 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp, vfid); if (!mlxsw_sp_vport) { netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n"); - return; + goto just_remove; } vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport); @@ -1106,19 +1119,29 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp, vid = fid; } + adding = adding && mlxsw_sp_port->learning; + +do_fdb_op: err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid, - adding && mlxsw_sp_port->learning, - true); + adding, true); if (err) { if (net_ratelimit()) netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n"); return; } + if (!do_notification) + return; mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning, mlxsw_sp_port->learning_sync, adding, mac, vid, mlxsw_sp_lag_get(mlxsw_sp, lag_id)->dev); + return; + +just_remove: + adding = false; + do_notification = false; + goto do_fdb_op; } static void mlxsw_sp_fdb_notify_rec_process(struct mlxsw_sp *mlxsw_sp, diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c index 040b8978d6ca..9c4b41a4df7d 100644 --- a/drivers/net/plip/plip.c +++ b/drivers/net/plip/plip.c @@ -1249,6 +1249,7 @@ static void plip_attach (struct parport *port) struct net_device *dev; struct net_local *nl; char name[IFNAMSIZ]; + struct pardev_cb plip_cb; if ((parport[0] == -1 && (!timid || !port->devices)) || plip_searchfor(parport, port->number)) { @@ -1273,9 +1274,15 @@ static void plip_attach (struct parport *port) nl = netdev_priv(dev); nl->dev = dev; - nl->pardev = parport_register_device(port, dev->name, plip_preempt, - plip_wakeup, plip_interrupt, - 0, dev); + + memset(&plip_cb, 0, sizeof(plip_cb)); + plip_cb.private = dev; + plip_cb.preempt = plip_preempt; + plip_cb.wakeup = plip_wakeup; + plip_cb.irq_func = plip_interrupt; + + nl->pardev = parport_register_dev_model(port, dev->name, + &plip_cb, unit); if (!nl->pardev) { printk(KERN_ERR "%s: parport_register failed\n", name); @@ -1315,10 +1322,23 @@ static void plip_detach (struct parport *port) /* Nothing to do */ } +static int plip_probe(struct pardevice *par_dev) +{ + struct device_driver *drv = par_dev->dev.driver; + int len = strlen(drv->name); + + if (strncmp(par_dev->name, drv->name, len)) + return -ENODEV; + + return 0; +} + static struct parport_driver plip_driver = { - .name = "plip", - .attach = plip_attach, - .detach = plip_detach + .name = "plip", + .probe = plip_probe, + .match_port = plip_attach, + .detach = plip_detach, + .devmodel = true, }; static void __exit plip_cleanup_module (void) @@ -1326,8 +1346,6 @@ static void __exit plip_cleanup_module (void) struct net_device *dev; int i; - parport_unregister_driver (&plip_driver); - for (i=0; i < PLIP_MAX; i++) { if ((dev = dev_plip[i])) { struct net_local *nl = netdev_priv(dev); @@ -1339,6 +1357,8 @@ static void __exit plip_cleanup_module (void) dev_plip[i] = NULL; } } + + parport_unregister_driver(&plip_driver); } #ifndef MODULE |