new ADDIF to cascade interfaces

This commit is contained in:
Karsten Keil 2001-04-11 10:21:10 +00:00
parent 6aa14349ad
commit 8ee3b77e36
4 changed files with 233 additions and 273 deletions

View File

@ -172,6 +172,25 @@ disconnect_if(hisaxinstance_t *inst, u_int prim, hisaxif_t *hif) {
return(err);
}
static int
add_if(hisaxinstance_t *inst, u_int prim, hisaxif_t *hif) {
hisaxif_t *myif;
if (!inst)
return(-EINVAL);
if (!hif)
return(-EINVAL);
if (hif->stat & IF_UP) {
myif = &inst->down;
} else if (hif->stat & IF_DOWN) {
myif = &inst->up;
} else
return(-EINVAL);
APPEND_TO_LIST(hif, myif);
inst->obj->own_ctrl(inst, prim, hif);
return(0);
}
static char tmpbuf[4096];
static int
debugout(hisaxinstance_t *inst, logdata_t *log)
@ -217,6 +236,8 @@ static int central_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(disconnect_if(data, prim, arg));
case MGR_ADDIF | REQUEST:
return(add_if(data, prim, arg));
case MGR_CONNECT | REQUEST:
return(ConnectIF(data, arg));
case MGR_LOADFIRM | REQUEST:

View File

@ -131,6 +131,12 @@ l2down(layer2_t *l2, u_int prim, int dinfo, int len, void *arg) {
return(err);
}
static int
l2_chain_down(hisaxif_t *hif, u_int prim, int dinfo, int len, void *arg) {
if (!hif || !hif->fdata)
return(-EINVAL);
return(l2down(hif->fdata, prim, dinfo, len, arg));
}
static int
l2down_phd(layer2_t *l2, struct sk_buff *skb) {
@ -2090,6 +2096,19 @@ l2_manager(void *data, u_int prim, void *arg) {
}
return(SetIF(inst, arg, prim, l2from_up, l2from_down, l2l));
break;
case MGR_ADDIF | REQUEST:
if (!l2l) {
printk(KERN_WARNING "l2_manager addif l2 no instance\n");
return(-EINVAL);
}
if (arg) {
hisaxif_t *hif = arg;
if (hif->stat & IF_UP) {
hif->fdata = l2l;
hif->func = l2_chain_down;
}
}
break;
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
if (!l2l) {

View File

@ -13,7 +13,7 @@
#define MAX_HEADER_LEN 4
#define FLG_MGR_SETSTACK 1
#define FLG_DOWN_BUSY 2
#define FLG_MGR_OWNSTACK 2
typedef struct _hisaxdevice {
struct _hisaxdevice *prev;
@ -35,9 +35,8 @@ typedef struct _devicelayer {
hisaxdevice_t *dev;
hisaxinstance_t inst;
hisaxinstance_t *slave;
hisaxif_t sif;
struct sk_buff_head queue;
struct sk_buff *last_skb;
hisaxif_t s_up;
hisaxif_t s_down;
int iaddr;
int lm_st;
int Flags;
@ -53,8 +52,8 @@ static u_char stbuf[1000];
static int device_debug = 0;
static int from_up_down(hisaxif_t *, u_int, int, int, void *);
static int from_peer(hisaxif_t *, u_int, int, int, void *);
static int to_peer(hisaxif_t *, u_int, int, int, void *);
// static int from_peer(hisaxif_t *, u_int, int, int, void *);
// static int to_peer(hisaxif_t *, u_int, int, int, void *);
static int
@ -117,8 +116,30 @@ stack_inst_flg(hisaxdevice_t *dev, hisaxstack_t *st, int bit, int clear)
return(ret);
}
static hisaxstack_t *
clone_stack(int addr)
{
int err;
hisaxstack_t *st;
hisaxinstance_t inst;
memset(&inst, 0, sizeof(hisaxinstance_t));
st = get_stack4id(addr);
if (!st)
return(NULL);
err = udev_obj.ctrl(NULL, MGR_NEWSTACK | REQUEST, &inst);
if (err)
return(NULL);
memcpy(&inst.st->pid, &st->pid, sizeof(hisax_pid_t));
inst.st->child = st->child;
inst.st->mgr = NULL;
return(st);
}
static int
create_layer(hisaxdevice_t *dev, hisaxstack_t *st, layer_info_t *linfo, int *adr) {
create_layer(hisaxdevice_t *dev, hisaxstack_t *st, layer_info_t *linfo,
int *adr, int mgr)
{
hisaxlayer_t *layer;
int i, ret;
devicelayer_t *nl;
@ -177,6 +198,10 @@ create_layer(hisaxdevice_t *dev, hisaxstack_t *st, layer_info_t *linfo, int *adr
}
}
}
if (mgr) {
st->mgr = &nl->inst;
test_and_set_bit(FLG_MGR_OWNSTACK, &nl->Flags);
}
nl->inst.down.owner = &nl->inst;
nl->inst.up.owner = &nl->inst;
nl->inst.obj = &udev_obj;
@ -186,7 +211,6 @@ create_layer(hisaxdevice_t *dev, hisaxstack_t *st, layer_info_t *linfo, int *adr
nl->iaddr = nl->inst.id | IADDR_BIT;
*adr++ = nl->iaddr;
if (inst) {
skb_queue_head_init(&nl->queue);
nl->slave = inst;
*adr = inst->id;
} else
@ -195,31 +219,32 @@ create_layer(hisaxdevice_t *dev, hisaxstack_t *st, layer_info_t *linfo, int *adr
}
static int
reconnect(devicelayer_t *dl)
{
hisaxinstance_t *peer;
remove_if(devicelayer_t *dl, int stat) {
hisaxif_t *hif,*phif,*shif;
int err;
if (dl->inst.down.owner != &dl->inst) {
peer = dl->inst.down.owner;
if (peer->down.fdata == dl) {
memcpy(&peer->down, &dl->inst.down, sizeof(hisaxif_t));
memset(&dl->inst.down, 0, sizeof(hisaxif_t));
} else if (peer->up.fdata == dl) {
memcpy(&peer->up, &dl->inst.down, sizeof(hisaxif_t));
memset(&dl->inst.down, 0, sizeof(hisaxif_t));
}
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG __FUNCTION__":dl(%p) stat(%x)\n", dl, stat);
phif = NULL;
if (stat & IF_UP) {
hif = &dl->inst.up;
shif = &dl->s_up;
if (shif->owner)
phif = &shif->owner->down;
else if (stat & IF_DOWN)
hif = &dl->inst.down;
shif = &dl->s_down;
if (shif->owner)
phif = &shif->owner->up;
} else {
printk(KERN_WARNING __FUNCTION__": stat not UP/DOWN\n");
return(-EINVAL);
}
if (dl->inst.up.owner != &dl->inst) {
peer = dl->inst.up.owner;
if (peer->down.fdata == dl) {
memcpy(&peer->down, &dl->inst.up, sizeof(hisaxif_t));
memset(&dl->inst.up, 0, sizeof(hisaxif_t));
} else if (peer->up.fdata == dl) {
memcpy(&peer->up, &dl->inst.up, sizeof(hisaxif_t));
memset(&dl->inst.up, 0, sizeof(hisaxif_t));
}
}
return(0);
err = udev_obj.ctrl(hif->peer, MGR_DISCONNECT | REQUEST, hif);
if (phif)
memcpy(phif, shif, sizeof(hisaxif_t));
REMOVE_FROM_LIST(hif);
return(err);
}
static int
@ -234,13 +259,9 @@ del_layer(devicelayer_t *dl) {
printk(KERN_DEBUG __FUNCTION__": iaddr %x inst %s slave %p\n",
dl->iaddr, inst->name, dl->slave);
}
reconnect(dl);
remove_if(dl, IF_UP);
remove_if(dl, IF_DOWN);
if (dl->slave) {
discard_queue(&dl->queue);
if (dl->last_skb) {
dev_kfree_skb(dl->last_skb);
dl->last_skb = NULL;
}
dl->slave->obj->own_ctrl(dl->slave, MGR_UNREGLAYER | REQUEST,
NULL);
dl->slave = NULL;
@ -270,21 +291,22 @@ del_layer(devicelayer_t *dl) {
dl->iaddr = 0;
REMOVE_FROM_LISTBASE(dl, dev->layer);
udev_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
if (test_and_clear_bit(FLG_MGR_OWNSTACK, &dl->Flags)) {
udev_obj.ctrl(inst->st, MGR_DELSTACK | REQUEST, NULL);
}
kfree(dl);
return(0);
}
static int
connect_if_req(hisaxdevice_t *dev, iframe_t *iff) {
hisaxif_t *hif, *phif;
devicelayer_t *dl;
int stat,err=-ENXIO;
interface_info_t *ifi = (interface_info_t *)&iff->data.p;
hisaxinstance_t *inst;
hisaxinstance_t *peer;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG __FUNCTION__": addr:%x own(%x) peer(%X)\n",
printk(KERN_DEBUG __FUNCTION__": addr:%x own(%x) peer(%x)\n",
iff->addr, ifi->owner, ifi->peer);
if (!(dl=get_devlayer(dev, iff->addr)))
return(-ENXIO);
@ -298,117 +320,104 @@ connect_if_req(hisaxdevice_t *dev, iframe_t *iff) {
ifi->peer);
return(-ENODEV);
}
if (inst != &dl->inst) {
printk(KERN_WARNING __FUNCTION__": owner(%x) not our\n",
return(ConnectIF(inst, peer));
}
static int
set_if_req(hisaxdevice_t *dev, iframe_t *iff) {
hisaxif_t *hif,*phif,*shif;
int stat;
interface_info_t *ifi = (interface_info_t *)&iff->data.p;
devicelayer_t *dl;
hisaxinstance_t *inst, *peer;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG __FUNCTION__": addr:%x own(%x) peer(%x)\n",
iff->addr, ifi->owner, ifi->peer);
if (!(dl=get_devlayer(dev, iff->addr)))
return(-ENXIO);
if (!(inst = get_instance4id(ifi->owner))) {
printk(KERN_WARNING __FUNCTION__": owner(%x) not found\n",
ifi->owner);
return(-EINVAL);
return(-ENODEV);
}
if (!(peer = get_instance4id(ifi->peer))) {
printk(KERN_WARNING __FUNCTION__": peer(%x) not found\n",
ifi->peer);
return(-ENODEV);
}
if (ifi->stat == IF_UP) {
hif = &dl->inst.up;
phif = &peer->down;
shif = &dl->s_up;
stat = IF_DOWN;
} else if (ifi->stat == IF_DOWN) {
hif = &dl->inst.down;
shif = &dl->s_down;
phif = &peer->up;
stat = IF_UP;
} else {
printk(KERN_WARNING __FUNCTION__": if not UP/DOWN\n");
return(-EINVAL);
}
if (hif->stat != IF_NOACTIV)
if (shif->stat != IF_NOACTIV) {
printk(KERN_WARNING __FUNCTION__": save if busy\n");
return(-EBUSY);
if (phif->stat != IF_NOACTIV) { /* install splitter */
if (!(inst = phif->peer))
return(-EINVAL);
memcpy(&dl->inst.down, phif, sizeof(hisaxif_t));
phif->func = from_peer;
phif->fdata = dl;
if (stat == IF_UP) {
stat = IF_DOWN;
phif = &inst->down;
} else {
stat = IF_UP;
phif = &inst->up;
}
memcpy(&dl->inst.up, phif, sizeof(hisaxif_t));
phif->func = to_peer;
phif->fdata = dl;
err = 0;
if (dl->slave) {
dl->sif.stat = stat;
dl->sif.owner = &dl->inst;
dl->sif.peer = dl->slave;
err = dl->slave->obj->own_ctrl(dl->slave, MGR_SETIF |
REQUEST, &dl->sif);
if (err)
dl->sif.stat = IF_NOACTIV;
}
} else {
hif->stat = stat;
hif->peer = peer;
err = udev_obj.ctrl(&dl->inst, MGR_CONNECT | REQUEST,
hif->peer);
if (err)
hif->stat = IF_NOACTIV;
}
return(err);
if (hif->stat != IF_NOACTIV) {
printk(KERN_WARNING __FUNCTION__": own if busy\n");
return(-EBUSY);
}
hif->stat = stat;
hif->owner = inst;
memcpy(shif, phif, sizeof(hisaxif_t));
memset(phif, 0, sizeof(hisaxif_t));
return(peer->obj->own_ctrl(peer, iff->prim, hif));
}
static int
set_if_req(hisaxdevice_t *dev, iframe_t *iff) {
hisaxif_t *hif = NULL;
devicelayer_t *dl;
int *ip, err=-ENXIO;
add_if_req(hisaxdevice_t *dev, iframe_t *iff) {
hisaxif_t *hif;
interface_info_t *ifi = (interface_info_t *)&iff->data.p;
hisaxinstance_t *inst, *peer;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG __FUNCTION__": addr:%x\n", iff->addr);
if (iff->len != sizeof(int))
return(-EINVAL);
if (!(dl=get_devlayer(dev, iff->addr)))
return(-ENXIO);
ip = &iff->data.i;
if (iff->addr & IF_UP) {
hif = &dl->inst.up;
if (hif->stat == IF_NOACTIV) {
hif->stat = IF_DOWN;
hif->extentions = *ip++;
err = udev_obj.ctrl(dl->inst.st, MGR_CONNECT | REQUEST, hif);
if (err)
hif->stat = IF_NOACTIV;
} else
err = -EBUSY;
} else if (iff->addr & IF_DOWN) {
hif = &dl->inst.down;
if (hif->stat == IF_NOACTIV) {
hif->stat = IF_UP;
err = udev_obj.ctrl(dl->inst.st, MGR_CONNECT | REQUEST, hif);
if (err)
hif->stat = IF_NOACTIV;
} else
err = -EBUSY;
printk(KERN_DEBUG __FUNCTION__": addr:%x own(%x) peer(%x)\n",
iff->addr, ifi->owner, ifi->peer);
if (!(inst = get_instance4id(ifi->owner))) {
printk(KERN_WARNING __FUNCTION__": owner(%x) not found\n",
ifi->owner);
return(-ENODEV);
}
return(err);
if (!(peer = get_instance4id(ifi->peer))) {
printk(KERN_WARNING __FUNCTION__": peer(%x) not found\n",
ifi->peer);
return(-ENODEV);
}
if (ifi->stat == IF_DOWN) {
hif = &inst->up;
} else if (ifi->stat == IF_UP) {
hif = &inst->down;
} else {
printk(KERN_WARNING __FUNCTION__": if not UP/DOWN\n");
return(-EINVAL);
}
return(peer->obj->ctrl(peer, iff->prim, hif));
}
static int
del_if_req(hisaxdevice_t *dev, iframe_t *iff) {
devicelayer_t *dl;
int err=-ENXIO;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG __FUNCTION__": addr:%x\n", iff->addr);
if (!(dl=get_devlayer(dev, iff->addr)))
return(-ENXIO);
if (iff->addr & IF_UP)
err = udev_obj.ctrl(dl->inst.up.peer, MGR_DISCONNECT | REQUEST,
&dl->inst.up);
else if (iff->addr & IF_DOWN)
err = udev_obj.ctrl(dl->inst.down.peer, MGR_DISCONNECT | REQUEST,
&dl->inst.down);
return(err);
return(remove_if(dl, iff->addr));
}
static int
@ -512,6 +521,56 @@ hisax_wdata(hisaxdevice_t *dev, void *dp, int len) {
off.len = 0;
hisax_rdata(dev, &off, err);
break;
case (MGR_SETSTACK | REQUEST):
used = head + sizeof(hisax_pid_t);
if (len<used)
return(len);
off.addr = iff->addr;
off.dinfo = 0;
off.prim = MGR_SETSTACK | CONFIRM;
off.len = 0;
if ((st = get_stack4id(iff->addr))) {
stack_inst_flg(dev, st, FLG_MGR_SETSTACK, 0);
err = udev_obj.ctrl(st, iff->prim, &iff->data.i);
if (err<0)
off.len = err;
} else
off.len = -ENODEV;
hisax_rdata(dev, &off, 1);
break;
case (MGR_NEWSTACK | REQUEST):
used = head + sizeof(layer_info_t);
if (len<used)
return(len);
off.addr = iff->addr;
off.dinfo = 0;
off.prim = MGR_NEWSTACK | CONFIRM;
off.len = 8;
off.data.p = stbuf;
if ((st = clone_stack(iff->addr))) {
err = create_layer(dev, st,
(layer_info_t *)&iff->data.i, off.data.p, 1);
if (err<0)
off.len = err;
} else
off.len = -ENODEV;
hisax_rdata(dev, &off, 1);
break;
case (MGR_CLEARSTACK | REQUEST):
used = head;
off.addr = iff->addr;
off.prim = MGR_CLEARSTACK | CONFIRM;
off.dinfo = 0;
off.len = 0;
if ((st = get_stack4id(iff->addr))) {
stack_inst_flg(dev, st, FLG_MGR_SETSTACK, 1);
err = udev_obj.ctrl(st, iff->prim, NULL);
if (err<0)
off.len = err;
} else
off.len = -ENODEV;
hisax_rdata(dev, &off, 1);
break;
case (MGR_GETLAYER | REQUEST):
used = head + sizeof(u_int);
if (len<used)
@ -564,7 +623,7 @@ hisax_wdata(hisaxdevice_t *dev, void *dp, int len) {
off.data.p = stbuf;
if ((st = get_stack4id(iff->addr))) {
err = create_layer(dev, st,
(layer_info_t *)&iff->data.i, off.data.p);
(layer_info_t *)&iff->data.i, off.data.p, 0);
if (err<0)
off.len = err;
} else
@ -656,6 +715,16 @@ hisax_wdata(hisaxdevice_t *dev, void *dp, int len) {
off.len = set_if_req(dev, iff);
hisax_rdata(dev, &off, 1);
break;
case (MGR_ADDIF | REQUEST):
used = head + iff->len;
if (len<used)
return(len);
off.addr = iff->addr;
off.prim = MGR_ADDIF | CONFIRM;
off.dinfo = 0;
off.len = add_if_req(dev, iff);
hisax_rdata(dev, &off, 1);
break;
case (MGR_DISCONNECT | REQUEST):
used = head;
off.addr = iff->addr;
@ -664,38 +733,6 @@ hisax_wdata(hisaxdevice_t *dev, void *dp, int len) {
off.len = del_if_req(dev, iff);
hisax_rdata(dev, &off, 1);
break;
case (MGR_SETSTACK | REQUEST):
used = head + sizeof(hisax_pid_t);
if (len<used)
return(len);
off.addr = iff->addr;
off.dinfo = 0;
off.prim = MGR_SETSTACK | CONFIRM;
off.len = 0;
if ((st = get_stack4id(iff->addr))) {
stack_inst_flg(dev, st, FLG_MGR_SETSTACK, 0);
err = udev_obj.ctrl(st, iff->prim, &iff->data.i);
if (err<0)
off.len = err;
} else
off.len = -ENODEV;
hisax_rdata(dev, &off, 1);
break;
case (MGR_CLEARSTACK | REQUEST):
used = head;
off.addr = iff->addr;
off.prim = MGR_CLEARSTACK | CONFIRM;
off.dinfo = 0;
off.len = 0;
if ((st = get_stack4id(iff->addr))) {
stack_inst_flg(dev, st, FLG_MGR_SETSTACK, 1);
err = udev_obj.ctrl(st, iff->prim, NULL);
if (err<0)
off.len = err;
} else
off.len = -ENODEV;
hisax_rdata(dev, &off, 1);
break;
default:
used = head + iff->len;
if (len<used) {
@ -989,131 +1026,13 @@ from_up_down(hisaxif_t *hif, u_int prim, int dinfo, int len, void *arg) {
return(retval);
}
static int
from_peer(hisaxif_t *hif, u_int prim, int dinfo, int len, void *arg) {
int ret = -EINVAL;
devicelayer_t *dl;
struct sk_buff *nskb;
printk(KERN_DEBUG __FUNCTION__ ": prim(%x) di(%x) l(%d) arg(%p)\n",
prim, dinfo, len, arg);
if (!hif)
return(-EINVAL);
dl = hif->fdata;
if (!dl)
return(ret);
if (!dl->slave || !dl->sif.func) {
if (dl->inst.down.func)
ret = dl->inst.down.func(&dl->inst.down, prim, dinfo, len,
arg);
return(ret);
}
if (dinfo == DINFO_SKB) {
if (test_bit(FLG_DOWN_BUSY, &dl->Flags)) {
if (arg == dl->last_skb) {
if ((dl->last_skb = skb_dequeue(&dl->queue))) {
dl->inst.up.func(&dl->inst.up,
dl->last_skb->priority,
DINFO_SKB, 0, dl->last_skb);
} else
test_and_clear_bit(FLG_DOWN_BUSY,
&dl->Flags);
}
}
nskb = skb_clone(arg, GFP_ATOMIC);
ret = dl->sif.func(&dl->sif, prim, dinfo, len, arg);
if (ret) {
dev_kfree_skb(nskb);
if (dl->inst.down.func)
ret = dl->inst.down.func(&dl->inst.down, prim,
dinfo, len, arg);
} else {
if (dl->inst.down.func)
ret = dl->inst.down.func(&dl->inst.down, prim,
dinfo, len, nskb);
else
dev_kfree_skb(nskb);
if (ret)
dev_kfree_skb(nskb);
ret = 0; /* first delivery was OK */
}
} else {
ret = dl->sif.func(&dl->sif, prim, dinfo, len, arg);
if (ret) {
if (dl->inst.down.func)
ret = dl->inst.down.func(&dl->inst.down, prim,
dinfo, len, arg);
} else {
if (dl->inst.down.func)
dl->inst.down.func(&dl->inst.down, prim,
dinfo, len, arg);
}
}
return(ret);
}
static int
to_peer(hisaxif_t *hif, u_int prim, int dinfo, int len, void *arg) {
int ret = -EINVAL;
devicelayer_t *dl;
struct sk_buff *skb;
printk(KERN_DEBUG __FUNCTION__ ": prim(%x) di(%x) l(%d) arg(%p)\n",
prim, dinfo, len, arg);
if (!hif)
return(-EINVAL);
dl = hif->fdata;
if (!dl)
return(ret);
if (!dl->slave) {
if (dl->inst.up.func)
ret = dl->inst.up.func(&dl->inst.up, prim, dinfo,
len, arg);
return(ret);
}
if (dinfo == DINFO_SKB) {
if (test_and_set_bit(FLG_DOWN_BUSY, &dl->Flags)) {
skb = arg;
skb->priority = prim;
skb_queue_tail(&dl->queue, skb);
return(0);
}
dl->last_skb = arg;
ret = dl->inst.up.func(&dl->inst.up, prim, dinfo,
len, arg);
} else {
ret = dl->inst.up.func(&dl->inst.up, prim, dinfo,
len, arg);
}
return(ret);
}
static int
set_if(devicelayer_t *dl, u_int prim, hisaxif_t *hif)
{
int err = 0;
if (dl->slave && (hif->owner == dl->slave)) {
hif->peer = &dl->inst;
hif->fdata = dl;
hif->func = to_peer;
if ((prim & SUBCOMMAND_MASK) == REQUEST) {
if (dl->sif.stat == IF_NOACTIV) {
if (IF_TYPE(hif) == IF_UP)
dl->sif.stat = IF_DOWN;
else
dl->sif.stat = IF_UP;
dl->sif.owner = &dl->inst;
err = hif->owner->obj->own_ctrl(hif->owner,
MGR_SETIF | INDICATION, &dl->sif);
} else {
int_errtxt("REQ own stat(%x)", dl->sif.stat);
err= -EBUSY;
}
}
} else {
err = SetIF(&dl->inst, hif, prim, from_up_down, from_up_down, dl);
}
err = SetIF(&dl->inst, hif, prim, from_up_down, from_up_down, dl);
return(err);
}

View File

@ -43,6 +43,7 @@
#define MGR_CONNECT 0x0f3200
#define MGR_DISCONNECT 0x0f3300
#define MGR_SETIF 0x0f3400
#define MGR_ADDIF 0x0f3500
#define MGR_RELEASE 0x0f4500
#define MGR_CONTROL 0x0fe100
#define MGR_STATUS 0x0fe200
@ -219,7 +220,7 @@
#define IF_NOACTIV 0x00000000
#define IF_DOWN 0x01000000
#define IF_UP 0x02000000
#define IF_LOG 0x04000000
#define IF_CHAIN 0x04000000
#define IF_HANDSHAKE 0x08000000
#define IF_TYPEMASK 0x07000000
#define IF_ADDRMASK 0x00FFFFFF