📄 hp100.c
字号:
printk("hp100: %s: PCI I/O Bit has not been set. Setting...\n", dev->name);#endif pci_command |= PCI_COMMAND_IO; pci_write_config_word(pci_dev, PCI_COMMAND, pci_command); } if (!(pci_command & PCI_COMMAND_MASTER)) {#ifdef HP100_DEBUG printk("hp100: %s: PCI Master Bit has not been set. Setting...\n", dev->name);#endif pci_command |= PCI_COMMAND_MASTER; pci_write_config_word(pci_dev, PCI_COMMAND, pci_command); }#ifdef HP100_DEBUG printk("hp100: %s: PCI adapter found at 0x%x\n", dev->name, ioaddr);#endif if (hp100_probe1(dev, ioaddr, HP100_BUS_PCI, pci_dev) == 0) return 0; } } } if (pci_start_index > 0) return -ENODEV;#endif /* CONFIG_PCI */ /* Second: Probe all EISA possible port regions (if EISA bus present) */ for (ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400) { if (check_region(ioaddr, HP100_REGION_SIZE)) continue; if (hp100_probe1(dev, ioaddr, HP100_BUS_EISA, NULL) == 0) return 0; } /* Third: Probe all ISA possible port regions */ for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) { if (check_region(ioaddr, HP100_REGION_SIZE)) continue; if (hp100_probe1(dev, ioaddr, HP100_BUS_ISA, NULL) == 0) return 0; } return -ENODEV;}static int __init hp100_probe1(struct net_device *dev, int ioaddr, u_char bus, struct pci_dev *pci_dev){ int i; u_char uc, uc_1; u_int eisa_id; u_int chip; u_int memory_size = 0, virt_memory_size = 0; u_short local_mode, lsw; short mem_mapped; unsigned long mem_ptr_phys; void **mem_ptr_virt; struct hp100_private *lp; struct hp100_eisa_id *eid;#ifdef HP100_DEBUG_B hp100_outw(0x4201, TRACE); printk("hp100: %s: probe1\n", dev->name);#endif if (dev == NULL) {#ifdef HP100_DEBUG printk("hp100_probe1: %s: dev == NULL ?\n", dev->name);#endif return -EIO; } if (hp100_inw(HW_ID) != HP100_HW_ID_CASCADE) { return -ENODEV; } else { chip = hp100_inw(PAGING) & HP100_CHIPID_MASK;#ifdef HP100_DEBUG if (chip == HP100_CHIPID_SHASTA) printk("hp100: %s: Shasta Chip detected. (This is a pre 802.12 chip)\n", dev->name); else if (chip == HP100_CHIPID_RAINIER) printk("hp100: %s: Rainier Chip detected. (This is a pre 802.12 chip)\n", dev->name); else if (chip == HP100_CHIPID_LASSEN) printk("hp100: %s: Lassen Chip detected.\n", dev->name); else printk("hp100: %s: Warning: Unknown CASCADE chip (id=0x%.4x).\n", dev->name, chip);#endif } dev->base_addr = ioaddr; hp100_page(ID_MAC_ADDR); for (i = uc = eisa_id = 0; i < 4; i++) { eisa_id >>= 8; uc_1 = hp100_inb(BOARD_ID + i); eisa_id |= uc_1 << 24; uc += uc_1; } uc += hp100_inb(BOARD_ID + 4); if (uc != 0xff) { /* bad checksum? */ printk("hp100_probe: %s: bad EISA ID checksum at base port 0x%x\n", dev->name, ioaddr); return -ENODEV; } for (i = 0; i < HP100_EISA_IDS_SIZE; i++) if (hp100_eisa_ids[i].id == eisa_id) break; if (i >= HP100_EISA_IDS_SIZE) { for (i = 0; i < HP100_EISA_IDS_SIZE; i++) if ((hp100_eisa_ids[i].id & 0xf0ffffff) == (eisa_id & 0xf0ffffff)) break; if (i >= HP100_EISA_IDS_SIZE) { printk ("hp100_probe: %s: card at port 0x%x isn't known (id = 0x%x)\n", dev->name, ioaddr, eisa_id); return -ENODEV; } } eid = &hp100_eisa_ids[i]; if ((eid->id & 0x0f000000) < (eisa_id & 0x0f000000)) { printk("hp100_probe: %s: newer version of card %s at port 0x%x - unsupported\n", dev->name, eid->name, ioaddr); return -ENODEV; } for (i = uc = 0; i < 7; i++) uc += hp100_inb(LAN_ADDR + i); if (uc != 0xff) { printk("hp100_probe: %s: bad lan address checksum (card %s at port 0x%x)\n", dev->name, eid->name, ioaddr); return -EIO; } /* Make sure, that all registers are correctly updated... */ hp100_load_eeprom(dev, ioaddr); wait(); /* * Determine driver operation mode * * Use the variable "hp100_mode" upon insmod or as kernel parameter to * force driver modes: * hp100_mode=1 -> default, use busmaster mode if configured. * hp100_mode=2 -> enable shared memory mode * hp100_mode=3 -> force use of i/o mapped mode. * hp100_mode=4 -> same as 1, but re-set the enable bit on the card. */ /* * LSW values: * 0x2278 -> J2585B, PnP shared memory mode * 0x2270 -> J2585B, shared memory mode, 0xdc000 * 0xa23c -> J2585B, I/O mapped mode * 0x2240 -> EISA COMPEX, BusMaster (Shasta Chip) * 0x2220 -> EISA HP, I/O (Shasta Chip) * 0x2260 -> EISA HP, BusMaster (Shasta Chip) */#if 0 local_mode = 0x2270; hp100_outw(0xfefe, OPTION_LSW); hp100_outw(local_mode | HP100_SET_LB | HP100_SET_HB, OPTION_LSW);#endif /* hp100_mode value maybe used in future by another card */ local_mode = hp100_mode; if (local_mode < 1 || local_mode > 4) local_mode = 1; /* default */#ifdef HP100_DEBUG printk("hp100: %s: original LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW));#endif if (local_mode == 3) { hp100_outw(HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW); hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW); hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW); printk("hp100: %s: IO mapped mode forced.\n", dev->name); } else if (local_mode == 2) { hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW); hp100_outw(HP100_IO_EN | HP100_SET_LB, OPTION_LSW); hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_RESET_HB, OPTION_LSW); printk("hp100: %s: Shared memory mode requested.\n", dev->name); } else if (local_mode == 4) { if (chip == HP100_CHIPID_LASSEN) { hp100_outw(HP100_BM_WRITE | HP100_BM_READ | HP100_SET_HB, OPTION_LSW); hp100_outw(HP100_IO_EN | HP100_MEM_EN | HP100_RESET_LB, OPTION_LSW); printk("hp100: %s: Busmaster mode requested.\n", dev->name); } local_mode = 1; } if (local_mode == 1) { /* default behaviour */ lsw = hp100_inw(OPTION_LSW); if ((lsw & HP100_IO_EN) && (~lsw & HP100_MEM_EN) && (~lsw & (HP100_BM_WRITE | HP100_BM_READ))) {#ifdef HP100_DEBUG printk("hp100: %s: IO_EN bit is set on card.\n", dev->name);#endif local_mode = 3; } else if (chip == HP100_CHIPID_LASSEN && (lsw & (HP100_BM_WRITE | HP100_BM_READ)) == (HP100_BM_WRITE | HP100_BM_READ)) { printk("hp100: %s: Busmaster mode enabled.\n", dev->name); hp100_outw(HP100_MEM_EN | HP100_IO_EN | HP100_RESET_LB, OPTION_LSW); } else {#ifdef HP100_DEBUG printk("hp100: %s: Card not configured for BM or BM not supported with this card.\n", dev->name); printk("hp100: %s: Trying shared memory mode.\n", dev->name);#endif /* In this case, try shared memory mode */ local_mode = 2; hp100_outw(HP100_MEM_EN | HP100_SET_LB, OPTION_LSW); /* hp100_outw(HP100_IO_EN|HP100_RESET_LB, OPTION_LSW); */ } }#ifdef HP100_DEBUG printk("hp100: %s: new LSW = 0x%x\n", dev->name, hp100_inw(OPTION_LSW));#endif /* Check for shared memory on the card, eventually remap it */ hp100_page(HW_MAP); mem_mapped = ((hp100_inw(OPTION_LSW) & (HP100_MEM_EN)) != 0); mem_ptr_phys = 0UL; mem_ptr_virt = NULL; memory_size = (8192 << ((hp100_inb(SRAM) >> 5) & 0x07)); virt_memory_size = 0; /* For memory mapped or busmaster mode, we want the memory address */ if (mem_mapped || (local_mode == 1)) { mem_ptr_phys = (hp100_inw(MEM_MAP_LSW) | (hp100_inw(MEM_MAP_MSW) << 16)); mem_ptr_phys &= ~0x1fff; /* 8k alignment */ if (bus == HP100_BUS_ISA && (mem_ptr_phys & ~0xfffff) != 0) { printk("hp100: %s: Can only use programmed i/o mode.\n", dev->name); mem_ptr_phys = 0; mem_mapped = 0; local_mode = 3; /* Use programmed i/o */ } /* We do not need access to shared memory in busmaster mode */ /* However in slave mode we need to remap high (>1GB) card memory */ if (local_mode != 1) { /* = not busmaster */ /* We try with smaller memory sizes, if ioremap fails */ for (virt_memory_size = memory_size; virt_memory_size > 16383; virt_memory_size >>= 1) { if ((mem_ptr_virt = ioremap((u_long) mem_ptr_phys, virt_memory_size)) == NULL) {#ifdef HP100_DEBUG printk("hp100: %s: ioremap for 0x%x bytes high PCI memory at 0x%lx failed\n", dev->name, virt_memory_size, mem_ptr_phys);#endif } else {#ifdef HP100_DEBUG printk("hp100: %s: remapped 0x%x bytes high PCI memory at 0x%lx to %p.\n", dev->name, virt_memory_size, mem_ptr_phys, mem_ptr_virt);#endif break; } } if (mem_ptr_virt == NULL) { /* all ioremap tries failed */ printk("hp100: %s: Failed to ioremap the PCI card memory. Will have to use i/o mapped mode.\n", dev->name); local_mode = 3; virt_memory_size = 0; } } } if (local_mode == 3) { /* io mapped forced */ mem_mapped = 0; mem_ptr_phys = 0; mem_ptr_virt = NULL; printk("hp100: %s: Using (slow) programmed i/o mode.\n", dev->name); } /* Initialise the "private" data structure for this card. */ if ((dev->priv = kmalloc(sizeof(struct hp100_private), GFP_KERNEL)) == NULL) return -ENOMEM; lp = (struct hp100_private *) dev->priv; memset(lp, 0, sizeof(struct hp100_private)); spin_lock_init(&lp->lock); lp->id = eid; lp->chip = chip; lp->mode = local_mode; lp->bus = bus; lp->pci_dev = pci_dev; lp->priority_tx = hp100_priority_tx; lp->rx_ratio = hp100_rx_ratio; lp->mem_ptr_phys = mem_ptr_phys; lp->mem_ptr_virt = mem_ptr_virt; hp100_page(ID_MAC_ADDR); lp->soft_model = hp100_inb(SOFT_MODEL); lp->mac1_mode = HP100_MAC1MODE3; lp->mac2_mode = HP100_MAC2MODE3; memset(&lp->hash_bytes, 0x00, 8); dev->base_addr = ioaddr; lp->memory_size = memory_size; lp->virt_memory_size = virt_memory_size; lp->rx_ratio = hp100_rx_ratio; /* can be conf'd with insmod */ /* memory region for programmed i/o */ request_region(dev->base_addr, HP100_REGION_SIZE, eid->name); dev->open = hp100_open; dev->stop = hp100_close; if (lp->mode == 1) /* busmaster */ dev->hard_start_xmit = hp100_start_xmit_bm; else dev->hard_start_xmit = hp100_start_xmit; dev->get_stats = hp100_get_stats; dev->set_multicast_list = &hp100_set_multicast_list; /* Ask the card for which IRQ line it is configured */ if (bus == HP100_BUS_PCI) { dev->irq = pci_dev->irq; } else { hp100_page(HW_MAP); dev->irq = hp100_inb(IRQ_CHANNEL) & HP100_IRQMASK; if (dev->irq == 2) dev->irq = 9; } if (lp->mode == 1) /* busmaster */ dev->dma = 4; /* Ask the card for its MAC address and store it for later use. */ hp100_page(ID_MAC_ADDR); for (i = uc = 0; i < 6; i++) dev->dev_addr[i] = hp100_inb(LAN_ADDR + i); /* Reset statistics (counters) */ hp100_clear_stats(lp, ioaddr); SET_MODULE_OWNER(dev); ether_setup(dev); /* If busmaster mode is wanted, a dma-capable memory area is needed for * the rx and tx PDLs * PCI cards can access the whole PC memory. Therefore GFP_DMA is not * needed for the allocation of the memory area. */ /* TODO: We do not need this with old cards, where PDLs are stored * in the cards shared memory area. But currently, busmaster has been * implemented/tested only with the lassen chip anyway... */ if (lp->mode == 1) { /* busmaster */ /* Get physically continous memory for TX & RX PDLs */ if ((lp->page_vaddr = kmalloc(MAX_RINGSIZE + 0x0f, GFP_KERNEL)) == NULL) return -ENOMEM; lp->page_vaddr_algn = ((u_int *) (((u_int) (lp->page_vaddr) + 0x0f) & ~0x0f)); memset(lp->page_vaddr, 0, MAX_RINGSIZE + 0x0f);#ifdef HP100_DEBUG_BM printk("hp100: %s: Reserved DMA memory from 0x%x to 0x%x\n", dev->name, (u_int) lp->page_vaddr_algn, (u_int) lp->page_vaddr_algn + MAX_RINGSIZE);#endif lp->rxrcommit = lp->txrcommit = 0; lp->rxrhead = lp->rxrtail = &(lp->rxring[0]); lp->txrhead = lp->txrtail = &(lp->txring[0]); } /* Initialise the card. */ /* (I'm not really sure if it's a good idea to do this during probing, but * like this it's assured that the lan connection type can be sensed * correctly) */ hp100_hwinit(dev); /* Try to find out which kind of LAN the card is connected to. */ lp->lan_type = hp100_sense_lan(dev); /* Print out a message what about what we think we have probed. */ printk("hp100: %s: %s at 0x%x, IRQ %d, ", dev->name, lp->id->name, ioaddr, dev->irq); switch (bus) { case HP100_BUS_EISA: printk("EISA"); break; case HP100_BUS_PCI: printk("PCI"); break; default: printk("ISA"); break; } printk(" bus, %dk SRAM (rx/tx %d%%).\n", lp->memory_size >> 10, lp->rx_ratio); if (lp->mode == 2) { /* memory mapped */ printk("hp100: %s: Memory area at 0x%lx-0x%lx", dev->name, mem_ptr_phys, (mem_ptr_phys + (mem_ptr_phys > 0x100000 ? (u_long) lp->memory_size : 16 * 1024)) - 1); if (mem_ptr_virt) printk(" (virtual base %p)", mem_ptr_virt); printk(".\n"); /* Set for info when doing ifconfig */ dev->mem_start = mem_ptr_phys; dev->mem_end = mem_ptr_phys + lp->memory_size; } printk("hp100: %s: ", dev->name); if (lp->lan_type != HP100_LAN_ERR) printk("Adapter is attached to "); switch (lp->lan_type) { case HP100_LAN_100: printk("100Mb/s Voice Grade AnyLAN network.\n"); break; case HP100_LAN_10: printk("10Mb/s network.\n"); break; default: printk("Warning! Link down.\n"); } return 0;}/* This procedure puts the card into a stable init state */static void hp100_hwinit(struct net_device *dev){ int ioaddr = dev->base_addr; struct hp100_private *lp = (struct hp100_private *) dev->priv;#ifdef HP100_DEBUG_B hp100_outw(0x4202, TRACE); printk("hp100: %s: hwinit\n", dev->name);#endif /* Initialise the card. -------------------------------------------- */ /* Clear all pending Ints and disable Ints */ hp100_page(PERFORMANCE); hp100_outw(0xfefe, IRQ_MASK); /* mask off all ints */ hp100_outw(0xffff, IRQ_STATUS); /* clear all pending ints */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -