📄 sdla_fr.c
字号:
if (sendpacket[1] == 0x00 && sendpacket[2] == 0x80 && sendpacket[6] == 0x81 && sendpacket[7] == 0x37) { /* It's an IPX packet */ if (!enable_IPX) { /* Return 1 so we don't pass it up the stack. */ return 1; } } else { /* It's not IPX so return and pass it up the stack. */ return 0; } if (sendpacket[24] == 0x90 && sendpacket[25] == 0x04) { /* It's IPXWAN */ if (sendpacket[10] == 0x02 && sendpacket[42] == 0x00) { /* It's a timer request packet */ printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n", devname); /* Go through the routing options and answer no to every */ /* option except Unnumbered RIP/SAP */ for (i = 49; sendpacket[i] == 0x00; i += 5) { /* 0x02 is the option for Unnumbered RIP/SAP */ if (sendpacket[i + 4] != 0x02) { sendpacket[i + 1] = 0; } } /* Skip over the extended Node ID option */ if (sendpacket[i] == 0x04) i += 8; /* We also want to turn off all header compression opt. */ for (; sendpacket[i] == 0x80;) { sendpacket[i + 1] = 0; i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; } /* Set the packet type to timer response */ sendpacket[42] = 0x01; printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n", devname); } else if (sendpacket[42] == 0x02) { /* This is an information request packet */ printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n", devname); /* Set the packet type to information response */ sendpacket[42] = 0x03; /* Set the router name */ sendpacket[59] = 'F'; sendpacket[60] = 'P'; sendpacket[61] = 'I'; sendpacket[62] = 'P'; sendpacket[63] = 'E'; sendpacket[64] = '-'; sendpacket[65] = CVHexToAscii(network_number >> 28); sendpacket[66] = CVHexToAscii((network_number & 0x0F000000) >> 24); sendpacket[67] = CVHexToAscii((network_number & 0x00F00000) >> 20); sendpacket[68] = CVHexToAscii((network_number & 0x000F0000) >> 16); sendpacket[69] = CVHexToAscii((network_number & 0x0000F000) >> 12); sendpacket[70] = CVHexToAscii((network_number & 0x00000F00) >> 8); sendpacket[71] = CVHexToAscii((network_number & 0x000000F0) >> 4); sendpacket[72] = CVHexToAscii(network_number & 0x0000000F); for (i = 73; i < 107; i += 1) sendpacket[i] = 0; printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n", devname); } else { printk(KERN_INFO "%s: Unknown IPXWAN packet!\n", devname); return 0; } /* Set the WNodeID to our network address */ sendpacket[43] = (unsigned char) (network_number >> 24); sendpacket[44] = (unsigned char) ((network_number & 0x00FF0000) >> 16); sendpacket[45] = (unsigned char) ((network_number & 0x0000FF00) >> 8); sendpacket[46] = (unsigned char) (network_number & 0x000000FF); return 1; } /* If we get here, its an IPX-data packet so it'll get passed up the stack. */ /* switch the network numbers */ switch_net_numbers(sendpacket, network_number, 1); return 0;}/****** Background Polling Routines ****************************************//*============================================================================ * Main polling routine. * This routine is repeatedly called by the WANPIPE 'thead' to allow for * time-dependent housekeeping work. * * o fetch asynchronous network events. * * Notes: * 1. This routine may be called on interrupt context with all interrupts * enabled. Beware! */static void wpf_poll(sdla_t * card){/* struct device* dev = card->wandev.dev; */ fr508_flags_t *flags = card->flags; unsigned long host_cpu_flags; ++card->statistics.poll_entry; if (((jiffies - card->state_tick) < HZ) || (card->intr_mode == INTR_TEST_MODE)) return; disable_irq(card->hw.irq); ++card->irq_dis_poll_count; if (test_and_set_bit(0, (void *) &card->wandev.critical)) { ++card->statistics.poll_already_critical; save_flags(host_cpu_flags); cli(); if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count))) enable_irq(card->hw.irq); restore_flags(host_cpu_flags); return; } card->wandev.critical = 0x11; ++card->statistics.poll_processed; /* This is to be changed later ??? */ /* if( dev && dev->tbusy && !(flags->imask & 0x02) ) { printk(KERN_INFO "%s: Wpf_Poll: tbusy = 0x01, imask = 0x%02X\n", card->devname, flags->imask); } */ if (flags->event) { fr_mbox_t *mbox = card->mbox; int err; memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_READ_STATUS; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; if (err) fr_event(card, err, mbox); } card->wandev.critical = 0; save_flags(host_cpu_flags); cli(); if ((!card->irq_dis_if_send_count) && (!(--card->irq_dis_poll_count))) enable_irq(card->hw.irq); restore_flags(host_cpu_flags); card->state_tick = jiffies;}/****** Frame Relay Firmware-Specific Functions *****************************//*============================================================================ * Read firmware code version. * o fill string str with firmware version info. */static int fr_read_version(sdla_t * card, char *str){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_READ_CODE_VERSION; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); if (!err && str) { int len = mbox->cmd.length; memcpy(str, mbox->data, len); str[len] = '\0'; } return err;}/*============================================================================ * Set global configuration. */ static int fr_configure(sdla_t * card, fr_conf_t * conf){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int dlci_num = card->u.f.dlci_num; int err, i; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); memcpy(mbox->data, conf, sizeof(fr_conf_t)); if (dlci_num) for (i = 0; i < dlci_num; ++i) ((fr_conf_t *) mbox->data)->dlci[i] = card->u.f.node_dlci[i]; mbox->cmd.command = FR_SET_CONFIG; mbox->cmd.length = sizeof(fr_conf_t) + dlci_num * sizeof(short); err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); return err;}/*============================================================================ * Set DLCI configuration. */static int fr_dlci_configure(sdla_t * card, fr_dlc_conf_t * conf, unsigned dlci){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); memcpy(mbox->data, conf, sizeof(fr_dlc_conf_t)); mbox->cmd.dlci = (unsigned short) dlci; mbox->cmd.command = FR_SET_CONFIG; mbox->cmd.length = 0x0E; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry--); return err;}/*============================================================================ * Set interrupt mode. */static int fr_set_intr_mode(sdla_t * card, unsigned mode, unsigned mtu){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); if (card->hw.fwid == SFID_FR502) { fr502_intr_ctl_t *ictl = (void *) mbox->data; memset(ictl, 0, sizeof(fr502_intr_ctl_t)); ictl->mode = mode; ictl->tx_len = mtu; mbox->cmd.length = sizeof(fr502_intr_ctl_t); } else { fr508_intr_ctl_t *ictl = (void *) mbox->data; memset(ictl, 0, sizeof(fr508_intr_ctl_t)); ictl->mode = mode; ictl->tx_len = mtu; ictl->irq = card->hw.irq; mbox->cmd.length = sizeof(fr508_intr_ctl_t); } mbox->cmd.command = FR_SET_INTR_MODE; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); return err;}/*============================================================================ * Enable communications. */static int fr_comm_enable(sdla_t * card){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_COMM_ENABLE; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); return err;}/*============================================================================ * Disable communications. */static int fr_comm_disable(sdla_t * card){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_COMM_DISABLE; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); return err;}/*============================================================================ * Get communications error statistics. */static int fr_get_err_stats(sdla_t * card){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_READ_ERROR_STATS; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); if (!err) { fr_comm_stat_t *stats = (void *) mbox->data; card->wandev.stats.rx_over_errors = stats->rx_overruns; card->wandev.stats.rx_crc_errors = stats->rx_bad_crc; card->wandev.stats.rx_missed_errors = stats->rx_aborts; card->wandev.stats.rx_length_errors = stats->rx_too_long; card->wandev.stats.tx_aborted_errors = stats->tx_aborts; } return err;}/*============================================================================ * Get statistics. */static int fr_get_stats(sdla_t * card){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->cmd.command = FR_READ_STATISTICS; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); if (!err) { fr_link_stat_t *stats = (void *) mbox->data; card->wandev.stats.rx_frame_errors = stats->rx_bad_format; card->wandev.stats.rx_dropped = stats->rx_dropped + stats->rx_dropped2; } return err;}/*============================================================================ * Add DLCI(s) (Access Node only!). * This routine will perform the ADD_DLCIs command for the specified DLCI. */static int fr_add_dlci(sdla_t * card, int dlci, int num){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err, i; do { unsigned short *dlci_list = (void *) mbox->data; memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); for (i = 0; i < num; ++i) dlci_list[i] = card->u.f.node_dlci[i]; mbox->cmd.length = num * sizeof(short); mbox->cmd.command = FR_ADD_DLCI; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); return err;}/*============================================================================ * Activate DLCI(s) (Access Node only!). * This routine will perform the ACTIVATE_DLCIs command with a list of DLCIs. */static int fr_activate_dlci(sdla_t * card, int dlci, int num){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err, i; do { unsigned short *dlci_list = (void *) mbox->data; memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); for (i = 0; i < num; ++i) dlci_list[i] = card->u.f.node_dlci[i]; mbox->cmd.length = num * sizeof(short); mbox->cmd.command = FR_ACTIVATE_DLCI; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); return err;}/*============================================================================ * Issue in-channel signalling frame. */static int fr_issue_isf(sdla_t * card, int isf){ fr_mbox_t *mbox = card->mbox; int retry = MAX_CMD_RETRY; int err; do { memset(&mbox->cmd, 0, sizeof(fr_cmd_t)); mbox->data[0] = isf; mbox->cmd.length = 1; mbox->cmd.command = FR_ISSUE_IS_FRAME; err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT; } while (err && retry-- && fr_event(card, err, mbox)); return err;}/*============================================================================ * Send a frame (S502 version). */static int fr50
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -