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

📄 ni52.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
        {          int rstat;             /* free all RBD's until RBD_LAST is set */          totlen = 0;          while(!((rstat=rbd->status) & RBD_LAST))          {            totlen += rstat & RBD_MASK;            if(!rstat)            {              printk("%s: Whoops .. no end mark in RBD list\n",dev->name);              break;            }            rbd->status = 0;            rbd = (struct rbd_struct *) make32(rbd->next);          }          totlen += rstat & RBD_MASK;          rbd->status = 0;          printk("%s: received oversized frame! length: %d\n",dev->name,totlen);          p->stats.rx_dropped++;       }      }      else /* frame !(ok), only with 'save-bad-frames' */      {        printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);        p->stats.rx_errors++;      }      p->rfd_top->stat_high = 0;      p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */      p->rfd_top->rbd_offset = 0xffff;      p->rfd_last->last = 0;        /* delete RFD_SUSP  */      p->rfd_last = p->rfd_top;      p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */      p->scb->rfa_offset = make16(p->rfd_top);      if(debuglevel > 0)        printk("%d",cnt++);  }  if(automatic_resume)  {    WAIT_4_SCB_CMD();    p->scb->cmd_ruc = RUC_RESUME;    ni_attn586();    WAIT_4_SCB_CMD_RUC();  }#ifdef WAIT_4_BUSY  {    int i;    for(i=0;i<1024;i++)    {      if(p->rfd_top->status)        break;      DELAY_16();      if(i == 1023)        printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name);    }  }#endif#if 0  if(!at_least_one)  {     int i;    volatile struct rfd_struct *rfds=p->rfd_top;    volatile struct rbd_struct *rbds;    printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least);    for(i=0;i< (p->num_recv_buffs+4);i++)    {      rbds = (struct rbd_struct *) make32(rfds->rbd_offset);      printk("%04x:%04x ",rfds->status,rbds->status);      rfds = (struct rfd_struct *) make32(rfds->next);    }    printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);    printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);    }  old_at_least = at_least_one;#endif  if(debuglevel > 0)    printk("r");}/********************************************************** * handle 'Receiver went not ready'. */static void ni52_rnr_int(struct device *dev){  struct priv *p = (struct priv *) dev->priv;  p->stats.rx_errors++;  WAIT_4_SCB_CMD();    /* wait for the last cmd, WAIT_4_FULLSTAT?? */  p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */  ni_attn586();   WAIT_4_SCB_CMD_RUC();    /* wait for accept cmd. */  alloc_rfa(dev,(char *)p->rfd_first);/* maybe add a check here, before restarting the RU */  startrecv586(dev); /* restart RU */  printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus);}/********************************************************** * handle xmit - interrupt */static void ni52_xmt_int(struct device *dev){  int status;  struct priv *p = (struct priv *) dev->priv;  if(debuglevel > 0)    printk("X");  status = p->xmit_cmds[p->xmit_last]->cmd_status;  if(!(status & STAT_COMPL))    printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);  if(status & STAT_OK)  {    p->stats.tx_packets++;    p->stats.collisions += (status & TCMD_MAXCOLLMASK);  }  else   {    p->stats.tx_errors++;    if(status & TCMD_LATECOLL) {      printk("%s: late collision detected.\n",dev->name);      p->stats.collisions++;    }     else if(status & TCMD_NOCARRIER) {      p->stats.tx_carrier_errors++;      printk("%s: no carrier detected.\n",dev->name);    }     else if(status & TCMD_LOSTCTS)       printk("%s: loss of CTS detected.\n",dev->name);    else if(status & TCMD_UNDERRUN) {      p->stats.tx_fifo_errors++;      printk("%s: DMA underrun detected.\n",dev->name);    }    else if(status & TCMD_MAXCOLL) {      printk("%s: Max. collisions exceeded.\n",dev->name);      p->stats.collisions += 16;    }   }#if (NUM_XMIT_BUFFS > 1)  if( (++p->xmit_last) == NUM_XMIT_BUFFS)     p->xmit_last = 0;#endif  dev->tbusy = 0;  mark_bh(NET_BH);}/*********************************************************** * (re)start the receiver */ static void startrecv586(struct device *dev){  struct priv *p = (struct priv *) dev->priv;  WAIT_4_SCB_CMD();  WAIT_4_SCB_CMD_RUC();  p->scb->rfa_offset = make16(p->rfd_first);  p->scb->cmd_ruc = RUC_START;  ni_attn586();		/* start cmd. */  WAIT_4_SCB_CMD_RUC();	/* wait for accept cmd. (no timeout!!) */}/****************************************************** * send frame  */static int ni52_send_packet(struct sk_buff *skb, struct device *dev){  int len,i;#ifndef NO_NOPCOMMANDS  int next_nop;#endif  struct priv *p = (struct priv *) dev->priv;  if(dev->tbusy)  {    int tickssofar = jiffies - dev->trans_start;    if (tickssofar < 5)      return 1;#ifndef NO_NOPCOMMANDS    if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */    {      dev->tbusy = 0;#ifdef DEBUG      printk("%s: strange ... timeout with CU active?!?\n",dev->name);      printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);#endif      p->scb->cmd_cuc = CUC_ABORT;      ni_attn586();      WAIT_4_SCB_CMD();      p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);      p->scb->cmd_cuc = CUC_START;      ni_attn586();      WAIT_4_SCB_CMD();      dev->trans_start = jiffies;      dev_kfree_skb(skb, FREE_WRITE);      return 0;    }    else#endif    {#ifdef DEBUG      printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);      printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);      printk("%s: check, whether you set the right interrupt number!\n",dev->name);#endif      ni52_close(dev);      ni52_open(dev);    }    dev->trans_start = jiffies;    return 0;  }  if(skb == NULL)  {    dev_tint(dev);    return 0;  }  if (skb->len <= 0)    return 0;  if(skb->len > XMIT_BUFF_SIZE)  {    printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %ld bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);    return 0;  }  if (set_bit(0, (void*)&dev->tbusy)) {    printk("%s: Transmitter access conflict.\n", dev->name);    return 1;  }#if(NUM_XMIT_BUFFS > 1)  else if(set_bit(0,(void *) &p->lock)) {    printk("%s: Queue was locked\n",dev->name);    return 1;  }#endif  else  {    memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);    len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;#if (NUM_XMIT_BUFFS == 1)#  ifdef NO_NOPCOMMANDS#ifdef DEBUG    if(p->scb->cus & CU_ACTIVE)    {      printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name);      printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,p->xmit_cmds[0]->cmd_status);    }#endif    p->xmit_buffs[0]->size = TBD_LAST | len;    for(i=0;i<16;i++)    {      p->xmit_cmds[0]->cmd_status = 0;      WAIT_4_SCB_CMD();      if( (p->scb->cus & CU_STATUS) == CU_SUSPEND)        p->scb->cmd_cuc = CUC_RESUME;      else      {        p->scb->cbl_offset = make16(p->xmit_cmds[0]);        p->scb->cmd_cuc = CUC_START;      }      ni_attn586();      dev->trans_start = jiffies;      if(!i)        dev_kfree_skb(skb,FREE_WRITE);      WAIT_4_SCB_CMD();      if( (p->scb->cus & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */        break;      if(p->xmit_cmds[0]->cmd_status)        break;      if(i==15)        printk("%s: Can't start transmit-command.\n",dev->name);    }#  else    next_nop = (p->nop_point + 1) & 0x1;    p->xmit_buffs[0]->size = TBD_LAST | len;    p->xmit_cmds[0]->cmd_link   = p->nop_cmds[next_nop]->cmd_link                                 = make16((p->nop_cmds[next_nop]));    p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;    p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));    dev->trans_start = jiffies;    p->nop_point = next_nop;    dev_kfree_skb(skb,FREE_WRITE);#  endif#else    p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;    if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )       next_nop = 0;    p->xmit_cmds[p->xmit_count]->cmd_status  = 0;	/* linkpointer of xmit-command already points to next nop cmd */    p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop]));    p->nop_cmds[next_nop]->cmd_status = 0;    p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));    dev->trans_start = jiffies;    p->xmit_count = next_nop;     {      long flags;       save_flags(flags);      cli();      if(p->xmit_count != p->xmit_last)        dev->tbusy = 0;      p->lock = 0;      restore_flags(flags);    }    dev_kfree_skb(skb,FREE_WRITE);#endif  }  return 0;}/******************************************* * Someone wanna have the statistics  */static struct enet_statistics *ni52_get_stats(struct device *dev){  struct priv *p = (struct priv *) dev->priv;  unsigned short crc,aln,rsc,ovrn;  crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */  p->scb->crc_errs = 0;  aln = p->scb->aln_errs;  p->scb->aln_errs = 0;  rsc = p->scb->rsc_errs;  p->scb->rsc_errs = 0;  ovrn = p->scb->ovrn_errs;  p->scb->ovrn_errs = 0;  p->stats.rx_crc_errors += crc;  p->stats.rx_fifo_errors += ovrn;  p->stats.rx_frame_errors += aln;  p->stats.rx_dropped += rsc;  return &p->stats;}/******************************************************** * Set MC list ..   */static void set_multicast_list(struct device *dev){  if(!dev->start)  {    printk("%s: Can't apply promiscuous/multicastmode to a not running interface.\n",dev->name);    return;  }  dev->start = 0;  ni_disint();  alloc586(dev);  init586(dev);    startrecv586(dev);  ni_enaint();  dev->start = 1;}#ifdef MODULEstatic struct device dev_ni52 = {  "        ",  /* "ni5210": device name inserted by net_init.c */  0, 0, 0, 0,  0x300, 9,   /* I/O address, IRQ */  0, 0, 0, NULL, ni52_probe };/* set: io,irq,memstart,memend or set it when calling insmod */int irq=9;int io=0x300;long memstart=0; /* e.g 0xd0000 */long memend=0;   /* e.g 0xd4000 */int init_module(void){  if(io <= 0x0 || !memend || !memstart || irq < 2) {    printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");    return -ENODEV;  }  dev_ni52.irq = irq;  dev_ni52.base_addr = io;  dev_ni52.mem_end = memend;  dev_ni52.mem_start = memstart;  if (register_netdev(&dev_ni52) != 0)    return -EIO;  return 0;}void cleanup_module(void){  release_region(dev_ni52.base_addr, NI52_TOTAL_SIZE);  kfree(dev_ni52.priv);  dev_ni52.priv = NULL;  unregister_netdev(&dev_ni52);}#endif /* MODULE */#if 0/* * DUMP .. we expect a not running CMD unit and enough space */void ni52_dump(struct device *dev,void *ptr){  struct priv *p = (struct priv *) dev->priv;  struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;  int i;  p->scb->cmd_cuc = CUC_ABORT;  ni_attn586();  WAIT_4_SCB_CMD();  WAIT_4_SCB_CMD_RUC();  dump_cmd->cmd_status = 0;  dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST;  dump_cmd->dump_offset = make16((dump_cmd + 1));  dump_cmd->cmd_link = 0xffff;  p->scb->cbl_offset = make16(dump_cmd);  p->scb->cmd_cuc = CUC_START;  ni_attn586();  WAIT_4_STAT_COMPL(dump_cmd);  if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )        printk("%s: Can't get dump information.\n",dev->name);  for(i=0;i<170;i++) {    printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]);    if(i % 24 == 23)      printk("\n");  }  printk("\n");}#endif/* * END: linux/drivers/net/ni52.c  */

⌨️ 快捷键说明

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