⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ewrk3.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 4 页
字号:
	dev->init = init;              /* initialisation routine */    }    return dev;}static intewrk3_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;}/*** Read the EWRK3 EEPROM using this routine*/static int Read_EEPROM(u_long iobase, u_char eaddr){  int i;  outb((eaddr & 0x3f), EWRK3_PIR1);     /* set up 6 bits of address info */  outb(EEPROM_RD, EWRK3_IOPR);          /* issue read command */  for (i=0;i<5000;i++) inb(EWRK3_CSR);  /* wait 1msec */  return inw(EWRK3_EPROM1);             /* 16 bits data return */}/*** Write the EWRK3 EEPROM using this routine*/static int Write_EEPROM(short data, u_long iobase, u_char eaddr){  int i;  outb(EEPROM_WR_EN, EWRK3_IOPR);       /* issue write enable command */  for (i=0;i<5000;i++) inb(EWRK3_CSR);  /* wait 1msec */  outw(data, EWRK3_EPROM1);             /* write data to register */  outb((eaddr & 0x3f), EWRK3_PIR1);     /* set up 6 bits of address info */  outb(EEPROM_WR, EWRK3_IOPR);          /* issue write command */  for (i=0;i<75000;i++) inb(EWRK3_CSR); /* wait 15msec */  outb(EEPROM_WR_DIS, EWRK3_IOPR);      /* issue write disable command */  for (i=0;i<5000;i++) inb(EWRK3_CSR);  /* wait 1msec */  return 0;}/*** Look for a particular board name in the on-board EEPROM.*/static void EthwrkSignature(char *name, char *eeprom_image){  u_long i,j,k;  char *signatures[] = EWRK3_SIGNATURE;  strcpy(name, "");  for (i=0;*signatures[i] != '\0' && *name == '\0';i++) {    for (j=EEPROM_PNAME7,k=0;j<=EEPROM_PNAME0 && k<strlen(signatures[i]);j++) {      if (signatures[i][k] == eeprom_image[j]) {          /* track signature */	k++;      } else {                         /* lost signature; begin search again */	k=0;      }    }    if (k == strlen(signatures[i])) {      for (k=0; k<EWRK3_STRLEN; k++) {	name[k] = eeprom_image[EEPROM_PNAME7 + k];	name[EWRK3_STRLEN] = '\0';      }    }  }  return;                                   /* return the device name string */}/*** Look for a special sequence in the Ethernet station address PROM that** is common across all EWRK3 products.** ** Search the Ethernet address ROM for the signature. Since the ROM address** counter can start at an arbitrary point, the search must include the entire** probe sequence length plus the (length_of_the_signature - 1).** Stop the search IMMEDIATELY after the signature is found so that the** PROM address counter is correctly positioned at the start of the** ethernet address for later read out.*/static int DevicePresent(u_long iobase){  union {    struct {      u32 a;      u32 b;    } llsig;    char Sig[sizeof(u32) << 1];  } dev;  short sigLength;  char data;  int i, j, status = 0;  dev.llsig.a = ETH_PROM_SIG;  dev.llsig.b = ETH_PROM_SIG;  sigLength = sizeof(u32) << 1;  for (i=0,j=0;j<sigLength && i<PROBE_LENGTH+sigLength-1;i++) {    data = inb(EWRK3_APROM);    if (dev.Sig[j] == data) {   /* track signature */      j++;    } else {                    /* lost signature; begin search again */      if (data == dev.Sig[0]) {	j=1;      } else {	j=0;      }    }  }  if (j!=sigLength) {    status = -ENODEV;           /* search failed */  }  return status;}static u_char get_hw_addr(struct device *dev, u_char *eeprom_image, char chipType){  int i, j, k;  u_short chksum;  u_char crc, lfsr, sd, status = 0;  u_long iobase = dev->base_addr;  u16 tmp;  if (chipType == LeMAC2) {    for (crc=0x6a, j=0; j<ETH_ALEN; j++) {      sd = dev->dev_addr[j] = eeprom_image[EEPROM_PADDR0 + j];      outb(dev->dev_addr[j], EWRK3_PAR0 + j);      for (k=0; k<8; k++, sd >>= 1) {	lfsr = ((((crc & 0x02) >> 1) ^ (crc & 0x01)) ^ (sd & 0x01)) << 7;	crc = (crc >> 1) + lfsr;      }    }    if (crc != eeprom_image[EEPROM_PA_CRC]) status = -1;  } else {    for (i=0,k=0;i<ETH_ALEN;) {      k <<= 1 ;      if (k > 0xffff) k-=0xffff;      k += (u_char) (tmp = inb(EWRK3_APROM));      dev->dev_addr[i] = (u_char) tmp;      outb(dev->dev_addr[i], EWRK3_PAR0 + i);      i++;      k += (u_short) ((tmp = inb(EWRK3_APROM)) << 8);      dev->dev_addr[i] = (u_char) tmp;      outb(dev->dev_addr[i], EWRK3_PAR0 + i);      i++;      if (k > 0xffff) k-=0xffff;    }    if (k == 0xffff) k=0;    chksum = inb(EWRK3_APROM);    chksum |= (inb(EWRK3_APROM)<<8);    if (k != chksum) status = -1;  }  return status;}/*** Look for a particular board name in the EISA configuration space*/static int EISA_signature(char *name, s32 eisa_id){  u_long i;  char *signatures[] = EWRK3_SIGNATURE;  char ManCode[EWRK3_STRLEN];  union {    s32 ID;    char Id[4];  } Eisa;  int status = 0;  *name = '\0';  for (i=0; i<4; i++) {    Eisa.Id[i] = inb(eisa_id + i);  }  ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);  ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);  ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);  ManCode[3]=((Eisa.Id[2]&0x0f)+0x30);  ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);  ManCode[5]='\0';  for (i=0;(*signatures[i] != '\0') && (*name == '\0');i++) {    if (strstr(ManCode, signatures[i]) != NULL) {      strcpy(name,ManCode);      status = 1;    }  }  return status;                           /* return the device name string */}/*** Perform IOCTL call functions here. Some are privileged operations and the** effective uid is checked in those cases.*/static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd){  struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;  struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_data;  u_long iobase = dev->base_addr;  int i, j, status = 0;  u_char csr;  union {    u_char addr[HASH_TABLE_LEN * ETH_ALEN];    u_short val[(HASH_TABLE_LEN * ETH_ALEN) >> 1];  } tmp;  switch(ioc->cmd) {  case EWRK3_GET_HWADDR:             /* Get the hardware address */    for (i=0; i<ETH_ALEN; i++) {      tmp.addr[i] = dev->dev_addr[i];    }    ioc->len = ETH_ALEN;    if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {      memcpy_tofs(ioc->data, tmp.addr, ioc->len);    }    break;  case EWRK3_SET_HWADDR:             /* Set the hardware address */    if (suser()) {      if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN))) {	csr = inb(EWRK3_CSR);	csr |= (CSR_TXD|CSR_RXD);	outb(csr, EWRK3_CSR);                  /* Disable the TX and RX */	memcpy_fromfs(tmp.addr,ioc->data,ETH_ALEN);	for (i=0; i<ETH_ALEN; i++) {	  dev->dev_addr[i] = tmp.addr[i];	  outb(tmp.addr[i], EWRK3_PAR0 + i);	}	csr &= ~(CSR_TXD|CSR_RXD);             /* Enable the TX and RX */	outb(csr, EWRK3_CSR);      }    } else {      status = -EPERM;    }    break;  case EWRK3_SET_PROM:               /* Set Promiscuous Mode */    if (suser()) {      csr = inb(EWRK3_CSR);      csr |= CSR_PME;      csr &= ~CSR_MCE;      outb(csr, EWRK3_CSR);    } else {      status = -EPERM;    }    break;  case EWRK3_CLR_PROM:               /* Clear Promiscuous Mode */    if (suser()) {      csr = inb(EWRK3_CSR);      csr &= ~CSR_PME;      outb(csr, EWRK3_CSR);    } else {      status = -EPERM;    }    break;  case EWRK3_SAY_BOO:                /* Say "Boo!" to the kernel log file */    printk("%s: Boo!\n", dev->name);    break;  case EWRK3_GET_MCA:                /* Get the multicast address table */    if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {      while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */      if (lp->shmem_length == IO_ONLY) {	outb(0, EWRK3_IOPR);	outw(PAGE0_HTE, EWRK3_PIR1);	for (i=0; i<(HASH_TABLE_LEN >> 3); i++) {	  tmp.addr[i] = inb(EWRK3_DATA);	}      } else {	outb(0, EWRK3_MPR);	memcpy_fromio(tmp.addr, (char *)(lp->shmem_base + PAGE0_HTE), (HASH_TABLE_LEN >> 3));      }      ioc->len = (HASH_TABLE_LEN >> 3);      memcpy_tofs(ioc->data, tmp.addr, ioc->len);     }    lp->lock = 0;                               /* Unlock the page register */    break;  case EWRK3_SET_MCA:                /* Set a multicast address */    if (suser()) {      if (!(status=verify_area(VERIFY_READ, ioc->data, ETH_ALEN*ioc->len))) {	memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN * ioc->len);	set_multicast_list(dev);      }    } else {      status = -EPERM;    }    break;  case EWRK3_CLR_MCA:                /* Clear all multicast addresses */    if (suser()) {      set_multicast_list(dev);    } else {      status = -EPERM;    }    break;  case EWRK3_MCA_EN:                 /* Enable multicast addressing */    if (suser()) {      csr = inb(EWRK3_CSR);      csr |= CSR_MCE;      csr &= ~CSR_PME;      outb(csr, EWRK3_CSR);    } else {      status = -EPERM;    }    break;  case EWRK3_GET_STATS:              /* Get the driver statistics */    cli();    ioc->len = sizeof(lp->pktStats);    if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {      memcpy_tofs(ioc->data, &lp->pktStats, ioc->len);     }    sti();    break;  case EWRK3_CLR_STATS:              /* Zero out the driver statistics */    if (suser()) {      cli();      memset(&lp->pktStats, 0, sizeof(lp->pktStats));      sti();    } else {      status = -EPERM;    }    break;  case EWRK3_GET_CSR:                /* Get the CSR Register contents */    tmp.addr[0] = inb(EWRK3_CSR);    ioc->len = 1;    if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {      memcpy_tofs(ioc->data, tmp.addr, ioc->len);    }    break;  case EWRK3_SET_CSR:                /* Set the CSR Register contents */    if (suser()) {      if (!(status=verify_area(VERIFY_READ, ioc->data, 1))) {	memcpy_fromfs(tmp.addr, ioc->data, 1);	outb(tmp.addr[0], EWRK3_CSR);      }    } else {      status = -EPERM;    }    break;  case EWRK3_GET_EEPROM:             /* Get the EEPROM contents */    if (suser()) {      for (i=0; i<(EEPROM_MAX>>1); i++) {	tmp.val[i] = (short)Read_EEPROM(iobase, i);      }      i = EEPROM_MAX;      tmp.addr[i++] = inb(EWRK3_CMR);            /* Config/Management Reg. */      for (j=0;j<ETH_ALEN;j++) {	tmp.addr[i++] = inb(EWRK3_PAR0 + j);      }      ioc->len = EEPROM_MAX + 1 + ETH_ALEN;      if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {	memcpy_tofs(ioc->data, tmp.addr, ioc->len);      }    } else {      status = -EPERM;    }    break;  case EWRK3_SET_EEPROM:             /* Set the EEPROM contents */    if (suser()) {      if (!(status=verify_area(VERIFY_READ, ioc->data, EEPROM_MAX))) {	memcpy_fromfs(tmp.addr, ioc->data, EEPROM_MAX);	for (i=0; i<(EEPROM_MAX>>1); i++) {	  Write_EEPROM(tmp.val[i], iobase, i);	}      }    } else {      status = -EPERM;    }    break;  case EWRK3_GET_CMR:                /* Get the CMR Register contents */    tmp.addr[0] = inb(EWRK3_CMR);    ioc->len = 1;    if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {      memcpy_tofs(ioc->data, tmp.addr, ioc->len);    }    break;  case EWRK3_SET_TX_CUT_THRU:        /* Set TX cut through mode */    if (suser()) {      lp->txc = 1;    } else {      status = -EPERM;    }    break;  case EWRK3_CLR_TX_CUT_THRU:        /* Clear TX cut through mode */    if (suser()) {      lp->txc = 0;    } else {      status = -EPERM;    }    break;  default:    status = -EOPNOTSUPP;  }  return status;}#ifdef MODULEstatic char devicename[9] = { 0, };static struct device thisEthwrk = {  devicename, /* device name is inserted by /linux/drivers/net/net_init.c */  0, 0, 0, 0,  0x300, 5,   /* I/O address, IRQ */  0, 0, 0, NULL, ewrk3_probe };	static int io=0x300;	/* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */static int irq=5;	/* or use the insmod io= irq= options 		*/intinit_module(void){  thisEthwrk.base_addr=io;  thisEthwrk.irq=irq;  if (register_netdev(&thisEthwrk) != 0)    return -EIO;  return 0;}voidcleanup_module(void){  if (thisEthwrk.priv) {    kfree(thisEthwrk.priv);    thisEthwrk.priv = NULL;  }  thisEthwrk.irq = 0;  unregister_netdev(&thisEthwrk);  release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE);}#endif /* MODULE *//* * Local variables: *  compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c" * *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c ewrk3.c" * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -