📄 depca.c
字号:
for (i=0; i<(HASH_TABLE_LEN>>3); i++){ /* Clear the multicast table */ lp->init_block.mcast_table[i]=0; } /* Add multicast addresses */ for (i=0;i<dev->mc_count;i++) { /* for each address in the list */ addrs=dmi->dmi_addr; dmi=dmi->next; if ((*addrs & 0x01) == 1) { /* multicast address? */ crc = 0xffffffff; /* init CRC for each address */ for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */ /* process each address bit */ for (bit = *addrs++,j=0;j<8;j++, bit>>=1) { crc = (crc << 1) ^ ((((crc<0?1:0) ^ bit) & 0x01) ? poly : 0); } } hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */ for (j=0;j<5;j++) { /* ... in reverse order. */ hashcode = (hashcode << 1) | ((crc>>=1) & 1); } byte = hashcode >> 3; /* bit[3-5] -> byte in filter */ bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */ lp->init_block.mcast_table[byte] |= bit; } } } return;}#ifdef CONFIG_MCA/*** Microchannel bus I/O device probe*/__initfunc(static voidmca_probe(struct device *dev, u_long ioaddr)){ unsigned char pos[2]; unsigned char where; unsigned long iobase; int irq; int slot = 0; /* ** See if we've been here before. */ if ((!ioaddr && autoprobed) || (ioaddr && !loading_module)) return; if (MCA_bus) { /* ** Search for the adapter. If an address has been given, search ** specifically for the card at that address. Otherwise find the ** first card in the system. */ while ((dev!=NULL) && ((slot=mca_find_adapter(DE212_ID, slot)) != MCA_NOTFOUND)) { pos[0] = mca_read_stored_pos(slot, 2); pos[1] = mca_read_stored_pos(slot, 3); /* ** IO of card is handled by bits 1 and 2 of pos0. ** ** bit2 bit1 IO ** 0 0 0x2c00 ** 0 1 0x2c10 ** 1 0 0x2c20 ** 1 1 0x2c30 */ where = (pos[0] & 6) >> 1; iobase = 0x2c00 + (0x10 * where); if ((ioaddr) && (ioaddr != iobase)) { /* ** Card was found, but not at the right IO location. Continue ** scanning from the next MCA slot up for another card. */ slot++; continue; } /* ** Found the adapter we were looking for. Now start setting it up. ** ** First work on decoding the IRQ. It's stored in the lower 4 bits ** of pos1. Bits are as follows (from the ADF file): ** ** Bits ** 3 2 1 0 IRQ ** -------------------- ** 0 0 1 0 5 ** 0 0 0 1 9 ** 0 1 0 0 10 ** 1 0 0 0 11 **/ where = pos[1] & 0x0f; switch(where) { case 1: irq = 9; break; case 2: irq = 5; break; case 4: irq = 10; break; case 8: irq = 11; break; default: printk("%s: mca_probe IRQ error. You should never get here (%d).\n", dev->name, where); return; } /* ** Shared memory address of adapter is stored in bits 3-5 of pos0. ** They are mapped as follows: ** ** Bit ** 5 4 3 Memory Addresses ** 0 0 0 C0000-CFFFF (64K) ** 1 0 0 C8000-CFFFF (32K) ** 0 0 1 D0000-DFFFF (64K) ** 1 0 1 D8000-DFFFF (32K) ** 0 1 0 E0000-EFFFF (64K) ** 1 1 0 E8000-EFFFF (32K) */ where = (pos[0] & 0x18) >> 3; mem = 0xc0000 + (where * 0x10000); if (pos[0] & 0x20) { mem += 0x8000; } /* ** Get everything allocated and initialized... (almost just ** like the ISA and EISA probes) */ if (DevicePresent(iobase) != 0) { /* ** If the MCA configuration says the card should be here, ** it really should be here. */ printk(KERN_ERR "%s: MCA reports card at 0x%lx but it is notresponding.\n", dev->name, iobase); } if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) { if ((dev = alloc_device(dev, iobase)) != NULL) { dev->irq = irq; if (depca_hw_init(dev, iobase, slot) == 0) { /* ** Adapter initialized correctly: Name it in ** /proc/mca. */ mca_set_adapter_name(slot, "DE210/212 Ethernet Adapter"); mca_mark_as_used(slot); num_depcas++; } num_eth++; } } else if (autoprobed) { printk(KERN_WARNING "%s: region already allocated at 0x%04lx.\n", dev->name, iobase); } /* ** If this is a probe by a module, return after setting up the ** given card. */ if (ioaddr) return; /* ** Set up to check the next slot and loop. */ slot++; } } return;}#endif/*** ISA bus I/O device probe*/__initfunc(static voidisa_probe(struct device *dev, u_long ioaddr)){ int i = num_depcas, maxSlots; s32 ports[] = DEPCA_IO_PORTS; if (!ioaddr && autoprobed) return ; /* Been here before ! */ if (ioaddr > 0x400) return; /* EISA Address */ if (i >= MAX_NUM_DEPCAS) return; /* Too many ISA adapters */ if (ioaddr == 0) { /* Autoprobing */ maxSlots = MAX_NUM_DEPCAS; } else { /* Probe a specific location */ ports[i] = ioaddr; maxSlots = i + 1; } for (; (i<maxSlots) && (dev!=NULL) && ports[i]; i++) { if (check_region(ports[i], DEPCA_TOTAL_SIZE) == 0) { if (DevicePresent(ports[i]) == 0) { if ((dev = alloc_device(dev, ports[i])) != NULL) { if (depca_hw_init(dev, ports[i], -1) == 0) { num_depcas++; } num_eth++; } } } else if (autoprobed) { printk("%s: region already allocated at 0x%04x.\n", dev->name, ports[i]); } } return;}/*** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually** the motherboard. Upto 15 EISA devices are supported.*/__initfunc(static voideisa_probe(struct device *dev, u_long ioaddr)){ int i, maxSlots; u_long iobase; char name[DEPCA_STRLEN]; if (!ioaddr && autoprobed) return ; /* Been here before ! */ if ((ioaddr < 0x400) && (ioaddr > 0)) return; /* ISA Address */ if (ioaddr == 0) { /* Autoprobing */ iobase = EISA_SLOT_INC; /* Get the first slot address */ i = 1; maxSlots = MAX_EISA_SLOTS; } else { /* Probe a specific location */ iobase = ioaddr; i = (ioaddr >> 12); maxSlots = i + 1; } if ((iobase & 0x0fff) == 0) iobase += DEPCA_EISA_IO_PORTS; for (; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) { if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) { if (EISA_signature(name, EISA_ID)) { if (DevicePresent(iobase) == 0) { if ((dev = alloc_device(dev, iobase)) != NULL) { if (depca_hw_init(dev, iobase, -1) == 0) { num_depcas++; } num_eth++; } } } } else if (autoprobed) { printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase); } } return;}/*** Search the entire 'eth' device list for a fixed probe. If a match isn't** found then check for an autoprobe or unused device location. If they** are not available then insert a new device structure at the end of** the current list.*/__initfunc(static struct device *alloc_device(struct device *dev, u_long iobase)){ struct device *adev = NULL; int fixed = 0, new_dev = 0; num_eth = depca_dev_index(dev->name); if (loading_module) return dev; while (1) { if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr==0)) && !adev) { adev=dev; } else if ((dev->priv == NULL) && (dev->base_addr==iobase)) { fixed = 1; } else { if (dev->next == NULL) { new_dev = 1; } else if (strncmp(dev->next->name, "eth", 3) != 0) { new_dev = 1; } } if ((dev->next == NULL) || new_dev || fixed) break; dev = dev->next; num_eth++; } if (adev && !fixed) { dev = adev; num_eth = depca_dev_index(dev->name); new_dev = 0; } if (((dev->next == NULL) && ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) || new_dev) { num_eth++; /* New device */ dev = insert_device(dev, iobase, depca_probe); } return dev;}/*** If at end of eth device list and can't use current entry, malloc** one up. If memory could not be allocated, print an error message.*/__initfunc(static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *))){ struct device *new; new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL); if (new == NULL) { printk("eth%d: Device not initialised, insufficient memory\n",num_eth); return NULL; } else { new->next = dev->next; dev->next = new; dev = dev->next; /* point to the new device */ dev->name = (char *)(dev + 1); if (num_eth > 9999) { sprintf(dev->name,"eth????");/* New device name */ } else { sprintf(dev->name,"eth%d", num_eth);/* New device name */ } dev->base_addr = iobase; /* assign the io address */ dev->init = init; /* initialisation routine */ } return dev;}__initfunc(static intdepca_dev_index(char *s)){ int i=0, j=0; for (;*s; s++) { if (isdigit(*s)) { j=1; i = (i * 10) + (*s - '0'); } else if (j) break; } return i;}/*** Look for a particular board name in the on-board Remote Diagnostics** and Boot (readb) ROM. This will also give us a clue to the network RAM** base address.*/__initfunc(static voidDepcaSignature(char *name, u_long paddr)){ u_int i,j,k; const char *signatures[] = DEPCA_SIGNATURE; char tmpstr[16]; /* Copy the first 16 bytes of ROM */ for (i=0;i<16;i++) { tmpstr[i] = readb(paddr+0xc000+i); } /* Check if PROM contains a valid string */ for (i=0;*signatures[i]!='\0';i++) { for (j=0,k=0;j<16 && k<strlen(signatures[i]);j++) { if (signatures[i][k] == tmpstr[j]) { /* track signature */ k++; } else { /* lost signature; begin search again */ k=0; } } if (k == strlen(signatures[i])) break; } /* Check if name string is valid, provided there's no PROM */ if (*name && (i == unknown)) { for (i=0;*signatures[i]!='\0';i++) { if (strcmp(name,signatures[i]) == 0) break; } } /* Update search results */ strcpy(name,signatures[i]); adapter = i; return;}/*** Look for a special sequence in the Ethernet station address PROM that** is common across all DEPCA products. Note that the original DEPCA needs** its ROM address counter to be initialized and enabled. Only enable** if the first address octet is a 0x08 - this minimises the chances of** messing around with some other hardware, but it assumes that this DEPCA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -