Esempio n. 1
0
int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
{
    struct mpoa_client *mpc;
    struct lec_priv *priv;

    if (mpcs == NULL) {
        init_timer(&mpc_timer);
        mpc_timer_refresh();

        /* This lets us now how our LECs are doing */
        register_netdevice_notifier(&mpoa_notifier);
    }

    mpc = find_mpc_by_itfnum(arg);
    if (mpc == NULL) {
        dprintk("mpoa: mpoad_attach: allocating new mpc for itf %d\n", arg);
        mpc = alloc_mpc();
        if (mpc == NULL)
            return -ENOMEM;
        mpc->dev_num = arg;
        mpc->dev = find_lec_by_itfnum(arg); /* NULL if there was no lec */
    }
    if (mpc->mpoad_vcc) {
        printk("mpoa: mpoad_attach: mpoad is already present for itf %d\n", arg);
        return -EADDRINUSE;
    }

    if (mpc->dev) { /* check if the lec is LANE2 capable */
        priv = (struct lec_priv *)mpc->dev->priv;
        if (priv->lane_version < 2) {
            dev_put(mpc->dev);
            mpc->dev = NULL;
        } else
            priv->lane2_ops->associate_indicator = lane2_assoc_ind;
    }

    mpc->mpoad_vcc = vcc;
    vcc->dev = &mpc_dev;
    vcc_insert_socket(vcc->sk);
    set_bit(ATM_VF_META,&vcc->flags);
    set_bit(ATM_VF_READY,&vcc->flags);

    if (mpc->dev) {
        char empty[ATM_ESA_LEN];
        memset(empty, 0, ATM_ESA_LEN);

        start_mpc(mpc, mpc->dev);
        /* set address if mpcd e.g. gets killed and restarted.
         * If we do not do it now we have to wait for the next LE_ARP
         */
        if ( memcmp(mpc->mps_ctrl_addr, empty, ATM_ESA_LEN) != 0 )
            send_set_mps_ctrl_addr(mpc->mps_ctrl_addr, mpc);
    }

    __module_get(THIS_MODULE);
    return arg;
}
Esempio n. 2
0
static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned long event, void *dev_ptr)
{
	struct net_device *dev;
	struct mpoa_client *mpc;
	struct lec_priv *priv;

	dev = (struct net_device *)dev_ptr;
	if (dev->name == NULL || strncmp(dev->name, "lec", 3))
		return NOTIFY_DONE; /* we are only interested in lec:s */
	
	switch (event) {
	case NETDEV_REGISTER:       /* a new lec device was allocated */
		priv = (struct lec_priv *)dev->priv;
		if (priv->lane_version < 2)
			break;
		priv->lane2_ops->associate_indicator = lane2_assoc_ind;
		mpc = find_mpc_by_itfnum(priv->itfnum);
		if (mpc == NULL) {
			dprintk("mpoa: mpoa_event_listener: allocating new mpc for %s\n",
			       dev->name);
			mpc = alloc_mpc();
			if (mpc == NULL) {
				printk("mpoa: mpoa_event_listener: no new mpc");
				break;
			}
		}
		mpc->dev_num = priv->itfnum;
		mpc->dev = dev;
		dev_hold(dev);
		dprintk("mpoa: (%s) was initialized\n", dev->name);
		break;
	case NETDEV_UNREGISTER:
		/* the lec device was deallocated */
		mpc = find_mpc_by_lec(dev);
		if (mpc == NULL)
			break;
		dprintk("mpoa: device (%s) was deallocated\n", dev->name);
		stop_mpc(mpc);
		dev_put(mpc->dev);
		mpc->dev = NULL;
		break;
	case NETDEV_UP:
		/* the dev was ifconfig'ed up */
		mpc = find_mpc_by_lec(dev);
		if (mpc == NULL)
			break;
		if (mpc->mpoad_vcc != NULL) {
			start_mpc(mpc, dev);
		}
		break;
	case NETDEV_DOWN:
		/* the dev was ifconfig'ed down */
		/* this means that the flow of packets from the
		 * upper layer stops
		 */
		mpc = find_mpc_by_lec(dev);
		if (mpc == NULL)
			break;
		if (mpc->mpoad_vcc != NULL) {
			stop_mpc(mpc);
		}
		break;
	case NETDEV_REBOOT:
	case NETDEV_CHANGE:
	case NETDEV_CHANGEMTU:
	case NETDEV_CHANGEADDR:
	case NETDEV_GOING_DOWN:
		break;
	default:
		break;
	}

	return NOTIFY_DONE;
}