/**************************************************************** * This driver can only be compiled as a module and it * can only be loaded ONCE per system. There is no * support yet for multiple cards with one driver. To * load more than one card, try creating multiple copies * of rlmod.o, naming the copies uniquely, and loading * one copy per card. * * This driver does not support probing. To change irq * or io port at runtime enter the following: * insmod rl2mod irq=x io=y * * *****************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_NET_RADIO /* If wireless extension exist in the kernel */ #include #endif /* CONFIG_NET_RADIO */ #include "lld.h" #include "rl2lls.h" #include ".version.h" /**************************************************************** * some LLD structures for use by send routine * * *****************************************************************/ #ifdef BUFFER static struct LLS_Buffers { struct LLDTxPacketDescriptor txDesc; struct LLDTxFragmentList txFragList; struct sk_buff *save_skbuff_ptr; } bfr_list[LLDMAXSEND]; int ring; #else static struct LLDTxPacketDescriptor txDesc; /* save pointer for release in LLSSendComplete */ static struct sk_buff *saveptr; static struct LLDTxFragmentList txFragList; #endif /**************************************************************** * LLS Routines Required by the LLD * * *****************************************************************/ void LLSReceiveLookAhead (unsigned_8 *Buffer, unsigned_16 Length, unsigned_16 Status, unsigned_16 RSSI) { struct LLDRxPacketDescriptor rxDesc; struct sk_buff *skb; struct net_local *lp = thisRangeLan.priv; int i; #ifdef WIRELESS_EXT lp->wstats.qual.level = RSSI; #endif /* WIRELESS_EXT */ /* allocate the buffer for the kernel */ skb=dev_alloc_skb(Length); if(skb==NULL) { lp->stats.rx_dropped++; return; } /* prepare a 1-item fragment list for LLD */ rxDesc.LLDRxFragCount = 1; rxDesc.LLDRxFragList[0].FSDataLen = Length; rxDesc.LLDRxFragList[0].FSDataPtr = skb->data; /* retrieve whole packet from LLD */ LLDReceive(&rxDesc,0,Length); /* load up the other elements for the kernel */ skb->len=Length; skb->dev=&thisRangeLan; skb->protocol=eth_type_trans(skb,&thisRangeLan); /* increments the stats count */ lp->stats.rx_packets++; /* tell linux we have a packet*/ netif_rx(skb); } unsigned_16 LLSSendComplete (struct LLDTxPacketDescriptor *PktDesc) { struct net_local *lp = thisRangeLan.priv; int i; /* note the successful transmission */ lp->attempted_tx_packets++; #ifdef BUFFER i = PktDesc->LLDTxdriverWS[1]; #if 1 if (bfr_list[i].txDesc.LLDTxdriverWS[0] == CLEAR) printk("buffer wasn't used!\n"); else { #endif /* free up the kernel buffer and the buffer structure element */ dev_kfree_skb(bfr_list[i].save_skbuff_ptr, FREE_WRITE); bfr_list[i].txDesc.LLDTxdriverWS[0] = CLEAR; /* send completed, free up the resources */ /* only check for equality, though. Otherwise, rl2_start_xmit */ /* can be reentrant, i.e., don't want to set tbusy=0 if _start_xmit */ /* needs it =1. */ if(LLDMAXSEND-1 == outcount--) { thisRangeLan.tbusy = 0; mark_bh(NET_BH); } #if 1 } #endif #else /* free the SKB and let upper layer know we sent the packet */ dev_kfree_skb(saveptr, FREE_WRITE); thisRangeLan.tbusy = 0; mark_bh(NET_BH); #endif } unsigned_8 LLSRegisterInterrupt (unsigned_8 IntNum, void (*CallBackFunc) ()) { if(request_irq(IntNum, &rl2_interrupt, 0, thisRangeLan.name, &thisRangeLan)) { return FAILURE; } return SUCCESS; } unsigned_16 LLSGetCurrentTime (void) { /* just system ticks for use by the CLLD. I believe it's calibrated by linux to be 1ms/jiffy. */ return jiffies; } unsigned_32 LLSGetCurrentTimeLONG (void) { /* just system ticks for use by the CLLD. I believe it's calibrated by linux to be 1ms/jiffy. */ return jiffies; } /**************************************************************** * These 3 LLS routines will never be called but are * included since the linker will expect them * * *****************************************************************/ void LLSRawReceiveLookAhead (unsigned_8 Buffer[], unsigned int Length) { printk("%s: RawReceiveLA %d bytes\n", thisRangeLan.name, Length); } unsigned_16 LLSRawSendComplete (unsigned_8 *Buffer) { printk("%s: RawSendComplete\n", thisRangeLan.name); } unsigned_8 LLSDeRegisterInterrupt (unsigned_8 IntNum) { printk("%s: LLSDDeRegisterInt\n", thisRangeLan.name); return SUCCESS; } void LLSPingReceiveLookAhead (unsigned_8 *Buffer, unsigned_16 Length, unsigned_16 Status, unsigned_16 RSSI) { printk("%s: PingReceiveLookAhead\n", thisRangeLan.name); } unsigned_16 LLSSendProximPktComplete (struct LLDTxPacketDescriptor FAR *PktDesc, unsigned_8 Status) { printk("%s: LLSSendProximPktComplete\n", thisRangeLan.name); } /**************************************************************** ***************************************************************** * Linux-required routines start here. These routines * will make use of the LLD routines in CLLD and do * the kernel registration, init, close, etc. * * ***************************************************************** *****************************************************************/ static int rl2_ioctl(struct device *dev, struct ifreq *rq, int cmd) { #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ struct iwreq * wrq = (struct iwreq *) rq; #endif /* WIRELESS_EXT */ struct rl2_ioctl *ioc = (struct rl2_ioctl *) &rq->ifr_data; unsigned char tmp[128]; int ret = 0; /* support rl2cfg to be backward compatible */ if (cmd == SIOCDEVPRIVATE) { switch(ioc->cmd) { case RL2NODETABLE: if(!suser()) return -EPERM; rl2_ioctl_printnodes(); break; case RL2INFO: rl2_ioctl_nodeinfo(); break; case RL2MASTEROPTS: if(!suser()) return -EPERM; memcpy_fromfs(tmp,ioc->data,sizeof(struct rl2_master_opts)); rl2_ioctl_setmaster( (struct rl2_master_opts*) tmp); break; case RL2LISTAPS: RL2_Ioctl_Listaps(); break; case RL2ROAM: if(!suser()) return -EPERM; LLDRoam(); break; } } #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ /* support wireless extensions to the kernel */ else { switch(cmd) { /* we'll set a name that identifies the card */ case SIOCGIWNAME: if (LLDMicroISA) { strcpy(wrq->u.name, "RL2/Micro ISA"); return 0; } else if (LLDOEM) { strcpy(wrq->u.name, "RL2/Mini ISA"); return 0; } if (LLDOnePieceFlag) { strcpy(wrq->u.name, "RL2/7400"); return 0; } else if (LLDPCMCIA) { strcpy(wrq->u.name, "RL2/7200"); return 0; } strcpy(wrq->u.name, "RL2/ISA"); break; /* This domain in RangeLAN2-speak */ /* Set it if SU */ case SIOCSIWNWID: if(!suser()) { ret = -EPERM; break; } if (wrq->u.nwid.on == 0) { ret = -EOPNOTSUPP; break; } if (wrq->u.nwid.nwid<16 && wrq->u.nwid.nwid>=0) { LLDDomain = wrq->u.nwid.nwid; LLDNeedReset = 1; } else ret = -EINVAL; break; /* get domain */ case SIOCGIWNWID: wrq->u.nwid.nwid = LLDDomain; break; /* this is channel in RangeLAN2-speak */ /* set it if SU */ case SIOCSIWFREQ: if(!suser()) return -EPERM; if (wrq->u.freq.m<16 && wrq->u.freq.m>0) { LLDChannel = (wrq->u.freq.m); LLDNeedReset = 1; } else ret = -EINVAL; break; /* get channel */ case SIOCGIWFREQ: wrq->u.freq.e = 0; wrq->u.freq.m = LLDChannel; break; case SIOCSIPSUBC: if(!suser()) return -EPERM; break; case SIOCGIPSUBC: break; case SIOCGIWRANGE: /* Basic checking... */ if(wrq->u.data.pointer != (caddr_t) 0) { struct iw_range range; /* Verify the user buffer */ ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(struct iw_range)); if(ret) break; /* Set the length (useless : its constant...) */ wrq->u.data.length = sizeof(struct iw_range); /* Set information in the range struct */ range.throughput = 1.6 * 1024 * 1024; /* don't argue on this ! */ range.min_nwid = 0; range.max_nwid = 15; /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable) */ range.num_channels = 15; range.num_frequency = 0; range.sensitivity = 0; range.max_qual.qual = 2; range.max_qual.level = 255; range.max_qual.noise = 0; /* Copy structure to the user buffer */ memcpy_tofs(wrq->u.data.pointer, &range, sizeof(struct iw_range)); } break; case SIOCGIWPRIV: /* Basic checking... */ if(wrq->u.data.pointer != (caddr_t) 0) { struct iw_priv_args priv[] = { /* cmd, set_args, get_args, name */ { SIOCSIPSUBC, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0, "setsubchan" }, { SIOCGIPSUBC, 0, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, "getsubchan" }, { SIOCSIPSTNT, IW_PRIV_TYPE_BYTE | 16, 0, "sethisto" }, { SIOCGIPSTNT, 0, IW_PRIV_TYPE_INT | 16, "gethisto" } }; /* Verify the user buffer */ ret = verify_area(VERIFY_WRITE, wrq->u.data.pointer, sizeof(priv)); if(ret) break; /* Set the number of ioctl available */ wrq->u.data.length = 4; /* Copy structure to the user buffer */ memcpy_tofs(wrq->u.data.pointer, (u_char *) priv, sizeof(priv)); } break; default: ret = -EOPNOTSUPP; } } #endif /* WIRELESS_EXT */ /* make sure we get messages from the card */ if (!poll_on) LLDPoll(); return ret; } /**************************************************************** * polltime () * routine to yield some time to LLDPoll * * *****************************************************************/ void polltime(unsigned long d) { if(poll_on) { LLDPoll(); init_timer(&poll_timer); poll_timer.function=polltime; poll_timer.expires=jiffies + POLL_FREQ; add_timer(&poll_timer); } } static void rl2_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* check for re-entrancy and then all LLDIsr() */ if(thisRangeLan.interrupt) printk("%s: reentrant IRQ\n", thisRangeLan.name); /* process the interrupt */ thisRangeLan.interrupt = 1; LLDIsr(); thisRangeLan.interrupt = 0; return; } static int rl2_start_xmit(struct sk_buff *skb, struct device *dev) { struct net_local *lp = dev->priv; int i, tmp, result; /* check if we've flagged ourselves as busy. Upper layers should call us if we're busy unless concerned we are dead. */ if(dev->tbusy) { /* LLD will restart itself so we'll ignore upper layer when it kicks us */ return 1; } /* This checks if the system thinks we've missed the tx-done (LLSSendComplete) signal. If this happens it's either impatient or CLLD has a bug. */ if (skb == NULL ) { printk("%s: missed LLSSendComplete interrupt.\n", thisRangeLan.name); dev_tint(dev); return 0; } if(skb->len <= 0 || dev == NULL) { printk("%s: null device\n", thisRangeLan.name); return 0; } /* set us as busy and also check if it was busy */ if(set_bit(0,(void *)&dev->tbusy) != 0) { printk("%s: Transmitter access conflict.\n", thisRangeLan.name); dev_kfree_skb(skb, FREE_WRITE); return 0; } #ifdef BUFFER /* find the first free buffer pointer */ for (i=0 ; istats.tx_dropped++; dev_kfree_skb(skb, FREE_WRITE); return 0; } i = ring; #endif bfr_list[i].txDesc.LLDTxdriverWS[0] = SET; /* save the buffer pointer to free in LLSSendComplete */ bfr_list[i].save_skbuff_ptr = skb; /*fill in the info for transmit decriptor*/ bfr_list[i].txFragList.LLDTxFragList[0].FSDataPtr = skb->data; bfr_list[i].txDesc.LLDTxDataLength = bfr_list[i].txFragList.LLDTxFragList[0].FSDataLen = skb->len; /* give packet over to LLD for transmission */ if (bfr_list[i].txDesc.LLDTxdriverWS[0]==CLEAR) printk ("Clear going into LLDSend!!!\n"); result = LLDSend(&bfr_list[i].txDesc); #if 1 if (outcount > LLDMAXSEND-1) printk("max outcount reached = %d\n", outcount); #endif /* check for max buffering. */ if (outcount++ < LLDMAXSEND-1) { dev->tbusy = 0; mark_bh(NET_BH); } /* we're trying to be very careful here. LLSSendComplete() */ /* is looking for outcount to be = to LLDMAXSEND to set tbusy=0 */ /* We want to be sure that doesn't happen until it's ok here. */ /* so don't increment outcount until we're cool on tbusy or we */ /* we might cause reentrancy. */ #else /* save the skb for release in LLSSendComplete */ saveptr = skb; /* point frag list to our static structure that has 1 fragments */ txFragList.LLDTxFragmentCount = 1; txDesc.LLDTxFragmentListPtr = &txFragList; txFragList.LLDTxFragList[0].FSDataPtr = skb->data; /* fill in the length for transmit decriptor */ txDesc.LLDTxDataLength = skb->len; txDesc.LLDImmediateDataLength = 0; txFragList.LLDTxFragList[0].FSDataLen = skb->len; result = LLDSend(&txDesc); #endif /* return codes aren't used by LLDSend() as Linux expects but but we'll check anyway. 0 means it took it (not that it was sent). 1 means it was queued (delayed). 0xff means there was an error but I don't belive LLDSend() will return that to us (keep in mind LLDSend() gets call within CLLD also. */ if(result==1) printk("%s: send delayed\n", thisRangeLan.name); else if(result) { lp->stats.tx_errors++; printk("%s: LLDsend transmit failure!!\n", thisRangeLan.name); } return 0; } static struct enet_statistics *rl2_get_stats(struct device *dev) { struct net_local *lp = dev->priv; int clld_dropped; clld_dropped = (int) (LLDOutSyncDrp + LLDTimedQDrp + LLDFailureDrp); clld_dropped += (int) (LLDOutSyncQDrp + LLDNoReEntrantDrp + LLDSendDisabledDrp); lp->stats.tx_packets = lp->attempted_tx_packets - clld_dropped; lp->stats.tx_errors = clld_dropped; return &(lp->stats); } #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ /***************************************************************** Get wireless statistics Called by /proc/net/wireless... *****************************************************************/ static struct iw_statistics *rl2_get_wireless_stats(struct device * dev) { struct net_local *lp = dev->priv; if ( (lp->wstats.status = LLDSyncState) ) lp->wstats.status = 1; /* Copy data to wireless stuff */ if ( (lp->wstats.qual.qual = LLDSyncState) ) if (LLDTxMode) lp->wstats.qual.qual = 2; else lp->wstats.qual.qual = 1; lp->wstats.qual.noise = 0; lp->wstats.qual.updated = 0; lp->wstats.discard.nwid = 0L; lp->wstats.discard.code = 0L; lp->wstats.discard.misc = 0L; return &(lp->wstats); } #endif /* WIRELESS_EXT */ /****************************************************************/ /* Init Failure (reason) Codes for rl2_probe(), i.e, LLDInit()*/ /* 0 - Successful Initialization */ /* 1 - Error resetting the RFNC */ /* 2 - Error setting the interrupt vector */ /* 3 - Error sending the initialize command */ /* 4 - Error getting the ROM version */ /* 5 - Error getting the global address */ /* 6 - Error setting the local address */ /* 7 - Error setting the inactivity time out */ /* 8 - Error disabling hopping */ /* 9 - Error setting security ID */ /* 10 - Error sending configure MAC */ /* 11 - Error sending set roaming parameters command*/ /* 12 - Error sending multicast command */ /* 13 - Error in card and socket services */ /* 14 - Error configuring socket - improper card seating*/ /* 15 - Error configuring socket - power imporperly supplied*/ /* 16 - Error configuring socket - no PCMCIA bus ready signal*/ /****************************************************************/ static int rl2_probe(struct device *dev) { int inival,i; unsigned_32 flags; /* set the card type */ switch (CardType) { case RL2ISA: /* RangeLAN2 ISA - set as default */ LLDPCMCIA = 0; LLDOEM = 0; LLDMicroISA = 0; break; case RL2MISA: /* RangeLAN2 630x series Mini ISA */ LLDPCMCIA = 0; LLDOEM = 1; LLDMicroISA = 0; break; case RL2UISA: /* RangeLAN2 633x series Micro design-in module */ LLDPCMCIA = 0; LLDOEM = 1; LLDMicroISA = 1; break; case RL2PCCARD: /* RangeLAN2 PC Cards (test implementation) */ LLDPCMCIA = 1; LLDOEM = 0; LLDMicroISA = 0; break; case SYMPNPISA: /* Symphony PnP ISA Card */ LLDPCMCIA = 0; LLDOEM = 0; LLDMicroISA = 1; break; default: /* invalid setting */ printk("%s: Can't init RangeLan, Invalid card type.\n",dev->name); return -ENODEV; break; } /* If it's a PC Card, dummy_cs.c already got the wndow for us. Just use it. */ if (!LLDPCMCIA) { /* this should be code to probe for cards */ /* We don't support it and supposedly it's bad to */ /* autoprobe in a module. */ if(dev->base_addr == 0) { printk("%s: RangeLan can't autoprobe\n",dev->name); return -ENODEV; } /* check if this io region is used. */ if (check_region(dev->base_addr, LLDIORange1)) return -ENODEV; /* request the resources and register the region */ request_region(dev->base_addr, LLDIORange1, thisRangeLan.name); } LLDIOAddress1 = dev->base_addr; LLDIntLine1 = dev->irq; /* LLDInit() brings up the card with all default values or values that are preset. It returns error codes as commented above. */ flags=PreserveFlag(); inival = LLDInit(); RestoreFlag(flags); if(inival) { printk("%s: Can't init RangeLan, reason %d.\n",dev->name,inival); free_irq(dev->irq, &thisRangeLan); release_region(dev->base_addr, LLDIORange1); return -ENODEV; } /* print info to logs since we initialized properly */ printk(version); printk("rlmod.o: Original linux port, 2/96, by Paul "); printk("Chinn (loomer@1000klub.com).\n"); #ifdef BUFFER printk("%s: Proxim Card Type %d (BUFF) %#3.3lx, IRQ %d, ROM %s, mac", #else printk("%s: Proxim Card Type %d (NOBUFF) %#3.3lx, IRQ %d, ROM %s, mac", #endif dev->name, CardType, dev->base_addr, dev->irq, LLDROMVersion); for(i=0;i<6;i++) { dev->dev_addr[i] = LLDNodeAddress[i]; printk(" %2.2x", dev->dev_addr[i]); } printk(".\n"); /* Initialize the private space in the device structure. */ if (dev->priv == NULL) { dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); if (dev->priv == NULL) return -ENOMEM; } memset(dev->priv, 0, sizeof(struct net_local)); /* register some routines with the kernel */ dev->open = &rl2_open; dev->stop = &rl2_close; dev->hard_start_xmit = &rl2_start_xmit; dev->get_stats = rl2_get_stats; /* dev->set_multicast_list = &set_multicast_list; */ dev->do_ioctl = rl2_ioctl; #ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ dev->get_wireless_stats = rl2_get_wireless_stats; #endif ether_setup(dev); /* all done */ return 0; } int rl2_init() { /* CLLD does it's own resets. If this gets called, CLLD */ /* may have crashed. */ printk("%s: rl2_init was called.\n", thisRangeLan.name); return 1; } #ifdef MODULE int init_module(void) { int result = 0; /* some flags that can be set when the module is loaded */ thisRangeLan.base_addr = io; thisRangeLan.irq = irq; LLDMemoryAddress1 = win; /* in Linux, an io of 0 means auto probe. I've read that it's not */ /* a good idea to autoprobe in loadable modules. Also, I don't know */ /* how to support it for RL2. */ if (io == 0) { printk(KERN_WARNING "rlmod.o: This driver doesn't support auto-probing!\n"); return 0; } /* Register the device with the kernel. Note that thisRangeLan has */ /* rl2_probe as a paramter. register_netdev call it. rl2_probe does the */ /* initialization stuff. */ if (result = register_netdev(&thisRangeLan) != 0) return result; return 0; } static int rl2_open(struct device *dev) { struct net_local *lp = dev->priv; int i; /* what are we checking here? I think if this *works*, the driver is up so we don't open. */ if(LLDReset()) return -ENODEV; /* start the polling timer */ poll_on = 1; init_timer(&poll_timer); poll_timer.expires=POLL_FREQ; poll_timer.function=polltime; add_timer(&poll_timer); #ifdef BUFFER outcount = ring = 0; /* initialize our pre-defined buffers for CLLD */ for (i=0 ; istats.rx_packets = lp->attempted_tx_packets = 0; lp->stats.rx_dropped = lp->stats.tx_dropped = 0; lp->stats.rx_errors = lp->stats.tx_errors = 0; lp->stats.multicast = 0; /* init some stuff in our kernel device structure */ dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; /* flag the module as 'in use' */ MOD_INC_USE_COUNT; return 0; } static int rl2_close(struct device *dev) { /* flag the modules as 'not in use' */ MOD_DEC_USE_COUNT; /* shut down the poll timer */ del_timer(&poll_timer); poll_on = 0; /* stop the card. */ LLDStop(); /* tell the kernel the device isn't running */ dev->start = 0; return 0; } void cleanup_module(void) { /* stop the poll timer for LLDPoll() */ del_timer(&poll_timer); /* free kernel memory that isn't freed otherwise. */ if (thisRangeLan.priv) kfree_s(thisRangeLan.priv, sizeof(struct net_local)); /* unregister the driver from the kernel */ unregister_netdev(&thisRangeLan); /* free the resources. */ free_irq(thisRangeLan.irq, &thisRangeLan); release_region(thisRangeLan.base_addr, LLDIORange1); } #endif /* MODULE */ /**************************************************************** ***************************************************************** * The following stuff is all called from rl2_ioctl() * * ***************************************************************** *****************************************************************/ char *types[]={"Station", "Alt", "Master"}; static struct timer_list list_timer={NULL,NULL,10*HZ,0,EndSearch}; /**************************************************************** LLDSearchAndContinue () * * an experimental routine to generate a list of * masters within the current domain * * *****************************************************************/ unsigned_8 LLDSearchAndContinue (void) {/* unsigned_8 i; struct PacketizeSearchCont *CmdPktPtr; CmdPktPtr = (struct PacketizeSearchCont *) PacketizePktBuf; CmdPktPtr->PSCHeader.PHCmd = INIT_COMMANDS_CMD; CmdPktPtr->PSCHeader.PHSeqNo = PacketSeqNum | RAWMASK; IncPacketSeqNum (); CmdPktPtr->PSCHeader.PHFnNo = SEARCH_N_CONT_FN; CmdPktPtr->PSCHeader.PHRsv = RESERVED; CmdPktPtr->PSCDomain = (unsigned_8)(LLDDomain << 4); CmdPktPtr->PSCListSize = 1; CmdPktPtr->PSCSyncChSub = 0; for ( i = 0; i < NAMELENGTH; i++ ) { CmdPktPtr->PSCSyncName [i] = 0; } if (LLDPacketizeSend ((unsigned_8 *)CmdPktPtr, sizeof(struct PacketizeSearchCont))) { return (FAILURE); } return (SUCCESS); */} /**************************************************************** EndSearch () * * Stops what was initiated by * LLDSearchAndContinue () * * *****************************************************************/ void EndSearch(unsigned long d) { static unsigned_8 abortcmd[]={'A',0,3,0 }; abortcmd[1] = PacketSeqNum; IncPacketSeqNum (); LLDPacketizeSend ((unsigned_8 *)abortcmd,4); printk("EndOfSearch\n"); } void rl2_ioctl_nodeinfo(void) { printk("%s d=%d CardType=%d ",types[LLDNodeType], LLDDomain, CardType); if(LLDNodeType != MASTER) { if(LLDSyncState) printk("Synced to %s, c/s=%d/%d\n", LLDMSTASyncName,LLDMSTASyncChannel,LLDMSTASyncSubChannel); else printk("Out of Sync\n"); } else printk("Name=%s c/s=%d/%d\n", LLDMSTAName, LLDChannel, LLDSubChannel); } /**************************************************************** RL2_Ioctl_Listaps () * * Lists the APs find by * LLDSearchAndContinue () * * *****************************************************************/ void RL2_Ioctl_Listaps(void) { if(LLDNodeType != MASTER) { printk("Search&Cont=%d\n",LLDSearchAndSync()); printk("Synced to %s, c/s=%d/%d\n", LLDMSTASyncName,LLDMSTASyncChannel,LLDMSTASyncSubChannel); list_timer.expires=jiffies + 10*HZ; add_timer(&list_timer); } else printk("To use this function, make the card a station.\n"); } void rl2_ioctl_setmaster(struct rl2_master_opts *opts) { int i, result; if(opts->type == 4) { /*set security ID*/ for(i=0; i<3; i++) LLDSecurityID[i]=opts->id[i]; printk("Setting ID to %2.2x%2.2x%2.2x = ", LLDSecurityID[0],LLDSecurityID[1],LLDSecurityID[2]); SendEnableEEPROMWrite(); result = SendSetSecurityID(); printk("%d \n", result); SendDisableEEPROMWrite(); Delay(1000); /*give the command a chance to complete*/ LLDNeedReset=1; return; } if(opts->type <= MASTER) LLDNodeType = opts->type; if(opts->domain < 16) LLDDomain = opts->domain; if(opts->channel <= 15) LLDChannel = opts->channel; if(opts->subchannel <= 16) LLDSubChannel = opts->subchannel; if(opts->name[0]) memcpy(LLDMSTAName,opts->name,12); if(opts->roamconfig <= 2) LLDRoamConfig(opts->roamconfig); if(opts->macoptimize <= 2) LLDMacOptimize(opts->macoptimize); LLDNeedReset=1; } void rl2_ioctl_printnodes(void) {/* unsigned_8 link; int i; printk("rl2_ioctl: Displaying NodeTable:\n"); link = MRUNodeEntry; while(link != 0xff) { for(i=0;i<6;i++) printk("%2.2x:",NodeTable[link].Address[i]); if(NodeTable[link].BridgeState) { printk(" via "); for(i=0;i<6;i++) printk("%2.2x:",NodeTable[link].Route[i]); printk("t/o in %d secs", ( BRIDGETIMEOUT - (LLSGetCurrentTime() - NodeTable[link].BridgeStartTime) ) / TPS); } printk("\n"); link = NodeTable[link].TimeLink; } */}