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; }
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; }