📄 lanstreamer.c
字号:
__u16 arb_word;#if STREAMER_NETWORK_MONITOR struct trh_hdr *mac_hdr;#endif writew(streamer_priv->arb, streamer_mmio + LAPA); arb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8; if (arb_word == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */ writew(streamer_priv->arb + 6, streamer_mmio + LAPA); streamer_priv->mac_rx_buffer = buff_off = ntohs(readw(streamer_mmio + LAPDINC)); header_len=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; /* 802.5 Token-Ring Header Length */ frame_len = ntohs(readw(streamer_mmio + LAPDINC));#if STREAMER_DEBUG { int i; __u16 next; __u8 status; __u16 len; writew(ntohs(buff_off), streamer_mmio + LAPA); /*setup window to frame data */ next = htons(readw(streamer_mmio + LAPDINC)); status = ntohs(readw(streamer_mmio + LAPDINC)) & 0xff; len = ntohs(readw(streamer_mmio + LAPDINC)); /* print out 1st 14 bytes of frame data */ for (i = 0; i < 7; i++) { printk("Loc %d = %04x\n", i, ntohs(readw (streamer_mmio + LAPDINC))); } printk("next %04x, fs %02x, len %04x \n", next, status, len); }#endif if (!(mac_frame = dev_alloc_skb(frame_len))) { printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name); goto drop_frame; } /* Walk the buffer chain, creating the frame */ do { int i; __u16 rx_word; writew(htons(buff_off), streamer_mmio + LAPA); /* setup window to frame data */ next_ptr = ntohs(readw(streamer_mmio + LAPDINC)); readw(streamer_mmio + LAPDINC); /* read thru status word */ buffer_len = ntohs(readw(streamer_mmio + LAPDINC)); if (buffer_len > 256) break; i = 0; while (i < buffer_len) { rx_word=ntohs(readw(streamer_mmio+LAPDINC)); frame_data[i]=rx_word >> 8; frame_data[i+1]=rx_word & 0xff; i += 2; } memcpy(skb_put(mac_frame, buffer_len), frame_data, buffer_len); } while (next_ptr && (buff_off = next_ptr));#if STREAMER_NETWORK_MONITOR printk(KERN_WARNING "%s: Received MAC Frame, details: \n", dev->name); mac_hdr = (struct trh_hdr *) mac_frame->data; printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name, mac_hdr->daddr[0], mac_hdr->daddr[1], mac_hdr->daddr[2], mac_hdr->daddr[3], mac_hdr->daddr[4], mac_hdr->daddr[5]); printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev->name, mac_hdr->saddr[0], mac_hdr->saddr[1], mac_hdr->saddr[2], mac_hdr->saddr[3], mac_hdr->saddr[4], mac_hdr->saddr[5]);#endif mac_frame->dev = dev; mac_frame->protocol = tr_type_trans(mac_frame, dev); netif_rx(mac_frame); /* Now tell the card we have dealt with the received frame */drop_frame: /* Set LISR Bit 1 */ writel(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM); /* Is the ASB free ? */ if (!(readl(streamer_priv->streamer_mmio + SISR) & SISR_ASB_FREE)) { streamer_priv->asb_queued = 1; writel(LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); return; /* Drop out and wait for the bottom half to be run */ } writew(streamer_priv->asb, streamer_mmio + LAPA); writew(htons(ASB_RECEIVE_DATA << 8), streamer_mmio+LAPDINC); writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); writew(0, streamer_mmio + LAPDINC); writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD); writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); streamer_priv->asb_queued = 2; return; } else if (arb_word == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */ writew(streamer_priv->arb + 6, streamer_mmio + LAPA); lan_status = ntohs(readw(streamer_mmio + LAPDINC)); fdx_prot_error = ntohs(readw(streamer_mmio+LAPD)) >> 8; /* Issue ARB Free */ writew(LISR_ARB_FREE, streamer_priv->streamer_mmio + LISR_SUM); lan_status_diff = (streamer_priv->streamer_lan_status ^ lan_status) & lan_status; if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR)) { if (lan_status_diff & LSC_LWF) printk(KERN_WARNING "%s: Short circuit detected on the lobe\n", dev->name); if (lan_status_diff & LSC_ARW) printk(KERN_WARNING "%s: Auto removal error\n", dev->name); if (lan_status_diff & LSC_FPE) printk(KERN_WARNING "%s: FDX Protocol Error\n", dev->name); if (lan_status_diff & LSC_RR) printk(KERN_WARNING "%s: Force remove MAC frame received\n", dev->name); /* Adapter has been closed by the hardware */ /* reset tx/rx fifo's and busmaster logic */ /* @TBD. no llc reset on autostreamer writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL); udelay(1); writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); */ netif_stop_queue(dev); netif_carrier_off(dev); printk(KERN_WARNING "%s: Adapter must be manually reset.\n", dev->name); } /* If serious error */ if (streamer_priv->streamer_message_level) { if (lan_status_diff & LSC_SIG_LOSS) printk(KERN_WARNING "%s: No receive signal detected \n", dev->name); if (lan_status_diff & LSC_HARD_ERR) printk(KERN_INFO "%s: Beaconing \n", dev->name); if (lan_status_diff & LSC_SOFT_ERR) printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame \n", dev->name); if (lan_status_diff & LSC_TRAN_BCN) printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n", dev->name); if (lan_status_diff & LSC_SS) printk(KERN_INFO "%s: Single Station on the ring \n", dev->name); if (lan_status_diff & LSC_RING_REC) printk(KERN_INFO "%s: Ring recovery ongoing\n", dev->name); if (lan_status_diff & LSC_FDX_MODE) printk(KERN_INFO "%s: Operating in FDX mode\n", dev->name); } if (lan_status_diff & LSC_CO) { if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Counter Overflow \n", dev->name); /* Issue READ.LOG command */ writew(streamer_priv->srb, streamer_mmio + LAPA); writew(htons(SRB_READ_LOG << 8),streamer_mmio+LAPDINC); writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); writew(0, streamer_mmio + LAPDINC); streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); } if (lan_status_diff & LSC_SR_CO) { if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); /* Issue a READ.SR.COUNTERS */ writew(streamer_priv->srb, streamer_mmio + LAPA); writew(htons(SRB_READ_SR_COUNTERS << 8), streamer_mmio+LAPDINC); writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); } streamer_priv->streamer_lan_status = lan_status; } /* Lan.change.status */ else printk(KERN_WARNING "%s: Unknown arb command \n", dev->name);}static void streamer_asb_bh(struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; if (streamer_priv->asb_queued == 1) { /* Dropped through the first time */ writew(streamer_priv->asb, streamer_mmio + LAPA); writew(htons(ASB_RECEIVE_DATA << 8),streamer_mmio+LAPDINC); writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); writew(0, streamer_mmio + LAPDINC); writew(htons(streamer_priv->mac_rx_buffer), streamer_mmio + LAPD); writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ, streamer_priv->streamer_mmio + LISR_SUM); streamer_priv->asb_queued = 2; return; } if (streamer_priv->asb_queued == 2) { __u8 rc; writew(streamer_priv->asb + 2, streamer_mmio + LAPA); rc=ntohs(readw(streamer_mmio+LAPD)) >> 8; switch (rc) { case 0x01: printk(KERN_WARNING "%s: Unrecognized command code \n", dev->name); break; case 0x26: printk(KERN_WARNING "%s: Unrecognized buffer address \n", dev->name); break; case 0xFF: /* Valid response, everything should be ok again */ break; default: printk(KERN_WARNING "%s: Invalid return code in asb\n", dev->name); break; } } streamer_priv->asb_queued = 0;}static int streamer_change_mtu(struct net_device *dev, int mtu){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u16 max_mtu; if (streamer_priv->streamer_ring_speed == 4) max_mtu = 4500; else max_mtu = 18000; if (mtu > max_mtu) return -EINVAL; if (mtu < 100) return -EINVAL; dev->mtu = mtu; streamer_priv->pkt_buf_sz = mtu + TR_HLEN; return 0;}#if STREAMER_NETWORK_MONITOR#ifdef CONFIG_PROC_FSstatic int streamer_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data){ struct streamer_private *sdev=NULL; struct pci_dev *pci_device = NULL; int len = 0; off_t begin = 0; off_t pos = 0; int size; struct net_device *dev; size = sprintf(buffer, "IBM LanStreamer/MPC Chipset Token Ring Adapters\n"); pos += size; len += size; for(sdev=dev_streamer; sdev; sdev=sdev->next) { pci_device=sdev->pci_dev; dev=pci_get_drvdata(pci_device); size = sprintf_info(buffer + len, dev); len += size; pos = begin + len; if (pos < offset) { len = 0; begin = pos; } if (pos > offset + length) break; } /* for */ *start = buffer + (offset - begin); /* Start of wanted data */ len -= (offset - begin); /* Start slop */ if (len > length) len = length; /* Ending slop */ return len;}static int sprintf_info(char *buffer, struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; struct streamer_adapter_addr_table sat; struct streamer_parameters_table spt; int size = 0; int i; writew(streamer_priv->streamer_addr_table_addr, streamer_mmio + LAPA); for (i = 0; i < 14; i += 2) { __u16 io_word; __u8 *datap = (__u8 *) & sat; io_word=ntohs(readw(streamer_mmio+LAPDINC)); datap[size]=io_word >> 8; datap[size+1]=io_word & 0xff; } writew(streamer_priv->streamer_parms_addr, streamer_mmio + LAPA); for (i = 0; i < 68; i += 2) { __u16 io_word; __u8 *datap = (__u8 *) & spt; io_word=ntohs(readw(streamer_mmio+LAPDINC)); datap[size]=io_word >> 8; datap[size+1]=io_word & 0xff; } size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); size += sprintf(buffer + size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x\n", dev->name, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], sat.node_addr[0], sat.node_addr[1], sat.node_addr[2], sat.node_addr[3], sat.node_addr[4], sat.node_addr[5], sat.func_addr[0], sat.func_addr[1], sat.func_addr[2], sat.func_addr[3]); size += sprintf(buffer + size, "\n%6s: Token Ring Parameters Table:\n", dev->name); size += sprintf(buffer + size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", dev->name); size += sprintf(buffer + size, "%6s: %02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x :\n", dev->name, spt.phys_addr[0], spt.phys_addr[1], spt.phys_addr[2], spt.phys_addr[3], spt.up_node_addr[0], spt.up_node_addr[1], spt.up_node_addr[2], spt.up_node_addr[3], spt.up_node_addr[4], spt.up_node_addr[4], spt.poll_addr[0], spt.poll_addr[1], spt.poll_addr[2], spt.poll_addr[3], spt.poll_addr[4], spt.poll_addr[5], ntohs(spt.acc_priority), ntohs(spt.auth_source_class), ntohs(spt.att_code)); size += sprintf(buffer + size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name); size += sprintf(buffer + size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x : %04x : %04x : %04x : \n", dev->name, spt.source_addr[0], spt.source_addr[1], spt.source_addr[2], spt.source_addr[3], spt.source_addr[4], spt.source_addr[5], ntohs(spt.beacon_type), ntohs(spt.major_vector), ntohs(spt.lan_status), ntohs(spt.local_ring), ntohs(spt.mon_error), ntohs(spt.frame_correl)); size += sprintf(buffer + size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", dev->name); size += sprintf(buffer + size, "%6s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -