📄 zd1211.c
字号:
/* 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 + -