📄 lanstreamer.c
字号:
return IRQ_HANDLED;}static int streamer_xmit(struct sk_buff *skb, struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; unsigned long flags ; spin_lock_irqsave(&streamer_priv->streamer_lock, flags); if (streamer_priv->free_tx_ring_entries) { streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].status = 0; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].bufcnt_framelen = 0x00020000 | skb->len; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buffer = cpu_to_le32(pci_map_single(streamer_priv->pci_dev, skb->data, skb->len, PCI_DMA_TODEVICE)); streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd1 = skb->len; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd2 = 0; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].rsvd3 = 0; streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free].buflen = skb->len; streamer_priv->tx_ring_skb[streamer_priv->tx_ring_free] = skb; streamer_priv->free_tx_ring_entries--;#if STREAMER_DEBUG_PACKETS { int i; printk("streamer_xmit packet print:\n"); for (i = 0; i < skb->len; i++) { printk("%x:", skb->data[i]); if (((i + 1) % 16) == 0) printk("\n"); } printk("\n"); }#endif writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, &streamer_priv->streamer_tx_ring[streamer_priv->tx_ring_free], sizeof(struct streamer_tx_desc), PCI_DMA_TODEVICE)), streamer_mmio + TX2LFDA); (void)readl(streamer_mmio + TX2LFDA); streamer_priv->tx_ring_free = (streamer_priv->tx_ring_free + 1) & (STREAMER_TX_RING_SIZE - 1); spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags); return 0; } else { netif_stop_queue(dev); spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags); return 1; }}static int streamer_close(struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; unsigned long flags; int i; netif_stop_queue(dev); netif_carrier_off(dev); writew(streamer_priv->srb, streamer_mmio + LAPA); writew(htons(SRB_CLOSE_ADAPTER << 8),streamer_mmio+LAPDINC); writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); spin_lock_irqsave(&streamer_priv->streamer_lock, flags); streamer_priv->srb_queued = 1; writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags); while (streamer_priv->srb_queued) { interruptible_sleep_on_timeout(&streamer_priv->srb_wait, jiffies + 60 * HZ); if (signal_pending(current)) { printk(KERN_WARNING "%s: SRB timed out.\n", dev->name); printk(KERN_WARNING "SISR=%x MISR=%x LISR=%x\n", readw(streamer_mmio + SISR), readw(streamer_mmio + MISR_RUM), readw(streamer_mmio + LISR)); streamer_priv->srb_queued = 0; break; } } streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); for (i = 0; i < STREAMER_RX_RING_SIZE; i++) { if (streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]) { dev_kfree_skb(streamer_priv->rx_ring_skb[streamer_priv->rx_ring_last_received]); } streamer_priv->rx_ring_last_received = (streamer_priv->rx_ring_last_received + 1) & (STREAMER_RX_RING_SIZE - 1); } /* reset tx/rx fifo's and busmaster logic */ /* TBD. Add graceful way to reset the LLC channel without doing a soft reset. writel(readl(streamer_mmio+BCTL)|(3<<13),streamer_mmio+BCTL); udelay(1); writel(readl(streamer_mmio+BCTL)&~(3<<13),streamer_mmio+BCTL); */#if STREAMER_DEBUG writew(streamer_priv->srb, streamer_mmio + LAPA); printk("srb): "); for (i = 0; i < 2; i++) { printk("%x ", ntohs(readw(streamer_mmio + LAPDINC))); } printk("\n");#endif free_irq(dev->irq, dev); return 0;}static void streamer_set_rx_mode(struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; __u8 options = 0; struct dev_mc_list *dmi; unsigned char dev_mc_address[5]; int i; writel(streamer_priv->srb, streamer_mmio + LAPA); options = streamer_priv->streamer_copy_all_options; if (dev->flags & IFF_PROMISC) options |= (3 << 5); /* All LLC and MAC frames, all through the main rx channel */ else options &= ~(3 << 5); /* Only issue the srb if there is a change in options */ if ((options ^ streamer_priv->streamer_copy_all_options)) { /* Now to issue the srb command to alter the copy.all.options */ writew(htons(SRB_MODIFY_RECEIVE_OPTIONS << 8), streamer_mmio+LAPDINC); writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); writew(htons((streamer_priv->streamer_receive_options << 8) | options),streamer_mmio+LAPDINC); writew(htons(0x4a41),streamer_mmio+LAPDINC); writew(htons(0x4d45),streamer_mmio+LAPDINC); writew(htons(0x5320),streamer_mmio+LAPDINC); writew(0x2020, streamer_mmio + LAPDINC); streamer_priv->srb_queued = 2; /* Can't sleep, use srb_bh */ writel(LISR_SRB_CMD, streamer_mmio + LISR_SUM); streamer_priv->streamer_copy_all_options = options; return; } /* Set the functional addresses we need for multicast */ writel(streamer_priv->srb,streamer_mmio+LAPA); dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ; for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) { dev_mc_address[0] |= dmi->dmi_addr[2] ; dev_mc_address[1] |= dmi->dmi_addr[3] ; dev_mc_address[2] |= dmi->dmi_addr[4] ; dev_mc_address[3] |= dmi->dmi_addr[5] ; } writew(htons(SRB_SET_FUNC_ADDRESS << 8),streamer_mmio+LAPDINC); writew(htons(STREAMER_CLEAR_RET_CODE << 8), streamer_mmio+LAPDINC); writew(0,streamer_mmio+LAPDINC); writew(htons( (dev_mc_address[0] << 8) | dev_mc_address[1]),streamer_mmio+LAPDINC); writew(htons( (dev_mc_address[2] << 8) | dev_mc_address[3]),streamer_mmio+LAPDINC); streamer_priv->srb_queued = 2 ; writel(LISR_SRB_CMD,streamer_mmio+LISR_SUM);}static void streamer_srb_bh(struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; __u16 srb_word; writew(streamer_priv->srb, streamer_mmio + LAPA); srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; switch (srb_word) { /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous) * At some point we should do something if we get an error, such as * resetting the IFF_PROMISC flag in dev */ case SRB_MODIFY_RECEIVE_OPTIONS: srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; switch (srb_word) { case 0x01: printk(KERN_WARNING "%s: Unrecognized srb command\n", dev->name); break; case 0x04: printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); break; default: if (streamer_priv->streamer_message_level) printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n", dev->name, streamer_priv->streamer_copy_all_options, streamer_priv->streamer_receive_options); break; } /* switch srb[2] */ break; /* SRB_SET_GROUP_ADDRESS - Multicast group setting */ case SRB_SET_GROUP_ADDRESS: srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; switch (srb_word) { case 0x00: break; case 0x01: printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name); break; case 0x04: printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); break; case 0x3c: printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n", dev->name); break; case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */ printk(KERN_WARNING "%s: Group address registers full\n", dev->name); break; case 0x55: printk(KERN_INFO "%s: Group Address already set.\n", dev->name); break; default: break; } /* switch srb[2] */ break; /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list */ case SRB_RESET_GROUP_ADDRESS: srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; switch (srb_word) { case 0x00: break; case 0x01: printk(KERN_WARNING "%s: Unrecognized srb command \n", dev->name); break; case 0x04: printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); break; case 0x39: /* Must deal with this if individual multicast addresses used */ printk(KERN_INFO "%s: Group address not found \n", dev->name); break; default: break; } /* switch srb[2] */ break; /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode */ case SRB_SET_FUNC_ADDRESS: srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; switch (srb_word) { case 0x00: if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Functional Address Mask Set \n", dev->name); break; case 0x01: printk(KERN_WARNING "%s: Unrecognized srb command \n", dev->name); break; case 0x04: printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); break; default: break; } /* switch srb[2] */ break; /* SRB_READ_LOG - Read and reset the adapter error counters */ case SRB_READ_LOG: srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; switch (srb_word) { case 0x00: { int i; if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Read Log command complete\n", dev->name); printk("Read Log statistics: "); writew(streamer_priv->srb + 6, streamer_mmio + LAPA); for (i = 0; i < 5; i++) { printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); } printk("\n"); } break; case 0x01: printk(KERN_WARNING "%s: Unrecognized srb command \n", dev->name); break; case 0x04: printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); break; } /* switch srb[2] */ break; /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */ case SRB_READ_SR_COUNTERS: srb_word=ntohs(readw(streamer_mmio+LAPDINC)) >> 8; switch (srb_word) { case 0x00: if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Read Source Routing Counters issued\n", dev->name); break; case 0x01: printk(KERN_WARNING "%s: Unrecognized srb command \n", dev->name); break; case 0x04: printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n", dev->name); break; default: break; } /* switch srb[2] */ break; default: printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n", dev->name); break; } /* switch srb[0] */}static struct net_device_stats *streamer_get_stats(struct net_device *dev){ struct streamer_private *streamer_priv; streamer_priv = (struct streamer_private *) dev->priv; return (struct net_device_stats *) &streamer_priv->streamer_stats;}static int streamer_set_mac_address(struct net_device *dev, void *addr){ struct sockaddr *saddr = addr; struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; if (netif_running(dev)) { printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name); return -EIO; } memcpy(streamer_priv->streamer_laa, saddr->sa_data, dev->addr_len); if (streamer_priv->streamer_message_level) { printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n", dev->name, streamer_priv->streamer_laa[0], streamer_priv->streamer_laa[1], streamer_priv->streamer_laa[2], streamer_priv->streamer_laa[3], streamer_priv->streamer_laa[4], streamer_priv->streamer_laa[5]); } return 0;}static void streamer_arb_cmd(struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; __u8 header_len; __u16 frame_len, buffer_len; struct sk_buff *mac_frame;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -