📄 sdla_fr.c
字号:
static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming);static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number);/* Lock Functions: SMP supported */void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags);void s508_s514_lock(sdla_t *card, unsigned long *smp_flags);unsigned short calc_checksum (char *, int);static int setup_fr_header(struct sk_buff *skb, struct net_device* dev, char op_mode);/****** Public Functions ****************************************************//*============================================================================ * Frame relay protocol initialization routine. * * This routine is called by the main WANPIPE module during setup. At this * point adapter is completely initialized and firmware is running. * o read firmware version (to make sure it's alive) * o configure adapter * o initialize protocol-specific fields of the adapter data space. * * Return: 0 o.k. * < 0 failure. */int wpf_init(sdla_t *card, wandev_conf_t *conf){ int err; fr508_flags_t* flags; union { char str[80]; fr_conf_t cfg; } u; fr_buf_info_t* buf_info; int i; printk(KERN_INFO "\n"); /* Verify configuration ID */ if (conf->config_id != WANCONFIG_FR) { printk(KERN_INFO "%s: invalid configuration ID %u!\n", card->devname, conf->config_id); return -EINVAL; } /* Initialize protocol-specific fields of adapter data space */ switch (card->hw.fwid) { case SFID_FR508: card->mbox = (void*)(card->hw.dpmbase + FR508_MBOX_OFFS); card->flags = (void*)(card->hw.dpmbase + FR508_FLAG_OFFS); if(card->hw.type == SDLA_S514) { card->mbox += FR_MB_VECTOR; card->flags += FR_MB_VECTOR; } card->isr = &fr_isr; break; default: return -EINVAL; } flags = card->flags; /* Read firmware version. Note that when adapter initializes, it * clears the mailbox, so it may appear that the first command was * executed successfully when in fact it was merely erased. To work * around this, we execute the first command twice. */ if (fr_read_version(card, NULL) || fr_read_version(card, u.str)) return -EIO; printk(KERN_INFO "%s: running frame relay firmware v%s\n", card->devname, u.str); /* Adjust configuration */ conf->mtu += FR_HEADER_LEN; conf->mtu = (conf->mtu >= MIN_LGTH_FR_DATA_CFG) ? min_t(unsigned int, conf->mtu, FR_MAX_NO_DATA_BYTES_IN_FRAME) : FR_CHANNEL_MTU + FR_HEADER_LEN; conf->bps = min_t(unsigned int, conf->bps, 2048000); /* Initialze the configuration structure sent to the board to zero */ memset(&u.cfg, 0, sizeof(u.cfg)); memset(card->u.f.dlci_to_dev_map, 0, sizeof(card->u.f.dlci_to_dev_map)); /* Configure adapter firmware */ u.cfg.mtu = conf->mtu; u.cfg.kbps = conf->bps / 1000; u.cfg.cir_fwd = u.cfg.cir_bwd = 16; u.cfg.bc_fwd = u.cfg.bc_bwd = 16; u.cfg.options = 0x0000; printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname); switch (conf->u.fr.signalling) { case WANOPT_FR_ANSI: u.cfg.options = 0x0000; break; case WANOPT_FR_Q933: u.cfg.options |= 0x0200; break; case WANOPT_FR_LMI: u.cfg.options |= 0x0400; break; case WANOPT_NO: u.cfg.options |= 0x0800; break; default: printk(KERN_INFO "%s: Illegal Signalling option\n", card->wandev.name); return -EINVAL; } card->wandev.signalling = conf->u.fr.signalling; if (conf->station == WANOPT_CPE) { if (conf->u.fr.signalling == WANOPT_NO){ printk(KERN_INFO "%s: ERROR - For NO signalling, station must be set to Node!", card->devname); return -EINVAL; } u.cfg.station = 0; u.cfg.options |= 0x8000; /* auto config DLCI */ card->u.f.dlci_num = 0; } else { u.cfg.station = 1; /* switch emulation mode */ /* For switch emulation we have to create a list of dlci(s) * that will be sent to be global SET_DLCI_CONFIGURATION * command in fr_configure() routine. */ card->u.f.dlci_num = min_t(unsigned int, max_t(unsigned int, conf->u.fr.dlci_num, 1), 100); for ( i = 0; i < card->u.f.dlci_num; i++) { card->u.f.node_dlci[i] = (unsigned short) conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16; } } if (conf->clocking == WANOPT_INTERNAL) u.cfg.port |= 0x0001; if (conf->interface == WANOPT_RS232) u.cfg.port |= 0x0002; if (conf->u.fr.t391) u.cfg.t391 = min_t(unsigned int, conf->u.fr.t391, 30); else u.cfg.t391 = 5; if (conf->u.fr.t392) u.cfg.t392 = min_t(unsigned int, conf->u.fr.t392, 30); else u.cfg.t392 = 15; if (conf->u.fr.n391) u.cfg.n391 = min_t(unsigned int, conf->u.fr.n391, 255); else u.cfg.n391 = 2; if (conf->u.fr.n392) u.cfg.n392 = min_t(unsigned int, conf->u.fr.n392, 10); else u.cfg.n392 = 3; if (conf->u.fr.n393) u.cfg.n393 = min_t(unsigned int, conf->u.fr.n393, 10); else u.cfg.n393 = 4; if (fr_configure(card, &u.cfg)) return -EIO; if (card->hw.type == SDLA_S514) { buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR + FR508_RXBC_OFFS); card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase); card->u.f.rxmb_base = (void*)(buf_info->rse_base + card->hw.dpmbase); card->u.f.rxmb_last = (void*)(buf_info->rse_base + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) + card->hw.dpmbase); }else{ buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS); card->rxmb = (void*)(buf_info->rse_next - FR_MB_VECTOR + card->hw.dpmbase); card->u.f.rxmb_base = (void*)(buf_info->rse_base - FR_MB_VECTOR + card->hw.dpmbase); card->u.f.rxmb_last = (void*)(buf_info->rse_base + (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) - FR_MB_VECTOR + card->hw.dpmbase); } card->u.f.rx_base = buf_info->buf_base; card->u.f.rx_top = buf_info->buf_top; card->u.f.tx_interrupts_pending = 0; card->wandev.mtu = conf->mtu; card->wandev.bps = conf->bps; card->wandev.interface = conf->interface; card->wandev.clocking = conf->clocking; card->wandev.station = conf->station; card->poll = NULL; card->exec = &wpf_exec; card->wandev.update = &update; card->wandev.new_if = &new_if; card->wandev.del_if = &del_if; card->wandev.state = WAN_DISCONNECTED; card->wandev.ttl = conf->ttl; card->wandev.udp_port = conf->udp_port; card->disable_comm = &disable_comm; card->u.f.arp_dev = NULL; /* Intialize global statistics for a card */ init_global_statistics( card ); card->TracingEnabled = 0; /* Interrupt Test */ Intr_test_counter = 0; card->intr_mode = INTR_TEST_MODE; err = intr_test( card ); printk(KERN_INFO "%s: End of Interrupt Test rc=0x%x count=%i\n", card->devname,err,Intr_test_counter); if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { printk(KERN_ERR "%s: Interrupt Test Failed, Counter: %i\n", card->devname, Intr_test_counter); printk(KERN_ERR "Please choose another interrupt\n"); err = -EIO; return err; } printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", card->devname, Intr_test_counter); /* Apr 28 2000. Nenad Corbic * Enable commnunications here, not in if_open or new_if, since * interfaces come down when the link is disconnected. */ /* If you enable comms and then set ints, you get a Tx int as you * perform the SET_INT_TRIGGERS command. So, we only set int * triggers and then adjust the interrupt mask (to disable Tx ints) * before enabling comms. */ if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY | FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) , card->wandev.mtu, 0)) { return -EIO; } flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER); if (fr_comm_enable(card)) { return -EIO; } wanpipe_set_state(card, WAN_CONNECTED); spin_lock_init(&card->u.f.if_send_lock); printk(KERN_INFO "\n"); return 0;}/******* WAN Device Driver Entry Points *************************************//*============================================================================ * Update device status & statistics. */static int update(struct wan_device* wandev){ volatile sdla_t* card; unsigned long timeout; fr508_flags_t* flags; /* sanity checks */ if ((wandev == NULL) || (wandev->private == NULL)) return -EFAULT; if (wandev->state == WAN_UNCONFIGURED) return -ENODEV; card = wandev->private; flags = card->flags; card->u.f.update_comms_stats = 1; card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE; flags->imask |= FR_INTR_TIMER; timeout = jiffies; for(;;) { if(card->u.f.update_comms_stats == 0) break; if (time_after(jiffies, timeout + 1 * HZ)){ card->u.f.update_comms_stats = 0; return -EAGAIN; } } return 0;}/*============================================================================ * Create new logical channel. * This routine is called by the router when ROUTER_IFNEW IOCTL is being * handled. * o parse media- and hardware-specific configuration * o make sure that a new channel can be created * o allocate resources, if necessary * o prepare network device structure for registaration. * * Return: 0 o.k. * < 0 failure (channel will not be created) */static int new_if(struct wan_device* wandev, struct net_device* dev, wanif_conf_t* conf){ sdla_t* card = wandev->private; fr_channel_t* chan; int dlci = 0; int err = 0; if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { printk(KERN_INFO "%s: Invalid interface name!\n", card->devname); return -EINVAL; } /* allocate and initialize private data */ chan = kmalloc(sizeof(fr_channel_t), GFP_KERNEL); if (chan == NULL) return -ENOMEM; memset(chan, 0, sizeof(fr_channel_t)); strcpy(chan->name, conf->name); chan->card = card; /* verify media address */ if (isdigit(conf->addr[0])) { dlci = dec_to_uint(conf->addr, 0); if (dlci && (dlci <= HIGHEST_VALID_DLCI)) { chan->dlci = dlci; } else { printk(KERN_ERR "%s: Invalid DLCI %u on interface %s!\n", wandev->name, dlci, chan->name); err = -EINVAL; } } else { printk(KERN_ERR "%s: Invalid media address on interface %s!\n", wandev->name, chan->name); err = -EINVAL; } if ((chan->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){ printk(KERN_INFO "%s: Enabling, true interface type encoding.\n", card->devname); } /* Setup wanpipe as a router (WANPIPE) even if it is * a bridged DLCI, or as an API */ if (strcmp(conf->usedby, "WANPIPE") == 0 || strcmp(conf->usedby, "BRIDGE") == 0 || strcmp(conf->usedby, "BRIDGE_N") == 0){ if(strcmp(conf->usedby, "WANPIPE") == 0){ chan->common.usedby = WANPIPE; printk(KERN_INFO "%s: Running in WANPIPE mode.\n", card->devname); }else if(strcmp(conf->usedby, "BRIDGE") == 0){ chan->common.usedby = BRIDGE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -