1111

static int dmfe_packet_receive( PKT *skb, END_DEVICE *dev )
{
    UCHAR tmp1,tmp2;
    UWORD tmp3;
    UCHAR rxbyte;
    UCHAR *rdptr;
    UWORD i, RxStatus, RxLen, GoodPacket, tmplen;
    int   oldv;
	UWORD RxStatus_tmp,data_tmp;

   	/* Check packet ready or not */
  	rxbyte=ior(dev,0xf0);
 	/* Got most updated data */
   	rxbyte=ior(dev,0xf0); 		/*這個地方爲什麼要讀兩次0xf0,今天看到一個帖子,說是實驗證明,讀取的第一次一定是0x00,第二次纔是0x01,呵呵,確實奇怪,並且這個0xf0寄存器也很奇怪,因爲這個寄存器中的數據時sram中的數據,也就是說是保持着和dm9000內部緩衝池的第一個字節的數據,並且讀完後指針不會移動,這個和下面的0xf2寄存器剛好相反,正因爲這樣,纔有了這裏的操作時序*/
  
    /* Status check: this byte must be 0 or 1 */
    if( rxbyte > DM9000_PKT_RDY )
    {
        iow(dev, 0x05, DM9000_REG05_OFF);   /* Stop Device */
        iow(dev, 0xff, DM9000_REGFF_OFF);   /* Stop Device */

        /* dev->device_wait_reset = 1; */
        DM9000_DEBUG_LOGMSG("rx need reset\n", 1, 2, 3, 4, 5, 6);
        dm9000Reset( dev );
        dm9000Config( dev );
        return 2;
    }

    /* packet ready to receive check */
    if( rxbyte == DM9000_PKT_RDY )
    {
        /* A packet ready now  & Get status/length */
        GoodPacket = 1;
        if( dev->io_mode == 1 )
        {
            /* Byte mode */  
          	tmp1=ior(dev,0xf2);  /*這裏的操作和上面一樣,不過是讀取0xf2,但是0xf2和0xf0不一樣,0xf2也是內存中的數據,但是指針會移動,所以說剛開始讀取的數據也是從幀開頭讀的,並沒有因爲讀取了0xf0而向後移動*/
			tmp2=ior(dev,0xf2);
            RxStatus = tmp1 + (tmp2 << 8);
        
          	tmp1=ior(dev,0xf2);
			tmp2=ior(dev,0xf2);
            RxLen = tmp1 + (tmp2<<8);
        }
        else{
			outb(dev->io_addr, 0xf2);
			RxStatus = SWAP16(inb(dev->io_data));

			RxLen = inb(dev->io_data);		
        }
        
        if( RxLen < 0x40)
        {
            DRV_LOG (DRV_DEBUG_RX, "packet too small \n", 1, 2, 3, 4, 5, 6);
            GoodPacket = 0;
        }
        if( RxLen > DM9000_PKT_MAX )
        {
            DRV_LOG (DRV_DEBUG_RX, "packet too big need reset \n", 1, 2, 3, 4, 5, 6);
            dm9000Reset( dev );
            dm9000Config( dev );
            return 2;
        }
		
        if( RxStatus & 0xbf)
        {
            GoodPacket = 0;
            DRV_LOG (DRV_DEBUG_RX, "packet error \n", RxStatus, 2, 3, 4, 5, 6);
        }
	
        /* Move data from DM9000 */
        skb->len = 0;
        if( GoodPacket && (skb != NULL) )
        {   /* good packet*/
            skb->len = RxLen;
            rdptr = skb->pData;
            /* Read received packet from RX SARM */
            if (dev->io_mode == 1)
            {
                /* Byte mode */
                for( i=0; i<RxLen; i++ )
                   rdptr[i]=dm9k_inb(dev->io_data);
            }
            else{  
                /* Word mode */
                tmplen = (RxLen + 1) / 2;
                for( i = 0; i < tmplen; i++ ){
                	//DM9000_IN_WORD( *((UWORD *)rdptr)++ );   
                	data_tmp=inb(dev->io_data);
                	((unsigned short *)rdptr)[i] = SWAP16(data_tmp);
					//((unsigned short *)rdptr)[i] = SWAP16(inb(dev->io_data));
                }
            }
            return 0;
        }
        else
        {   /* bad packet*/
            /* Without buffer or error packet */
            if( dev->io_mode == 1 ){
                /* Byte mode */
                for( i = 0; i < RxLen; i++ )
                    //DM9000_IN_BYTE( tmp1 );
					tmp1=dm9k_inb(dev->io_data);
            }
            else
            {
                /* Word mode */
                tmplen = (RxLen + 1) / 2;
                for( i = 0; i < tmplen; i++ )
                   // DM9000_IN_WORD( tmp3 );
					(unsigned short )tmp3 = SWAP16(inb(dev->io_data));
            }
            /*INT_UNLOCK(oldv);*/
            return 1;
        }
    }
    DM9000_DEBUG_LOGMSG("no ready \n", 1, 2, 3, 4, 5, 6);
    return 1;
}

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章