예제 #1
0
/*
 * segment the img and use the ptr and length to remember info on each segment
 *
 */
static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
			     u32 buffer_len)
{
	struct r8192_priv   *priv = ieee80211_priv(dev);
	bool		    rt_status = true;
	u16		    frag_threshold;
	u16		    frag_length, frag_offset = 0;
	//u16		    total_size;
	int		    i;

	rt_firmware	    *pfirmware = priv->pFirmware;
	struct sk_buff	    *skb;
	unsigned char	    *seg_ptr;
	cb_desc		    *tcb_desc;
	u8                  bLastIniPkt;

	firmware_init_param(dev);
	//Fragmentation might be required
	frag_threshold = pfirmware->cmdpacket_frag_thresold;
	do {
		if ((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold ;
			bLastIniPkt = 0;

		} else {
			frag_length = buffer_len - frag_offset;
			bLastIniPkt = 1;

		}

		/* Allocate skb buffer to contain firmware info and tx descriptor info
		 * add 4 to avoid packet appending overflow.
		 * */
		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
		if (!skb)
			return false;
		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
		tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
		tcb_desc->queue_index = TXCMD_QUEUE;
		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
		tcb_desc->bLastIniPkt = bLastIniPkt;

		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
		seg_ptr = skb->data;
		/*
		 * Transform from little endian to big endian
		 * and pending  zero
		 */
		for(i=0 ; i < frag_length; i+=4) {
			*seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
			*seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
			*seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
			*seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
		}
		tcb_desc->txbuf_size= (u16)i;
		skb_put(skb, i);

		if (!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
			(priv->ieee80211->queue_stop) ) {
			RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
		} else {
			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
		}

		code_virtual_address += frag_length;
		frag_offset += frag_length;

	}while(frag_offset < buffer_len);

	return rt_status;

}
예제 #2
0
bool cmpk_message_handle_tx(
	struct net_device *dev,
	u8	*code_virtual_address,
	u32	packettype,
	u32	buffer_len)
{

	bool				rt_status = true;
	struct r8192_priv *priv = rtllib_priv(dev);
	u16				frag_threshold;
	u16				frag_length = 0, frag_offset = 0;
	struct rt_firmware *pfirmware = priv->pFirmware;
	struct sk_buff		*skb;
	unsigned char		*seg_ptr;
	struct cb_desc *tcb_desc;
	u8				bLastIniPkt;

	struct tx_fwinfo_8190pci *pTxFwInfo = NULL;

	RT_TRACE(COMP_CMDPKT, "%s(),buffer_len is %d\n", __func__, buffer_len);
	firmware_init_param(dev);
	frag_threshold = pfirmware->cmdpacket_frag_thresold;

	do {
		if ((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold;
			bLastIniPkt = 0;

		} else {
			frag_length = (u16)(buffer_len - frag_offset);
			bLastIniPkt = 1;
		}

		skb  = dev_alloc_skb(frag_length +
				     priv->rtllib->tx_headroom + 4);

		if (skb == NULL) {
			rt_status = false;
			goto Failed;
		}

		memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
		tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
		tcb_desc->queue_index = TXCMD_QUEUE;
		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL;
		tcb_desc->bLastIniPkt = bLastIniPkt;
		tcb_desc->pkt_size = frag_length;

		seg_ptr = skb_put(skb, priv->rtllib->tx_headroom);
		pTxFwInfo = (struct tx_fwinfo_8190pci *)seg_ptr;
		memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci));
		memset(pTxFwInfo, 0x12, 8);

		seg_ptr = skb_put(skb, frag_length);
		memcpy(seg_ptr, code_virtual_address, (u32)frag_length);

		priv->rtllib->softmac_hard_start_xmit(skb, dev);

		code_virtual_address += frag_length;
		frag_offset += frag_length;

	} while (frag_offset < buffer_len);

	write_nic_byte(dev, TPPoll, TPPoll_CQ);
Failed:
	return rt_status;
}
예제 #3
0
/*-----------------------------------------------------------------------------
 * Function:	cmpk_message_handle_tx()
 *
 * Overview:	Driver internal module can call the API to send message to
 *				firmware side. For example, you can send a debug command packet.
 *				Or you can send a request for FW to modify RLX4181 LBUS HW bank.
 *				Otherwise, you can change MAC/PHT/RF register by firmware at
 *				run time. We do not support message more than one segment now.
 *
 * Input:		NONE
 *
 * Output:		NONE
 *
 * Return:		NONE
 *
 * Revised History:
 *	When		Who		Remark
 *	05/06/2008	amy		porting from windows code.
 *
 *---------------------------------------------------------------------------*/
 extern	rt_status	cmpk_message_handle_tx(
	struct net_device *dev,
	u8*	codevirtualaddress,
	u32	packettype,
	u32	buffer_len)
{

	bool 	    rt_status = true;
#ifdef RTL8192U
	return rt_status;
#else
	struct r8192_priv   *priv = ieee80211_priv(dev);
	u16		    frag_threshold;
	u16		    frag_length, frag_offset = 0;
	//u16		    total_size;
	//int		    i;

	rt_firmware	    *pfirmware = priv->pFirmware;
	struct sk_buff	    *skb;
	unsigned char	    *seg_ptr;
	cb_desc		    *tcb_desc;
	u8                  bLastIniPkt;

	firmware_init_param(dev);
	//Fragmentation might be required
	frag_threshold = pfirmware->cmdpacket_frag_thresold;
	do {
		if((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold ;
			bLastIniPkt = 0;

		} else {
			frag_length = buffer_len - frag_offset;
			bLastIniPkt = 1;

		}

		/* Allocate skb buffer to contain firmware info and tx descriptor info
		 * add 4 to avoid packet appending overflow.
		 * */
		#ifdef RTL8192U
		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
		#else
		skb  = dev_alloc_skb(frag_length + 4);
		#endif
		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
		tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
		tcb_desc->queue_index = TXCMD_QUEUE;
		tcb_desc->bCmdOrInit = packettype;
		tcb_desc->bLastIniPkt = bLastIniPkt;

		#ifdef RTL8192U
		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
		#endif

		seg_ptr = skb_put(skb, buffer_len);
		/*
		 * Transform from little endian to big endian
		 * and pending  zero
		 */
		memcpy(seg_ptr,codevirtualaddress,buffer_len);
		tcb_desc->txbuf_size= (u16)buffer_len;


		if(!priv->ieee80211->check_nic_enough_desc(dev,tcb_desc->queue_index)||
			(!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index]))||\
			(priv->ieee80211->queue_stop) ) {
			RT_TRACE(COMP_FIRMWARE,"=====================================================> tx full!\n");
			skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
		} else {
			priv->ieee80211->softmac_hard_start_xmit(skb,dev);
		}

		codevirtualaddress += frag_length;
		frag_offset += frag_length;

	}while(frag_offset < buffer_len);

	return rt_status;


#endif
}	/* CMPK_Message_Handle_Tx */
예제 #4
0
static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
			     u32 buffer_len)
{
	struct r8192_priv *priv = rtllib_priv(dev);
	u16		    frag_threshold;
	u16		    frag_length, frag_offset = 0;
	int		    i;

	struct rt_firmware *pfirmware = priv->pFirmware;
	struct sk_buff	    *skb;
	unsigned char	    *seg_ptr;
	struct cb_desc *tcb_desc;
	u8                  bLastIniPkt;

	firmware_init_param(dev);
	frag_threshold = pfirmware->cmdpacket_frag_thresold;
	do {
		if ((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold;
			bLastIniPkt = 0;

		} else {
			frag_length = buffer_len - frag_offset;
			bLastIniPkt = 1;

		}

		skb  = dev_alloc_skb(frag_length + 4);
		memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
		tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
		tcb_desc->queue_index = TXCMD_QUEUE;
		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
		tcb_desc->bLastIniPkt = bLastIniPkt;

		seg_ptr = skb->data;
		for (i = 0; i < frag_length; i += 4) {
			*seg_ptr++ = ((i+0) < frag_length) ?
				     code_virtual_address[i+3] : 0;
			*seg_ptr++ = ((i+1) < frag_length) ?
				     code_virtual_address[i+2] : 0;
			*seg_ptr++ = ((i+2) < frag_length) ?
				     code_virtual_address[i+1] : 0;
			*seg_ptr++ = ((i+3) < frag_length) ?
				     code_virtual_address[i+0] : 0;
		}
		tcb_desc->txbuf_size = (u16)i;
		skb_put(skb, i);

		if (!priv->rtllib->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
		    (!skb_queue_empty(&priv->rtllib->skb_waitQ[tcb_desc->queue_index])) ||
		    (priv->rtllib->queue_stop)) {
			RT_TRACE(COMP_FIRMWARE,
				 "===================> tx full!\n");
			skb_queue_tail(&priv->rtllib->skb_waitQ
					[tcb_desc->queue_index], skb);
		} else {
		priv->rtllib->softmac_hard_start_xmit(skb, dev);
		}

		code_virtual_address += frag_length;
		frag_offset += frag_length;

	} while (frag_offset < buffer_len);

	write_nic_byte(dev, TPPoll, TPPoll_CQ);

	return true;
}
예제 #5
0
/*
 * segment the img and use the ptr and length to remember info on each segment
 */
static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address,
			     u32 buffer_len)
{
	struct r8192_priv *priv = ieee80211_priv(dev);
	bool rt_status = true;
	u16 frag_threshold;
	u16 frag_length, frag_offset = 0;
	int i;

	rt_firmware *pfirmware = priv->pFirmware;
	struct sk_buff *skb;
	unsigned char *seg_ptr;
	cb_desc *tcb_desc;
	u8 bLastIniPkt;

	firmware_init_param(dev);

	/* Fragmentation might be required */
	frag_threshold = pfirmware->cmdpacket_frag_thresold;
	do {
		if ((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold ;
			bLastIniPkt = 0;
		} else {
			frag_length = buffer_len - frag_offset;
			bLastIniPkt = 1;
		}

		/*
		 * Allocate skb buffer to contain firmware info and tx
		 * descriptor info add 4 to avoid packet appending overflow.
		 */
		skb  = dev_alloc_skb(frag_length + 4);
		memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
		tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
		tcb_desc->queue_index = TXCMD_QUEUE;
		tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT;
		tcb_desc->bLastIniPkt = bLastIniPkt;

		seg_ptr = skb->data;

		/*
		 * Transform from little endian to big endian and pending zero
		 */
		for (i = 0; i < frag_length; i += 4) {
			*seg_ptr++ = ((i+0) < frag_length) ?
					code_virtual_address[i+3] : 0;

			*seg_ptr++ = ((i+1) < frag_length) ?
					code_virtual_address[i+2] : 0;

			*seg_ptr++ = ((i+2) < frag_length) ?
					code_virtual_address[i+1] : 0;

			*seg_ptr++ = ((i+3) < frag_length) ?
					code_virtual_address[i+0] : 0;
		}
		tcb_desc->txbuf_size = (u16)i;
		skb_put(skb, i);
		priv->ieee80211->softmac_hard_start_xmit(skb, dev);

		code_virtual_address += frag_length;
		frag_offset += frag_length;

	} while (frag_offset < buffer_len);

	return rt_status;
}
예제 #6
0
/*-----------------------------------------------------------------------------
 * Function:	cmpk_message_handle_tx()
 *
 * Overview:	Driver internal module can call the API to send message to
 *				firmware side. For example, you can send a debug command packet.
 *				Or you can send a request for FW to modify RLX4181 LBUS HW bank.
 *				Otherwise, you can change MAC/PHT/RF register by firmware at
 *				run time. We do not support message more than one segment now.
 *
 * Input:		NONE
 *
 * Output:		NONE
 *
 * Return:		NONE
 *
 * Revised History:
 *	When		Who		Remark
 *	05/06/2008	amy		porting from windows code.
 *
 *---------------------------------------------------------------------------*/
RT_STATUS cmpk_message_handle_tx(
	struct net_device *dev,
	u8*	code_virtual_address,
	u32	packettype,
	u32	buffer_len)
{

	RT_STATUS 	    rt_status = RT_STATUS_SUCCESS;
#ifdef RTL8192U
	return rt_status;
#else
	struct r8192_priv   *priv = ieee80211_priv(dev);
	u16		    frag_threshold;
	u16		    frag_length = 0, frag_offset = 0;
	rt_firmware	    *pfirmware = priv->pFirmware;
	struct sk_buff	    *skb;
	unsigned char	    *seg_ptr;
	cb_desc		    *tcb_desc;
	u8                  bLastIniPkt;

	PTX_FWINFO_8190PCI      pTxFwInfo = NULL;
        int i;

	//spin_lock_irqsave(&priv->tx_lock,flags);
	RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
	firmware_init_param(dev);
	//Fragmentation might be required
	frag_threshold = pfirmware->cmdpacket_frag_thresold;
        do {
            if((buffer_len - frag_offset) > frag_threshold) {
                frag_length = frag_threshold ;
                bLastIniPkt = 0;

            } else {
                frag_length =(u16)(buffer_len - frag_offset);
                bLastIniPkt = 1;

            }

            /* Allocate skb buffer to contain firmware info and tx descriptor info
             * add 4 to avoid packet appending overflow.
             * */
#ifdef RTL8192U
            skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4);
#else
            skb  = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4);
#endif
            if(skb == NULL) {
                rt_status = RT_STATUS_FAILURE;
                goto Failed;
            }

            memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
            tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
            tcb_desc->queue_index = TXCMD_QUEUE;
            tcb_desc->bCmdOrInit = packettype;
            tcb_desc->bLastIniPkt = bLastIniPkt;
            tcb_desc->pkt_size = frag_length;

#ifdef RTL8192U
            skb_reserve(skb, USB_HWDESC_HEADER_LEN);
#endif

            //seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom);
            seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom);

            pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr;
            memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
            memset(pTxFwInfo,0x12,8);

            seg_ptr +=sizeof(TX_FWINFO_8190PCI);

            /*
             * Transform from little endian to big endian
             * and pending  zero
             */
            seg_ptr = skb->tail;
            for(i=0 ; i < frag_length; i+=4) {
                *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0;
                *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0;
                *seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0;
                *seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0;
            }
            skb_put(skb, i);
            priv->ieee80211->softmac_hard_start_xmit(skb,dev);

            code_virtual_address += frag_length;
            frag_offset += frag_length;

        }while(frag_offset < buffer_len);

Failed:
	//spin_unlock_irqrestore(&priv->tx_lock,flags);
	return rt_status;


#endif
}	/* CMPK_Message_Handle_Tx */
예제 #7
0
/*-----------------------------------------------------------------------------
 * Function:	cmpk_message_handle_tx()
 *
 * Overview:	Driver internal module can call the API to send message to 
 *				firmware side. For example, you can send a debug command packet.
 *				Or you can send a request for FW to modify RLX4181 LBUS HW bank.
 *				Otherwise, you can change MAC/PHT/RF register by firmware at
 *				run time. We do not support message more than one segment now.
 *
 * Input:		NONE
 *
 * Output:		NONE
 *
 * Return:		NONE
 *
 * Revised History:
 *	When		Who		Remark
 *	05/06/2008	amy		porting from windows code.  
 *	
 *---------------------------------------------------------------------------*/
 extern	RT_STATUS cmpk_message_handle_tx(
	struct net_device *dev,
	u8*	codevirtualaddress,
	u32	packettype,
	u32	buffer_len)
{
		
	RT_STATUS 	    rt_status = RT_STATUS_SUCCESS;
#ifdef RTL8192U
	return rt_status;
#else
	struct r8192_priv   *priv = ieee80211_priv(dev);
	u16		    frag_threshold;
	u16		    frag_length = 0, frag_offset = 0;
	//u16		    total_size;
	//int		    i;
	unsigned int	    flags;	
	rt_firmware	    *pfirmware = priv->pFirmware;
	struct sk_buff	    *skb;
	unsigned char	    *seg_ptr;
	cb_desc		    *tcb_desc;	
	u8                  bLastIniPkt;

	PTX_FWINFO_8190PCI      pTxFwInfo = NULL;
        struct buffer* buflist;
        tx_desc_819x_pci *pdesc = NULL;
        ptx_ring tail;
        ptx_ring begin;
        u32 *buf;
        int count;
        int i;
        int remain;
        int buflen;
	spin_lock_irqsave(&priv->tx_lock,flags);
	RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len);
	firmware_init_param(dev);
	//Fragmentation might be required
	frag_threshold = pfirmware->cmdpacket_frag_thresold;
	do {
		if((buffer_len - frag_offset) > frag_threshold) {
			frag_length = frag_threshold ;
			bLastIniPkt = 0;

		} else {
			frag_length =(u16)(buffer_len - frag_offset);
			bLastIniPkt = 1;
	
		}
		tail=priv->txcmdringtail;
		begin=priv->txcmdring;
		buflist = priv->txcmdbufstail;
		count = priv->txringcount;
	
		pdesc = (tx_desc_819x_pci *)(tail->desc);
		if(!buflist){
			printk("TX CMD buffer error, cannot TX CMD frames. \n");
			rt_status = RT_STATUS_FAILURE;
			goto Failed;
                }
                buf=buflist->buf;
                buflen=priv->txfwbuffersize;
                if(pdesc->OWN)
	{
                        printk("No more TX desc, returning \n");
                        priv->stats.txrdu++;
			rt_status = RT_STATUS_FAILURE;
                        goto Failed;
                }
	

		/* Allocate skb buffer to contain firmware info and tx descriptor info 
		 * add 4 to avoid packet appending overflow.
		 * */
		#ifdef RTL8192U
		skb  = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4); 
#else
		skb  = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4); 
#endif
		if(skb == NULL)
		{
                        rt_status = RT_STATUS_FAILURE;
                        goto Failed;
		}		
		
		memcpy((unsigned char *)(skb->cb),&dev,sizeof(dev));
		tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE);
		tcb_desc->queue_index = TXCMD_QUEUE;
		tcb_desc->bCmdOrInit = packettype;
		tcb_desc->bLastIniPkt = bLastIniPkt;

		#ifdef RTL8192U
		skb_reserve(skb, USB_HWDESC_HEADER_LEN);
		#endif
		
		seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom);
		
                remain=skb->len;
		pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr;
                memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI));
                memset(pTxFwInfo,0x12,8);
						
		seg_ptr +=sizeof(TX_FWINFO_8190PCI);
                memset(pdesc,0,12);
                pdesc->LINIP = tcb_desc->bLastIniPkt;
                pdesc->FirstSeg = 1;//first segment;
                pdesc->LastSeg = 1;//first segment;
                pdesc->CmdInit = DESC_PACKET_TYPE_NORMAL;
                pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8;
                pdesc->PktSize = (u16)(frag_length+pdesc->Offset);
                pdesc->QueueSelect = QSLT_CMD;
                pdesc->TxFWInfoSize = 0x08;
                pdesc->RATid = (u8)DESC_PACKET_TYPE_INIT;
                pdesc->TxBufferSize = skb->len;
                pdesc->TxBuffAddr = buflist->dma;
                pdesc->OWN = 1;
			
		/* 
		 * Transform from little endian to big endian 
                 * and pending  zero
		 */
		memcpy(seg_ptr,codevirtualaddress,frag_length);
		for(i=0;i<buflen&& remain >0;i++,remain--){
                        ((u8*)buf)[i]=skb->data[i]; //copy data into descriptor pointed DMAble buffer
                        if(remain == 4 && i+4 >= buflen) break;
                        /* ensure the last desc has at least 4 bytes payload */

                }
		if(remain == 0)
			dev_kfree_skb_any(skb);	
#if 0	
			{
			int k;
			printk("------------tx cmd------------\n");
			for(k = 0; k<i; k++)
				printk(" 0x%x",((u8*)buf)[k]);
			printk("\n");
			}
		{
			int m;
			printk("-------------cmd desc----------\n");
			for(m=0;m<32;m++)
				printk(" 0x%x",((u8*)pdesc)[m]);
			printk("\n");	
		}
#endif     
	        if(((tail->desc) - (begin->desc))/8 == count-1)
                        tail=begin;
		else
                        tail=tail->next;
                buflist=buflist->next;
                mb();
                priv->txcmdringtail=tail;
                priv->txcmdbufstail=buflist;
	
		codevirtualaddress += frag_length;
		frag_offset += frag_length;
		write_nic_word(dev,TPPoll,TPPoll_CQ);
	}while(frag_offset < buffer_len);

Failed:	
	spin_unlock_irqrestore(&priv->tx_lock,flags);
	return rt_status;
		

#endif
}	/* CMPK_Message_Handle_Tx */