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

📄 iphase.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		buf_desc_ptr->buf_start_hi = rx_pkt_start >> 16;  		buf_desc_ptr->buf_start_lo = rx_pkt_start & 0x0000ffff;  		buf_desc_ptr++;		  		rx_pkt_start += iadev->rx_buf_sz;  	}  	IF_INIT(printk("Rx Buffer desc ptr: 0x%0x\n", (u32)(buf_desc_ptr));)          i = FREE_BUF_DESC_Q*iadev->memSize; 	writew(i >> 16,  iadev->reass_reg+REASS_QUEUE_BASE);         writew(i, iadev->reass_reg+FREEQ_ST_ADR);        writew(i+iadev->num_rx_desc*sizeof(u_short),                                          iadev->reass_reg+FREEQ_ED_ADR);        writew(i, iadev->reass_reg+FREEQ_RD_PTR);        writew(i+iadev->num_rx_desc*sizeof(u_short),                                         iadev->reass_reg+FREEQ_WR_PTR);    	/* Fill the FREEQ with all the free descriptors. */  	freeq_st_adr = readw(iadev->reass_reg+FREEQ_ST_ADR);  	freeq_start = (u_short *)(iadev->reass_ram+freeq_st_adr);  	for(i=1; i<=iadev->num_rx_desc; i++)  	{  		*freeq_start = (u_short)i;  		freeq_start++;  	}  	IF_INIT(printk("freeq_start: 0x%0x\n", (u32)freeq_start);)          /* Packet Complete Queue */        i = (PKT_COMP_Q * iadev->memSize) & 0xffff;        writew(i, iadev->reass_reg+PCQ_ST_ADR);        writew(i+iadev->num_vc*sizeof(u_short), iadev->reass_reg+PCQ_ED_ADR);        writew(i, iadev->reass_reg+PCQ_RD_PTR);        writew(i, iadev->reass_reg+PCQ_WR_PTR);        /* Exception Queue */        i = (EXCEPTION_Q * iadev->memSize) & 0xffff;        writew(i, iadev->reass_reg+EXCP_Q_ST_ADR);        writew(i + NUM_RX_EXCP * sizeof(RX_ERROR_Q),                                              iadev->reass_reg+EXCP_Q_ED_ADR);        writew(i, iadev->reass_reg+EXCP_Q_RD_PTR);        writew(i, iadev->reass_reg+EXCP_Q_WR_PTR);      	/* Load local copy of FREEQ and PCQ ptrs */        iadev->rfL.fdq_st = readw(iadev->reass_reg+FREEQ_ST_ADR) & 0xffff;       	iadev->rfL.fdq_ed = readw(iadev->reass_reg+FREEQ_ED_ADR) & 0xffff ;	iadev->rfL.fdq_rd = readw(iadev->reass_reg+FREEQ_RD_PTR) & 0xffff;	iadev->rfL.fdq_wr = readw(iadev->reass_reg+FREEQ_WR_PTR) & 0xffff;        iadev->rfL.pcq_st = readw(iadev->reass_reg+PCQ_ST_ADR) & 0xffff;	iadev->rfL.pcq_ed = readw(iadev->reass_reg+PCQ_ED_ADR) & 0xffff;	iadev->rfL.pcq_rd = readw(iadev->reass_reg+PCQ_RD_PTR) & 0xffff;	iadev->rfL.pcq_wr = readw(iadev->reass_reg+PCQ_WR_PTR) & 0xffff;	        IF_INIT(printk("INIT:pcq_st:0x%x pcq_ed:0x%x pcq_rd:0x%x pcq_wr:0x%x",               iadev->rfL.pcq_st, iadev->rfL.pcq_ed, iadev->rfL.pcq_rd,               iadev->rfL.pcq_wr);)		  	/* just for check - no VP TBL */  	/* VP Table */  	/* writew(0x0b80, iadev->reass_reg+VP_LKUP_BASE); */  	/* initialize VP Table for invalid VPIs  		- I guess we can write all 1s or 0x000f in the entire memory  		  space or something similar.  	*/    	/* This seems to work and looks right to me too !!! */          i =  REASS_TABLE * iadev->memSize;	writew((i >> 3), iadev->reass_reg+REASS_TABLE_BASE);    	/* initialize Reassembly table to I don't know what ???? */  	reass_table = (u16 *)(iadev->reass_ram+i);          j = REASS_TABLE_SZ * iadev->memSize;	for(i=0; i < j; i++)  		*reass_table++ = NO_AAL5_PKT;         i = 8*1024;       vcsize_sel =  0;       while (i != iadev->num_vc) {          i /= 2;          vcsize_sel++;       }       i = RX_VC_TABLE * iadev->memSize;       writew(((i>>3) & 0xfff8) | vcsize_sel, iadev->reass_reg+VC_LKUP_BASE);       vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);          j = RX_VC_TABLE_SZ * iadev->memSize;	for(i = 0; i < j; i++)  	{  		/* shift the reassembly pointer by 3 + lower 3 bits of   		vc_lkup_base register (=3 for 1K VCs) and the last byte   		is those low 3 bits.   		Shall program this later.  		*/  		*vc_table = (i << 6) | 15;	/* for invalid VCI */  		vc_table++;  	}          /* ABR VC table */        i =  ABR_VC_TABLE * iadev->memSize;        writew(i >> 3, iadev->reass_reg+ABR_LKUP_BASE);                           i = ABR_VC_TABLE * iadev->memSize;	abr_vc_table = (struct abr_vc_table *)(iadev->reass_ram+i);          j = REASS_TABLE_SZ * iadev->memSize;        memset ((char*)abr_vc_table, 0, j * sizeof(struct abr_vc_table ) );    	for(i = 0; i < j; i++) {   				abr_vc_table->rdf = 0x0003;             	abr_vc_table->air = 0x5eb1;	       	abr_vc_table++;   	        }  	/* Initialize other registers */    	/* VP Filter Register set for VC Reassembly only */  	writew(0xff00, iadev->reass_reg+VP_FILTER);          writew(0, iadev->reass_reg+XTRA_RM_OFFSET);	writew(0x1,  iadev->reass_reg+PROTOCOL_ID);	/* Packet Timeout Count  related Registers : 	   Set packet timeout to occur in about 3 seconds	   Set Packet Aging Interval count register to overflow in about 4 us 	*/          writew(0xF6F8, iadev->reass_reg+PKT_TM_CNT );        ptr16 = (u16*)j;        i = ((u32)ptr16 >> 6) & 0xff;	ptr16  += j - 1;	i |=(((u32)ptr16 << 2) & 0xff00);        writew(i, iadev->reass_reg+TMOUT_RANGE);        /* initiate the desc_tble */        for(i=0; i<iadev->num_tx_desc;i++)            iadev->desc_tbl[i].timestamp = 0;	/* to clear the interrupt status register - read it */  	readw(iadev->reass_reg+REASS_INTR_STATUS_REG);     	/* Mask Register - clear it */  	writew(~(RX_FREEQ_EMPT|RX_PKT_RCVD), iadev->reass_reg+REASS_MASK_REG);    	skb_queue_head_init(&iadev->rx_dma_q);  	iadev->rx_free_desc_qhead = NULL;   	iadev->rx_open =(struct atm_vcc **)kmalloc(4*iadev->num_vc,GFP_KERNEL);	if (!iadev->rx_open)  	{  		printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n",		dev->number);  		return -ENOMEM;  	}  	memset(iadev->rx_open, 0, 4*iadev->num_vc);          iadev->rxing = 1;        iadev->rx_pkt_cnt = 0;	/* Mode Register */  	writew(R_ONLINE, iadev->reass_reg+MODE_REG);  	return 0;  }    /*  	The memory map suggested in appendix A and the coding for it.   	Keeping it around just in case we change our mind later.    		Buffer descr	0x0000 (128 - 4K)  		UBR sched	0x1000 (1K - 4K)  		UBR Wait q	0x2000 (1K - 4K)  		Commn queues	0x3000 Packet Ready, Trasmit comp(0x3100)  					(128 - 256) each  		extended VC	0x4000 (1K - 8K)  		ABR sched	0x6000	and ABR wait queue (1K - 2K) each  		CBR sched	0x7000 (as needed)  		VC table	0x8000 (1K - 32K)  */    static void tx_intr(struct atm_dev *dev)  {  	IADEV *iadev;  	unsigned short status;          unsigned long flags;	iadev = INPH_IA_DEV(dev);    	status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG);          if (status & TRANSMIT_DONE){           IF_EVENT(printk("Tansmit Done Intr logic run\n");)           spin_lock_irqsave(&iadev->tx_lock, flags);           ia_tx_poll(iadev);           spin_unlock_irqrestore(&iadev->tx_lock, flags);           writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);           if (iadev->close_pending)                 wake_up(&iadev->close_wait);        }     	  	if (status & TCQ_NOT_EMPTY)  	{  	    IF_EVENT(printk("TCQ_NOT_EMPTY int received\n");)  	}  }    static void tx_dle_intr(struct atm_dev *dev){        IADEV *iadev;        struct dle *dle, *cur_dle;         struct sk_buff *skb;        struct atm_vcc *vcc;        struct ia_vcc  *iavcc;        u_int dle_lp;        unsigned long flags;        iadev = INPH_IA_DEV(dev);        spin_lock_irqsave(&iadev->tx_lock, flags);           dle = iadev->tx_dle_q.read;        dle_lp = readl(iadev->dma+IPHASE5575_TX_LIST_ADDR) &                                         (sizeof(struct dle)*DLE_ENTRIES - 1);        cur_dle = (struct dle*)(iadev->tx_dle_q.start + (dle_lp >> 4));        while (dle != cur_dle)        {            /* free the DMAed skb */             skb = skb_dequeue(&iadev->tx_dma_q);             if (!skb) break;            vcc = ATM_SKB(skb)->vcc;            if (!vcc) {                  printk("tx_dle_intr: vcc is null\n");		  spin_unlock_irqrestore(&iadev->tx_lock, flags);                  dev_kfree_skb_any(skb);                  return;            }            iavcc = INPH_IA_VCC(vcc);            if (!iavcc) {                  printk("tx_dle_intr: iavcc is null\n");		  spin_unlock_irqrestore(&iadev->tx_lock, flags);                  dev_kfree_skb_any(skb);                  return;            }            if (vcc->qos.txtp.pcr >= iadev->rate_limit) {               if ((vcc->pop) && (skb->len != 0))               {                      vcc->pop(vcc, skb);               }                else {                 dev_kfree_skb_any(skb);               }            }            else { /* Hold the rate-limited skb for flow control */               IA_SKB_STATE(skb) |= IA_DLED;               skb_queue_tail(&iavcc->txing_skb, skb);            }            IF_EVENT(printk("tx_dle_intr: enque skb = 0x%x \n", (u32)skb);)            if (++dle == iadev->tx_dle_q.end)                 dle = iadev->tx_dle_q.start;        }        iadev->tx_dle_q.read = dle;        spin_unlock_irqrestore(&iadev->tx_lock, flags);}  static int open_tx(struct atm_vcc *vcc)  {  	struct ia_vcc *ia_vcc;  	IADEV *iadev;  	struct main_vc *vc;  	struct ext_vc *evc;          int ret;	IF_EVENT(printk("iadev: open_tx entered vcc->vci = %d\n", vcc->vci);)  	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;  	iadev = INPH_IA_DEV(vcc->dev);                  if (iadev->phy_type & FE_25MBIT_PHY) {           if (vcc->qos.txtp.traffic_class == ATM_ABR) {               printk("IA:  ABR not support\n");               return -EINVAL;            }	  if (vcc->qos.txtp.traffic_class == ATM_CBR) {               printk("IA:  CBR not support\n");               return -EINVAL;           }        }        ia_vcc =  INPH_IA_VCC(vcc);        memset((caddr_t)ia_vcc, 0, sizeof(struct ia_vcc));        if (vcc->qos.txtp.max_sdu >                          (iadev->tx_buf_sz - sizeof(struct cpcs_trailer))){           printk("IA:  SDU size over the configured SDU size %d\n",                                                          iadev->tx_buf_sz);           kfree(ia_vcc);           return -EINVAL;         }	ia_vcc->vc_desc_cnt = 0;        ia_vcc->txing = 1;        /* find pcr */        if (vcc->qos.txtp.max_pcr == ATM_MAX_PCR)            vcc->qos.txtp.pcr = iadev->LineRate;        else if ((vcc->qos.txtp.max_pcr == 0)&&( vcc->qos.txtp.pcr <= 0))           vcc->qos.txtp.pcr = iadev->LineRate;        else if ((vcc->qos.txtp.max_pcr > vcc->qos.txtp.pcr) && (vcc->qos.txtp.max_pcr> 0))            vcc->qos.txtp.pcr = vcc->qos.txtp.max_pcr;        if (vcc->qos.txtp.pcr > iadev->LineRate)             vcc->qos.txtp.pcr = iadev->LineRate;        ia_vcc->pcr = vcc->qos.txtp.pcr;        if (ia_vcc->pcr > (iadev->LineRate / 6) ) ia_vcc->ltimeout = HZ / 10;        else if (ia_vcc->pcr > (iadev->LineRate / 130)) ia_vcc->ltimeout = HZ;        else if (ia_vcc->pcr <= 170) ia_vcc->ltimeout = 16 * HZ;        else ia_vcc->ltimeout = 2700 * HZ  / ia_vcc->pcr;        if (ia_vcc->pcr < iadev->rate_limit)           skb_queue_head_init (&ia_vcc->txing_skb);        if (ia_vcc->pcr < iadev->rate_limit) {           if (vcc->qos.txtp.max_sdu != 0) {               if (ia_vcc->pcr > 60000)                  vcc->sk->sndbuf = vcc->qos.txtp.max_sdu * 5;               else if (ia_vcc->pcr > 2000)                  vcc->sk->sndbuf = vcc->qos.txtp.max_sdu * 4;               else                 vcc->sk->sndbuf = 3*vcc->qos.txtp.max_sdu;           }           else             vcc->sk->sndbuf = 24576;        }           	vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR;  	evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR;  	vc += vcc->vci;  	evc += vcc->vci;  	memset((caddr_t)vc, 0, sizeof(struct main_vc));  	memset((caddr_t)evc, 0, sizeof(struct ext_vc));  	  	/* store the most significant 4 bits of vci as the last 4 bits   		of first part of atm header.  	   store the last 12 bits of vci as first 12 bits of the second  		part of the atm header.  	*/  	evc->atm_hdr1 = (vcc->vci >> 12) & 0x000f;  	evc->atm_hdr2 = (vcc->vci & 0x0fff) << 4;   	/* check the following for different traffic classes */  	if (vcc->qos.txtp.traffic_class == ATM_UBR)  	{  		vc->type = UBR;                  vc->status = CRC_APPEND;		vc->acr = cellrate_to_float(iadev->LineRate);                  if (vcc->qos.txtp.pcr > 0)                    vc->acr = cellrate_to_float(vcc->qos.txtp.pcr);                  IF_UBR(printk("UBR: txtp.pcr = 0x%x f_rate = 0x%x\n",                                              vcc->qos.txtp.max_pcr,vc->acr);)	}  	else if (vcc->qos.txtp.traffic_class == ATM_ABR)  	{       srv_cls_param_t srv_p;		IF_ABR(printk("Tx ABR VCC\n");)                  init_abr_vc(iadev, &srv_p);                if (vcc->qos.txtp.pcr > 0)                    srv_p.pcr = vcc->qos.txtp.pcr;                if (vcc->qos.txtp.min_pcr > 0) {                   int tmpsum = iadev->sum_mcr+iadev->sum_cbr+vcc->qos.txtp.min_pcr;                   if (tmpsum > iadev->LineRate)                       return -EBUSY;                   srv_p.mcr = vcc->qos.txtp.min_pcr;                   iadev->sum_mcr += vcc->qos.txtp.min_pcr;                }                 else srv_p.mcr = 0;                if (vcc->qos.txtp.icr)                   srv_p.icr = vcc->qos.txtp.icr;                if (vcc->qos.txtp.tbe)                   srv_p.tbe = vcc->qos.txtp.tbe;                if (vcc->qos.txtp.frtt)                   srv_p.frtt = vcc->qos.txtp.frtt;                if (vcc->qos.txtp.rif)                   srv_p.rif = vcc->qos.txtp.rif;                if (vcc->qos.txtp.rdf)                   srv_p.rdf = vcc->qos.txtp.rdf;                if (vcc->qos.txtp.nrm_pres)                   srv_p.nrm = vcc->qos.txtp.nrm;                if (vcc->qos.txtp.trm_pres)                   srv_p.trm = vcc->qos.txtp.trm;                if (vcc->qos.txtp.adtf_pres)                   srv_p.adtf = vcc->qos.txtp.adtf;                if (vcc->qos.txtp.cdf_pres)                   srv_p.cdf = vcc->qos.txtp.cdf;                    if (srv_p.icr > srv_p.pcr)                   srv_p.icr = srv_p.pcr;                    IF_ABR(printk("ABR:vcc->qos.txtp.max_pcr = %d  mcr = %d\n",                                                       srv_p.pcr, srv_p.mcr);)		ia_open_abr_vc(iadev, &srv_p, vcc, 1);	} else if (vcc->qos.txtp.traffic_class == ATM_CBR) {                if (iadev->phy_type & FE_25MBIT_PHY) {                    printk("IA:  CBR not support\n");                    return -EINVAL;                 }                if (vcc->qos.txtp.max_pcr > iadev->LineRate) {                   IF_CBR(printk("PCR is 

⌨️ 快捷键说明

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