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

📄 zd1211.c

📁 该代码为linux下通过usb驱动实现的无线网络驱动程序,在2.6.18的内核下调试通过
💻 C
📖 第 1 页 / 共 5 页
字号:
/* src/zd1211.c
*
*                                            
*
* Copyright (C) 2004 ZyDAS Inc.  All Rights Reserved.
* --------------------------------------------------------------------
*
*
*
*   The contents of this file are subject to the Mozilla Public
*   License Version 1.1 (the "License"); you may not use this file
*   except in compliance with the License. You may obtain a copy of
*   the License at http://www.mozilla.org/MPL/
*
*   Software distributed under the License is distributed on an "AS
*   IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
*   implied. See the License for the specific language governing
*   rights and limitations under the License.
*
*   Alternatively, the contents of this file may be used under the
*   terms of the GNU Public License version 2 (the "GPL"), in which
*   case the provisions of the GPL are applicable instead of the
*   above.  If you wish to allow the use of your version of this file
*   only under the terms of the GPL and not to allow others to use
*   your version of this file under the MPL, indicate your decision
*   by deleting the provisions above and replace them with the notice
*   and other provisions required by the GPL.  If you do not delete
*   the provisions above, a recipient may use your version of this
*   file under either the MPL or the GPL.
*
* -------------------------------------------------------------------- */

#include <linux/config.h>
#include <net/checksum.h>
#include <linux/tcp.h>
#include <linux/udp.h>


#include "zddebug.h"
#include "zdhw.h"
#include "zd1211.h"
#include "zdcompat.h"
#include "zdglobal.h"
#include "zdmisc.h"

u8 WS11UPh[]
#if fMERGE_RX_FRAME
    #if ZDCONF_LP_SUPPORT == 1
        #include "WS11UPhR_Turbo.h"
    #elif ZDCONF_LP_SUPPORT == 0
	    #include "WS11UPhR.h"
    #else
        #error "ZDCONF_LP_SUPPORT isn't defined"
    #endif
    u8 WS11UPhm[]
	#include "WS11UPhm.h"
#else
    #include "WS11UPhm.h"
#endif
    
u8 WS11Ur[]
	#include "WS11Ur.h"

u8 WS11Ub[]
	#include "WS11Ub.h"


u8 WS11Ur2[(0xEE00 - 0xEC00) * 2] = { 0x0F, 0x9F, 0x00, 0xEE };  // JMP 0xEE00


extern zd_80211Obj_t dot11Obj;
extern struct net_device *g_dev;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */
#  define SUBMIT_URB(u,f)       usb_submit_urb(u,f)
#  define USB_ALLOC_URB(u,f)    usb_alloc_urb(u,f)
#else
#  define SUBMIT_URB(u,f)       usb_submit_urb(u)
#  define USB_ALLOC_URB(u,f)    usb_alloc_urb(u)
#endif



inline void zd1211_DumpErrorCode(struct zd1205_private *macp, int err)
{
    switch (err){
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))        
        case USB_ST_CRC:
            ZD1211DEBUG(0, "USB_ST_CRC\n");
            break;

        //case USB_ST_BITSTUFF:
            //ZD1211DEBUG(0, "USB_ST_BITSTUFF\n");
            //break;

        //case USB_ST_NORESPONSE:
            //ZD1211DEBUG(0, "USB_ST_NORESPONSE\n");
            //break;

        case USB_ST_DATAOVERRUN:
            ZD1211DEBUG(0, "USB_ST_DATAOVERRUN\n");
            break;

        case USB_ST_DATAUNDERRUN:
            ZD1211DEBUG(0, "USB_ST_DATAUNDERRUN\n");
            break;

        case USB_ST_BUFFEROVERRUN:
            ZD1211DEBUG(0, "USB_ST_BUFFEROVERRUN\n");
            break;

        case USB_ST_BUFFERUNDERRUN:
            ZD1211DEBUG(0, "USB_ST_BUFFERUNDERRUN\n");
            break;

        case USB_ST_INTERNALERROR:
            ZD1211DEBUG(0, "USB_ST_INTERNALERROR\n");
            break;

        //case USB_ST_SHORT_PACKET:
            //ZD1211DEBUG(0, "USB_ST_SHORT_PACKET\n");
            //break;

        case USB_ST_PARTIAL_ERROR:
            ZD1211DEBUG(0, "USB_ST_PARTIAL_ERROR\n");
            break;

        case USB_ST_URB_KILLED:
            ZD1211DEBUG(0, "USB_ST_URB_KILLED\n");
            break;

        case USB_ST_URB_PENDING:
            ZD1211DEBUG(0, "USB_ST_URB_PENDING\n");
            break;

        case USB_ST_REMOVED:
            ZD1211DEBUG(0, "USB_ST_REMOVED\n");
            break;

        case USB_ST_TIMEOUT:
            ZD1211DEBUG(0, "USB_ST_TIMEOUT\n");
            break;

        case USB_ST_NOTSUPPORTED:
            ZD1211DEBUG(0, "USB_ST_NOTSUPPORTED\n");
            break;





        case USB_ST_BANDWIDTH_ERROR:
            ZD1211DEBUG(0, "USB_ST_BANDWIDTH_ERROR\n");
            break;

        case USB_ST_URB_INVALID_ERROR:
            ZD1211DEBUG(0, "USB_ST_URB_INVALID_ERROR\n");
            break;

        case USB_ST_URB_REQUEST_ERROR:
            ZD1211DEBUG(0, "USB_ST_URB_REQUEST_ERROR\n");
            break;

        case USB_ST_STALL:
            ZD1211DEBUG(0, "USB_ST_STALL\n");
            break;

        case -ENOMEM:
            ZD1211DEBUG(0, "ENOMEM\n");
            break;   
#endif

        default:
            ZD1211DEBUG(0, "USB ST Code = %d\n",err);
            
        break;                                                                                  
    }   
    macp->dbg_flag=0;

}


void zd1211_DumpReadMultipleReg(struct zd1205_private *macp, u16 adr0)
{
	u16  ReadAddr[cMAX_MULTI_READ_REG_NUM];
	u16  ReadData[cMAX_MULTI_READ_REG_NUM];
	u16  ReadIndex = 0;

    FPRINT_V("adr0", adr0);
    
    for (ReadIndex = 0; ReadIndex < cMAX_MULTI_READ_REG_NUM;)



        mFILL_READ_REGISTER(adr0++);
        
    zd1211_USB_PACKAGE_READ_REGISTER(ReadAddr, ReadData, ReadIndex, false);

    for (ReadIndex = 0; ReadIndex < 8; ReadIndex ++)
        printk("%04X, ", ReadData[ReadIndex]);
        
    printk("\n");
    printk("      ");
    
    for (; ReadIndex < cMAX_MULTI_READ_REG_NUM; ReadIndex ++)
        printk("%04X, ", ReadData[ReadIndex]);
    printk("\n");
}



// len0: in word, adr: word offset
void zd1211_WriteEEPROM(struct zd1205_private *macp, u16 rom_adr, u16 ram_adr, u16 len0)
{
	u32  tmpvalue;
	u16  WriteAddr[cMAX_MULTI_WRITE_REG_NUM];
	u16  WriteData[cMAX_MULTI_WRITE_REG_NUM];
	u16  WriteIndex = 0;

    tmpvalue = zd1211_readl(ZD1211_CLOCK_CTRL, false);
    mFILL_WRITE_REGISTER(ZD1211_CLOCK_CTRL, mSET_BIT((u16) tmpvalue, bZD1211_CLOCK_EEPROM));
    mFILL_WRITE_REGISTER(UMAC_EPROM_ROM_ADDR, rom_adr);
    mFILL_WRITE_REGISTER(UMAC_EPROM_RAM_ADDR, ram_adr);
    mFILL_WRITE_REGISTER(UMAC_EPROM_DMA_LEN_DIR, bmEPROM_XFER_DIR | len0);
    mFILL_WRITE_REGISTER(ZD1211_CLOCK_CTRL, mCLR_BIT((u16) tmpvalue, bZD1211_CLOCK_EEPROM));
    zd1211_WriteMultiRegister(WriteAddr, WriteData, WriteIndex, false);
}


#if fMERGE_RX_FRAME
int zd1211_ChangeToFlashAble(struct zd1205_private *macp)
{
	u32 tmpvalue;
	
	if (!macp->bFlashable){
		int	LoadRet;

		zd_writel(0x01, FW_SOFT_RESET);
 
		macp->bDisableTx = 1;
		//USB_StopTxEP(macp); 

		macp->bAllowAccessRegister = 0;

		LoadRet = zd1211_LoadUSBSpecCode(macp, WS11UPhm, sizeof(WS11UPhm),
							  cFIRMWARE_START_ADDR, true);
		if (LoadRet){
			FPRINT("Load WS11UPhm fail");
			return 1;
		}

		ZD1211DEBUG(0, "Load WS11UPhm Done\n");

		//macp->bAllowAccessRegister = 1;
		macp->bFlashable = 1;
		
#if fWRITE_WORD_REG || fREAD_MUL_REG
		// Must get this information before any register write
		tmpvalue = zd1211_readl(cADDR_ENTRY_TABLE, FALSE);
		macp->AddrEntryTable = (u16) tmpvalue;
#endif

	}

	return 0;
}
#endif	

/*
int zd1211_UpdateBootCode(struct zd1205_private *macp, u16 *pCheckSum, u16 *pEEPROMData,
                            u32 EEPROMLen)
{
	u32 i;
	//int ret;
	u16  WriteAddr[cMAX_MULTI_WRITE_REG_NUM];
	u16  WriteData[cMAX_MULTI_WRITE_REG_NUM];
	u16  WriteIndex = 0;
	u16  ROMBufAdr = cBOOTCODE_START_ADDR;

	ZD1211DEBUG(0, "UpdateBootCode\n");

	for (i=0; i<EEPROMLen; i+=(2*WRITE_WORD_TO_EEPROM_PER_TIME)){
		for (WriteIndex=0; WriteIndex<WRITE_WORD_TO_EEPROM_PER_TIME/2; ){
			if (ROMBufAdr >= cINT_VECT_ADDR){
				FPRINT("Exceed max address");
				break;
			}
			mFILL_WRITE_REGISTER(ROMBufAdr ++,
				pEEPROMData[WriteIndex * 2] | (pEEPROMData[WriteIndex * 2 + 1] << 8));
		}

		if (WriteIndex)
			zd1211_WriteMultiRegister(WriteAddr, WriteData, WriteIndex, false);

		if (ROMBufAdr >= cINT_VECT_ADDR){
			FPRINT("Exceed max address1");
			return 0;
		}

		pEEPROMData += WRITE_WORD_TO_EEPROM_PER_TIME;
	}

	if (EEPROMLen % (2*WRITE_WORD_TO_EEPROM_PER_TIME)){
		for (WriteIndex = 0; WriteIndex < (EEPROMLen % (2 * WRITE_WORD_TO_EEPROM_PER_TIME)) / 2;){
			if (ROMBufAdr >= cINT_VECT_ADDR){
				FPRINT("Exceed max address2");
				break;
			}

			mFILL_WRITE_REGISTER(ROMBufAdr ++,
				pEEPROMData[WriteIndex * 2] | (pEEPROMData[WriteIndex * 2 + 1] << 8));
		}

		if (WriteIndex)
			zd1211_WriteMultiRegister(WriteAddr, WriteData, WriteIndex, false);
	}

	return 0;
}
*/



/*
int zd1211_USB_Write_EEPROM(struct zd1205_private *macp, u16 *pEEPROMData, u32 EEPROMLen) //in bytes
{
    u16 CheckSum = 0;
    int ret;
    
    ZD1211DEBUG(0, "USB_Write_EEPROM\n");

    macp->bDisableTx = 1;

    //USB_StopTxEP(macp); 

    ret = zd1211_UpdateBootCode(macp, &CheckSum, pEEPROMData, EEPROMLen);
    if (ret != 0)
        return ret;

    zd1211_WriteEEPROM(macp, 0, cBOOTCODE_START_ADDR, cEEPROM_SIZE - cLOAD_VECT_LEN);
	//macp->bDisableTx = 0;

	return 0;

}
*/



int zd1211_USB_WRITE_EEPROM_DATA(struct zd1205_private *macp, PUSB_EEPROM_DATA	pData, int DataLen)
{
 	int ret;
	u8 *pBuffer;
	//int memflags = GFP_KERNEL;
 	
	ZD1211DEBUG(0, "USB_WRITE_EEPROM_DATA\n");

	if (!macp->bUSBDeveiceAttached){
		return 1;
	}

	down(&macp->reg_sem);

	pBuffer = kmalloc(DataLen, GFP_KERNEL);
	
	if (!pBuffer) {
		up(&macp->reg_sem);
		return -ENOMEM;
	}
	else
		memcpy(pBuffer, (u8 *)pData, DataLen);
               
	if (macp->ep4isIntOut)   	
		usb_fill_int_urb(macp->reg_urb, macp->usb,
			usb_sndintpipe(macp->usb, EP_REG_OUT),
			pBuffer, DataLen, 
			zd1211_reg_cb, macp, 1);
	else
		usb_fill_bulk_urb(macp->reg_urb, macp->usb,
			usb_sndbulkpipe(macp->usb, EP_REG_OUT),
			pBuffer, DataLen,
			zd1211_reg_cb, macp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
	macp->reg_urb->transfer_flags |= URB_ASYNC_UNLINK;     
#endif

	if ((ret = SUBMIT_URB(macp->reg_urb, GFP_ATOMIC))){
		printk(KERN_ERR "zd1211: failed reg_urb\n");
		zd1211_DumpErrorCode(macp, ret);
		goto out;
	}	

	wait_event(macp->regSet_wait, test_bit(ZD1211_CMD_FINISH, &macp->flags));
	clear_bit(ZD1211_CMD_FINISH, &macp->flags);
    
out:
	kfree(pBuffer);
	up(&macp->reg_sem);
	return ret;	
}

#if fPROG_FLASH_BY_FW
int zd1211_USB_ProgramFlash(struct zd1205_private *macp, u16 *Value, u16 RegCount)
{
	u8 *pRegBuffer = NULL;

	int ret;
	u16 size = sizeof(USB_WRITE_REG);

	u16 bufSize;
	int ii;
  
	ZD1211DEBUG(0, "USB_ProgramFlash\n");

	if ((RegCount == 0) || (!macp->bUSBDeveiceAttached))
		return 0;

	down(&macp->reg_sem);
	pRegBuffer = kmalloc(size, GFP_KERNEL);

	if (!pRegBuffer) {
		up(&macp->reg_sem);
		return -ENOMEM;
	}
	else
		memset(pRegBuffer, 0x0, size);                     
 
	((PUSB_WRITE_REG)pRegBuffer)->RequestID = zd_cpu_to_le16(REGID_PROG_FLSH);
	((PUSB_SET_RF) pRegBuffer)->Value       = Value[0];
	((PUSB_SET_RF) pRegBuffer)->Index       = Value[1];

	for (ii = 2; ii < RegCount; ii ++)
		((PUSB_SET_RF)pRegBuffer)->Data[ii - 2] = Value[ii];

	bufSize = sizeof(u16) * (1+RegCount);
    
	if (macp->ep4isIntOut)                   
		usb_fill_int_urb(macp->reg_urb, macp->usb,
			usb_sndintpipe(macp->usb, EP_REG_OUT),
			pRegBuffer, bufSize, 
			zd1211_reg_cb, macp, 1);
	else
		usb_fill_bulk_urb(macp->reg_urb, macp->usb,
			usb_sndbulkpipe(macp->usb, EP_REG_OUT),
			pRegBuffer, bufSize,
			zd1211_reg_cb, macp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))		     
	macp->reg_urb->transfer_flags |= URB_ASYNC_UNLINK;	     
#endif
	
	if ((ret = SUBMIT_URB(macp->reg_urb, GFP_KERNEL))){
		printk(KERN_ERR "zd1211: failed reg_urb\n");
		zd1211_DumpErrorCode(macp, ret);
		goto out;
	}	

	wait_event(macp->regSet_wait, test_bit(ZD1211_CMD_FINISH, &macp->flags));
	clear_bit(ZD1211_CMD_FINISH, &macp->flags);
   
out:
	kfree(pRegBuffer);
	up(&macp->reg_sem);		
	return ret;	
}
#endif


// return 0: success
int zd1211_USB_PACKAGE_READ_REGISTER(u16 *Address, u16 *pValue, u16 RegCount, u8 bAddUSBCSRAddress)
{
	struct zd1205_private *macp = g_dev->priv;
	u8 *pRegBuffer = NULL;
	int ret = 0;
	u16 size = sizeof(USB_READ_REG_REQ);
	u16 bufSize;
	int ii;
	//int memflags = GFP_KERNEL;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
	if (in_interrupt()){
#else
	
	if (in_atomic()){
#endif
		printk(KERN_ERR "********zd1211_USB_PACKAGE_READ_REGISTER in_interrupt*********\n");
		return 0;
	}
	down(&macp->reg_sem); 
	
	if ((RegCount == 0) || (!macp->bUSBDeveiceAttached) || (!test_bit(ZD1211_RUNNING, &macp->flags))){

⌨️ 快捷键说明

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