Commit 1a371ea1 authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller
Browse files

ionic: Add netdev-event handling



When the netdev gets a new name from userland, pass that name
down to the NIC for internal tracking.

Signed-off-by: default avatarShannon Nelson <snelson@pensando.io>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0f3154e6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ struct ionic {
	DECLARE_BITMAP(lifbits, IONIC_LIFS_MAX);
	unsigned int nintrs;
	DECLARE_BITMAP(intrs, IONIC_INTR_CTRL_REGS_MAX);
	struct work_struct nb_work;
	struct notifier_block nb;
};

struct ionic_admin_ctx {
+62 −0
Original line number Diff line number Diff line
@@ -1955,10 +1955,66 @@ int ionic_lifs_init(struct ionic *ionic)
	return 0;
}

static void ionic_lif_notify_work(struct work_struct *ws)
{
}

static void ionic_lif_set_netdev_info(struct ionic_lif *lif)
{
	struct ionic_admin_ctx ctx = {
		.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
		.cmd.lif_setattr = {
			.opcode = IONIC_CMD_LIF_SETATTR,
			.index = cpu_to_le16(lif->index),
			.attr = IONIC_LIF_ATTR_NAME,
		},
	};

	strlcpy(ctx.cmd.lif_setattr.name, lif->netdev->name,
		sizeof(ctx.cmd.lif_setattr.name));

	ionic_adminq_post_wait(lif, &ctx);
}

static struct ionic_lif *ionic_netdev_lif(struct net_device *netdev)
{
	if (!netdev || netdev->netdev_ops->ndo_start_xmit != ionic_start_xmit)
		return NULL;

	return netdev_priv(netdev);
}

static int ionic_lif_notify(struct notifier_block *nb,
			    unsigned long event, void *info)
{
	struct net_device *ndev = netdev_notifier_info_to_dev(info);
	struct ionic *ionic = container_of(nb, struct ionic, nb);
	struct ionic_lif *lif = ionic_netdev_lif(ndev);

	if (!lif || lif->ionic != ionic)
		return NOTIFY_DONE;

	switch (event) {
	case NETDEV_CHANGENAME:
		ionic_lif_set_netdev_info(lif);
		break;
	}

	return NOTIFY_DONE;
}

int ionic_lifs_register(struct ionic *ionic)
{
	int err;

	INIT_WORK(&ionic->nb_work, ionic_lif_notify_work);

	ionic->nb.notifier_call = ionic_lif_notify;

	err = register_netdevice_notifier(&ionic->nb);
	if (err)
		ionic->nb.notifier_call = NULL;

	/* only register LIF0 for now */
	err = register_netdev(ionic->master_lif->netdev);
	if (err) {
@@ -1974,6 +2030,12 @@ int ionic_lifs_register(struct ionic *ionic)

void ionic_lifs_unregister(struct ionic *ionic)
{
	if (ionic->nb.notifier_call) {
		unregister_netdevice_notifier(&ionic->nb);
		cancel_work_sync(&ionic->nb_work);
		ionic->nb.notifier_call = NULL;
	}

	/* There is only one lif ever registered in the
	 * current model, so don't bother searching the
	 * ionic->lif for candidates to unregister