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

📄 sonic.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
    int status;    while (rd->in_use == 0) {	struct sk_buff *skb;	int pkt_len;	unsigned char *pkt_ptr;		status = rd->rx_status;	if (sonic_debug > 3)	  printk ("status %x, cur_rx %d, cur_rra %x\n",status,lp->cur_rx,lp->cur_rra);	if (status & SONIC_RCR_PRX) {	    	    pkt_len = rd->rx_pktlen;	    pkt_ptr = (char *)sonic_chiptomem((rd->rx_pktptr_h << 16) +						      rd->rx_pktptr_l);	    	    if (sonic_debug > 3)	      printk ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n", pkt_ptr,lp->rba,		      rd->rx_pktptr_h,rd->rx_pktptr_l,		      SONIC_READ(SONIC_RBWC1),SONIC_READ(SONIC_RBWC0));		    /* Malloc up new buffer. */	    skb = dev_alloc_skb(pkt_len+2);	    if (skb == NULL) {		printk("%s: Memory squeeze, dropping packet.\n", dev->name);		lp->stats.rx_dropped++;		break;	    }	    skb->dev = dev;	    skb_reserve(skb,2);	/* 16 byte align */	    skb_put(skb,pkt_len);	/* Make room */	    eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0);	    skb->protocol=eth_type_trans(skb,dev);	    netif_rx(skb);			/* pass the packet to upper layers */	    lp->stats.rx_packets++;	    lp->stats.rx_bytes += pkt_len;	    	} else {	    /* This should only happen, if we enable accepting broken packets. */	    lp->stats.rx_errors++;	    if (status & SONIC_RCR_FAER) lp->stats.rx_frame_errors++;	    if (status & SONIC_RCR_CRCR) lp->stats.rx_crc_errors++;	}		rd->in_use = 1;	rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK];	/* now give back the buffer to the receive buffer area */	if (status & SONIC_RCR_LPKT) {	    /*	     * this was the last packet out of the current receice buffer	     * give the buffer back to the SONIC	     */	    lp->cur_rra += sizeof(sonic_rr_t);	    if (lp->cur_rra > (lp->rra_laddr + (SONIC_NUM_RRS-1) * sizeof(sonic_rr_t)))		lp->cur_rra = lp->rra_laddr;	    SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff);	} else	    printk ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n",dev->name);    }    /*     * If any worth-while packets have been received, dev_rint()     * has done a mark_bh(NET_BH) for us and will work on them     * when we get to the bottom-half routine.     */    return;}/* * Get the current statistics. * This may be called with the device open or closed. */static struct net_device_stats *sonic_get_stats(struct net_device *dev){    struct sonic_local *lp = (struct sonic_local *)dev->priv;    unsigned int base_addr = dev->base_addr;    /* read the tally counter from the SONIC and reset them */    lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT);    SONIC_WRITE(SONIC_CRCT,0xffff);    lp->stats.rx_frame_errors += SONIC_READ(SONIC_FAET);    SONIC_WRITE(SONIC_FAET,0xffff);    lp->stats.rx_missed_errors += SONIC_READ(SONIC_MPT);    SONIC_WRITE(SONIC_MPT,0xffff);        return &lp->stats;}/* * Set or clear the multicast filter for this adaptor. */static voidsonic_multicast_list(struct net_device *dev){    struct sonic_local *lp = (struct sonic_local *)dev->priv;        unsigned int base_addr = dev->base_addr;        unsigned int rcr;    struct dev_mc_list *dmi = dev->mc_list;    unsigned char *addr;    int i;    rcr = SONIC_READ(SONIC_RCR) & ~(SONIC_RCR_PRO | SONIC_RCR_AMC);    rcr |= SONIC_RCR_BRD; /* accept broadcast packets */        if (dev->flags & IFF_PROMISC) {         /* set promiscuous mode */	rcr |= SONIC_RCR_PRO;    } else {	if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 15)) {	    rcr |= SONIC_RCR_AMC;	} else {	    if (sonic_debug > 2)	      printk ("sonic_multicast_list: mc_count %d\n",dev->mc_count);	    lp->cda.cam_enable = 1; /* always enable our own address */	    for (i = 1; i <= dev->mc_count; i++) {		addr = dmi->dmi_addr;		dmi = dmi->next;		lp->cda.cam_desc[i].cam_cap0 = addr[1] << 8 | addr[0];		lp->cda.cam_desc[i].cam_cap1 = addr[3] << 8 | addr[2];		lp->cda.cam_desc[i].cam_cap2 = addr[5] << 8 | addr[4];		lp->cda.cam_enable |= (1 << i);	    }	    SONIC_WRITE(SONIC_CDC,16);	    /* issue Load CAM command */	    SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);	    	    SONIC_WRITE(SONIC_CMD,SONIC_CR_LCAM);	}    }        if (sonic_debug > 2)      printk("sonic_multicast_list: setting RCR=%x\n",rcr);        SONIC_WRITE(SONIC_RCR,rcr);}/* * Initialize the SONIC ethernet controller. */static int sonic_init(struct net_device *dev){    unsigned int base_addr = dev->base_addr;    unsigned int cmd;    struct sonic_local *lp = (struct sonic_local *)dev->priv;    unsigned int rra_start;    unsigned int rra_end;    int i;        /*     * put the Sonic into software-reset mode and     * disable all interrupts     */    SONIC_WRITE(SONIC_ISR,0x7fff);    SONIC_WRITE(SONIC_IMR,0);    SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);      /*     * clear software reset flag, disable receiver, clear and     * enable interrupts, then completely initialize the SONIC     */    SONIC_WRITE(SONIC_CMD,0);    SONIC_WRITE(SONIC_CMD,SONIC_CR_RXDIS);    /*     * initialize the receive resource area     */    if (sonic_debug > 2)      printk ("sonic_init: initialize receive resource area\n");        rra_start = lp->rra_laddr & 0xffff;    rra_end   = (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff;      for (i = 0; i < SONIC_NUM_RRS; i++) {	lp->rra[i].rx_bufadr_l = (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff;	lp->rra[i].rx_bufadr_h = (lp->rba_laddr + i * SONIC_RBSIZE) >> 16;	lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1;	lp->rra[i].rx_bufsize_h = 0;    }    /* initialize all RRA registers */    SONIC_WRITE(SONIC_RSA,rra_start);    SONIC_WRITE(SONIC_REA,rra_end);    SONIC_WRITE(SONIC_RRP,rra_start);    SONIC_WRITE(SONIC_RWP,rra_end);    SONIC_WRITE(SONIC_URRA,lp->rra_laddr >> 16);    SONIC_WRITE(SONIC_EOBC,(SONIC_RBSIZE-2) >> 1);        lp->cur_rra = lp->rra_laddr + (SONIC_NUM_RRS-1) * sizeof(sonic_rr_t);    /* load the resource pointers */    if (sonic_debug > 3)      printk("sonic_init: issueing RRRA command\n");      SONIC_WRITE(SONIC_CMD,SONIC_CR_RRRA);    i = 0;    while (i++ < 100) {	if (SONIC_READ(SONIC_CMD) & SONIC_CR_RRRA)	  break;    }        if (sonic_debug > 2)      printk("sonic_init: status=%x\n",SONIC_READ(SONIC_CMD));        /*     * Initialize the receive descriptors so that they     * become a circular linked list, ie. let the last     * descriptor point to the first again.     */    if (sonic_debug > 2)      printk ("sonic_init: initialize receive descriptors\n");          for (i=0; i<SONIC_NUM_RDS; i++) {	lp->rda[i].rx_status = 0;	lp->rda[i].rx_pktlen = 0;	lp->rda[i].rx_pktptr_l = 0;	lp->rda[i].rx_pktptr_h = 0;	lp->rda[i].rx_seqno = 0;	lp->rda[i].in_use = 1;		       		lp->rda[i].link = lp->rda_laddr + (i+1) * sizeof (sonic_rd_t);    }    /* fix last descriptor */    lp->rda[SONIC_NUM_RDS-1].link = lp->rda_laddr;    lp->cur_rx = 0;    SONIC_WRITE(SONIC_URDA,lp->rda_laddr >> 16);    SONIC_WRITE(SONIC_CRDA,lp->rda_laddr & 0xffff);        /*      * initialize transmit descriptors     */    if (sonic_debug > 2)      printk ("sonic_init: initialize transmit descriptors\n");    for (i = 0; i < SONIC_NUM_TDS; i++) {	lp->tda[i].tx_status = 0;	lp->tda[i].tx_config = 0;	lp->tda[i].tx_pktsize = 0;	lp->tda[i].tx_frag_count = 0;	lp->tda[i].link = (lp->tda_laddr + (i+1) * sizeof (sonic_td_t)) | SONIC_END_OF_LINKS;    }    lp->tda[SONIC_NUM_TDS-1].link = (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS;        SONIC_WRITE(SONIC_UTDA,lp->tda_laddr >> 16);    SONIC_WRITE(SONIC_CTDA,lp->tda_laddr & 0xffff);    lp->cur_tx = lp->dirty_tx = 0;        /*     * put our own address to CAM desc[0]     */    lp->cda.cam_desc[0].cam_cap0 = dev->dev_addr[1] << 8 | dev->dev_addr[0];    lp->cda.cam_desc[0].cam_cap1 = dev->dev_addr[3] << 8 | dev->dev_addr[2];    lp->cda.cam_desc[0].cam_cap2 = dev->dev_addr[5] << 8 | dev->dev_addr[4];    lp->cda.cam_enable = 1;        for (i=0; i < 16; i++)      lp->cda.cam_desc[i].cam_entry_pointer = i;    /*     * initialize CAM registers     */    SONIC_WRITE(SONIC_CDP, lp->cda_laddr & 0xffff);    SONIC_WRITE(SONIC_CDC,16);        /*     * load the CAM     */    SONIC_WRITE(SONIC_CMD,SONIC_CR_LCAM);        i = 0;    while (i++ < 100) {	if (SONIC_READ(SONIC_ISR) & SONIC_INT_LCD)	  break;    }    if (sonic_debug > 2) {	printk("sonic_init: CMD=%x, ISR=%x\n",	       SONIC_READ(SONIC_CMD),	       SONIC_READ(SONIC_ISR));    }    /*     * enable receiver, disable loopback     * and enable all interrupts     */    SONIC_WRITE(SONIC_CMD,SONIC_CR_RXEN | SONIC_CR_STP);    SONIC_WRITE(SONIC_RCR,SONIC_RCR_DEFAULT);    SONIC_WRITE(SONIC_TCR,SONIC_TCR_DEFAULT);    SONIC_WRITE(SONIC_ISR,0x7fff);    SONIC_WRITE(SONIC_IMR,SONIC_IMR_DEFAULT);    cmd = SONIC_READ(SONIC_CMD);    if ((cmd & SONIC_CR_RXEN) == 0 ||	(cmd & SONIC_CR_STP) == 0)      printk("sonic_init: failed, status=%x\n",cmd);    if (sonic_debug > 2)      printk("sonic_init: new status=%x\n",SONIC_READ(SONIC_CMD));    return(0);}/* * Local variables: *  compile-command: "mipsel-linux-gcc -D__KERNEL__ -D__mips64 -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -mcpu=r4000 -c sonic.c" *  version-control: t *  kept-new-versions: 5 *  tab-width: 4 * End: */

⌨️ 快捷键说明

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