wifi driver

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1636 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
dennis.zhang.os@gmail.com 2011-07-17 16:48:14 +00:00
parent ef90978b16
commit b29605dce4
44 changed files with 148049 additions and 0 deletions

8
wifi/os/os_defs.h Normal file
View File

@ -0,0 +1,8 @@
/*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
#ifndef _OS_HEADER1_
#define _OS_HEADER1_
#endif /* _OS_HEADER1 */

37
wifi/os/os_headers.h Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
#ifndef _OS_HEADERS_H
#define _OS_HEADERS_H
#ifndef __ATTRIB_ALIGN__
#define __ATTRIB_ALIGN__ (__aligned(4)) //changed by dennis for compiler compatibility
#endif
#ifndef __ATTRIB_PACK__
//#define __ATTRIB_PACK__ __attribute__ ((packed))
//#define __ATTRIB_PACK__ //changed by dennis for compiler compatibility
#endif
/* RT_Thread header files */
#include <rtconfig.h>
#include <rtthread.h>
#include <rtdef.h>
#include <stdio.h>
#include <string.h>
/* New Code to synchronize between IEEE Power save and PM*/
#ifdef ENABLE_PM
#endif
/* ASM files */
/* Net header files */
/* Wireless header */
#endif

105
wifi/os/os_timers.h Normal file
View File

@ -0,0 +1,105 @@
/*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
#ifndef _OS_TIMERS_H
#define _OS_TIMERS_H
#include "os_defs.h"
typedef struct __WLAN_DRV_TIMER
{
//struct timer_list tl;
struct rt_timer tl;
void (*timeoutfunction)(void* parameter);
void (*timer_function) (void *context);
void *timer_parameter;
void *function_context;
unsigned int time_period;
char * name;
BOOLEAN timer_is_periodic;
BOOLEAN timer_is_canceled;
char init_flag; /*0:uninitialized 1:initialized 2:has been used at least once*/
} WLAN_DRV_TIMER, *PWLAN_DRV_TIMER;
static void TimerHandler(void* fcontext)
{
PWLAN_DRV_TIMER timer = (PWLAN_DRV_TIMER) fcontext;
timer->timer_function(timer->function_context);
// if (timer->timer_is_periodic == TRUE) {
// mod_timer(&timer->tl, jiffies + ((timer->time_period * HZ) / 1000));
// }
}
static void
InitializeTimer(PWLAN_DRV_TIMER timer,
void (*TimerFunction) (void *context), void *FunctionContext,char *name)
{
timer->timeoutfunction = TimerHandler;
timer->timer_parameter=timer;
if(name!=NULL)
timer->name=name;
// then tell the proxy which function to call and what to pass it
timer->timer_function = TimerFunction;
timer->function_context = FunctionContext;
timer->timer_is_canceled = FALSE;
timer->init_flag=1;
}
static void
SetTimer(PWLAN_DRV_TIMER timer, unsigned int MillisecondPeriod)
{
/* timer->time_period = MillisecondPeriod;
timer->timer_is_periodic = FALSE;
timer->tl.expires = jiffies + (MillisecondPeriod * HZ) / 1000;
add_timer(&timer->tl);
timer->timer_is_canceled = FALSE;
*/
}
static void
ModTimer(PWLAN_DRV_TIMER timer, unsigned int MillisecondPeriod)
{
int tick= (MillisecondPeriod/1000)*RT_TICK_PER_SECOND;
timer->timer_is_periodic = FALSE;
timer->time_period = MillisecondPeriod;
if(timer->init_flag==1)
{
rt_timer_init(&timer->tl, timer->name, timer->timeoutfunction,timer->timer_parameter,
tick,RT_TIMER_FLAG_ONE_SHOT);
timer->init_flag=2;
}else if(timer->init_flag==2){
rt_timer_control(&timer->tl, RT_TIMER_CTRL_SET_TIME, &tick);
}
rt_timer_start(&timer->tl);
timer->timer_is_periodic = FALSE;
}
static void
SetPeriodicTimer(PWLAN_DRV_TIMER timer, unsigned int MillisecondPeriod)
{
/* timer->time_period = MillisecondPeriod;
timer->timer_is_periodic = TRUE;
timer->tl.expires = jiffies + (MillisecondPeriod * HZ) / 1000;
add_timer(&timer->tl);
timer->timer_is_canceled = FALSE;
*/
}
#define FreeTimer(x) do {} while (0)
static void CancelTimer(WLAN_DRV_TIMER * timer)
{
/* del_timer(&timer->tl);
timer->timer_is_canceled = TRUE;
*/
rt_timer_detach(&timer->tl);
}
#endif /* _OS_TIMERS_H */

119073
wifi/spi/gspi8686.h Normal file

File diff suppressed because it is too large Load Diff

29
wifi/spi/gspi_debug.h Normal file
View File

@ -0,0 +1,29 @@
/*
* Debugging macros
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
#define DEBUG_SSP_LEVEL3
#ifdef DEBUG_SSP_LEVEL0
#define spi_debug1(...)
#define spi_debug2(...)
#define spi_debug3(...)
#endif
#ifdef DEBUG_SSP_LEVEL1
#define spi_debug1 rt_kprintf
#define spi_debug2 //rt_kprintf
#define spi_debug3 //rt_kprintf
#endif
#ifdef DEBUG_SSP_LEVEL2
#define spi_debug1 rt_kprintf
#define spi_debug2 rt_kprintf
#define spi_debug3 //rt_kprintf
#endif
#ifdef DEBUG_SSP_LEVEL3
#define spi_debug1 rt_kprintf
#define spi_debug2 rt_kprintf
#define spi_debug3 rt_kprintf
#endif

519
wifi/spi/gspi_io.c Normal file
View File

@ -0,0 +1,519 @@
/*
* File: gspi_io.c
* Desc: Low level SSP driver on pxa27x for GSPI
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
01/30/06: Add kernel 2.6 support for GSPI8xxx/Bulverde
********************************************************/
#include "sep4020.h"
#include "rtthread.h"
#include "gspi_io.h"
#include "gspi_debug.h"
static int DMA_ENABLE=1;
int g_dummy_clk_reg = 0;
int g_dummy_clk_ioport = 0;
int g_bus_mode_reg = 0x02;
gspihost_info_t *G_gspiinfo;
static struct rt_semaphore gspi_lock;
static struct rt_event txrxevent; //only set or rec the 0x01
#define DMA_TX_ONLY (1)
#define DMA_TX_RX (2)
#define DMA_Dummy_TX (4)
#define DMA_NO_ACTION (0)
static char DMA_ACTION;
#define MaskWarning(x) ((x)=(x))
extern void rt_hw_interrupt_install(rt_uint32_t vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler);
extern void rt_hw_interrupt_umask(rt_uint32_t vector);
static int gspi_acquire_io(void)
{
rt_sem_take(&gspi_lock, RT_WAITING_FOREVER);
return 0;
}
static void gspi_release_io(void)
{
rt_sem_release(&gspi_lock);
return;
}
static char transmittembuf[2048];
void setup_write_dma(char * data ,int n)
{
unsigned int regval=0;
int i;
/*clear the interupt*/
/*0 is tx channel */
*(volatile unsigned long*)DMAC_INTINTERRCLR_V |= 0x1;
*(volatile unsigned long*)DMAC_INTINTERRCLR_V &= (~0x1); //clear the erro interupt
*(volatile unsigned long*)DMAC_INTTCCLEAR_V |= 0x1;
*(volatile unsigned long*)DMAC_INTTCCLEAR_V &= (~0x1); //clear the interupt
/*set source address*/
*(volatile unsigned long*)DMAC_C0SRCADDR_V = (unsigned int)data;
/*set target address*/
*(volatile unsigned long*)DMAC_C0DESTADDR_V = SSI_DR;
/*clear the size*/
//*(volatile unsigned long*)DMAC_C0CONTROL_V = 0;
//desc->dcmd |= DCMD_ENDIRQEN | n;
/*set transfer size,data width is 2 bytes,burst size is 4*2bytes,source Address Increment*/
regval=((n/2) <<14)+(0x1<<12)+(0x1<<9)+(0x1<<6)+((0x0)<<3)+(0x0);
*(volatile unsigned long*)DMAC_C0CONTROL_V = regval;
/*write data from memory to ssi*/
// *(volatile unsigned long*)DMAC_C0CONFIGURATION_V=0;
*(volatile unsigned long*)DMAC_C0DESCRIPTOR_V = 0;
/* 2) start DMA channel */
/*spi dma set*/
*(volatile unsigned long*)SSI_DMATDLR_V=0x2; // (0x10009050)//tx DMA threadthold
if(DMA_ACTION==DMA_TX_RX)
{
#if 0
*(volatile unsigned long*)SSI_DMARDLR_V=0x2;
*(volatile unsigned long*)SSI_DMACR_V|=(0x3); //0x1 rxDMAenable 0x2 txDMAenable
*(volatile unsigned long*)DMAC_C1CONFIGURATION_V = ((0x5)<<7) +((0x2)<<1)+0x01;
*(volatile unsigned long*)DMAC_C0CONFIGURATION_V = ((0x5)<<11)+((0x1)<<1)+0x01;
#else
*(volatile unsigned long*)SSI_DMARDLR_V=0x4;
*(volatile unsigned long*)SSI_DMACR_V|=(0x1); //0x1 rxDMAenable 0x2 txDMAenable
*(volatile unsigned long*)DMAC_C1CONFIGURATION_V = ((0x5)<<7) +((0x2)<<1)+0x01;
for(i=0;i<n/2;i++)
{
while((*(volatile unsigned long*)SSI_SR_V&2)==0);
*(volatile unsigned long* )SSI_DR_V = 0;
}
#endif
}else if(DMA_ACTION==DMA_TX_ONLY)
{
*(volatile unsigned long*)SSI_DMACR_V|=(0x1<<1); //0x1 rxDMAenable 0x2 txDMAenable
*(volatile unsigned long*)DMAC_C0CONFIGURATION_V = ((0x5)<<11)+((0x1)<<1)+0x01;
}
}
int gspi_write_data_direct(u8 * data, u16 reg, u16 n)
{
int i;
u16 *dat;
rt_uint32_t e;
gspi_acquire_io();
/* N bytes are sent wrt to 16 bytes, convert it to 8 bytes */
n = (n * 2);
/*active CS signal*/
*(volatile unsigned long*)(GPIO_PORTD_DATA_V)&=~0x04;
reg |= 0x8000;
rt_memcpy(transmittembuf, &reg, sizeof(u16));
rt_memcpy(transmittembuf + sizeof(u16), data, (n - 2));
if((n>16)&&(DMA_ENABLE==1))
{
//Write data by DMA mode
DMA_ACTION=DMA_TX_ONLY;
setup_write_dma(transmittembuf,n);
rt_event_recv(&txrxevent,0x01,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&e);
}else{
//Write data through SSDR by CPU mode
dat = (u16 *) transmittembuf;
*(volatile unsigned long*)SSI_DMACR_V&=(~0x3); //0x1 rxDMAenable 0x2 txDMAenable
for (i = 0; i < (n / 2); i++) {
while((*(volatile unsigned long*)SSI_SR_V&2)==0){}
*(volatile unsigned long*)SSI_DR_V = *dat++; //add for 4020
}
if ((n % 4) != 0) {
while((*(volatile unsigned long*)SSI_SR_V&2)==0){}
*(volatile unsigned long*)SSI_DR_V = 0;//add for 4020
}
while((*(volatile unsigned long*)SSI_SR_V&1)==1);
}
/*inactive CS frame*/
*(volatile unsigned long*)(GPIO_PORTD_DATA_V)|=0x04;
gspi_release_io();
return 0;
}
int gspi_write_reg( u16 reg, u16 val)
{
gspi_write_data_direct((u8 *) & val, reg, 2);
return 0;
}
int gspi_write_data( u16 * data, u16 size)
{
gspi_write_data_direct((u8 *) & data[1], data[0], 2);
return 0;
}
static char rectembuf[2048+1024];
static char rxtxdummybuf[2048+1024];
void
gspi_write_to_read(int n,u16 reg,u16*data)
{
u16 temp;
/*config the receive channel*/
/*set source address*/
*(volatile unsigned long*)DMAC_C1SRCADDR_V = SSI_DR;
/*set target address*/
*(volatile unsigned long*)DMAC_C1DESTADDR_V = (unsigned int)data;
/*clear the size*/
// *(volatile unsigned long*)DMAC_C1CONTROL_V = 0; //~(0x3ffd000)
/*set transfer size,data width is 2 bytes,burst size is 4*2bytes,source Address Increment*/
*(volatile unsigned long*)DMAC_C1CONTROL_V = ((n /2)<<14)+(1<<13) + (1<<9) + (1<<6)+((0x3)<<3) +(0x3);
/*receive data from ssi*/
*(volatile unsigned long*)DMAC_C1CONFIGURATION_V = ((0x5)<<7) +((0x2)<<1)+0x01;
*(volatile unsigned long*)DMAC_C1DESCRIPTOR_V = 0;
#if 0
/*config the transfer channel*/
/*set source address*/
*(volatile unsigned long*)DMAC_C0SRCADDR_V = gspiinfo->phys_addr_rw;
/*set target address*/
*(volatile unsigned long*)DMAC_C0DESTADDR_V = SSI_DR;
/*clear the size*/
*(volatile unsigned long*)DMAC_C0CONTROL_V = ~(0x3ffd000);
/*set transfer size,data width is 2 bytes,burst size is 4*2bytes,source Address Increment*/
*(volatile unsigned long*)DMAC_C0CONTROL_V = (n <<14)|(1<<12) | (1<<9) | (1<<6) |((011)<<3) | (011);
/*write data from memory to ssi*/
*(volatile unsigned long*)DMAC_C0CONFIGURATION_V = ((0101)<<11) | ((01)<<1);
/*set address of next descripor */
*(volatile unsigned long*)DMAC_C0DESCRIPTOR_V = 0;
*(volatile unsigned long*)DMAC_C1DESCRIPTOR_V = 0;
/* Start Rx for read */
*(volatile unsigned long*)DMAC_C1CONFIGURATION_V = 0x01; //enable channel 1
/* Start Tx for dummy write */
*(volatile unsigned long*)DMAC_C0CONFIGURATION_V = 0x01; //enable channel 0
#endif
#if 1
/* Write the register to read */
*(volatile unsigned long*)SSI_DMACR_V&=(~0x3); //0x1 rxDMAenable 0x2 txDMAenable
*(volatile unsigned long* )SSI_DR_V = reg;
while((*(volatile unsigned long*)SSI_SR_V&8))
temp = *(volatile unsigned long* )SSI_DR_V;
temp=temp;
#endif
setup_write_dma(rxtxdummybuf ,n);
}
void setup_read_dma(u16 reg, u16 * data, int n)
{
/*clear the interupt*/
*(volatile unsigned long*)DMAC_INTINTERRCLR_V |= 0x2;
*(volatile unsigned long*)DMAC_INTINTERRCLR_V &= (~0x2); //clear the erro interupt
*(volatile unsigned long*)DMAC_INTTCCLEAR_V |= 0x2;
*(volatile unsigned long*)DMAC_INTTCCLEAR_V &= (~0x2);
gspi_write_to_read(n, reg,data);
}
int gspi_read_data_direct(u8 * data, u16 reg, u16 n)
{
int fifonum=0;
int i;
u32 nothing;
u16 *dat;
rt_uint32_t e;
int retry = 0;
int timeout = 100;
int dmaflag=0;
MaskWarning(nothing);
if (gspi_acquire_io()) {
return -1;
}
for(fifonum=0;fifonum<16;fifonum++)//clear fifo add by vincent for 4020
{
nothing = *(volatile unsigned long* )SSI_DR_V;
}
n = ((n + g_dummy_clk_ioport) * 2);
/*active SPI CS */
*(volatile unsigned long*)(GPIO_PORTD_DATA_V)&=~0x04;
///Process the data
#if 1
if(n>16&&(DMA_ENABLE==1))
//if((DMA_ENABLE==1))
{
DMA_ACTION=DMA_TX_RX;
dmaflag=1;
do {
retry = 0;
spi_debug3("DMA MODEL");
DMA_ACTION=DMA_TX_RX;
setup_read_dma(reg,(u16*) rectembuf, n);
rt_event_recv(&txrxevent,0x01,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&e);
if (rectembuf[(g_dummy_clk_ioport + 1) * 2] == 0xff) {
if (!rt_memcmp(&rectembuf[(g_dummy_clk_ioport + 1) * 2],&rxtxdummybuf[2], 5)) {
retry = 1;
}
}
} while ( retry && --timeout);
if (!timeout)
spi_debug1("Timeout for gspi_read_data_direct\n");
}else
#endif
{
dat=(u16*)rectembuf;
*(volatile unsigned long*)SSI_DMACR_V&=(~0x3); //0x1 rxDMAenable 0x2 txDMAenable
while((*(volatile unsigned long*)SSI_SR_V&2)==0);
*(volatile unsigned long* )SSI_DR_V = reg;
for (i = 0; i < (n / 2); i++) {
while((*(volatile unsigned long*)SSI_SR_V&2)==0);
*(volatile unsigned long* )SSI_DR_V = 0;
while((*(volatile unsigned long*)SSI_SR_V&8)==0);
*dat = *(volatile unsigned long* )SSI_DR_V;
dat++;
}
}
*(volatile unsigned long*)(GPIO_PORTD_DATA_V)|=0x04;
if(dmaflag==1)
rt_memcpy(data, rectembuf + (g_dummy_clk_ioport + 1) * 2+12,
(n - (g_dummy_clk_ioport + 1) * 2+12));
else
rt_memcpy(data, rectembuf + (g_dummy_clk_ioport + 1) * 2,
(n - (g_dummy_clk_ioport + 1) * 2));
gspi_release_io();
return 0;
}
int gspi_read_data( u16 * data, u16 size)
{
return gspi_read_data_direct((u8 *) & data[1], data[0], 2);
}
int gspi_read_reg( u16 reg, u16 * val)
{
gspi_read_data_direct((u8 *) val, reg, 2);
return 0;
}
extern void sbi_interrupt(int vector);
static void spi_interrupt(int dev)
{
unsigned int intstate;
unsigned int rcl;
MaskWarning(rcl);
intstate=*(volatile unsigned long*)SSI_ISR_V;
// spi_debug1("spi spi_interrupt\r\n");
if(intstate&0x01)
{
spi_debug1("spi tx fifo empty\r\n");
}
if(intstate&(0x01<<1))
{
spi_debug1("spi tx fifo up over\r\n");
rcl=*(volatile unsigned long*)SSI_TXOICR_V;
}
if(intstate&(0x01<<2))
{
spi_debug1("spi Rx fifo down over\r\n");
rcl=*(volatile unsigned long*)SSI_RXUICR_V;
}
if(intstate&(0x01<<3))
{
spi_debug1("spi rx fifo up over\r\n");
rcl=*(volatile unsigned long*)SSI_RXOICR_V;
}
if(intstate&(0x01<<4))
{
spi_debug1("spi rx fifo full\r\n");
}
rcl=*(volatile unsigned long*)SSI_ICR_V;
}
static void dma_interrupt(int dev)
{
unsigned int intstatus;
unsigned int endstatus;
unsigned int errstatus;
unsigned int rcl;
rcl=rcl;
intstatus=*(volatile unsigned long*)DMAC_INTSTATUS_V;
endstatus=*(volatile unsigned long*)DMAC_INTTCSTATUS_V;
errstatus=*(volatile unsigned long*)DMAC_INTERRORSTATUS_V;
spi_debug1("dma int int 0x%x,end 0x%x,err0x%x\r\n",intstatus,endstatus,errstatus);
if(intstatus&0x01) //channel 0 tx channel
{
if(endstatus&0x01)
{
*(volatile unsigned long*)DMAC_INTTCCLEAR_V=endstatus|0x01;
*(volatile unsigned long*)DMAC_INTTCCLEAR_V=endstatus&(~0x01);
}
if(errstatus&0x01)
{
*(volatile unsigned long*)DMAC_INTERRORSTATUS_V=endstatus|0x01;
*(volatile unsigned long*)DMAC_INTERRORSTATUS_V=endstatus&(~0x01);
}
if(DMA_ACTION==DMA_TX_ONLY)
{
rt_event_send(&txrxevent, 0X01);
}
*(volatile unsigned long*)SSI_DMACR_V&=(~0x01); //0x1 rxDMAenable 0x2 txDMAenable
}
if(intstatus&0x02) //channel 1 rx channel
{
if(endstatus&0x02)
{
*(volatile unsigned long*)DMAC_INTTCCLEAR_V=endstatus|0x02;
*(volatile unsigned long*)DMAC_INTTCCLEAR_V=endstatus&(~0x02);
}
if(errstatus&0x02)
{
*(volatile unsigned long*)DMAC_INTERRORSTATUS_V=endstatus|0x02;
*(volatile unsigned long*)DMAC_INTERRORSTATUS_V=endstatus&(~0x02);
}
if(DMA_ACTION==DMA_TX_RX)
{
rt_event_send(&txrxevent, 0X01);
*(volatile unsigned long*)SSI_DMACR_V&=(~0x02); //0x1 rxDMAenable 0x2 txDMAenable
}
}
// *(volatile unsigned long*)(SSI_SSIENR_V)= 0x00; //disable SSI
// *(volatile unsigned long*)(SSI_SER_V)= 0x00; //disable SSI channel0
rcl=*(volatile unsigned long*)SSI_ICR_V;
rcl=*(volatile unsigned long*)SSI_RXOICR_V;
rcl=*(volatile unsigned long*)SSI_RXUICR_V;
// *(volatile unsigned long*)(SSI_SSIENR_V)= 0x01; //disable SSI
// *(volatile unsigned long*)(SSI_SER_V)= 0x01; //disable SSI channel0
DMA_ACTION=0;
}
extern void rt_hw_interrupt_install(rt_uint32_t vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler);
int gspi_register_irq(int * irqnum)
{
disable_irq(INTSRC_EXINT4) ;
*(volatile unsigned long*)(GPIO_PORTA_DIR_V) |= (0X1)<<4;
*(volatile unsigned long*)(GPIO_PORTA_SEL_V )|= (0X1)<<4;
*(volatile unsigned long*)(GPIO_PORTA_INCTL_V) |= (0X1)<<4;
*(volatile unsigned long*)(GPIO_PORTA_INTRCTL_V) |= (0X11)<<8;//low level enable irq
*(volatile unsigned long*)(GPIO_PORTA_INTRCLR_V) |= (0X1)<<4; //add for 4020 GPA6
*irqnum= INTSRC_EXINT4;
rt_hw_interrupt_install(INTSRC_EXINT4, sbi_interrupt, RT_NULL);
rt_hw_interrupt_umask(INTSRC_EXINT4);
return 0;
}
void gspi_irq_clear(void)
{
*(volatile unsigned long*)(GPIO_PORTA_INTRCLR_V) |= (0X1)<<4; //add for 4020 GPA6
}
static int dma_init( void )
{
// *(volatile unsigned long*)(DMAC_ENBLDCHNS_V ) = (1<<0)+(1<<1); //enable the channels
if(DMA_ENABLE==1)
{
rt_memset(rxtxdummybuf,0x00,(2048+1024));
rt_hw_interrupt_install(INTSRC_SSI, spi_interrupt, RT_NULL);
rt_hw_interrupt_umask(INTSRC_SSI);
enable_irq(INTSRC_SSI);
}
rt_hw_interrupt_install(INTSRC_DMAC, dma_interrupt, RT_NULL);
rt_hw_interrupt_umask(INTSRC_DMAC);
enable_irq(INTSRC_DMAC);
spi_debug3("\nDMA Initialization done....\n");
return 0;
}
static int gspihost_init_hw(void)
{
*(volatile unsigned long*)(GPIO_PORTD_DIR_V)&=~0x04;
*(volatile unsigned long*)(GPIO_PORTD_SEL_V)&=~0x1b;
*(volatile unsigned long*)(GPIO_PORTD_SEL_V)|= 0x04;
*(volatile unsigned long*)(SSI_SSIENR_V)= 0x00; //disable SSI
*(volatile unsigned long*)(SSI_BAUDR_V) = 0x08; //set baudrate
*(volatile unsigned long*)(SSI_TXFLR_V) = 0x00;
*(volatile unsigned long*)(SSI_RXFLR_V) = 0x00;
*(volatile unsigned long*)(SSI_CONTROL0_V) = 0x0f; //?configure SSI channel0
*(volatile unsigned long*)(SSI_IMR_V) = 0x00;//0x1f; //mask all irqs of ssi
*(volatile unsigned long*)(SSI_SER_V)= 0x01; //enable SSI channel0
*(volatile unsigned long*)(SSI_SSIENR_V)= 0x01; //enable SSI
return 0;
}
int gspihost_init(void)
{
int ret=RT_EOK;
spi_debug1("gspihost_init\n");
ret=rt_sem_init(&gspi_lock, "wifi_gspi", 1, RT_IPC_FLAG_FIFO);
if(ret!=RT_EOK)
ret=rt_event_init(&txrxevent, "spievent", RT_IPC_FLAG_FIFO);
if(ret!=RT_EOK)
return ret;
gspihost_init_hw();
if( DMA_ENABLE==1)
dma_init();
return 0;
}

116
wifi/spi/gspi_io.h Normal file
View File

@ -0,0 +1,116 @@
/*
* File: gspi_io.h
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
#ifndef _GSPI_IO_H
#define _GSPI_IO_H
typedef char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed long s32;
typedef unsigned long u32;
typedef signed long long s64;
typedef unsigned long long u64;
#define GPIO_PORTA_DIR_V (0x1000f004)
#define GPIO_PORTA_SEL_V (0x1000f008)
#define GPIO_PORTA_INCTL_V (0x1000f00c)
#define GPIO_PORTA_INTRCTL_V (0x1000f010)
#define GPIO_PORTA_INTRCLR_V (0x1000f014)
#define GPIO_PORTD_DIR_V (0x1000f034)
#define GPIO_PORTD_SEL_V (0x1000f038)
#define GPIO_PORTD_DATA_V (0x1000f040)
#define SSI_CONTROL0_V (0x10009000)
#define SSI_CONTROL1_V (0x10009004)
#define SSI_SSIENR_V (0x10009008)
#define SSI_SER_V (0x10009010)
#define SSI_BAUDR_V (0x10009014)
#define SSI_TXFLR_V (0x10009020)
#define SSI_RXFLR_V (0x1000901C)
#define SSI_SR_V (0x10009028)
#define SSI_IMR_V (0x1000902c)
#define SSI_ISR_V (0x10009030)
#define SSI_TXOICR_V (0x10009038)
#define SSI_RXOICR_V (0x1000903C)
#define SSI_RXUICR_V (0x10009040)
#define SSI_DR_V (0x10009060)
#define SSI_DMACR_V (0x1000904C)
#define SSI_ICR_V (0x10009048)
#define SSI_DMATDLR_V (0x10009050)
#define SSI_DMARDLR_V (0x10009054)
#define DMAC_INTSTATUS_V (0x11001020)
#define DMAC_INTTCSTATUS_V (0x11001050)
#define DMAC_INTTCCLEAR_V (0x11001060)
#define DMAC_INTINTERRCLR_V (0x11001090)
#define DMAC_INTTCCLEAR_V (0x11001060)
#define DMAC_INTERRORSTATUS_V (0x11001090)
#define DMAC_INTERRCLR_V (0x11001080)
#define DMAC_C0SRCADDR_V (0x11001000)
#define DMAC_C1SRCADDR_V (0x11001100)
#define DMAC_C0DESTADDR_V (0x11001004)
#define DMAC_C1DESTADDR_V (0x11001104)
#define DMAC_C0CONTROL_V (0x1100100C)
#define DMAC_C1CONTROL_V (0x1100110C)
#define DMAC_C0CONFIGURATION_V (0x11001010)
#define DMAC_C1CONFIGURATION_V (0x11001110)
#define DMAC_C0DESCRIPTOR_V (0x11001014)
#define DMAC_C1DESCRIPTOR_V (0x11001114)
#define DMAC_ENBLDCHNS_V (0x110010B0)
#define GSPI_OK 0
typedef struct gspihost_info gspihost_info_t;
typedef gspihost_info_t *gspihost_info_p;
typedef struct gspi_card_rec *gspi_card_rec_p;
typedef struct gspi_card_rec io_card_rec_t;
typedef io_card_rec_t *io_card_rec_p;
struct gspi_card_rec
{
u8 magic[4];
gspihost_info_p ctrlr; // Back Reference to Host Controller
int (*add) (gspi_card_rec_p card);
int (*remove) (gspi_card_rec_p card);
// IRQ_RET_TYPE(*user_isr) (int, void *, struct pt_regs *);
void *user_arg;
u16 chiprev;
};
struct gspihost_info
{
int irq;
u16 dev_id;
int dma_init; /* physical address */
unsigned char *iodata; /* I/O data buffer */
unsigned char *iorw; /* I/O data buffer */
gspi_card_rec_p card;
};
extern int gspi_read_reg(u16 reg, u16 * data);
extern int gspi_write_reg(u16 reg, u16 data);
extern int gspi_read_data(u16 * data, u16 size);
extern int gspi_write_data(u16 * data, u16 size);
//extern int gspi_read_data_direct(u8 * data, u16 reg, u16 size);
extern int gspi_write_data_direct(u8 * data, u16 reg, u16 n);
extern int gspi_read_data_direct(u8 * data, u16 reg, u16 n);
//extern int gspi_write_data_direct(u8 * data, u16 reg, u16 size);
extern void gspi_irq_clear(void);//FOR 4020
extern int gspihost_init(void);
#endif /* _GSPI_IO_H */

2135
wifi/spi/helper.h Normal file

File diff suppressed because it is too large Load Diff

840
wifi/spi/if_gspi.c Normal file
View File

@ -0,0 +1,840 @@
/** @file if_gspi.c
* @brief This file contains generic GSPI functions
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/********************************************************
Change log:
09/26/05: Add Doxygen format comments
10/20/05: Add GSPI8686 support
01/30/06: Add kernel 2.6 support for GSPI8xxx/Bulverde
********************************************************/
#include "if_gspi.h"
#include "if_gspi_debug.h"
#include "gspi_io.h"
//#include "helper.h"
//#include "gspi8686.h"
#include "rtthread.h"
#include "sep4020.h"
#define HIC_DEFAULT_VALUE 0
/********************************************************
Local Variables
********************************************************/
/********************************************************
Global Variables
********************************************************/
extern int gspi_register_irq(int * irqnum);
extern int g_dummy_clk_reg;
extern int g_dummy_clk_ioport;
/********************************************************
Local Functions
********************************************************/
static int gspi_read_reg32(wlan_private * priv,u16 offset, u32 * data);
static int gspi_read_host_int_status(wlan_private * priv,u8 * data);
static int gspi_read_event_scratch(wlan_private * priv);
static wlan_private *pwlanpriv;
static wlan_private *(*wlan_add_callback) (void *dev_id);
static int (*wlan_remove_callback) (void *dev_id);
/**
* @brief clear the auto generate interrupt bit in Host
* Interrupt Control register
*
* @param priv A pointer to wlan_private structure
* @return NA
*/
static void gspi_init_HOST_INT_CTRL_REG(wlan_private * priv)
{
gspi_write_reg(HOST_INT_CTRL_REG,HIC_DEFAULT_VALUE & ~(HIC_TxDnldAuto|HIC_RxUpldAuto | HIC_CmdDnldAuto|HIC_CmdUpldAuto));
}
/**
* @brief This function re-enable the interrupt of the mask bit.
*
* @param priv A pointer to wlan_private structure
* @param mask interrupt mask
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int gspi_write_host_int_status(wlan_private * priv,u16 mask)
{
if (gspi_write_reg(HOST_INT_STATUS_REG, ~mask)) {
rt_kprintf("gspi_write_reg failed\n");
return WLAN_STATUS_FAILURE;
}
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function used to poll CmdDnLdRdy bit of Host Interrupt Status Register
*
* @param cardp A pointer to gspi_card_rec structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int wait_for_hostintstatus(void *card)
{
#define MAX_WAIT_TRIES 100
int i = 0,y;
u16 stat;
for (i = 0; i < MAX_WAIT_TRIES; ++i) {
gspi_read_reg(HOST_INT_STATUS_REG, &stat);
if (stat & GHIS_CmdDnLdRdy)
return WLAN_STATUS_SUCCESS;
for(y=0;y<1000;y++);
//rt_thread_delay(1);//may be for loop more suitable
}
return WLAN_STATUS_FAILURE;
}
/**
* @brief This function read a 32bit value from GSPI register
*
* @param priv A pointer to wlan_private structure
* @param reg GSPI hardware register
* @param data A pointer to return the register value
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int gspi_read_reg32(wlan_private * priv, u16 reg, u32 * data)
{
u16 readdt[3];
if (gspi_read_data_direct((u8 *) readdt, reg, 4) < 0) {
rt_kprintf( "Error on gspi_read_reg32(%02x)\n", reg);
return WLAN_STATUS_FAILURE;
}
memcpy(data, readdt, 4);
#ifdef GSPI_TX_RX_DEBUG
rt_kprintf("read reg32(0x%x) = 0x%x\n", reg, *data);
#endif
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function read the host inerrrupt status register
*
* @param priv A pointer to wlan_private structure
* @param curHIS A pointer to return the value of Host Interrupt Status register
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int gspi_read_host_int_status(wlan_private * priv, u8 * curHIS)
{
int ret;
u16 his;
ret = gspi_read_reg(HOST_INT_STATUS_REG, &his);
if (!ret)
*curHIS = (u8) his;
return ret;
}
/**
* @brief Read Event cause from the event scratch register
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int
gspi_read_event_scratch(wlan_private * priv)
{
int ret;
ENTER();
ret = gspi_read_reg32(priv, SCRATCH_3_REG, &priv->adapter->EventCause);
if (ret < 0) {
rt_kprintf("ERROR: Event Scratch Pad Register Read!\n");
return ret;
}
rt_kprintf("The event is %x\n", priv->adapter->EventCause);
priv->adapter->EventCause <<= 3;
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function enables the host interrupts mask
*
* @param priv A pointer to wlan_private structure
* @param mask the interrupt mask
* @return WLAN_STATUS_SUCCESS
*/
static int
enable_host_int_mask(wlan_private * priv, u8 mask)
{
int ret = WLAN_STATUS_SUCCESS;
/* Enabling TxDnldRdy, RxDnldRdy, CmdUpldRdy, CmdDnldRdy, CardEvent
* interrupts */
gspi_write_reg(HOST_INT_STATUS_MASK_REG,HISM_TxDnLdRdy | HISM_RxUpLdRdy | HISM_CmdDnLdRdy|HISM_CardEvent | HISM_CmdUpLdRdy);
return ret;
}
/** @brief This function disables the host interrupts mask.
*
* @param priv A pointer to wlan_private structure
* @param mask the interrupt mask
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int disable_host_int_mask(wlan_private * priv,u8 int_mask)
{
return gspi_write_reg(HOST_INT_STATUS_MASK_REG, 0x00);
}
/********************************************************
Global Functions
********************************************************/
/**
* @brief This is the interrupt handler for GSPI device
*
* @param irq The irq of GSPI device.
* @param dev_id A pointer to net_device structure
* @param fp A pointer to pt_regs structure
* @return n/a
*/
void sbi_interrupt(int dev)
{
disable_irq(INTSRC_EXINT4) ;
wlan_interrupt((struct rt_wlan_dev *)dev);
}
/**
* @brief Call back function when New Hardware insert.
*
* This function will notify wlan driver a new hardware insert.
*
* @param card A pointer to struct net_device
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int sbi_add_card(void* card)
{
if (!wlan_add_callback)
return WLAN_STATUS_FAILURE;
pwlanpriv = wlan_add_callback(card);
return (pwlanpriv != NULL) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE;
}
/**
* @brief Call back function when Hardware been removed.
*
* This function will notify wlan driver a hardware removed.
*
* @param card A pointer to struct net_device
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_remove_card(void *card)
{
if (!wlan_remove_callback)
return WLAN_STATUS_FAILURE;
pwlanpriv = NULL;
return wlan_remove_callback(card);
}
/**
* @brief wlan driver call this function to register to bus driver
*
* This function will be used to register wlan driver's add/remove callback function.
*
* @param add wlan driver's call back funtion for add card.
* @param remove wlan driver's call back funtion for remove card.
* @param arg not been used
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
/*
struct gspi_card_rec cardp;
int sbi_register(wlan_notifier_fn_add add, wlan_notifier_fn_remove remove,void *arg)
{
struct gspi_card_rec cardp;
wlan_add_callback = add;
wlan_remove_callback = remove;
cardp.add = sbi_add_card;
cardp.remove = sbi_remove_card;
// cardp.user_isr = sbi_interrupt;
sbi_add_card(&cardp);
return 0;
}
*/
/**
* @brief wlan driver call this function to unregister to bus driver
*
* This function will be used to unregister wlan driver.
*
* @return NA
*/
void
sbi_unregister(void)
{
// unregister_user(&gspi_notifier);
}
/**
* @brief fake function for gspi interface hardware
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS
*/
int
sbi_get_cis_info(wlan_private * priv)
{
return WLAN_STATUS_SUCCESS;
}
/**
* @brief fake function for gspi interface hardware
*
* @param card_p not used
* @return WLAN_STATUS_SUCCESS
*/
int
sbi_probe_card(void *card_p)
{
return WLAN_STATUS_SUCCESS;
}
#define IPFIELD_ALIGN_OFFSET 2
/**
* @brief This function read the current interrupt status register.
*
* @param priv A pointer to wlan_private structure
* @param ireg A pointer to hold the return interrupt status value
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int sbi_get_int_status(wlan_private * priv, u8 * ireg)
{
int ret = WLAN_STATUS_SUCCESS;
u8 tmp;
struct sk_buff *skb=RT_NULL;
u8 *cmdBuf;
wlan_adapter *Adapter = priv->adapter;
disable_host_int_mask(priv, HIM_DISABLE);
ret = gspi_read_host_int_status(priv, &tmp);
gspi_irq_clear();
enable_irq(priv->wlan_dev.netdev->irq);
/* re-map bit 0 and bit 1 for WLAN module since the definition is different */
*ireg = tmp & (~(GHIS_TxDnLdRdy | GHIS_RxUpLdRdy));
if (tmp & GHIS_TxDnLdRdy) {
priv->wlan_dev.dnld_sent = DNLD_RES_RECEIVED;
*ireg |= HIS_TxDnLdRdy;
}
if (tmp & GHIS_RxUpLdRdy) {
*ireg |= HIS_RxUpLdRdy;
}
if (*ireg & HIS_RxUpLdRdy) {
if((skb=rt_malloc(sizeof(struct sk_buff)))==RT_NULL)
{
ifspi_debug1 ("no memry for skb\n\r");
goto done;
}
rt_memset(skb,0x00,sizeof(struct sk_buff));
INIT_LIST_HEAD((struct list_head *)skb);
skb->data = rt_malloc(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
if (!skb->data) {
ifspi_debug1("No free skb data buf\n");
priv->stats.rx_dropped++;
ret = WLAN_STATUS_FAILURE;
rt_free(skb);
goto done;
}
/*16 Byte Align the IP fields */ /*why the IPFIELD_ALIGN_OFFSET is 2 not 16*/
skb->head=skb->data;
skb->data=(unsigned char *)(((u32)skb->data+3)&0xfffffffc);
wlan_debug3("data buf skb %x data %x",(u32)skb,(u32)skb->head);
/* skb->tail is passed as we are calling skb_put after we
* are reading the data */
if (sbi_card_to_host(priv, MVMS_DAT,
&priv->wlan_dev.upld_len,
skb->data,
MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) < 0) {
ifspi_debug1("ERROR: Data Transfer from device failed\n");
if (skb)
{
rt_free(skb);
if(skb->head!=RT_NULL)
rt_free(skb->head);
}
ret = WLAN_STATUS_FAILURE;
goto done;
}
ifspi_debug3( "Data <= FW\n");
skb->len+= priv->wlan_dev.upld_len;
list_add_tail((struct list_head *) skb,
(struct list_head *) &Adapter->RxSkbQ);
}
if (*ireg & HIS_CmdUpLdRdy) {
if (!Adapter->CurCmd) {
cmdBuf = priv->wlan_dev.upld_buf;
} else {
cmdBuf = Adapter->CurCmd->BufVirtualAddr;
}
if (sbi_card_to_host(priv, MVMS_CMD,
&priv->wlan_dev.upld_len,
cmdBuf, WLAN_UPLD_SIZE) < 0) {
ifspi_debug1("ERROR: Data Transfer from device failed\n");
ret = WLAN_STATUS_FAILURE;
goto done;
}
}
done:
enable_host_int_mask(priv, HIM_ENABLE);
// ifspi_debug2("GSPI int status = %02x:%02x\n", *ireg, Adapter->HisRegCpy);
return ret;
}
/**
* @brief initial the gspi hardware
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int sbi_card_init(wlan_private * priv)
{
u16 host_int_mask;
u16 chiprev;
u32 irq_num;
gspi_write_reg( SPU_BUS_MODE_REG, BUS_MODE_16_NO_DELAY);
gspi_read_reg( CHIPREV_REG, &chiprev);
ifspi_debug2("Chiprev is %x", chiprev);
priv->adapter->chip_rev = chiprev;
/* Read the HOST_INT_STATUS_REG for ACK the first interrrupt got
* from the bootloader. If we don't do this we get a interrupt
* as soon as we register the irq. */
gspi_read_reg(HOST_INT_STATUS_REG, &host_int_mask);
if (gspi_register_irq((int*)&irq_num) != GSPI_OK){
ifspi_debug1("gspi_register_irq failed\n");
return WLAN_STATUS_FAILURE;
}
enable_host_int_mask(priv, HIM_ENABLE);
gspi_init_HOST_INT_CTRL_REG(priv);
priv->wlan_dev.netdev->irq = irq_num;
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function check the firmware download status
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_verify_fw_download(wlan_private * priv)
{
int i;
u32 scr4;
for (i = 0; i < MAX_FIRMWARE_POLL_TRIES; ++i) {
if (gspi_read_reg32(priv,SCRATCH_4_REG, &scr4) < 0) {
rt_kprintf( "Read from Scratch 4 failed !!!\n");
return WLAN_STATUS_FAILURE;
}
if (scr4 == FIRMWARE_DNLD_OK) {
rt_kprintf("FW download successful !!!\n");
return WLAN_STATUS_SUCCESS;
}
rt_thread_delay(100);
}
return WLAN_STATUS_FAILURE;
}
/**
* @brief This function download the firmware to the hardware
*
* @param priv A pointer to wlan_private structure
* @param firmware A pointer to firmware
* @param firmwarelen the len of firmware
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_download_wlan_fw_image( wlan_private * priv,const u8 * firmware,
int firmwarelen)
{
int ret,i;
u16 dlimage[1024];
u16 len;
u32 cnt = 0;
// rt_kprintf("Downloading FW of size %d bytes\n", firmwarelen);
//printk(KERN_ERR "Downloading--FW of size %d bytes\n", firmwarelen);
/* Wait initially for the first non-zero value */
do {
for(i=0;i<1000;i++);
gspi_read_reg(SCRATCH_1_REG, &len);
} while (!len);
//printk(KERN_ERR "LEN size %d bytes\n", len);
for (;;) {
if (wait_for_hostintstatus(RT_NULL)) {
rt_kprintf("FW download died\n");
return WLAN_STATUS_FAILURE;
}
gspi_read_reg(SCRATCH_1_REG, &len);
if (!len) {
break;
}
if (len & 1) {
// rt_kprintf("CRC Error\n");
len &= ~1;
} else {
// rt_kprintf(".");
}
memcpy(dlimage, firmware + cnt, len);
gspi_write_data_direct((u8 *) dlimage, CMD_RDWRPORT_REG,
(len / 2) + 1);
gspi_write_reg(HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
cnt += len;
}
/*printk(KERN_ERR "\nFW Image of Size %d bytes downloaded, cnt %d\n",
firmwarelen,cnt);*/
// rt_kprintf("\nFW Image of Size bytes downloaded, cnt %d\n",
// firmwarelen, cnt);
ret = WLAN_STATUS_SUCCESS;
return ret;
}
/**
* @brief This function will call sbi_download_wlan_fw_image to download the firmware
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_prog_firmware_w_helper(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
if (Adapter->fmimage != NULL) {
return sbi_download_wlan_fw_image(priv,
Adapter->fmimage,
Adapter->fmimage_len);
} else {
rt_kprintf("No external FW image\n");
return WLAN_STATUS_FAILURE;
}
}
/**
* @brief This function is used to download firmware to hardware
*
* @param priv A pointer to wlan_private structure
* @param firmware A pointer to fimware
* @param firmwarelen firmware length
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_prog_firmware_image(wlan_private * priv, const u8 * firmware,
int firmwarelen)
{
int ret = WLAN_STATUS_SUCCESS;
u16 dlimage[FIRMWARE_DNLD_PCKCNT];
int fwblknow;
for (fwblknow = 0; fwblknow < firmwarelen;
fwblknow += FIRMWARE_DNLD_PCKCNT) {
gspi_write_reg(SCRATCH_1_REG, FIRMWARE_DNLD_PCKCNT);
if (wait_for_hostintstatus(RT_NULL)) {
rt_kprintf("FW download died\n");
return WLAN_STATUS_FAILURE;
}
rt_memcpy(dlimage, firmware + fwblknow, FIRMWARE_DNLD_PCKCNT);
gspi_write_data_direct((u8 *) dlimage, CMD_RDWRPORT_REG,
(FIRMWARE_DNLD_PCKCNT / 2) + 1);
gspi_write_reg(HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
}
/* Writing 0 to Scr1 is to indicate the end of Firmware dwld */
gspi_write_reg(SCRATCH_1_REG, FIRMWARE_DNLD_END);
gspi_write_reg(HOST_INT_STATUS_REG, 0x0000);
gspi_write_reg(CARD_INT_CAUSE_REG, CIC_CmdDnLdOvr);
ret = WLAN_STATUS_SUCCESS;
return ret;
}
/**
* @brief This function will call sbi_prog_firmware_image to
* download the firmware
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_prog_firmware(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
if (Adapter->fmimage != NULL) {
return sbi_prog_firmware_image(priv,
Adapter->fmimage,
Adapter->fmimage_len);
} else {
ifspi_debug3( "No external FW image\n");
return WLAN_STATUS_FAILURE;
}
}
/**
* @brief This function will call sbi_prog_firmware_image to
* download the helperimage
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_prog_helper(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
if (Adapter->helper != NULL) {
return sbi_prog_firmware_image(priv,
Adapter->helper, Adapter->helper_len);
} else {
rt_kprintf("No external helper image\n");
return WLAN_STATUS_FAILURE;
}
}
/**
* @brief wlan driver call this function to register the device
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS
*/
int spi_register_dev(wlan_private * priv)
{
int ret = WLAN_STATUS_SUCCESS;
ENTER();
/* Initialize the private structure */
strncpy(priv->wlan_dev.name, "gspi0", sizeof(priv->wlan_dev.name));
priv->wlan_dev.ioport = 0;
priv->wlan_dev.upld_rcv = 0;
priv->wlan_dev.upld_typ = 0;
priv->wlan_dev.upld_len = 0;
sbi_card_init(priv);
LEAVE();
return ret;
}
/**
* @brief enable the host interrupt on the GSPI device
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS
*/
int
sbi_enable_host_int(wlan_private * priv)
{
gspi_irq_clear();
enable_irq(priv->wlan_dev.netdev->irq);
return WLAN_STATUS_SUCCESS;
}
/**
* @brief Disable the Host interrupt on the GSPI device
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS
*/
int sbi_disable_host_int(wlan_private * priv)
{
disable_irq(priv->wlan_dev.netdev->irq);
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function is used to send the data/cmd to hardware
*
* @param priv A pointer to wlan_private structure
* @param type 1--Cmd, 0--Data
* @param payload A point to the data or cmd buffer
* @param nb len of data/cmd buffer
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb)
{
int ret = WLAN_STATUS_SUCCESS;
u16 writeReg;
u8 intType;
ENTER();
intType = type ? CIC_CmdDnLdOvr : CIC_TxDnLdOvr;
writeReg = (type) ? CMD_RDWRPORT_REG : DATA_RDWRPORT_REG;
priv->wlan_dev.dnld_sent = (type) ? DNLD_CMD_SENT : DNLD_DATA_SENT;
if (nb & 0x0001)
nb += 1;
/*
* If the bytes written is not a multiple of four then make it
* a multiple of four as the RWPORT is 4 byte aligned from
* the host
*/
if (!(nb % 4))
ret = gspi_write_data_direct(payload, writeReg, (nb / 2) + 1);
else
ret = gspi_write_data_direct(payload, writeReg, (nb / 2) + 2);
gspi_write_reg(CARD_INT_CAUSE_REG, intType);
LEAVE();
return ret;
}
/**
* @brief This function is used to read data/cmd from the card.
*
* @param priv A pointer to wlan_private structure
* @param type 1--Cmd, 0--Data
* @param nb A point to return how many bytes has been read back from hardware
* @param payload A point to data buffer for receive data/cmd
* @param npayload the size of payload buffer
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_card_to_host(wlan_private * priv, u32 type,
u32 * nb, u8 * payload, u16 npayload)
{
int ret = WLAN_STATUS_SUCCESS;
u16 len;
u16 intType = 0, readReg;
ENTER();
intType = type ? CIC_CmdUpLdOvr : CIC_RxUpLdOvr;
readReg = type ? CMD_RDWRPORT_REG : DATA_RDWRPORT_REG;
gspi_read_reg((type) ? SCRATCH_2_REG : SCRATCH_1_REG, &len);
if (!len || len > npayload) {
ifspi_debug3( "Error packet of len %d\n", len);
len = MRVDRV_ETH_RX_PACKET_BUFFER_SIZE;
}
if (len & 0x0001)
len += 1;
if (!(len % 4))
ret = gspi_read_data_direct(payload, readReg, (len / 2) + 1);
else
ret = gspi_read_data_direct(payload, readReg, (len / 2) + 2);
gspi_write_reg(CARD_INT_CAUSE_REG, intType);
*nb = len;
LEAVE();
return ret;
}
/**
* @brief This function is used to read the event cause from card
* and re-enable event interrupt.
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
sbi_read_event_cause(wlan_private * priv)
{
gspi_read_event_scratch(priv);
/* re-enable the interrupt */
gspi_write_host_int_status(priv, GHIS_CardEvent);
/* generate interrupt to firmware */
gspi_write_reg(CARD_INT_CAUSE_REG, CIC_HostEvent);
return WLAN_STATUS_SUCCESS;
}
/**
* @brief configure hardware to quit deep sleep state
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int sbi_exit_deep_sleep(wlan_private * priv)
{
/* set Wakeup bit */
return gspi_write_reg(HOST_INT_CTRL_REG,
HIC_DEFAULT_VALUE | HIC_WakeUp);
}
/**
* @brief clear the Wake up bit in Host Interrupt Control Register
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int sbi_reset_deepsleep_wakeup( wlan_private *priv)
{
/* clear wakeup bit */
return gspi_write_reg(HOST_INT_CTRL_REG,
HIC_DEFAULT_VALUE & ~HIC_WakeUp);
}

110
wifi/spi/if_gspi.h Normal file
View File

@ -0,0 +1,110 @@
/** @file if_gspi.h
* @brief This file contains MSU registers definition
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
09/26/05: Add Doxygen format comments
********************************************************/
#ifndef __GSPIREG_H_
#define __GSPIREG_H_
#include "..\wlan\include.h" //changed by dennis
/* GSPI Registers Offset. All the resgisters are at DWORD boundary */
#define DEVICEID_CTRL_REG 0x00
#define CHIPREV_REG 0x02
#define IO_READBASE_REG 0x04
#define IO_WRITEBASE_REG 0x08
#define IO_RDWRPORT_REG 0x0C
#define CMD_READBASE_REG 0x10
#define CMD_WRITEBASE_REG 0x14
#define CMD_RDWRPORT_REG 0x18
#define DATA_READBASE_REG 0x1C
#define DATA_WRITEBASE_REG 0x20
#define DATA_RDWRPORT_REG 0x24
#define SCRATCH_1_REG 0x28
#define SCRATCH_2_REG 0x2C
#define SCRATCH_3_REG 0x30
#define SCRATCH_4_REG 0x34
#define TX_FRAME_SEQ_NUM_REG 0x38
#define TX_FRAME_STATUS_REG 0x3C
#define HOST_INT_CTRL_REG 0x40
#define CARD_INT_CAUSE_REG 0x44
#define CARD_INT_STATUS_REG 0x48
#define CARD_INT_EVENT_MASK_REG 0x4C
#define CARD_INT_STATUS_MASK_REG 0x50
#define CARD_INT_RESET_SELECT_REG 0x54
#define HOST_INT_CAUSE_REG 0x58
#define HOST_INT_STATUS_REG 0x5C
#define HOST_INT_EVENT_MASK_REG 0x60
#define HOST_INT_STATUS_MASK_REG 0x64
#define HOST_INT_RESET_SELECT_REG 0x68
#define DELAY_READ_REG 0x6C
#define SPU_BUS_MODE_REG 0x70
#define BUS_MODE_16_NO_DELAY 0x02
/* Bit definition for CARD_INT_CAUSE (Card Interrupt Cause) */
#define CIC_TxDnLdOvr B_BIT_0
#define CIC_RxUpLdOvr B_BIT_1
#define CIC_CmdDnLdOvr B_BIT_2
#define CIC_HostEvent B_BIT_3
#define CIC_CmdUpLdOvr B_BIT_4
#define CIC_PwrDown B_BIT_5
/* Bit definition for HOST_INT_STATUS (Host Interrupt Status) */
#define GHIS_TxDnLdRdy B_BIT_0
#define GHIS_RxUpLdRdy B_BIT_1
#define GHIS_CmdDnLdRdy B_BIT_2
#define GHIS_CardEvent B_BIT_3
#define GHIS_CmdUpLdRdy B_BIT_4
#define GHIS_IOWrFifoOvrflow B_BIT_5
#define GHIS_IORdFifoUndrflow B_BIT_6
#define GHIS_DATAWrFifoOvrflow B_BIT_7
#define GHIS_DATARdFifoUndrflow B_BIT_8
#define GHIS_CMDWrFifoOvrflow B_BIT_9
#define GHIS_CMDRdFifoUndrflow B_BIT_10
/* Bit definition for HOST_INT_STATUS_MASK_REG (Host Interrupt Status Mask) */
#define HISM_TxDnLdRdy B_BIT_0
#define HISM_RxUpLdRdy B_BIT_1
#define HISM_CmdDnLdRdy B_BIT_2
#define HISM_CardEvent B_BIT_3
#define HISM_CmdUpLdRdy B_BIT_4
#define HISM_IOWrFifoOvrflow B_BIT_5
#define HISM_IORdFifoUndrflow B_BIT_6
#define HISM_DATAWrFifoOvrflow B_BIT_7
#define HISM_DATARdFifoUndrflow B_BIT_8
#define HISM_CMDWrFifoOvrflow B_BIT_9
#define HISM_CMDRdFifoUndrflow B_BIT_10
/* Bit definition for HOST_INT_CTRL_REG (Host Interrupt Control) */
#define HIC_WakeUp B_BIT_0
#define HIC_WlanRdy B_BIT_1
#define HIC_TxDnldAuto B_BIT_5
#define HIC_RxUpldAuto B_BIT_6
#define HIC_CmdDnldAuto B_BIT_7
#define HIC_CmdUpldAuto B_BIT_8
/* Bit definition for SPU_BUS_MODE_REG (SPU Bus mode register)*/
#define SBM_DataFormat_2 B_BIT_2
/* Value to check once the firmware is downloaded */
#define FIRMWARE_DNLD_OK 0x88888888
/* Value to write to indicate end of firmware dnld */
#define FIRMWARE_DNLD_END 0x0000
#define FIRMWARE_DNLD_PCKCNT 64
#endif /* __GSPIREG_H_ */

38
wifi/spi/if_gspi_debug.h Normal file
View File

@ -0,0 +1,38 @@
/** @file if_gspi.h
* @brief This file contains MSU registers definition
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
09/26/05: Add Doxygen format comments
********************************************************/
#ifndef __IF_GSPI_DEBUG_H_
#define __IF_GSPI_DEBUG_H_
#define DEBUG_IF_SSP_LEVEL3
#ifdef DEBUG_IF_SSP_LEVEL0
#define ifspi_debug1(...)
#define ifspi_debug2(...)
#define ifspi_debug3(...)
#endif
#ifdef DEBUG_IF_SSP_LEVEL1
#define ifspi_debug1(a...) rt_kprintf(a)
#define ifspi_debug2(a...) do{}while(0)
#define ifspi_debug3(a...) do{}while(0)
#endif
#ifdef DEBUG_IF_SSP_LEVEL2
#define ifspi_debug1(a...) rt_kprintf(a)
#define ifspi_debug2(a...) rt_kprintf(a)
#define ifspi_debug3(a...) do{}while(0)
#endif
#ifdef DEBUG_IF_SSP_LEVEL3
#define ifspi_debug1(a...) rt_kprintf(a)
#define ifspi_debug2(a...) rt_kprintf(a)
#define ifspi_debug3(a...) rt_kprintf(a)
#endif
#endif /* __GSPIREG_H_ */

7484
wifi/wlan/gspibin.h Normal file

File diff suppressed because it is too large Load Diff

135
wifi/wlan/helper_gspi.h Normal file
View File

@ -0,0 +1,135 @@
char helpgspibin[]={
0x03,0x00,0x00,0xEA,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x50,0x00,0x9F,0xE5,0x10,0x0F,0x01,0xEE,0x00,0x00,0xE0,0xE3,
0x48,0x10,0x9F,0xE5,0x0C,0x00,0x81,0xE5,0x18,0x00,0x91,0xE5,0x20,0x08,0xA0,0xE1,
0x0B,0x00,0x50,0xE3,0x04,0x00,0x00,0x0A,0x1B,0x00,0x50,0xE3,0x02,0x00,0x00,0x0A,
0x2C,0x00,0x9F,0xE5,0x30,0x00,0x81,0xE5,0x01,0x00,0x00,0xEA,0x24,0x00,0x9F,0xE5,
0x30,0x00,0x81,0xE5,0x20,0xD0,0x9F,0xE5,0x20,0x00,0x9F,0xE5,0x00,0x10,0x90,0xE5,
0x1C,0x20,0x9F,0xE5,0x00,0x10,0x82,0xE5,0x06,0x00,0x00,0xEA,0x74,0x1F,0x00,0x00,
0x00,0x20,0x00,0x80,0x12,0x09,0x00,0x00,0xE7,0x3A,0x07,0x14,0x00,0x20,0x00,0x04,
0x04,0x00,0x00,0x00,0xFC,0xFF,0x00,0x00,0xC4,0x80,0x8F,0xE2,0x03,0x00,0x98,0xE8,
0x08,0x00,0x80,0xE0,0x08,0x10,0x81,0xE0,0x01,0xB0,0x40,0xE2,0x01,0x00,0x50,0xE1,
0x13,0x00,0x00,0x0A,0x70,0x00,0xB0,0xE8,0x05,0x00,0x54,0xE1,0xFA,0xFF,0xFF,0x0A,
0x01,0x00,0x14,0xE3,0x0B,0x40,0x84,0x10,0x01,0x00,0x15,0xE3,0x0B,0x50,0x85,0x10,
0x02,0x00,0x15,0xE3,0x09,0x50,0x85,0x10,0x03,0x50,0xC5,0xE3,0x10,0x60,0x56,0xE2,
0x8C,0x10,0xB4,0x28,0x8C,0x10,0xA5,0x28,0xFB,0xFF,0xFF,0x8A,0x86,0x6E,0xB0,0xE1,
0x0C,0x00,0xB4,0x28,0x0C,0x00,0xA5,0x28,0x04,0x70,0x94,0x44,0x04,0x70,0x85,0x44,
0xE9,0xFF,0xFF,0xEA,0x08,0x20,0x98,0xE5,0x0C,0x30,0x98,0xE5,0x08,0x20,0x82,0xE0,
0x08,0x30,0x83,0xE0,0x01,0xC0,0x42,0xE2,0x00,0x70,0xA0,0xE3,0x00,0x00,0xA0,0xE3,
0x00,0x60,0xA0,0xE3,0x00,0xB0,0xA0,0xE3,0x03,0x00,0x52,0xE1,0x10,0x00,0x00,0x0B,
0x30,0x00,0xB2,0xE8,0x01,0x00,0x14,0xE3,0x0C,0x40,0x84,0x10,0x02,0x00,0x14,0xE3,
0x09,0x40,0x84,0x10,0x03,0x40,0xC4,0xE3,0x10,0x50,0x55,0xE2,0xC1,0x08,0xA4,0x28,
0xFC,0xFF,0xFF,0x8A,0x85,0x5E,0xB0,0xE1,0x41,0x00,0xA4,0x28,0x04,0x70,0x84,0x44,
0xF0,0xFF,0xFF,0xEA,0x18,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,
0x54,0x00,0x00,0x00,0x04,0xF0,0x1F,0xE5,0x80,0x01,0x00,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0x01,0x00,0x00,0x00,0x00,0x00,0xC0,
0x3C,0x06,0x00,0x00,0xE4,0x07,0x00,0x00,0x00,0x08,0x00,0xC0,0x78,0x00,0x00,0x00,
0xA8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x00,0xC0,0x00,0x00,0x00,0x00,
0x78,0x08,0x00,0xC0,0x70,0x00,0x00,0x00,0x70,0x47,0x70,0x47,0x00,0x47,0x08,0x47,
0x10,0x47,0x18,0x47,0x20,0x47,0x28,0x47,0x30,0x47,0x38,0x47,0x78,0x47,0x00,0x00,
0x03,0x00,0x52,0xE3,0x83,0x00,0x00,0x9A,0x03,0xC0,0x10,0xE2,0x08,0x00,0x00,0x0A,
0x01,0x30,0xD1,0xE4,0x02,0x00,0x5C,0xE3,0x0C,0x20,0x82,0xE0,0x01,0xC0,0xD1,0x94,
0x01,0x30,0xC0,0xE4,0x01,0x30,0xD1,0x34,0x04,0x20,0x42,0xE2,0x01,0xC0,0xC0,0x94,
0x01,0x30,0xC0,0x34,0x03,0x30,0x11,0xE2,0x63,0x00,0x00,0x0A,0x04,0x20,0x52,0xE2,
0x74,0x00,0x00,0x3A,0x03,0xC0,0x31,0xE7,0x02,0x00,0x53,0xE3,0x08,0x00,0x00,0x0A,
0x0F,0x00,0x00,0x8A,0x2C,0x34,0xA0,0xE1,0x04,0xC0,0xB1,0xE5,0x04,0x20,0x52,0xE2,
0x0C,0x3C,0x83,0xE1,0x04,0x30,0x80,0xE4,0xF9,0xFF,0xFF,0x2A,0x01,0x10,0x81,0xE2,
0x68,0x00,0x00,0xEA,0x2C,0x38,0xA0,0xE1,0x04,0xC0,0xB1,0xE5,0x04,0x20,0x52,0xE2,
0x0C,0x38,0x83,0xE1,0x04,0x30,0x80,0xE4,0xF9,0xFF,0xFF,0x2A,0x02,0x10,0x81,0xE2,
0x60,0x00,0x00,0xEA,0x2C,0x3C,0xA0,0xE1,0x04,0xC0,0xB1,0xE5,0x04,0x20,0x52,0xE2,
0x0C,0x34,0x83,0xE1,0x04,0x30,0x80,0xE4,0xF9,0xFF,0xFF,0x2A,0x03,0x10,0x81,0xE2,
0x58,0x00,0x00,0xEA,0x78,0x47,0x00,0x00,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0x00,0x00,
0x0E,0x50,0xA0,0xE1,0x3C,0x00,0x00,0xEB,0x05,0xE0,0xA0,0xE1,0x00,0x40,0xA0,0xE1,
0x0D,0x10,0xA0,0xE1,0x0A,0x30,0xA0,0xE1,0x07,0x00,0xC0,0xE3,0x60,0xD0,0x80,0xE2,
0x10,0x40,0x2D,0xE9,0xF0,0x00,0x00,0xEB,0x10,0x40,0xBD,0xE8,0x07,0xD0,0xC1,0xE3,
0x00,0x60,0xA0,0xE3,0x00,0x70,0xA0,0xE3,0x00,0x80,0xA0,0xE3,0x00,0xB0,0xA0,0xE3,
0x04,0xC0,0xA0,0xE1,0xC0,0x09,0xAC,0xE8,0xC0,0x09,0xAC,0xE8,0xC0,0x09,0xAC,0xE8,
0xC0,0x09,0xAC,0xE8,0x1F,0x40,0x2D,0xE9,0x00,0x00,0xA0,0xE3,0x00,0x10,0xA0,0xE3,
0xFF,0xFF,0xFF,0xEB,0x40,0x10,0x81,0xE2,0x01,0x60,0x80,0xE0,0x44,0x6F,0x86,0xE2,
0x1C,0x60,0x84,0xE5,0x18,0x10,0x84,0xE5,0x01,0x00,0xA0,0xE3,0x14,0x00,0x84,0xE5,
0x1F,0x40,0xBD,0xE8,0x02,0x10,0xA0,0xE1,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0x00,0x00,
0x10,0x40,0x2D,0xE9,0x00,0x20,0xA0,0xE1,0x00,0x00,0xA0,0xE3,0xFF,0xFF,0xFF,0xEB,
0x10,0x40,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,0xD4,0xFF,0xFF,0xEB,0x36,0x00,0x00,0xFA,
0x1C,0xC0,0x9F,0xE5,0x0F,0xC0,0x8C,0xE0,0x01,0x00,0x1C,0xE3,0x0D,0xE0,0x8F,0x12,
0x0F,0xE0,0xA0,0x01,0x1C,0xFF,0x2F,0xE1,0x01,0xC0,0x8F,0xE2,0x1C,0xFF,0x2F,0xE1,
0x00,0xF0,0x52,0xF8,0xC5,0x03,0x00,0x00,0x78,0x47,0x00,0x00,0x01,0x40,0x2D,0xE9,
0x50,0x00,0x00,0xFB,0x01,0x40,0xBD,0xE8,0x01,0x00,0x00,0xEA,0x78,0x47,0x00,0x00,
0x00,0x00,0xE0,0xE3,0x53,0x00,0x00,0xEA,0x78,0x47,0x00,0x00,0x00,0x00,0x9F,0xE5,
0x1E,0xFF,0x2F,0xE1,0x88,0x08,0x00,0xC0,0x78,0x47,0x00,0x00,0x10,0x40,0x2D,0xE9,
0x20,0x20,0x52,0xE2,0x05,0x00,0x00,0x3A,0x18,0x50,0xB1,0x28,0x18,0x50,0xA0,0x28,
0x18,0x50,0xB1,0x28,0x18,0x50,0xA0,0x28,0x20,0x20,0x52,0x22,0xF9,0xFF,0xFF,0x2A,
0x02,0xCE,0xB0,0xE1,0x18,0x50,0xB1,0x28,0x18,0x50,0xA0,0x28,0x18,0x00,0xB1,0x48,
0x18,0x00,0xA0,0x48,0x10,0x40,0xBD,0xE8,0x02,0xCF,0xB0,0xE1,0x04,0x30,0x91,0x24,
0x04,0x30,0x80,0x24,0x1E,0xFF,0x2F,0x01,0x82,0x2F,0xB0,0xE1,0x01,0x20,0xD1,0x44,
0x01,0x30,0xD1,0x24,0x01,0xC0,0xD1,0x24,0x01,0x20,0xC0,0x44,0x01,0x30,0xC0,0x24,
0x01,0xC0,0xC0,0x24,0x1E,0xFF,0x2F,0xE1,0x10,0xB5,0x04,0x1C,0x00,0xF0,0x00,0xF8,
0x20,0x1C,0xFF,0xF7,0xAC,0xEF,0x10,0xBC,0x08,0xBC,0x18,0x47,0xF0,0xB5,0x04,0x1C,
0x0D,0x1C,0x83,0xB0,0x00,0xF0,0xDA,0xE9,0x00,0x94,0x01,0x95,0x00,0x20,0x00,0xF0,
0x00,0xF8,0x02,0x90,0x26,0x48,0x69,0x46,0x78,0x44,0x00,0xF0,0x00,0xF8,0x05,0x1C,
0x0E,0x1C,0x00,0xA9,0x03,0xC9,0x00,0xF0,0x00,0xF8,0x00,0xF0,0x00,0xF8,0x00,0xF0,
0x00,0xF8,0x00,0x21,0x00,0x20,0x00,0xF0,0x00,0xF8,0x07,0x1C,0xFF,0xF7,0x96,0xEF,
0x04,0x1C,0x00,0x21,0x07,0x62,0x00,0x20,0x00,0xF0,0x00,0xF8,0x41,0x1C,0x61,0x62,
0x00,0x21,0x00,0x20,0x00,0xF0,0x00,0xF8,0x00,0x21,0xA0,0x62,0x00,0x20,0x00,0xF0,
0x00,0xF8,0x00,0x21,0xE0,0x62,0x00,0x20,0x00,0xF0,0x00,0xF8,0x20,0x63,0x00,0xF0,
0x00,0xF8,0x00,0xF0,0x00,0xF8,0x00,0xF0,0x00,0xF8,0x00,0xF0,0x00,0xF8,0x00,0xF0,
0x00,0xF8,0x00,0xF0,0x00,0xF8,0x00,0xF0,0x00,0xF8,0x00,0xF0,0x00,0xF8,0x28,0x1C,
0x31,0x1C,0x03,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x08,0xB5,0x00,0xF0,0x00,0xF8,
0x00,0xF0,0x00,0xF8,0x00,0xF0,0x00,0xF8,0x01,0xB0,0x08,0xBC,0x18,0x47,0x00,0x00,
0x94,0x00,0x00,0x00,0x78,0x47,0x00,0x00,0x18,0x00,0xA0,0xE3,0x08,0x10,0x9F,0xE5,
0x56,0x34,0x12,0xEF,0x1E,0xFF,0x2F,0xE1,0x09,0x00,0x00,0x00,0x26,0x00,0x02,0x00,
0x78,0x47,0x00,0x00,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0x00,0x00,0x10,0x40,0x2D,0xE9,
0xA1,0xFF,0xFF,0xEB,0x04,0x00,0x80,0xE2,0x10,0x40,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,
0x00,0x47,0x00,0x00,0xFE,0xB5,0x00,0x20,0x02,0x90,0x01,0x90,0x4D,0x48,0x01,0x26,
0xC0,0x6B,0x05,0x28,0x19,0xD2,0x02,0xA3,0x1B,0x5C,0x5B,0x00,0x9F,0x44,0x00,0x00,
0x03,0x04,0x04,0x04,0x04,0x00,0x00,0x26,0x47,0x4A,0x00,0x21,0x11,0x60,0x84,0x00,
0x46,0x48,0x51,0x60,0x91,0x60,0x46,0x4D,0x01,0x59,0x28,0x1C,0xFF,0xF7,0x37,0xFE,
0x44,0x48,0x00,0x59,0xFF,0xF7,0x32,0xFE,0x00,0xE0,0xFE,0xE7,0x01,0x98,0x00,0x28,
0x09,0xD0,0x41,0x48,0x80,0x69,0x00,0x0C,0x00,0x02,0x10,0x21,0x08,0x43,0x05,0x1C,
0x00,0x20,0x01,0x90,0x00,0xE0,0x10,0x25,0x3C,0x4F,0x28,0x1C,0x39,0x59,0xFF,0xF7,
0x1E,0xFE,0x00,0x2E,0x04,0xD0,0x3A,0x48,0x00,0x59,0xFF,0xF7,0x17,0xFE,0x00,0x26,
0x00,0x20,0x00,0x90,0x37,0x48,0x00,0x59,0xFF,0xF7,0x10,0xFE,0x30,0x48,0x2E,0x4F,
0x0F,0xC8,0x0F,0xC7,0x10,0x3F,0x38,0x68,0x01,0x28,0x0F,0xD0,0x04,0x28,0x0D,0xD0,
0x01,0x20,0x2E,0x4F,0x05,0x43,0x28,0x1C,0x39,0x59,0xFF,0xF7,0x00,0xFE,0x2C,0x48,
0x00,0x59,0xFF,0xF7,0xFB,0xFD,0x00,0x98,0x00,0x28,0xE3,0xD0,0x22,0x48,0x00,0x68,
0x01,0x28,0x18,0xD0,0x04,0x28,0x0C,0xD1,0x24,0x4F,0x00,0x20,0x39,0x59,0xFF,0xF7,
0xEE,0xFD,0x23,0x48,0x00,0x59,0xFF,0xF7,0xE9,0xFD,0x1B,0x48,0x40,0x68,0xFF,0xF7,
0x8F,0xFF,0x19,0x49,0x00,0x20,0x08,0x60,0x48,0x60,0x88,0x60,0xC8,0x60,0x02,0x98,
0x00,0x28,0xAB,0xD0,0xFE,0xBD,0x19,0x4F,0x13,0x48,0x39,0x59,0x85,0x68,0x28,0x1C,
0xFF,0xF7,0xD5,0xFD,0x16,0x48,0x00,0x59,0xFF,0xF7,0xD0,0xFD,0x00,0x20,0x00,0x90,
0x14,0x48,0x00,0x59,0xFF,0xF7,0xCA,0xFD,0x13,0x48,0x00,0x59,0xFF,0xF7,0xC6,0xFD,
0x00,0x28,0x01,0xD1,0x01,0x26,0xDC,0xE7,0x01,0x20,0x05,0x43,0x28,0x1C,0x39,0x59,
0xFF,0xF7,0xBD,0xFD,0x0A,0x48,0x00,0x59,0xFF,0xF7,0xB8,0xFD,0x00,0x98,0x00,0x28,
0xCF,0xD1,0xE5,0xE7,0xC0,0xFF,0x00,0x00,0x78,0x08,0x00,0xC0,0x14,0x08,0x00,0xC0,
0x00,0x0A,0x00,0xC0,0x00,0x08,0x00,0xC0,0x00,0x20,0x00,0x80,0x64,0x08,0x00,0xC0,
0x3C,0x08,0x00,0xC0,0x28,0x08,0x00,0xC0,0x50,0x08,0x00,0xC0,0x04,0x00,0x9F,0xE5,
0x40,0x1D,0x80,0xE2,0x0E,0xF0,0xA0,0xE1,0x00,0x10,0x00,0x04,0x01,0x49,0x05,0x20,
0x48,0x61,0x70,0x47,0x00,0x0C,0x00,0x80,0x70,0x47,0x00,0x00,0x00,0x20,0x70,0x47,
0x70,0x47,0x00,0x00,0x70,0x47,0x00,0x00,0x70,0x47,0x00,0x00,0x03,0x48,0x04,0x49,
0x08,0x80,0x40,0x07,0x41,0x88,0x41,0x80,0x70,0x47,0x00,0x00,0x04,0x80,0x00,0x00,
0x20,0x00,0x00,0x80,0x01,0x21,0xC9,0x07,0x48,0x88,0x40,0x07,0xFC,0xD5,0x70,0x47,
0x02,0x49,0x03,0x48,0x01,0x80,0x8F,0x21,0xC1,0x83,0x70,0x47,0x04,0x80,0x00,0x00,
0x20,0x00,0x00,0x80,0x01,0x21,0xC9,0x07,0x88,0x62,0x70,0x47,0x01,0x21,0xC9,0x07,
0x88,0x63,0x70,0x47,0x05,0x4A,0x80,0xB5,0x12,0x1D,0x05,0xCA,0x02,0x49,0x04,0x3A,
0xFF,0xF7,0x66,0xED,0x00,0x20,0x80,0xBD,0x00,0x0A,0x00,0xC0,0x78,0x08,0x00,0xC0,
0x80,0xB5,0xFF,0xF7,0xFF,0xFE,0x00,0x20,0x80,0xBD,0x00,0x00,0x04,0x21,0x48,0x07,
0x41,0x63,0x00,0x21,0x41,0x62,0x70,0x47,0x01,0x21,0xC9,0x07,0x48,0x6A,0x40,0x07,
0xFC,0xD5,0x70,0x47,0x01,0x21,0xC8,0x07,0x01,0x62,0x04,0x21,0x41,0x63,0x70,0x47,
0x01,0x21,0xC9,0x07,0x88,0x81,0x70,0x47,0x01,0x21,0xC9,0x07,0xC8,0x63,0x70,0x47,
0x02,0x48,0x00,0x21,0x01,0x81,0x0D,0x21,0x01,0x80,0x70,0x47,0x20,0x01,0x00,0x80,
0x02,0x49,0x08,0x89,0xC0,0x07,0xFC,0xD5,0x70,0x47,0x00,0x00,0x20,0x01,0x00,0x80,
0x03,0x48,0x0D,0x21,0x01,0x80,0x00,0x21,0x81,0x81,0x01,0x21,0x81,0x80,0x70,0x47,
0x20,0x01,0x00,0x80,0x01,0x49,0x08,0x61,0x70,0x47,0x00,0x00,0x00,0x01,0x00,0x80,
0x01,0x49,0x48,0x61,0x70,0x47,0x00,0x00,0x00,0x01,0x00,0x80,0x01,0x49,0x04,0x20,
0x08,0x83,0x70,0x47,0x40,0x00,0x00,0x80,0x03,0x49,0x08,0x89,0x40,0x07,0xFC,0xD5,
0x00,0x20,0x08,0x81,0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x80,0x01,0x49,0x04,0x20,
0x08,0x83,0x70,0x47,0x40,0x00,0x00,0x80,0x01,0x21,0xC9,0x07,0x88,0x62,0x70,0x47,
0x01,0x21,0xC9,0x07,0x48,0x61,0x70,0x47,0x78,0x47,0x00,0x00,0x10,0x40,0x2D,0xE9,
0x45,0xFF,0xFF,0xEB,0x00,0x10,0xA0,0xE3,0x00,0x10,0x80,0xE5,0x10,0x40,0xBD,0xE8,
0x1E,0xFF,0x2F,0xE1,0x19,0x05,0x00,0xC0,0xE9,0x04,0x00,0xC0,0xB9,0x05,0x00,0xC0,
0x05,0x06,0x00,0xC0,0x7D,0x05,0x00,0xC0,0x35,0x05,0x00,0xC0,0xF1,0x04,0x00,0xC0,
0xD9,0x05,0x00,0xC0,0x19,0x06,0x00,0xC0,0x91,0x05,0x00,0xC0,0x0D,0x05,0x00,0xC0,
0xE1,0x04,0x00,0xC0,0xA9,0x05,0x00,0xC0,0xF1,0x05,0x00,0xC0,0x71,0x05,0x00,0xC0,
0xF5,0x04,0x00,0xC0,0xD5,0x04,0x00,0xC0,0x99,0x05,0x00,0xC0,0xE5,0x05,0x00,0xC0,
0x65,0x05,0x00,0xC0,0x3D,0x05,0x00,0xC0,0xE5,0x04,0x00,0xC0,0x3D,0x05,0x00,0xC0,
0x3D,0x05,0x00,0xC0,0x3D,0x05,0x00,0xC0,0x2D,0x05,0x00,0xC0,0xED,0x04,0x00,0xC0,
0xCD,0x05,0x00,0xC0,0x11,0x06,0x00,0xC0,0x89,0x05,0x00,0xC0};

337
wifi/wlan/host.h Normal file
View File

@ -0,0 +1,337 @@
/** @file host.h
*
* @brief This file contains definitions of WLAN commands.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/********************************************************
Change log:
10/11/05: Add Doxygen format comments
01/11/06: Remove assoc response codes; full IEEE assoc resp now returned
04/06/06: Add TSPEC, queue metrics, and MSDU expiry support
04/10/06: Add power_adapt_cfg_ext command
04/18/06: Remove old Subscrive Event and add new Subscribe Event
implementation through generic hostcmd API
05/03/06: Add auto_tx hostcmd
05/04/06: Add IBSS coalescing related new hostcmd and event
08/28/06: Add LED_CTRL hostcmd
********************************************************/
#ifndef _HOST_H_
#define _HOST_H_
/** PUBLIC DEFINITIONS */
#define DEFAULT_AD_HOC_CHANNEL 6
#define DEFAULT_AD_HOC_CHANNEL_A 36
/** IEEE 802.11 OIDs */
#define OID_802_11_INFRASTRUCTURE_MODE 0x00008001
#define OID_802_11_FRAGMENTATION_THRESHOLD 0x00008002
#define OID_802_11_RTS_THRESHOLD 0x00008003
#define OID_802_11_ADD_WEP 0x00008004
#define OID_802_11_REMOVE_WEP 0x00008005
#define OID_802_11_TX_RETRYCOUNT 0x00008006
#define OID_802_11D_ENABLE 0x00008007
#define HostCmd_OPTION_WAITFORRSP 0x0002
/** Host Command ID */
#define HostCmd_CMD_GET_HW_SPEC 0x0003
#define HostCmd_CMD_802_11_RESET 0x0005
#define HostCmd_CMD_802_11_SCAN 0x0006
#define HostCmd_CMD_802_11_GET_LOG 0x000b
#define HostCmd_CMD_MAC_MULTICAST_ADR 0x0010
#define HostCmd_CMD_802_11_EEPROM_ACCESS 0x0059
#define HostCmd_CMD_802_11_ASSOCIATE 0x0012
#define HostCmd_CMD_802_11_SET_WEP 0x0013
#define HostCmd_CMD_802_11_SNMP_MIB 0x0016
#define HostCmd_CMD_MAC_REG_ACCESS 0x0019
#define HostCmd_CMD_BBP_REG_ACCESS 0x001a
#define HostCmd_CMD_RF_REG_ACCESS 0x001b
#define HostCmd_CMD_802_11_RADIO_CONTROL 0x001c
#define HostCmd_CMD_802_11_RF_CHANNEL 0x001d
#define HostCmd_CMD_802_11_RF_TX_POWER 0x001e
#define HostCmd_CMD_802_11_RSSI 0x001f
#define HostCmd_CMD_802_11_RF_ANTENNA 0x0020
#define HostCmd_CMD_802_11_PS_MODE 0x0021
#define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024
#define HostCmd_CMD_MAC_CONTROL 0x0028
#define HostCmd_CMD_802_11_AD_HOC_START 0x002b
#define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c
#define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e
#define HostCmd_CMD_802_11_DEEP_SLEEP 0x003e
#define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040
#define HostCmd_CMD_802_11_HOST_SLEEP_CFG 0x0043
#define HostCmd_CMD_802_11_WAKEUP_CONFIRM 0x0044
#define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D
#define HostCmd_CMD_802_11_EEPROM_ACCESS 0x0059
#define HostCmd_CMD_GSPI_BUS_CONFIG 0x005A
#define HostCmd_CMD_802_11_BAND_CONFIG 0x0058
#define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b
#define HostCmd_CMD_802_11_SLEEP_PARAMS 0x0066
#define HostCmd_CMD_802_11_INACTIVITY_TIMEOUT 0x0067
#define HostCmd_CMD_802_11_SLEEP_PERIOD 0x0068
#define HostCmd_CMD_802_11_BCA_CONFIG_TIMESHARE 0x0069
#define HostCmd_CMD_802_11_BG_SCAN_CONFIG 0x006b
#define HostCmd_CMD_802_11_BG_SCAN_QUERY 0x006c
#define HostCmd_CMD_802_11_CAL_DATA_EXT 0x006d
#define HostCmd_CMD_WMM_ADDTS_REQ 0x006E
#define HostCmd_CMD_WMM_DELTS_REQ 0x006F
#define HostCmd_CMD_WMM_QUEUE_CONFIG 0x0070
#define HostCmd_CMD_WMM_GET_STATUS 0x0071
#define HostCmd_CMD_802_11_TPC_CFG 0x0072
#define HostCmd_CMD_802_11_FW_WAKE_METHOD 0x0074
#define HostCmd_CMD_802_11_LED_CONTROL 0x004e
#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT 0x0075
#define HostCmd_CMD_802_11_RATE_ADAPT_RATESET 0x0076
#define HostCmd_CMD_802_11_CRYPTO 0x0078
#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f
#define HostCmd_CMD_802_11_POWER_ADAPT_CFG_EXT 0x007e
#define HostCmd_CMD_GET_TSF 0x0080
#define HostCmd_CMD_WMM_QUEUE_STATS 0x0081
#define HostCmd_CMD_802_11_AUTO_TX 0x0082
#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
#define HostCmd_CMD_MEM_ACCESS 0x0086
#ifdef MFG_CMD_SUPPORT
#define HostCmd_CMD_MFG_COMMAND 0x0089
#define HostCmd_RET_MFG_COMMAND 0x8089
#endif
#define HostCmd_CMD_TX_PKT_STATS 0x008d
#define HostCmd_CMD_802_11_LDO_CONFIG 0x0096
#define HostCmd_CMD_VERSION_EXT 0x0097
/* For the IEEE Power Save */
#define HostCmd_SubCmd_Enter_PS 0x0030
#define HostCmd_SubCmd_Exit_PS 0x0031
#define HostCmd_SubCmd_Sleep_Confirmed 0x0034
#define HostCmd_SubCmd_Full_PowerDown 0x0035
#define HostCmd_SubCmd_Full_PowerUp 0x0036
/* Command RET code, MSB is set to 1 */
#define HostCmd_RET_HW_SPEC_INFO 0x8003
#define HostCmd_RET_802_11_RESET 0x8005
#define HostCmd_RET_802_11_SCAN 0x8006
#define HostCmd_RET_802_11_GET_LOG 0x800b
#define HostCmd_RET_MAC_CONTROL 0x8028
#define HostCmd_RET_MAC_MULTICAST_ADR 0x8010
#define HostCmd_RET_802_11_DEAUTHENTICATE 0x8024
#define HostCmd_RET_802_11_ASSOCIATE 0x8012
#define HostCmd_RET_802_11_SET_WEP 0x8013
#define HostCmd_RET_802_3_STAT 0x8015
#define HostCmd_RET_802_11_SNMP_MIB 0x8016
#define HostCmd_RET_MAC_REG_ACCESS 0x8019
#define HostCmd_RET_BBP_REG_ACCESS 0x801a
#define HostCmd_RET_RF_REG_ACCESS 0x801b
#define HostCmd_RET_802_11_RADIO_CONTROL 0x801c
#define HostCmd_RET_802_11_RF_CHANNEL 0x801d
#define HostCmd_RET_802_11_RSSI 0x801f
#define HostCmd_RET_802_11_RF_TX_POWER 0x801e
#define HostCmd_RET_802_11_RF_ANTENNA 0x8020
#define HostCmd_RET_802_11_PS_MODE 0x8021
#define HostCmd_RET_802_11_AD_HOC_START 0x802B
#define HostCmd_RET_802_11_AD_HOC_JOIN 0x802C
#define HostCmd_RET_802_11_KEY_MATERIAL 0x805e
#define HostCmd_ACT_SET 0x0001
#define HostCmd_ACT_GET 0x0000
#define HostCmd_RET_802_11_AD_HOC_STOP 0x8040
#define HostCmd_RET_802_11_HOST_SLEEP_CFG 0x8043
#define HostCmd_RET_802_11_WAKEUP_CONFIRM 0x8044
#define HostCmd_RET_802_11_MAC_ADDRESS 0x804D
#define HostCmd_RET_802_11_EEPROM_ACCESS 0x8059
#define HostCmd_RET_CMD_GSPI_BUS_CONFIG 0x805A
#define HostCmd_RET_802_11_BAND_CONFIG 0x8058
#define HostCmd_RET_802_11_SLEEP_PARAMS 0x8066
#define HostCmd_RET_802_11_INACTIVITY_TIMEOUT 0x8067
#define HostCmd_RET_802_11_SLEEP_PERIOD 0x8068
#define HostCmd_RET_802_11_BCA_CONFIG_TIMESHARE 0x8069
#define HostCmd_RET_802_11D_DOMAIN_INFO 0x805B
#define HostCmd_RET_802_11_BG_SCAN_CONFIG 0x806b
#define HostCmd_RET_802_11_BG_SCAN_QUERY 0x806c
#define HostCmd_RET_802_11_CAL_DATA_EXT 0x806d
#define HostCmd_RET_WMM_ADDTS_REQ 0x806E
#define HostCmd_RET_WMM_DELTS_REQ 0x806F
#define HostCmd_RET_WMM_QUEUE_CONFIG 0x8070
#define HostCmd_RET_WMM_GET_STATUS 0x8071
#define HostCmd_RET_802_11_TPC_CFG 0x8072
#define HostCmd_RET_802_11_LED_CONTROL 0x804e
#define HostCmd_RET_802_11_FW_WAKE_METHOD 0x8074
#define HostCmd_RET_802_11_SUBSCRIBE_EVENT 0x8075
#define HostCmd_RET_802_11_RATE_ADAPT_RATESET 0x8076
#define HostCmd_RET_802_11_CRYPTO 0x8078
#define HostCmd_RTE_802_11_TX_RATE_QUERY 0x807f
#define HostCmd_RET_GET_TSF 0x8080
#define HostCmd_RET_WMM_QUEUE_STATS 0x8081
#define HostCmd_RET_802_11_POWER_ADAPT_CFG_EXT 0x807e
#define HostCmd_RET_802_11_AUTO_TX 0x8082
#define HostCmd_RET_802_11_IBSS_COALESCING_STATUS 0x8083
#define HostCmd_RET_MEM_ACCESS 0x8086
#define HostCmd_RET_802_11_LDO_CONFIG 0x8096
#define HostCmd_RET_VERSION_EXT 0x8097
/** General Result Code*/
/* OK */
#define HostCmd_RESULT_OK 0x0000
/* Genenral error */
#define HostCmd_RESULT_ERROR 0x0001
/* Command is not valid */
#define HostCmd_RESULT_NOT_SUPPORT 0x0002
/* Command is pending */
#define HostCmd_RESULT_PENDING 0x0003
/* System is busy (command ignored) */
#define HostCmd_RESULT_BUSY 0x0004
/* Data buffer is not big enough */
#define HostCmd_RESULT_PARTIAL_DATA 0x0005
/* Definition of action or option for each command */
/* Define general purpose action */
#define HostCmd_ACT_GEN_READ 0x0000
#define HostCmd_ACT_GEN_WRITE 0x0001
#define HostCmd_ACT_GEN_GET 0x0000
#define HostCmd_ACT_GEN_SET 0x0001
#define HostCmd_ACT_GEN_REMOVE 0x0002
#define HostCmd_ACT_GEN_OFF 0x0000
#define HostCmd_ACT_GEN_ON 0x0001
/* Define action or option for HostCmd_CMD_802_11_SET_WEP */
#define HostCmd_ACT_ADD 0x0002
#define HostCmd_ACT_REMOVE 0x0004
#define HostCmd_TYPE_WEP_40_BIT 0x0001
#define HostCmd_TYPE_WEP_104_BIT 0x0002
#define HostCmd_WEP_KEY_INDEX_MASK 0x3fff
/* Define action or option for HostCmd_CMD_802_11_SCAN */
#define HostCmd_BSS_TYPE_BSS 0x0001
#define HostCmd_BSS_TYPE_IBSS 0x0002
#define HostCmd_BSS_TYPE_ANY 0x0003
/* Define action or option for HostCmd_CMD_802_11_SCAN */
#define HostCmd_SCAN_TYPE_ACTIVE 0x0000
#define HostCmd_SCAN_TYPE_PASSIVE 0x0001
/* Radio type definitions for the channel TLV */
#define HostCmd_SCAN_RADIO_TYPE_BG 0
#define HostCmd_SCAN_RADIO_TYPE_A 1
/* Define action or option for HostCmd_CMD_MAC_CONTROL */
#define HostCmd_ACT_MAC_RX_ON 0x0001
#define HostCmd_ACT_MAC_TX_ON 0x0002
#define HostCmd_ACT_MAC_LOOPBACK_ON 0x0004
#define HostCmd_ACT_MAC_WEP_ENABLE 0x0008
#define HostCmd_ACT_MAC_ETHERNETII_ENABLE 0x0010
#define HostCmd_ACT_MAC_PROMISCUOUS_ENABLE 0x0080
#define HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100
#define HostCmd_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400
#define HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON 0x2000
/* Define action or option or constant for HostCmd_CMD_MAC_MULTICAST_ADR */
#define HostCmd_SIZE_MAC_ADR 6
#define HostCmd_MAX_MCAST_ADRS 32
#define RADIO_ON 0x01
#define RADIO_OFF 0x00
/* Define action or option for CMD_802_11_RF_CHANNEL */
#define HostCmd_OPT_802_11_RF_CHANNEL_GET 0x00
#define HostCmd_OPT_802_11_RF_CHANNEL_SET 0x01
#define HostCmd_ACT_SET_RX 0x0001
#define HostCmd_ACT_SET_TX 0x0002
#define HostCmd_ACT_SET_BOTH 0x0003
#define HostCmd_ACT_GET_RX 0x0004
#define HostCmd_ACT_GET_TX 0x0008
#define HostCmd_ACT_GET_BOTH 0x000c
/** Card Event definition */
#define MACREG_INT_CODE_DUMMY_HOST_WAKEUP_SIGNAL 0x00000001
#define MACREG_INT_CODE_LINK_LOST_WITH_SCAN 0x00000002
#define MACREG_INT_CODE_LINK_LOST 0x00000003
#define MACREG_INT_CODE_LINK_SENSED 0x00000004
#define MACREG_INT_CODE_MIB_CHANGED 0x00000006
#define MACREG_INT_CODE_INIT_DONE 0x00000007
#define MACREG_INT_CODE_DEAUTHENTICATED 0x00000008
#define MACREG_INT_CODE_DISASSOCIATED 0x00000009
#define MACREG_INT_CODE_PS_AWAKE 0x0000000a
#define MACREG_INT_CODE_PS_SLEEP 0x0000000b
#define MACREG_INT_CODE_MIC_ERR_MULTICAST 0x0000000d
#define MACREG_INT_CODE_MIC_ERR_UNICAST 0x0000000e
#define MACREG_INT_CODE_WM_AWAKE 0x0000000f
#define MACREG_INT_CODE_DEEP_SLEEP_AWAKE 0x00000010
#define MACREG_INT_CODE_ADHOC_BCN_LOST 0x00000011
#define MACREG_INT_CODE_HOST_SLEEP_AWAKE 0x00000012
#define MACREG_INT_CODE_WMM_STATUS_CHANGE 0x00000017
#define MACREG_INT_CODE_BG_SCAN_REPORT 0x00000018
#define MACREG_INT_CODE_RSSI_LOW 0x00000019
#define MACREG_INT_CODE_SNR_LOW 0x0000001a
#define MACREG_INT_CODE_MAX_FAIL 0x0000001b
#define MACREG_INT_CODE_RSSI_HIGH 0x0000001c
#define MACREG_INT_CODE_SNR_HIGH 0x0000001d
#define MACREG_INT_CODE_IBSS_COALESCED 0x0000001e
/* Define bitmap conditions for HOST_SLEEP_CFG */
#define HOST_SLEEP_CFG_CANCEL 0xffffffff
#endif /* _HOST_H_ */

1073
wifi/wlan/hostcmd.h Normal file

File diff suppressed because it is too large Load Diff

44
wifi/wlan/include.h Normal file
View File

@ -0,0 +1,44 @@
/** @file include.h
*
* @brief This file contains all the necessary include file.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/********************************************************
Change log:
10/11/05: Add Doxygen format comments
01/11/06: Conditional include file removal/addition
01/30/06: Add kernel 2.6 support
********************************************************/
#ifndef _INCLUDE_H_
#define _INCLUDE_H_
#include "..\os\os_headers.h"
#include "wlan_debug.h"
#include "wlan_types.h"
#include "wlan_defs.h"
#include "wlan_thread.h" //dennis
#include "wlan_wmm.h"
#include "wlan_11d.h"
#include "host.h"
#include "hostcmd.h"
#include "wlan_scan.h"
#include "wlan_join.h"
#include "wlan_dev.h"
#include "sbi.h"
#include "..\spi\gspi_io.h"
#include "wlan_wext.h"
#include "wlan_decl.h"
#endif /* _INCLUDE_H_ */

0
wifi/wlan/iw_tool.c Normal file
View File

153
wifi/wlan/rt_wlan_dev.c Normal file
View File

@ -0,0 +1,153 @@
#include <rtthread.h>
#include <netif/ethernetif.h>
#include "rt_wlan_dev.h"
#include "wlan_dev.h"
#include <rtthread.h>
#define WLAN_DEV 1
#if WLAN_DEV
#define DEV_TRACE rt_kprintf
#else
#define DEV_TRACE(...)
#endif
#define MAX_ADDR_LEN 6
static struct rt_wlan_dev wlan_eth;
extern int wlan_init_module(struct rt_wlan_dev * wlan_dev);
/* RT-Thread Device Interface */
/* initialize the interface */
static rt_err_t rt_wlan_dev_init(rt_device_t dev)
{
return RT_EOK;
}
static rt_err_t rt_wlan_dev_open(rt_device_t dev, rt_uint16_t oflag)
{
rt_err_t error=RT_EOK;
if(dev==RT_NULL||dev->user_data==RT_NULL)
{
error=-RT_EEMPTY;
goto done;
}
done:
return error;
}
static rt_err_t rt_wlan_dev_close(rt_device_t dev)
{
return RT_EOK;
}
static rt_size_t rt_wlan_dev_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
static rt_size_t rt_wlan_dev_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
rt_err_t rt_wlan_dev_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
rt_err_t error=RT_EOK;
struct rt_wlan_dev * wlan_dev;
wlan_private *priv = NULL;
struct WLAN_IO_CTRL_PAR * par;
char addressbuf[6]={0xff,0xff,0xff,0xff,0xff,0xff};
if(dev==RT_NULL||dev->user_data==RT_NULL)
{
error=-RT_EEMPTY;
goto done;
}
wlan_dev=dev->user_data;
priv=wlan_dev->priv;
switch (cmd)
{
case NIOCTL_GADDR:
/* get mac address */
//if (args) rt_memcpy(args, dm9000_device.dev_addr, 6);
//else return -RT_ERROR;
if(rt_memcmp(priv->adapter->CurrentAddr,addressbuf,6)==0)
{
error=-RT_ERROR;
break;
}
else{
rt_memcpy((u8*)args,priv->adapter->CurrentAddr,6);
}
break;
default :
break;
}
done:
return error;
}
/* ethernet device interface */
/* transmit packet. */
extern void
netif_set_addr(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
struct ip_addr *gw);
int wlan_set_addr(rt_uint32_t ipaddr,rt_uint32_t mask,rt_uint32_t gwaddr)
{
struct ip_addr myip,gwip,maskip;
/* myip 192.168.1.66->C0,A8,1,42*/
myip.addr=ipaddr;
/*gwip 192.168.1.1->C0,A8,1,1 */
gwip.addr=gwaddr;
/*maskip255.255.255.0,FF,FF,FF,0*/
maskip.addr=mask;
netif_set_addr(wlan_eth.parent.netif,&myip,&maskip,&gwip);
}
extern rt_err_t rt_wlan_dev_tx( rt_device_t dev, struct pbuf* p);
extern struct pbuf *rt_wlan_dev_rx(rt_device_t dev);
int rt_hw_wlan_dev_init(void)
{
rt_int32_t value=0;
rt_err_t error=RT_EOK;
/*
* SRAM Tx/Rx pointer automatically return to start address,
* Packet Transmitted, Packet Received
*/
wlan_eth.parent.parent.init = rt_wlan_dev_init;
wlan_eth.parent.parent.open = rt_wlan_dev_open;
wlan_eth.parent.parent.close = rt_wlan_dev_close;
wlan_eth.parent.parent.read = rt_wlan_dev_read;
wlan_eth.parent.parent.write = rt_wlan_dev_write;
wlan_eth.parent.parent.control = rt_wlan_dev_control;
wlan_eth.parent.parent.user_data =(void *)&wlan_eth ;
wlan_eth.parent.eth_rx = rt_wlan_dev_rx;
wlan_eth.parent.eth_tx = rt_wlan_dev_tx;
value=gspihost_init();
if(value<0)
{
error=-RT_ERROR;
goto done;
}
value=wlan_init_module(&wlan_eth);
if(value<0)
{
error=-RT_ERROR;
goto done;
}
eth_device_init(&(wlan_eth.parent), "wlan_eth0");
done:
return error;
}

32
wifi/wlan/rt_wlan_dev.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef __RT_WLAN_DEV_H__
#define __RT_WLAN_DEV_H__
#include <netif/ethernetif.h>
#include "lwipopts.h"
#include "wlan_types.h"
#define WLANMACADDRESSLENGTH (6)
//#define CMD
struct WLAN_IO_CTRL_PAR
{
/** parameters Header */
u16 inputlength;
u16 outputlength;
/** Command Body */
union
{
u8 MacAdd[MRVDRV_ETH_ADDR_LEN];
} params;
};
struct rt_wlan_dev
{
/* inherit from ethernet device */
struct eth_device parent;
void * priv ;
unsigned int irq;
char name[16];
char dev_addr[6];
};
int rt_hw_wlan_dev_init(void);
#endif

106
wifi/wlan/sbi.h Normal file
View File

@ -0,0 +1,106 @@
/** @file sbi.h
*
* @brief This file contains IF layer definitions.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
10/11/05: Add Doxygen format comments
01/05/06: Add kernel 2.6.x support
********************************************************/
#ifndef _SBI_H_
#define _SBI_H_
/**Bit Definition*/
#define B_BIT_0 0x01
#define B_BIT_1 0x02
#define B_BIT_2 0x04
#define B_BIT_3 0x08
#define B_BIT_4 0x10
#define B_BIT_5 0x20
#define B_BIT_6 0x40
#define B_BIT_7 0x80
#define B_BIT_8 0x100
#define B_BIT_9 0X200
#define B_BIT_10 0x400
/** INT Status Bit Definition*/
#define HIS_RxUpLdRdy B_BIT_0
#define HIS_TxDnLdRdy B_BIT_1
#define HIS_CmdDnLdRdy B_BIT_2
#define HIS_CardEvent B_BIT_3
#define HIS_CmdUpLdRdy B_BIT_4
#define HIS_WrFifoOvrflow B_BIT_5
#define HIS_RdFifoUndrflow B_BIT_6
#define HIS_WlanReady B_BIT_7
#define HIM_DISABLE 0xff
#define HIM_ENABLE 0x03
#define FIRMWARE_READY 0xfedc
#ifndef DEV_NAME_LEN
#define DEV_NAME_LEN 32
#endif
#define MAXKEYLEN 13
/* The number of times to try when polling for status bits */
#define MAX_POLL_TRIES 100
/* The number of times to try when waiting for downloaded firmware to
become active. (polling the scratch register). */
#define MAX_FIRMWARE_POLL_TRIES 100
#define FIRMWARE_TRANSFER_NBLOCK 2
#define SBI_EVENT_CAUSE_SHIFT 3
#define GSPI_BUS_DELAY_TIME_MODE 1
#define GSPI_BUS_DELAY_CLK_MODE 0
typedef enum _mv_sd_type
{
MVSD_DAT = 0,
MVSD_CMD = 1,
MVSD_EVENT = 3
} mv_sd_type;
/** Function Prototype Declaration */
typedef wlan_private *(*wlan_notifier_fn_add) (void *dev_id);
typedef int (*wlan_notifier_fn_remove) (void *dev_id);
//typedef IRQ_RET_TYPE(*isr_notifier_fn_t) (s32 irq, void *dev_id,struct pt_regs * reg);
typedef IRQ_RET_TYPE(*isr_notifier_fn_t) (s32 irq, void *dev_id,void* reg);
typedef IRQ_RET_TYPE(*handler_fn_t) (s32 irq, void *dev_id, void *);
/* Probe and Check if the card is present*/
int sbi_probe_card(void *card);
int sbi_register_dev(wlan_private * priv);
int sbi_disable_host_int(wlan_private * priv);
int sbi_get_int_status(wlan_private * priv, u8 *);
int sbi_register(wlan_notifier_fn_add, wlan_notifier_fn_remove, void *);
void sbi_unregister(void);
int sbi_prog_firmware(wlan_private *);
//int sbi_verify_fw_download(wlan_private *);
int sbi_prog_helper(wlan_private *);
int sbi_prog_firmware_w_helper(wlan_private *);
int sbi_read_event_cause(wlan_private *);
//int sbi_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
int sbi_card_to_host(wlan_private * priv, u32 type, u32 * nb, u8 * payload,
u16 npayload);
int sbi_enable_host_int(wlan_private *);
int sbi_exit_deep_sleep(wlan_private *);
int sbi_reset_deepsleep_wakeup(wlan_private *);
#ifdef ENABLE_PM
int sbi_suspend(wlan_private *);
int sbi_resume(wlan_private *);
#endif
int sbi_get_cis_info(wlan_private * priv);
#endif /* _SBI_H */

891
wifi/wlan/wlan_11d.c Normal file
View File

@ -0,0 +1,891 @@
/** @file wlan_11d.c
* @brief This file contains functions for 802.11D.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
10/04/05: Add Doxygen format comments
********************************************************/
#include "include.h"
/********************************************************
Local Variables
********************************************************/
#define TX_PWR_DEFAULT 10
static region_code_mapping_t region_code_mapping[] = {
{"US ", 0x10}, /* US FCC */
{"CA ", 0x20}, /* IC Canada */
{"SG ", 0x10}, /* Singapore */
{"EU ", 0x30}, /* ETSI */
{"AU ", 0x30}, /* Australia */
{"KR ", 0x30}, /* Republic Of Korea */
{"ES ", 0x31}, /* Spain */
{"FR ", 0x32}, /* France */
{"JP ", 0x40}, /* Japan */
{"JP ", 0x41}, /* Japan */
};
/********************************************************
Global Variables
********************************************************/
/* Following 2 structure defines the supported channels */
CHANNEL_FREQ_POWER channel_freq_power_UN_BG[] = {
{1, 2412, TX_PWR_DEFAULT},
{2, 2417, TX_PWR_DEFAULT},
{3, 2422, TX_PWR_DEFAULT},
{4, 2427, TX_PWR_DEFAULT},
{5, 2432, TX_PWR_DEFAULT},
{6, 2437, TX_PWR_DEFAULT},
{7, 2442, TX_PWR_DEFAULT},
{8, 2447, TX_PWR_DEFAULT},
{9, 2452, TX_PWR_DEFAULT},
{10, 2457, TX_PWR_DEFAULT},
{11, 2462, TX_PWR_DEFAULT},
{12, 2467, TX_PWR_DEFAULT},
{13, 2472, TX_PWR_DEFAULT},
{14, 2484, TX_PWR_DEFAULT}
};
CHANNEL_FREQ_POWER channel_freq_power_UN_AJ[] = {
{8, 5040, TX_PWR_DEFAULT},
{12, 5060, TX_PWR_DEFAULT},
{16, 5080, TX_PWR_DEFAULT},
{34, 5170, TX_PWR_DEFAULT},
{38, 5190, TX_PWR_DEFAULT},
{42, 5210, TX_PWR_DEFAULT},
{46, 5230, TX_PWR_DEFAULT},
{36, 5180, TX_PWR_DEFAULT},
{40, 5200, TX_PWR_DEFAULT},
{44, 5220, TX_PWR_DEFAULT},
{48, 5240, TX_PWR_DEFAULT},
{52, 5260, TX_PWR_DEFAULT},
{56, 5280, TX_PWR_DEFAULT},
{60, 5300, TX_PWR_DEFAULT},
{64, 5320, TX_PWR_DEFAULT},
{100, 5500, TX_PWR_DEFAULT},
{104, 5520, TX_PWR_DEFAULT},
{108, 5540, TX_PWR_DEFAULT},
{112, 5560, TX_PWR_DEFAULT},
{116, 5580, TX_PWR_DEFAULT},
{120, 5600, TX_PWR_DEFAULT},
{124, 5620, TX_PWR_DEFAULT},
{128, 5640, TX_PWR_DEFAULT},
{132, 5660, TX_PWR_DEFAULT},
{136, 5680, TX_PWR_DEFAULT},
{140, 5700, TX_PWR_DEFAULT},
{149, 5745, TX_PWR_DEFAULT},
{153, 5765, TX_PWR_DEFAULT},
{157, 5785, TX_PWR_DEFAULT},
{161, 5805, TX_PWR_DEFAULT},
{165, 5825, TX_PWR_DEFAULT},
/* {240, 4920, TX_PWR_DEFAULT},
{244, 4940, TX_PWR_DEFAULT},
{248, 4960, TX_PWR_DEFAULT},
{252, 4980, TX_PWR_DEFAULT},
channels for 11J JP 10M channel gap */
};
extern CHANNEL_FREQ_POWER *wlan_get_region_cfp_table(u8 region,
u8 band, int *cfp_no);
/********************************************************
Local Functions
********************************************************/
/**
* @brief This function convert Region string to code integer
* @param region region string
* @return region id
*/
static u8
wlan_region_2_code(s8 * region)
{
u8 i;
u8 size = sizeof(region_code_mapping) / sizeof(region_code_mapping_t);
for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++)
region[i] = toupper(region[i]);
for (i = 0; i < size; i++) {
if (!memcmp(region, region_code_mapping[i].region, COUNTRY_CODE_LEN))
return (region_code_mapping[i].code);
}
/* default is US */
return (region_code_mapping[0].code);
}
/**
* @brief This function converts interger code to region string
* @param code region code
* @return region string
*/
static u8 *
wlan_code_2_region(u8 code)
{
u8 i;
u8 size = sizeof(region_code_mapping) / sizeof(region_code_mapping_t);
for (i = 0; i < size; i++) {
if (region_code_mapping[i].code == code)
return (region_code_mapping[i].region);
}
/* default is US */
return (region_code_mapping[0].region);
}
/**
* @brief This function finds the NoOfChan-th chan after the firstChan
* @param band band
* @param firstChan first channel number
* @param NoOfChan number of channels
* @return the NoOfChan-th chan number
*/
static BOOLEAN
wlan_get_chan_11d(u8 band, u8 firstChan, u8 NoOfChan, u8 * chan)
/*find the NoOfChan-th chan after the firstChan*/
{
u8 i;
CHANNEL_FREQ_POWER *cfp;
u8 cfp_no;
// ENTER();
{
cfp = channel_freq_power_UN_BG;
cfp_no = sizeof(channel_freq_power_UN_BG) /
sizeof(CHANNEL_FREQ_POWER);
}
for (i = 0; i < cfp_no; i++) {
if ((cfp + i)->Channel == firstChan) {
rt_kprintf("firstChan found\n");
break;
}
}
if (i < cfp_no) {
/*if beyond the boundary */
if (i + NoOfChan < cfp_no) {
*chan = (cfp + i + NoOfChan)->Channel;
return TRUE;
}
}
// LEAVE();
return FALSE;
}
/**
* @brief This function Checks if chan txpwr is learned from AP/IBSS
* @param chan chan number
* @param parsed_region_chan pointer to parsed_region_chan_11d_t
* @return TRUE; FALSE
*/
BOOLEAN
wlan_channel_known_11d(u8 chan, parsed_region_chan_11d_t * parsed_region_chan)
{
chan_power_11d_t *chanPwr = parsed_region_chan->chanPwr;
u8 NoOfChan = parsed_region_chan->NoOfChan;
u8 i = 0;
ENTER();
for (i = 0; i < NoOfChan; i++) {
if (chan == chanPwr[i].chan) {
wlan_debug3( "11D: Found Chan:%d\n", chan);
LEAVE();
return TRUE;
}
}
LEAVE();
return FALSE;
}
/********************************************************
Global Functions
********************************************************/
/**
* @brief This function Converts chan to frequency
* @param chan channel number
* @param band band
* @return channel frequency
*/
u32
chan_2_freq(u8 chan, u8 band)
{
CHANNEL_FREQ_POWER *cf;
u16 cnt;
u16 i;
u32 freq = 0;
// ENTER();
{
cf = channel_freq_power_UN_BG;
cnt = sizeof(channel_freq_power_UN_BG) / sizeof(CHANNEL_FREQ_POWER);
}
for (i = 0; i < cnt; i++) {
if (chan == cf[i].Channel)
freq = cf[i].Freq;
}
// LEAVE();
return freq;
}
/**
* @brief This function generates domaininfo from parsed_region_chan
* @param parsed_region_chan pointer to parsed_region_chan_11d_t
* @param domaininfo pointer to wlan_802_11d_domain_reg_t
* @return WLAN_STATUS_SUCCESS
*/
int
wlan_generate_domain_info_11d(parsed_region_chan_11d_t * parsed_region_chan,
wlan_802_11d_domain_reg_t * domaininfo)
{
u8 NoOfSubband = 0;
u8 NoOfChan = parsed_region_chan->NoOfChan;
u8 NoOfParsedChan = 0;
u8 firstChan = 0, nextChan = 0, maxPwr = 0;
u8 i, flag = 0;
ENTER();
memcpy(domaininfo->CountryCode, parsed_region_chan->CountryCode,COUNTRY_CODE_LEN);
wlan_debug3("11D:NoOfChan=%d\n", NoOfChan);
// HEXDUMP("11D:parsed_region_chan:", (char *) parsed_region_chan,sizeof(parsed_region_chan_11d_t));
for (i = 0; i < NoOfChan; i++) {
if (!flag) {
flag = 1;
nextChan = firstChan = parsed_region_chan->chanPwr[i].chan;
maxPwr = parsed_region_chan->chanPwr[i].pwr;
NoOfParsedChan = 1;
continue;
}
if (parsed_region_chan->chanPwr[i].chan == nextChan + 1 &&
parsed_region_chan->chanPwr[i].pwr == maxPwr) {
nextChan++;
NoOfParsedChan++;
} else {
domaininfo->Subband[NoOfSubband].FirstChan = firstChan;
domaininfo->Subband[NoOfSubband].NoOfChan = NoOfParsedChan;
domaininfo->Subband[NoOfSubband].MaxTxPwr = maxPwr;
NoOfSubband++;
NoOfParsedChan = 1;
nextChan = firstChan = parsed_region_chan->chanPwr[i].chan;
maxPwr = parsed_region_chan->chanPwr[i].pwr;
}
}
if (flag) {
domaininfo->Subband[NoOfSubband].FirstChan = firstChan;
domaininfo->Subband[NoOfSubband].NoOfChan = NoOfParsedChan;
domaininfo->Subband[NoOfSubband].MaxTxPwr = maxPwr;
NoOfSubband++;
}
domaininfo->NoOfSubband = NoOfSubband;
wlan_debug3("NoOfSubband=%x\n", domaininfo->NoOfSubband);
// HEXDUMP("11D:domaininfo:", (char *) domaininfo,
// COUNTRY_CODE_LEN + 1 +
// sizeof(IEEEtypes_SubbandSet_t) * NoOfSubband);
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function generates parsed_region_chan from Domain Info learned from AP/IBSS
* @param region_chan pointer to REGION_CHANNEL
* @param *parsed_region_chan pointer to parsed_region_chan_11d_t
* @return N/A
*/
void wlan_generate_parsed_region_chan_11d(REGION_CHANNEL * region_chan,
parsed_region_chan_11d_t *
parsed_region_chan)
{
u8 i;
CHANNEL_FREQ_POWER *cfp;
ENTER();
if (region_chan == NULL) {
wlan_debug3("11D: region_chan is NULL\n");
return;
}
cfp = region_chan->CFP;
if (cfp == NULL) {
wlan_debug3( "11D: cfp equal NULL \n");
return;
}
parsed_region_chan->band = region_chan->Band;
parsed_region_chan->region = region_chan->Region;
memcpy(parsed_region_chan->CountryCode,
wlan_code_2_region(region_chan->Region), COUNTRY_CODE_LEN);
wlan_debug3("11D: region[0x%x] band[%d]\n", parsed_region_chan->region,
parsed_region_chan->band);
for (i = 0; i < region_chan->NrCFP; i++, cfp++) {
parsed_region_chan->chanPwr[i].chan = cfp->Channel;
parsed_region_chan->chanPwr[i].pwr = cfp->MaxTxPower;
wlan_debug3("11D: Chan[%d] Pwr[%d]\n",
parsed_region_chan->chanPwr[i].chan,
parsed_region_chan->chanPwr[i].pwr);
}
parsed_region_chan->NoOfChan = region_chan->NrCFP;
wlan_debug3("11D: NoOfChan[%d]\n", parsed_region_chan->NoOfChan);
LEAVE();
return;
}
/**
* @brief generate parsed_region_chan from Domain Info learned from AP/IBSS
* @param region region ID
* @param band band
* @param chan chan
* @return TRUE;FALSE
*/
BOOLEAN
wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan)
{
CHANNEL_FREQ_POWER *cfp;
int cfp_no;
u8 idx;
ENTER();
if ((cfp = wlan_get_region_cfp_table(region, band, &cfp_no)) == NULL) {
return FALSE;
}
for (idx = 0; idx < cfp_no; idx++) {
if (chan == (cfp + idx)->Channel) {
/* If Mrvl Chip Supported? */
if ((cfp + idx)->Unsupported) {
return FALSE;
} else {
return TRUE;
}
}
}
/*chan is not in the region table */
LEAVE();
return FALSE;
}
/**
* @brief This function checks if chan txpwr is learned from AP/IBSS
* @param chan chan number
* @param parsed_region_chan pointer to parsed_region_chan_11d_t
* @return WLAN_STATUS_SUCCESS
*/
int
wlan_parse_domain_info_11d(IEEEtypes_CountryInfoFullSet_t * CountryInfo,
u8 band,
parsed_region_chan_11d_t * parsed_region_chan)
{
u8 NoOfSubband, NoOfChan;
u8 lastChan, firstChan, curChan;
u8 region;
u8 idx = 0; /*chan index in parsed_region_chan */
u8 j, i;
ENTER();
/*Validation Rules:
1. Valid Region Code
2. First Chan increment
3. Channel range no overlap
4. Channel is valid?
5. Channel is supported by Region?
6. Others
*/
// HEXDUMP("CountryInfo:", (s8 *) CountryInfo, 30);
if ((*(CountryInfo->CountryCode)) == 0 ||
(CountryInfo->Len <= COUNTRY_CODE_LEN)) {
/* No region Info or Wrong region info: treat as No 11D info */
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/*Step1: check region_code */
parsed_region_chan->region = region =
wlan_region_2_code(CountryInfo->CountryCode);
wlan_debug3( "regioncode=%x\n", (u8) parsed_region_chan->region);
parsed_region_chan->band = band;
memcpy(parsed_region_chan->CountryCode, CountryInfo->CountryCode,
COUNTRY_CODE_LEN);
NoOfSubband = (CountryInfo->Len - COUNTRY_CODE_LEN) /
sizeof(IEEEtypes_SubbandSet_t);
for (j = 0, lastChan = 0; j < NoOfSubband; j++) {
if (CountryInfo->Subband[j].FirstChan <= lastChan) {
/*Step2&3. Check First Chan Num increment and no overlap */
wlan_debug3("11D: Chan[%d>%d] Overlap\n",
CountryInfo->Subband[j].FirstChan, lastChan);
continue;
}
firstChan = CountryInfo->Subband[j].FirstChan;
NoOfChan = CountryInfo->Subband[j].NoOfChan;
for (i = 0; idx < MAX_NO_OF_CHAN && i < NoOfChan; i++) {
/*step4: channel is supported? */
if (wlan_get_chan_11d(band, firstChan, i, &curChan)
== FALSE) {
/* Chan is not found in UN table */
wlan_debug3("chan is not supported: %d \n", i);
break;
}
lastChan = curChan;
/*step5: We don't need to Check if curChan is supported by mrvl in region */
parsed_region_chan->chanPwr[idx].chan = curChan;
parsed_region_chan->chanPwr[idx].pwr =
CountryInfo->Subband[j].MaxTxPwr;
idx++;
}
/*Step6: Add other checking if any */
}
parsed_region_chan->NoOfChan = idx;
wlan_debug3("NoOfChan=%x\n", parsed_region_chan->NoOfChan);
// HEXDUMP("11D:parsed_region_chan:", (s8 *) parsed_region_chan,
// 2 + COUNTRY_CODE_LEN + sizeof(parsed_region_chan_11d_t) * idx);
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function calculates the scan type for channels
* @param chan chan number
* @param parsed_region_chan pointer to parsed_region_chan_11d_t
* @return PASSIVE if chan is unknown; ACTIVE if chan is known
*/
u8
wlan_get_scan_type_11d(u8 chan, parsed_region_chan_11d_t * parsed_region_chan)
{
u8 scan_type = HostCmd_SCAN_TYPE_PASSIVE;
ENTER();
if (wlan_channel_known_11d(chan, parsed_region_chan)) {
wlan_debug3( "11D: Found and do Active Scan\n");
scan_type = HostCmd_SCAN_TYPE_ACTIVE;
} else {
wlan_debug3( "11D: Not Find and do Passive Scan\n");
}
LEAVE();
return scan_type;
}
/**
* @brief This function gets if 11D is enabled
* @param priv pointer to wlan_private
* @return ENABLE_11D;DISABLE_11D
*/
state_11d_t
wlan_get_state_11d(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
wlan_802_11d_state_t *state = &Adapter->State11D;
return (state->Enable11D);
}
/**
* @brief initialize internal variable for 11D
* @param priv pointer to wlan_private
* @return N/A
*/
void
wlan_init_11d(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
wlan_802_11d_state_t *state = &Adapter->State11D;
state->Enable11D = DISABLE_11D;
memset(&(priv->adapter->parsed_region_chan), 0,
sizeof(parsed_region_chan_11d_t));
return;
}
/**
* @brief This function enable/disable 11D
* @param priv pointer to wlan_private
* @param flag enable/disable flag
* @return WLAN_STATUS_SUCCESS; WLAN_STATUS_FAILURE
*/
int
wlan_enable_11d(wlan_private * priv, state_11d_t flag)
{
wlan_adapter *Adapter = priv->adapter;
wlan_802_11d_state_t *state = &Adapter->State11D;
int ret;
state_11d_t enable = flag;
ENTER();
state->Enable11D = flag;
/* send cmd to FW to enable/disable 11D fucntion in FW */
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_SNMP_MIB,
HostCmd_ACT_SET,
HostCmd_OPTION_WAITFORRSP,
OID_802_11D_ENABLE, &enable);
if (ret) {
wlan_debug3( "11D: Fail to enable 11D \n");
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function sets DOMAIN INFO to FW
* @param priv pointer to wlan_private
* @return WLAN_STATUS_SUCCESS; WLAN_STATUS_FAILURE
*/
int
wlan_set_domain_info_11d(wlan_private * priv)
{
int ret;
if (!wlan_get_state_11d(priv)) {
wlan_debug3( "11D: dnld domain Info with 11d disabled\n");
return WLAN_STATUS_SUCCESS;
}
ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
HostCmd_ACT_GEN_SET,
HostCmd_OPTION_WAITFORRSP, 0, NULL);
if (ret) {
wlan_debug3( "11D: Fail to dnld domain Info\n");
}
LEAVE();
return ret;
}
/**
* @brief This function setups scan channels
* @param priv pointer to wlan_private
* @param band band
* @return WLAN_STATUS_SUCCESS
*/
int
wlan_set_universaltable(wlan_private * priv, u8 band)
{
wlan_adapter *Adapter = priv->adapter;
u16 size = sizeof(CHANNEL_FREQ_POWER);
u16 i = 0;
ENTER();
memset(Adapter->universal_channel, 0, sizeof(Adapter->universal_channel));
{
Adapter->universal_channel[i].NrCFP =
sizeof(channel_freq_power_UN_BG) / size;
wlan_debug3("11D: BG-band NrCFP=%d\n",
Adapter->universal_channel[i].NrCFP);
Adapter->universal_channel[i].CFP = channel_freq_power_UN_BG;
Adapter->universal_channel[i].Valid = TRUE;
Adapter->universal_channel[i].Region = UNIVERSAL_REGION_CODE;
Adapter->universal_channel[i].Band = band;
i++;
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function implements command CMD_802_11D_DOMAIN_INFO
* @param priv pointer to wlan_private
* @param cmd pointer to cmd buffer
* @param cmdno cmd ID
* @param CmdOption cmd action
* @return WLAN_STATUS_SUCCESS
*/
int wlan_cmd_802_11d_domain_info(wlan_private * priv,HostCmd_DS_COMMAND * cmd, u16 cmdno,u16 CmdOption)
{
HostCmd_DS_802_11D_DOMAIN_INFO *pDomainInfo = &cmd->params.domaininfo;
MrvlIEtypes_DomainParamSet_t *domain = &pDomainInfo->Domain;
wlan_adapter *Adapter = priv->adapter;
u8 NoOfSubband = Adapter->DomainReg.NoOfSubband;
ENTER();
wlan_debug3("NoOfSubband=%x\n", NoOfSubband);
cmd->Command = wlan_cpu_to_le16(cmdno);
pDomainInfo->Action = wlan_cpu_to_le16(CmdOption);
if (CmdOption == HostCmd_ACT_GET) {
cmd->Size = wlan_cpu_to_le16(sizeof(pDomainInfo->Action) + S_DS_GEN);
// HEXDUMP("11D: 802_11D_DOMAIN_INFO:", (u8 *) cmd, (int) (cmd->Size));
LEAVE();
return WLAN_STATUS_SUCCESS;
}
domain->Header.Type = wlan_cpu_to_le16(TLV_TYPE_DOMAIN);
memcpy(domain->CountryCode, Adapter->DomainReg.CountryCode,
sizeof(domain->CountryCode));
domain->Header.Len =
wlan_cpu_to_le16(NoOfSubband * sizeof(IEEEtypes_SubbandSet_t) +
sizeof(domain->CountryCode));
if (NoOfSubband) {
memcpy(domain->Subband, Adapter->DomainReg.Subband,
NoOfSubband * sizeof(IEEEtypes_SubbandSet_t));
cmd->Size = wlan_cpu_to_le16(sizeof(pDomainInfo->Action) +
domain->Header.Len +
sizeof(MrvlIEtypesHeader_t) + S_DS_GEN);
} else {
cmd->Size = wlan_cpu_to_le16(sizeof(pDomainInfo->Action) + S_DS_GEN);
}
// HEXDUMP("11D:802_11D_DOMAIN_INFO:", (u8 *) cmd, (int) (cmd->Size));
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function implements private cmd: enable/disable 11D
* @param priv pointer to wlan_private
* @param wrq pointer to user data
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int wlan_cmd_enable_11d(wlan_private * priv, void*wrq)
{
#if 0
int data = 0;
int *val;
wlan_adapter *Adapter = priv->adapter;
ENTER();
data = *((int *) (wrq->u.name + SUBCMD_OFFSET));
wlan_debug3("Enable 11D: %s\n",
(data == CMD_ENABLED) ? "Enable" : "Disable");
switch (data) {
case CMD_ENABLED:
wlan_enable_11d(priv, ENABLE_11D);
break;
case CMD_DISABLED:
wlan_enable_11d(priv, DISABLE_11D);
break;
default:
break;
}
data =
(Adapter->State11D.Enable11D ==
ENABLE_11D) ? CMD_ENABLED : CMD_DISABLED;
val = (int *) wrq->u.name;
*val = data;
#endif
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function parses countryinfo from AP and download country info to FW
* @param priv pointer to wlan_private
* @param resp pointer to command response buffer
* @return WLAN_STATUS_SUCCESS; WLAN_STATUS_FAILURE
*/
int wlan_ret_802_11d_domain_info(wlan_private * priv, HostCmd_DS_COMMAND * resp)
{
HostCmd_DS_802_11D_DOMAIN_INFO_RSP
* domaininfo = &resp->params.domaininforesp;
MrvlIEtypes_DomainParamSet_t * domain = &domaininfo->Domain;
u16 Action = wlan_le16_to_cpu(domaininfo->Action);
s16 ret = WLAN_STATUS_SUCCESS;
u8 NoOfSubband = 0;
ENTER();
// HEXDUMP("11D DOMAIN Info Rsp Data:", (u8 *) resp, resp->Size);
NoOfSubband =
(wlan_le16_to_cpu(domain->Header.Len) -
3) / sizeof(IEEEtypes_SubbandSet_t);
/* countrycode 3 bytes */
wlan_debug3( "11D Domain Info Resp: NoOfSubband=%d\n", NoOfSubband);
if (NoOfSubband > MRVDRV_MAX_SUBBAND_802_11D) {
wlan_debug3("Invalid Numrer of Subband returned!!\n");
return WLAN_STATUS_FAILURE;
}
switch (Action) {
case HostCmd_ACT_SET: /*Proc Set Action */
break;
case HostCmd_ACT_GET:
break;
default:
wlan_debug3("Invalid Action:%d\n", domaininfo->Action);
ret = WLAN_STATUS_FAILURE;
break;
}
LEAVE();
return ret;
}
/**
* @brief This function parses countryinfo from AP and download country info to FW
* @param priv pointer to wlan_private
* @return WLAN_STATUS_SUCCESS; WLAN_STATUS_FAILURE
*/
int
wlan_parse_dnld_countryinfo_11d(wlan_private * priv)
{
int ret;
wlan_adapter *Adapter = priv->adapter;
ENTER();
if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
/* Skip new 11d download when roaming */
return WLAN_STATUS_SUCCESS;
}
if (wlan_get_state_11d(priv) == ENABLE_11D) {
memset(&Adapter->parsed_region_chan, 0,
sizeof(parsed_region_chan_11d_t));
ret =
wlan_parse_domain_info_11d(&Adapter->pAttemptedBSSDesc->
CountryInfo, 0,
&Adapter->parsed_region_chan);
if (ret == WLAN_STATUS_FAILURE) {
wlan_debug3( "11D: Err Parse domain_info from AP..\n");
LEAVE();
return ret;
}
memset(&Adapter->DomainReg, 0, sizeof(wlan_802_11d_domain_reg_t));
wlan_generate_domain_info_11d(&Adapter->parsed_region_chan,
&Adapter->DomainReg);
ret = wlan_set_domain_info_11d(priv);
if (ret) {
wlan_debug3( "11D: Err set domainInfo to FW\n");
LEAVE();
return ret;
}
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function generates 11D info from user specified regioncode and download to FW
* @param priv pointer to wlan_private
* @return WLAN_STATUS_SUCCESS; WLAN_STATUS_FAILURE
*/
int
wlan_create_dnld_countryinfo_11d(wlan_private * priv)
{
int ret;
wlan_adapter *Adapter = priv->adapter;
REGION_CHANNEL *region_chan;
u8 j;
ENTER();
wlan_debug3("11D:CurBssParams.Band[%d]\n", Adapter->CurBssParams.band);
if (wlan_get_state_11d(priv) == ENABLE_11D) {
/* update parsed_region_chan_11; dnld domaininf to FW */
for (j = 0; j < sizeof(Adapter->region_channel) /
sizeof(Adapter->region_channel[0]); j++) {
region_chan = &Adapter->region_channel[j];
wlan_debug3( "11D:[%d] region_chan->Band[%d]\n", j,
region_chan->Band);
if (!region_chan || !region_chan->Valid || !region_chan->CFP)
continue;
if (region_chan->Band != Adapter->CurBssParams.band)
continue;
break;
}
if (j >= sizeof(Adapter->region_channel) /
sizeof(Adapter->region_channel[0])) {
wlan_debug3("11D:region_chan not found. Band[%d]\n",
Adapter->CurBssParams.band);
LEAVE();
return WLAN_STATUS_FAILURE;
}
memset(&Adapter->parsed_region_chan, 0,
sizeof(parsed_region_chan_11d_t));
wlan_generate_parsed_region_chan_11d(region_chan,
&Adapter->parsed_region_chan);
memset(&Adapter->DomainReg, 0, sizeof(wlan_802_11d_domain_reg_t));
wlan_generate_domain_info_11d(&Adapter->parsed_region_chan,
&Adapter->DomainReg);
ret = wlan_set_domain_info_11d(priv);
if (ret) {
wlan_debug3("11D: Err set domainInfo to FW\n");
LEAVE();
return ret;
}
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}

109
wifi/wlan/wlan_11d.h Normal file
View File

@ -0,0 +1,109 @@
/** @file wlan_11d.h
* @brief This header file contains data structures and
* function declarations of 802.11d
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/*************************************************************
Change log:
09/26/05: add Doxygen format comments
************************************************************/
#ifndef _WLAN_11D_
#define _WLAN_11D_
#define MAX_CHAN_NUM 255
#define UNIVERSAL_REGION_CODE 0xff
/** (Beaconsize(256)-5(IEId,len,contrystr(3))/3(FirstChan,NoOfChan,MaxPwr)
*/
#define MAX_NO_OF_CHAN 40
typedef struct _REGION_CHANNEL *PREGION_CHANNEL;
typedef enum
{
DISABLE_11D = 0,
ENABLE_11D = 1,
} state_11d_t;
/** domain regulatory information */
typedef struct _wlan_802_11d_domain_reg
{
/** country Code*/
u8 CountryCode[COUNTRY_CODE_LEN];
/** No. of subband*/
u8 NoOfSubband;
IEEEtypes_SubbandSet_t Subband[MRVDRV_MAX_SUBBAND_802_11D];
} wlan_802_11d_domain_reg_t;
typedef struct _chan_power_11d
{
u8 chan;
u8 pwr;
} __ATTRIB_PACK__ chan_power_11d_t;
typedef struct _parsed_region_chan_11d
{
u8 band;
u8 region;
s8 CountryCode[COUNTRY_CODE_LEN];
chan_power_11d_t chanPwr[MAX_NO_OF_CHAN];
u8 NoOfChan;
} __ATTRIB_PACK__ parsed_region_chan_11d_t;
/** Data for state machine */
typedef struct _wlan_802_11d_state
{
/** True for Enabling 11D*/
BOOLEAN Enable11D;
} wlan_802_11d_state_t;
typedef struct _region_code_mapping
{
s8 region[COUNTRY_CODE_LEN];
u8 code;
} region_code_mapping_t;
/* function prototypes*/
int wlan_generate_domain_info_11d(parsed_region_chan_11d_t *
parsed_region_chan,
wlan_802_11d_domain_reg_t * domaininfo);
int wlan_parse_domain_info_11d(IEEEtypes_CountryInfoFullSet_t * CountryInfo,
u8 band,
parsed_region_chan_11d_t * parsed_region_chan);
u8 wlan_get_scan_type_11d(u8 chan,
parsed_region_chan_11d_t * parsed_region_chan);
u32 chan_2_freq(u8 chan, u8 band);
int wlan_set_domain_info_11d(wlan_private * priv);
state_11d_t wlan_get_state_11d(wlan_private * priv);
void wlan_init_11d(wlan_private * priv);
int wlan_enable_11d(wlan_private * priv, state_11d_t flag);
int wlan_set_universaltable(wlan_private * priv, u8 band);
void wlan_generate_parsed_region_chan_11d(PREGION_CHANNEL region_chan,
parsed_region_chan_11d_t *
parsed_region_chan);
int wlan_cmd_802_11d_domain_info(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, u16 cmdno,
u16 CmdOption);
//int wlan_cmd_enable_11d(wlan_private * priv, struct iwreq *wrq);
int wlan_ret_802_11d_domain_info(wlan_private * priv,
HostCmd_DS_COMMAND * resp);
int wlan_parse_dnld_countryinfo_11d(wlan_private * priv);
int wlan_create_dnld_countryinfo_11d(wlan_private * priv);
#endif /* _WLAN_11D_ */

2358
wifi/wlan/wlan_cmd.c Normal file

File diff suppressed because it is too large Load Diff

1477
wifi/wlan/wlan_cmdresp.c Normal file

File diff suppressed because it is too large Load Diff

29
wifi/wlan/wlan_debug.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _WLAN_DEBUG_H
#define _WLAN_DEBUG_H
#define WLAN_DEBUG_LEVEL_3
#ifdef WLAN_DEBUG_LEVEL_0
#define wlan_debug1(...)
#define wlan_debug2(...)
#define wlan_debug3(...)
#endif
#ifdef WLAN_DEBUG_LEVEL_1
#define wlan_debug1(a...) rt_kprintf(a)
#define wlan_debug2(...)
#define wlan_debug3(...)
#endif
#ifdef WLAN_DEBUG_LEVEL_2
#define wlan_debug1(a...) rt_kprintf(a)
#define wlan_debug2(a...) rt_kprintf(a)
#define wlan_debug3(...)
#endif
#ifdef WLAN_DEBUG_LEVEL_3
#define wlan_debug1(a...) rt_kprintf(a)
#define wlan_debug2(a...) rt_kprintf(a)
#define wlan_debug3(a...) rt_kprintf(a)
#endif
#define WLANEPARAMETER 101;
#endif

79
wifi/wlan/wlan_decl.h Normal file
View File

@ -0,0 +1,79 @@
/** @file wlan_decl.h
* @brief This file contains declaration referring to
* functions defined in other source files
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/******************************************************
Change log:
09/29/05: add Doxygen format comments
01/05/06: Add kernel 2.6.x support
01/11/06: Conditionalize new scan/join structures.
Move wlan_wext statics to their source file.
******************************************************/
#ifndef _WLAN_DECL_H_
#define _WLAN_DECL_H_
/** Function Prototype Declaration */
int wlan_init_fw(wlan_private * priv);
int wlan_tx_packet(wlan_private * priv, struct pbuf *skb);
void wlan_free_adapter(wlan_private * priv);
int SendNullPacket(wlan_private * priv, u8 flags);
BOOLEAN CheckLastPacketIndication(wlan_private * priv);
void Wep_encrypt(wlan_private * priv, u8 * Buf, u32 Len);
int FreeCmdBuffer(wlan_private * priv);
void CleanUpCmdCtrlNode(CmdCtrlNode * pTempNode);
CmdCtrlNode *GetFreeCmdCtrlNode(wlan_private * priv);
void SetCmdCtrlNode(wlan_private * priv,
CmdCtrlNode * pTempNode,
WLAN_OID cmd_oid, u16 wait_option, void *pdata_buf);
BOOLEAN Is_Command_Allowed(wlan_private * priv);
int PrepareAndSendCommand(wlan_private * priv,
u16 cmd_no,
u16 cmd_action,
u16 wait_option, WLAN_OID cmd_oid, void *pdata_buf);
void QueueCmd(wlan_adapter * Adapter, CmdCtrlNode * CmdNode, BOOLEAN addtail);
int SetDeepSleep(wlan_private * priv, BOOLEAN bDeepSleep);
int AllocateCmdBuffer(wlan_private * priv);
int ExecuteNextCommand(wlan_private * priv);
int wlan_process_event(wlan_private * priv);
void wlan_interrupt(struct rt_wlan_dev *);
u32 index_to_data_rate(u8 index);
u8 data_rate_to_index(u32 rate);
void HexDump(char *prompt, u8 * data, int len);
void get_version(wlan_adapter * adapter, char *version, int maxlen);
void wlan_read_write_rfreg(wlan_private * priv);
int wlan_process_rx_command(wlan_private * priv);
void wlan_process_tx(wlan_private * priv);
void CleanupAndInsertCmd(wlan_private * priv, CmdCtrlNode * pTempCmd);
void MrvDrvCommandTimerFunction(void *FunctionContext);
int wlan_set_regiontable(wlan_private * priv, u8 region, u8 band);
void wlan_clean_txrx(wlan_private * priv);
int wlan_host_sleep_activated_event(wlan_private * priv);
struct pbuf *ProcessRxedPacket(wlan_private * priv, struct sk_buff *);
void PSSleep(wlan_private * priv, int wait_option);
void PSConfirmSleep(wlan_private * priv, u16 PSMode);
void PSWakeup(wlan_private * priv, int wait_option);
void wlan_send_rxskbQ(wlan_private * priv);
extern void MacEventDisconnected(wlan_private * priv);
void INIT_LIST_HEAD(struct list_head *list);
void list_add_tail(struct list_head *new, struct list_head *head);
void list_add(struct list_head *new, struct list_head *head);
int list_empty(const struct list_head *head);
void list_del(struct list_head *entry);
#endif /* _WLAN_DECL_H_ */

512
wifi/wlan/wlan_defs.h Normal file
View File

@ -0,0 +1,512 @@
/** @file wlan_defs.h
* @brief This header file contains global constant/enum definitions,
* global variable declaration.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/*************************************************************
Change log:
10/11/05: add Doxygen format comments
01/11/06: Add NELEMENTS, BAND_XX defines
04/10/06: Add hostcmd generic API and power_adapt_cfg_ext command
************************************************************/
#ifndef _WLAN_DEFS_H_
#define _WLAN_DEFS_H_
#include "wlan_types.h" //changed by dennis
/** Global Varibale Declaration */
typedef struct rt_semaphore SEMAPHORE;
struct list_head {
struct list_head *next, *prev;
};
typedef int IRQ_RET_TYPE;
#define IRQ_RET return IRQ_HANDLED
typedef u8 BOOLEAN;
typedef int WLAN_STATUS;
/** Double-Word(32Bit) Bit definition */
#define DW_BIT_0 0x00000001
#define DW_BIT_1 0x00000002
#define DW_BIT_2 0x00000004
#define DW_BIT_3 0x00000008
#define DW_BIT_4 0x00000010
#define DW_BIT_5 0x00000020
#define DW_BIT_6 0x00000040
#define DW_BIT_7 0x00000080
#define DW_BIT_8 0x00000100
#define DW_BIT_9 0x00000200
#define DW_BIT_10 0x00000400
#define DW_BIT_11 0x00000800
#define DW_BIT_12 0x00001000
#define DW_BIT_13 0x00002000
#define DW_BIT_14 0x00004000
#define DW_BIT_15 0x00008000
#define DW_BIT_16 0x00010000
#define DW_BIT_17 0x00020000
#define DW_BIT_18 0x00040000
#define DW_BIT_19 0x00080000
#define DW_BIT_20 0x00100000
#define DW_BIT_21 0x00200000
#define DW_BIT_22 0x00400000
#define DW_BIT_23 0x00800000
#define DW_BIT_24 0x01000000
#define DW_BIT_25 0x02000000
#define DW_BIT_26 0x04000000
#define DW_BIT_27 0x08000000
#define DW_BIT_28 0x10000000
#define DW_BIT_29 0x20000000
#define DW_BIT_30 0x40000000
#define DW_BIT_31 0x80000000
/** Word (16bit) Bit Definition*/
#define W_BIT_0 0x0001
#define W_BIT_1 0x0002
#define W_BIT_2 0x0004
#define W_BIT_3 0x0008
#define W_BIT_4 0x0010
#define W_BIT_5 0x0020
#define W_BIT_6 0x0040
#define W_BIT_7 0x0080
#define W_BIT_8 0x0100
#define W_BIT_9 0x0200
#define W_BIT_10 0x0400
#define W_BIT_11 0x0800
#define W_BIT_12 0x1000
#define W_BIT_13 0x2000
#define W_BIT_14 0x4000
#define W_BIT_15 0x8000
/** Byte (8Bit) Bit definition*/
#define B_BIT_0 0x01
#define B_BIT_1 0x02
#define B_BIT_2 0x04
#define B_BIT_3 0x08
#define B_BIT_4 0x10
#define B_BIT_5 0x20
#define B_BIT_6 0x40
#define B_BIT_7 0x80
#define ENTER() wlan_debug3("Enter: %s, %s:%i\n", __FUNCTION__, __FILE__, __LINE__);
#define LEAVE() wlan_debug3("Leave: %s, %s:%i\n", __FUNCTION__, __FILE__, __LINE__);
#define HEXDUMP(x,y,z)
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef NELEMENTS
#define NELEMENTS(x) (sizeof(x)/sizeof(x[0]))
#endif
/** Buffer Constants */
/* The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical
* addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
* driver has more local TxPDs. Each TxPD on the host memory is associated
* with a Tx control node. The driver maintains 8 RxPD descriptors for
* station firmware to store Rx packet information.
*
* Current version of MAC has a 32x6 multicast address buffer.
*
* 802.11b can have up to 14 channels, the driver keeps the
* BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
*/
#define MRVDRV_SIZE_OF_PPA 0x00000008
#define MRVDRV_SIZE_OF_DPA 0x00000008
#define MRVDRV_NUM_OF_TxPD 0x00000020
#define MRVDRV_NUM_OF_CMD_BUFFER 10
#define MRVDRV_SIZE_OF_CMD_BUFFER (2 * 1024)
#define MRVDRV_MAX_BSSID_LIST 64
#define MRVDRV_TIMER_10S 10000
#define MRVDRV_TIMER_5S 5000
#define MRVDRV_TIMER_1S 1000
#define MRVDRV_SNAP_HEADER_LEN 8
#define MRVDRV_ETH_HEADER_SIZE 14
#define ARP_FILTER_MAX_BUF_SIZE 2
#define WLAN_UPLD_SIZE 2312
#define DEV_NAME_LEN 32
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
/** Misc constants */
/* This section defines 802.11 specific contants */
#define MRVDRV_MAX_REGION_CODE 7
#define MRVDRV_MAX_SSID_LIST_LENGTH 10
#define MRVDRV_IGNORE_MULTIPLE_DTIM 0xfffe
#define MRVDRV_MIN_MULTIPLE_DTIM 1
#define MRVDRV_MAX_MULTIPLE_DTIM 5
#define MRVDRV_DEFAULT_MULTIPLE_DTIM 1
#define MRVDRV_DEFAULT_LISTEN_INTERVAL 10
#define MRVDRV_DEFAULT_LOCAL_LISTEN_INTERVAL 0
#ifdef PROGRESSIVE_SCAN
#define MRVDRV_CHANNELS_PER_SCAN 4
#define MRVDRV_MAX_CHANNELS_PER_SCAN 14
#endif /* PROGRESSIVE_SCAN */
#define MRVDRV_CHANNELS_PER_ACTIVE_SCAN 14
#define MRVDRV_MIN_BEACON_INTERVAL 20
#define MRVDRV_MAX_BEACON_INTERVAL 1000
#define MRVDRV_BEACON_INTERVAL 100
#define MRVDRV_DEFAULT_WATCHDOG_TIMEOUT (2 * HZ)
#define MRVDRV_SCAN_WATCHDOG_TIMEOUT (10 * HZ)
/** TxPD Status */
/* Station firmware use TxPD status field to report final Tx transmit
* result, Bit masks are used to present combined situations.
*/
#define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
#define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08
/** Tx control node status */
#define MRVDRV_TX_CTRL_NODE_STATUS_IDLE 0x0000
/* Link spped */
#define MRVDRV_LINK_SPEED_1mbps 10000 /* in unit of 100bps */
#define MRVDRV_LINK_SPEED_11mbps 110000
/** RSSI-related defines */
/* RSSI constants are used to implement 802.11 RSSI threshold
* indication. if the Rx packet signal got too weak for 5 consecutive
* times, miniport driver (driver) will report this event to wrapper
*/
#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96)
/** RTS/FRAG related defines */
#define MRVDRV_RTS_MIN_VALUE 0
#define MRVDRV_RTS_MAX_VALUE 2347
#define MRVDRV_FRAG_MIN_VALUE 256
#define MRVDRV_FRAG_MAX_VALUE 2346
/* Fixed IE size is 8 bytes time stamp + 2 bytes beacon interval +
* 2 bytes cap */
#define MRVL_FIXED_IE_SIZE 12
/* This is for firmware specific length */
#define EXTRA_LEN 36
#define MRVDRV_MAXIMUM_ETH_PACKET_SIZE 1514
#define MRVDRV_ETH_TX_PACKET_BUFFER_SIZE \
(MRVDRV_MAXIMUM_ETH_PACKET_SIZE + sizeof(TxPD) + EXTRA_LEN)
#define MRVDRV_ETH_RX_PACKET_BUFFER_SIZE \
(MRVDRV_MAXIMUM_ETH_PACKET_SIZE + sizeof(RxPD) \
+ MRVDRV_SNAP_HEADER_LEN + EXTRA_LEN)
#define CMD_F_HOSTCMD (1 << 0)
/* to resolve CISCO AP extension */
#define MRVDRV_SCAN_LIST_VAR_IE_SPACE 256
#define FW_IS_WPA_ENABLED(_adapter) \
(_adapter->fwCapInfo & FW_CAPINFO_WPA)
#define FW_CAPINFO_WPA (1 << 0)
#define WLAN_802_11_AI_REQFI_CAPABILITIES 1
#define WLAN_802_11_AI_REQFI_LISTENINTERVAL 2
#define WLAN_802_11_AI_REQFI_CURRENTAPADDRESS 4
#define WLAN_802_11_AI_RESFI_CAPABILITIES 1
#define WLAN_802_11_AI_RESFI_STATUSCODE 2
#define WLAN_802_11_AI_RESFI_ASSOCIATIONID 4
#define MRVL_NUM_WEP_KEY 4
/** WPA Key LENGTH*/
/* Support 4 keys per key set */
#define MRVL_NUM_WPA_KEY_PER_SET 4
#define MRVL_MAX_WPA_KEY_LENGTH 32
#define WPA_AES_KEY_LEN 16
#define WPA_TKIP_KEY_LEN 32
/* A few details needed for WEP (Wireless Equivalent Privacy) */
/* 104 bits */
#define MAX_WEP_KEY_SIZE 13
/*40 bits RC4 - WEP*/
#define MIN_WEP_KEY_SIZE 5
#define RF_ANTENNA_1 0x1
#define RF_ANTENNA_2 0x2
#define RF_ANTENNA_AUTO 0xFFFF
#define KEY_INFO_ENABLED 0x01
#define SNR_BEACON 0
#define SNR_RXPD 1
#define NF_BEACON 2
#define NF_RXPD 3
/** MACRO DEFINITIONS */
#define CAL_NF(NF) ((s32)(-(s32)(NF)))
#define CAL_RSSI(SNR, NF) ((s32)((s32)(SNR) + CAL_NF(NF)))
#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI)))
#define DEFAULT_BCN_AVG_FACTOR 8
#define DEFAULT_DATA_AVG_FACTOR 8
#define MIN_BCN_AVG_FACTOR 1
#define MAX_BCN_AVG_FACTOR 8
#define MIN_DATA_AVG_FACTOR 1
#define MAX_DATA_AVG_FACTOR 8
#define AVG_SCALE 100
#define CAL_AVG_SNR_NF(AVG, SNRNF, N) \
(((AVG) == 0) ? ((u16)(SNRNF) * AVG_SCALE) : \
((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \
AVG_SCALE)) / N))
#define WLAN_STATUS_SUCCESS (0)
#define WLAN_STATUS_FAILURE (-1)
#define WLAN_STATUS_NOT_ACCEPTED (-2)
#define MAX_LEDS 3
#define LED_DISABLED 16
#define LED_BLINKING 2
/* S_SWAP : To swap 2 u8 */
#define S_SWAP(a,b) do { \
u8 t = SArr[a]; \
SArr[a] = SArr[b]; SArr[b] = t; \
} while(0)
/* SWAP: swap u8 */
#define SWAP_U8(a,b) {u8 t; t=a; a=b; b=t;}
/* SWAP: swap u8 */
#define SWAP_U16(a,b) {u16 t; t=a; a=b; b=t;}
#define wlan_le16_to_cpu(x) x
#define wlan_le32_to_cpu(x) x
#define wlan_le64_to_cpu(x) x
#define wlan_cpu_to_le16(x) x
#define wlan_cpu_to_le32(x) x
#define wlan_cpu_to_le64(x) x
#define endian_convert_TxPD(x)
#define endian_convert_RxPD(x)
#define endian_convert_GET_LOG(x)
#ifdef MFG_CMD_SUPPORT
#define SIOCCFMFG SIOCDEVPRIVATE
#endif /* MFG_CMD_SUPPORT */
/** ENUM definition*/
/** SNRNF_TYPE */
typedef enum _SNRNF_TYPE
{
TYPE_BEACON = 0,
TYPE_RXPD,
MAX_TYPE_B
} SNRNF_TYPE;
/** SNRNF_DATA*/
typedef enum _SNRNF_DATA
{
TYPE_NOAVG = 0,
TYPE_AVG,
MAX_TYPE_AVG
} SNRNF_DATA;
/** WLAN_802_11_AUTH_ALG*/
typedef enum _WLAN_802_11_AUTH_ALG
{
AUTH_ALG_OPEN_SYSTEM = 1,
AUTH_ALG_SHARED_KEY = 2,
AUTH_ALG_NETWORK_EAP = 8,
} WLAN_802_11_AUTH_ALG;
/** WLAN_802_11_ENCRYPTION_MODE */
typedef enum _WLAN_802_11_ENCRYPTION_MODE
{
CIPHER_NONE,
CIPHER_WEP40,
CIPHER_TKIP,
CIPHER_CCMP,
CIPHER_WEP104,
} WLAN_802_11_ENCRYPTION_MODE;
/** WLAN_802_11_POWER_MODE */
typedef enum _WLAN_802_11_POWER_MODE
{
Wlan802_11PowerModeCAM,
Wlan802_11PowerModeMAX_PSP,
Wlan802_11PowerModeFast_PSP,
/*not a real mode, defined as an upper bound */
Wlan802_11PowerModeMax
} WLAN_802_11_POWER_MODE;
/** PS_STATE */
typedef enum _PS_STATE
{
PS_STATE_FULL_POWER,
PS_STATE_AWAKE,
PS_STATE_PRE_SLEEP,
PS_STATE_SLEEP
} PS_STATE;
/** DNLD_STATE */
typedef enum _DNLD_STATE
{
DNLD_RES_RECEIVED,
DNLD_DATA_SENT,
DNLD_CMD_SENT
} DNLD_STATE;
/** WLAN_MEDIA_STATE */
typedef enum _WLAN_MEDIA_STATE
{
WlanMediaStateDisconnected,
WlanMediaStateConnected
} WLAN_MEDIA_STATE;
/** WLAN_802_11_PRIVACY_FILTER */
typedef enum _WLAN_802_11_PRIVACY_FILTER
{
Wlan802_11PrivFilterAcceptAll,
Wlan802_11PrivFilter8021xWEP
} WLAN_802_11_PRIVACY_FILTER;
/** mv_ms_type */
typedef enum _mv_ms_type
{
MVMS_DAT = 0,
MVMS_CMD = 1,
/* 2: reserved */
MVMS_EVENT = 3
} mv_ms_type;
/* Hardware status codes */
typedef enum _WLAN_HARDWARE_STATUS
{
WlanHardwareStatusReady,
WlanHardwareStatusInitializing,
WlanHardwareStatusReset,
WlanHardwareStatusClosing,
WlanHardwareStatusNotReady
} WLAN_HARDWARE_STATUS;
/** WLAN_802_11_AUTHENTICATION_MODE */
typedef enum _WLAN_802_11_AUTHENTICATION_MODE
{
Wlan802_11AuthModeOpen = 0x00,
Wlan802_11AuthModeShared = 0x01,
Wlan802_11AuthModeNetworkEAP = 0x80,
} WLAN_802_11_AUTHENTICATION_MODE;
/** WLAN_802_11_WEP_STATUS */
typedef enum _WLAN_802_11_WEP_STATUS
{
Wlan802_11WEPEnabled,
Wlan802_11WEPDisabled,
Wlan802_11WEPKeyAbsent,
Wlan802_11WEPNotSupported
} WLAN_802_11_WEP_STATUS;
/** SNMP_MIB_INDEX_e */
typedef enum _SNMP_MIB_INDEX_e
{
DesiredBssType_i = 0,
OpRateSet_i,
BcnPeriod_i,
DtimPeriod_i,
AssocRspTimeOut_i,
RtsThresh_i,
ShortRetryLim_i,
LongRetryLim_i,
FragThresh_i,
Dot11D_i,
Dot11H_i,
ManufId_i,
ProdId_i,
ManufOui_i,
ManufName_i,
ManufProdName_i,
ManufProdVer_i
} SNMP_MIB_INDEX_e;
/** KEY_TYPE_ID */
typedef enum _KEY_TYPE_ID
{
KEY_TYPE_ID_WEP = 0,
KEY_TYPE_ID_TKIP,
KEY_TYPE_ID_AES
} KEY_TYPE_ID;
/** KEY_INFO_WEP*/
typedef enum _KEY_INFO_WEP
{
KEY_INFO_WEP_DEFAULT_KEY = 0x01
} KEY_INFO_WEP;
/** KEY_INFO_TKIP */
typedef enum _KEY_INFO_TKIP
{
KEY_INFO_TKIP_MCAST = 0x01,
KEY_INFO_TKIP_UNICAST = 0x02,
KEY_INFO_TKIP_ENABLED = 0x04
} KEY_INFO_TKIP;
/** KEY_INFO_AES*/
typedef enum _KEY_INFO_AES
{
KEY_INFO_AES_MCAST = 0x01,
KEY_INFO_AES_UNICAST = 0x02,
KEY_INFO_AES_ENABLED = 0x04
} KEY_INFO_AES;
/** SNMP_MIB_VALUE_e */
typedef enum _SNMP_MIB_VALUE_e
{
SNMP_MIB_VALUE_INFRA = 1,
SNMP_MIB_VALUE_ADHOC
} SNMP_MIB_VALUE_e;
/** HWRateDropMode */
typedef enum _HWRateDropMode
{
NO_HW_RATE_DROP,
HW_TABLE_RATE_DROP,
HW_SINGLE_RATE_DROP
} HWRateDropMode;
typedef struct _wlan_private wlan_private;
typedef struct _wlan_adapter wlan_adapter;
typedef struct _HostCmd_DS_COMMAND HostCmd_DS_COMMAND;
extern u32 DSFreqList[15];
extern const char driver_version[];
extern u32 DSFreqList[];
extern u16 RegionCodeToIndex[MRVDRV_MAX_REGION_CODE];
extern u8 WlanDataRates[WLAN_SUPPORTED_RATES];
extern u8 SupportedRates[G_SUPPORTED_RATES];
extern wlan_private *wlanpriv;
extern int g_bus_mode_reg;
extern int g_dummy_clk_ioport;
extern int g_dummy_clk_reg;
#endif

483
wifi/wlan/wlan_dev.h Normal file
View File

@ -0,0 +1,483 @@
/** @file wlan_dev.h
* @brief This file contains definitions and data structures specific
* to Marvell 802.11 NIC. It contains the Device Information
* structure wlan_adapter.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/*************************************************************
Change log:
09/26/05: add Doxygen format comments
01/11/06: Conditionalize new scan/join structures.
04/18/06: Remove old Subscrive Event and add new Subscribe Event
implementation through generic hostcmd API
05/08/06: Remove PermanentAddr from Adapter
************************************************************/
#ifndef _WLAN_DEV_H_
#define _WLAN_DEV_H_
#include "include.h"
#include "wlan_thread.h"
#include "wlan_types.h"
#include "wlan_defs.h"
#include "rt_wlan_dev.h"
#include "..\os\os_timers.h"
#include "hostcmd.h"
#include <netif/ethernetif.h>
#define MAX_BSSID_PER_CHANNEL 16
/* For the extended Scan */
#define MAX_EXTENDED_SCAN_BSSID_LIST MAX_BSSID_PER_CHANNEL (MRVDRV_MAX_CHANNEL_SIZE + 1)
struct net_device_stats //this struct copied form LInux
{
unsigned long rx_packets; /* total packets received */
unsigned long tx_packets; /* total packets transmitted */
unsigned long rx_bytes; /* total bytes received */
unsigned long tx_bytes; /* total bytes transmitted */
unsigned long rx_errors; /* bad packets received */
unsigned long tx_errors; /* packet transmit problems */
unsigned long rx_dropped; /* no space in linux buffers */
unsigned long tx_dropped; /* no space available in linux */
unsigned long multicast; /* multicast packets received */
unsigned long collisions;
/* detailed rx_errors: */
unsigned long rx_length_errors;
unsigned long rx_over_errors; /* receiver ring buff overflow */
unsigned long rx_crc_errors; /* recved pkt with crc error */
unsigned long rx_frame_errors; /* recv'd frame alignment error */
unsigned long rx_fifo_errors; /* recv'r fifo overrun */
unsigned long rx_missed_errors; /* receiver missed packet */
/* detailed tx_errors */
unsigned long tx_aborted_errors;
unsigned long tx_carrier_errors;
unsigned long tx_fifo_errors;
unsigned long tx_heartbeat_errors;
unsigned long tx_window_errors;
/* for cslip etc */
unsigned long rx_compressed;
unsigned long tx_compressed;
};
typedef struct _PER_CHANNEL_BSSID_LIST_DATA
{
u8 ucStart;
u8 ucNumEntry;
} PER_CHANNEL_BSSID_LIST_DATA, *PPER_CHANNEL_BSSID_LIST_DATA;
typedef struct _MRV_BSSID_IE_LIST
{
WLAN_802_11_FIXED_IEs FixedIE;
u8 VariableIE[MRVDRV_SCAN_LIST_VAR_IE_SPACE];
} MRV_BSSID_IE_LIST, *PMRV_BSSID_IE_LIST;
#define MAX_REGION_CHANNEL_NUM 2
/** Chan-Freq-TxPower mapping table*/
typedef struct _CHANNEL_FREQ_POWER
{
/** Channel Number */
u16 Channel;
/** Frequency of this Channel */
u32 Freq;
/** Max allowed Tx power level */
u16 MaxTxPower;
/** TRUE:channel unsupported; FLASE:supported*/
BOOLEAN Unsupported;
} CHANNEL_FREQ_POWER;
/** region-band mapping table*/
typedef struct _REGION_CHANNEL
{
/** TRUE if this entry is valid */
BOOLEAN Valid;
/** Region code for US, Japan ... */
u8 Region;
/** Band B/G/A, used for BAND_CONFIG cmd */
u8 Band;
/** Actual No. of elements in the array below */
u8 NrCFP;
/** chan-freq-txpower mapping table*/
CHANNEL_FREQ_POWER *CFP;
} REGION_CHANNEL;
typedef struct _wlan_802_11_security_t
{
BOOLEAN WPAEnabled;
BOOLEAN WPA2Enabled;
WLAN_802_11_WEP_STATUS WEPStatus;
WLAN_802_11_AUTHENTICATION_MODE AuthenticationMode;
WLAN_802_11_ENCRYPTION_MODE EncryptionMode;
} wlan_802_11_security_t;
/** Current Basic Service Set State Structure */
typedef struct
{
BSSDescriptor_t BSSDescriptor;
/** band */
u8 band;
/** number of rates supported */
int NumOfRates;
/** supported rates*/
u8 DataRates[WLAN_SUPPORTED_RATES];
/** wmm enable? */
u8 wmm_enabled;
/** uapsd enable?*/
u8 wmm_uapsd_enabled;
} CurrentBSSParams_t;
/** sleep_params */
typedef struct SleepParams
{
u16 sp_error;
u16 sp_offset;
u16 sp_stabletime;
u8 sp_calcontrol;
u8 sp_extsleepclk;
u16 sp_reserved;
} SleepParams;
/** sleep_period */
typedef struct SleepPeriod
{
u16 period;
u16 reserved;
} SleepPeriod;
/** info for debug purpose */
typedef struct _wlan_dbg
{
u32 num_cmd_host_to_card_failure;
u32 num_cmd_sleep_cfm_host_to_card_failure;
u32 num_tx_host_to_card_failure;
u32 num_event_deauth;
u32 num_event_disassoc;
u32 num_event_link_lost;
u32 num_cmd_deauth;
u32 num_cmd_assoc_success;
u32 num_cmd_assoc_failure;
u32 num_tx_timeout;
u32 num_cmd_timeout;
u16 TimeoutCmdId;
u16 TimeoutCmdAct;
u16 LastCmdId;
u16 LastCmdRespId;
} wlan_dbg;
/** Data structure for the Marvell WLAN device */
typedef struct _wlan_dev
{
/** device name */
char name[DEV_NAME_LEN];
/** card pointer */
/** IO port */
u32 ioport;
/** Upload received */
u32 upld_rcv;
/** Upload type */
u32 upld_typ;
/** Upload length */
u32 upld_len;
/** netdev pointer */
// struct net_device *netdev;
struct rt_wlan_dev *netdev;
/* Upload buffer */
u8 upld_buf[WLAN_UPLD_SIZE];
/* Download sent:
bit0 1/0=data_sent/data_tx_done,
bit1 1/0=cmd_sent/cmd_tx_done,
all other bits reserved 0 */
u8 dnld_sent;
} wlan_dev_t, *pwlan_dev_t;
/* Data structure for WPS information */
typedef struct
{
IEEEtypes_VendorSpecific_t wpsIe;
BOOLEAN SessionEnable;
} wps_t;
/** Private structure for the MV device */
struct _wlan_private
{
int open;
wlan_adapter *adapter;
wlan_dev_t wlan_dev;
struct net_device_stats stats;
/** thread to service interrupts */
wlan_thread MainThread;
#ifdef REASSOCIATION
/** thread to service mac events */
wlan_thread ReassocThread;
#endif /* REASSOCIATION */
};
/** Wlan Adapter data structure*/
struct _wlan_adapter
{
u8 TmpTxBuf[WLAN_UPLD_SIZE] ;
/** STATUS variables */
WLAN_HARDWARE_STATUS HardwareStatus;
u32 FWReleaseNumber;
u32 fwCapInfo;
u8 chip_rev;
/** Command-related variables */
u16 SeqNum;
CmdCtrlNode *CmdArray;
/** Current Command */
CmdCtrlNode *CurCmd;
int CurCmdRetCode;
/** Command Queues */
/** Free command buffers */
struct list_head CmdFreeQ;
/** Pending command buffers */
struct list_head CmdPendingQ;
/** Variables brought in from private structure */
int irq;
/** Async and Sync Event variables */
u32 IntCounter;
u32 IntCounterSaved; /* save int for DS/PS */
u32 EventCause;
u8 nodeName[16]; /* nickname */
/** spin locks */
// spinlock_t QueueSpinLock __ATTRIB_ALIGN__;
// int QueueSpinLock ;//__ATTRIB_ALIGN__;
/** Timers */
WLAN_DRV_TIMER MrvDrvCommandTimer ;// __ATTRIB_ALIGN__;
BOOLEAN CommandTimerIsSet;
#ifdef REASSOCIATION
/**Reassociation timer*/
BOOLEAN ReassocTimerIsSet;
WLAN_DRV_TIMER MrvDrvTimer;// __ATTRIB_ALIGN__;
#endif /* REASSOCIATION */
/** Event Queues */
struct rt_event ds_awake_q;// __ATTRIB_ALIGN__;
u8 HisRegCpy;
/** bg scan related variable */
HostCmd_DS_802_11_BG_SCAN_CONFIG *bgScanConfig;
u32 bgScanConfigSize;
/** WMM related variable*/
WMM_DESC wmm;
/** current ssid/bssid related parameters*/
CurrentBSSParams_t CurBssParams;
WLAN_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
BSSDescriptor_t *pAttemptedBSSDesc;
WLAN_802_11_SSID AttemptedSSIDBeforeScan;
WLAN_802_11_SSID PreviousSSID;
u8 PreviousBSSID[MRVDRV_ETH_ADDR_LEN];
BSSDescriptor_t *ScanTable;
u32 NumInScanTable;
u8 ScanType;
u32 ScanMode;
u16 SpecificScanTime;
u16 ActiveScanTime;
u16 PassiveScanTime;
u16 BeaconPeriod;
u8 AdhocCreate;
BOOLEAN AdhocLinkSensed;
#ifdef REASSOCIATION
/** Reassociation on and off */
BOOLEAN Reassoc_on;
SEMAPHORE ReassocSem;
#endif /* REASSOCIATION */
BOOLEAN ATIMEnabled;
/** MAC address information */
u8 CurrentAddr[MRVDRV_ETH_ADDR_LEN];
u8 MulticastList[MRVDRV_MAX_MULTICAST_LIST_SIZE]
[MRVDRV_ETH_ADDR_LEN];
u32 NumOfMulticastMACAddr;
u16 HWRateDropMode;
u16 RateBitmap;
u16 Threshold;
u16 FinalRate;
/** control G Rates */
BOOLEAN adhoc_grate_enabled;
WLAN_802_11_ANTENNA TxAntenna;
WLAN_802_11_ANTENNA RxAntenna;
u8 AdhocChannel;
WLAN_802_11_FRAGMENTATION_THRESHOLD FragThsd;
WLAN_802_11_RTS_THRESHOLD RTSThsd;
u32 DataRate;
BOOLEAN Is_DataRate_Auto;
/** number of association attempts for the current SSID cmd */
u16 ListenInterval;
u8 TxRetryCount;
/** Tx-related variables (for single packet tx) */
struct sk_buff *CurrentTxSkb;
struct sk_buff RxSkbQ;
BOOLEAN TxLockFlag;
u16 gen_null_pkg;
// spinlock_t CurrentTxLock __ATTRIB_ALIGN__;
// int CurrentTxLock ; //temporarily
/** NIC Operation characteristics */
u16 CurrentPacketFilter;
u32 MediaConnectStatus;
u16 RegionCode;
u16 TxPowerLevel;
u8 MaxTxPowerLevel;
u8 MinTxPowerLevel;
/** POWER MANAGEMENT AND PnP SUPPORT */
BOOLEAN SurpriseRemoved;
u16 AtimWindow;
u16 PSMode; /* Wlan802_11PowerModeCAM=disable
Wlan802_11PowerModeMAX_PSP=enable */
u16 MultipleDtim;
u16 BCNMissTimeOut;
u32 PSState;
BOOLEAN NeedToWakeup;
PS_CMD_ConfirmSleep PSConfirmSleep;
u16 LocalListenInterval;
u16 NullPktInterval;
u16 AdhocAwakePeriod;
u16 fwWakeupMethod;
BOOLEAN IsDeepSleep;
BOOLEAN bWakeupDevRequired;
u32 WakeupTries;
BOOLEAN bHostSleepConfigured;
HostCmd_DS_802_11_HOST_SLEEP_CFG HSCfg;
/** ARP filter related variable */
u8 ArpFilter[ARP_FILTER_MAX_BUF_SIZE];
u32 ArpFilterSize;
/** Encryption parameter */
wlan_802_11_security_t SecInfo;
MRVL_WEP_KEY WepKey[MRVL_NUM_WEP_KEY];
u16 CurrentWepKeyIndex;
/** Buffer for TLVs passed from the application to be inserted into the
* association request to firmware
*/
u8 mrvlAssocTlvBuffer[MRVDRV_ASSOC_TLV_BUF_SIZE];
/** Length of the data stored in mrvlAssocTlvBuffer*/
u8 mrvlAssocTlvBufferLen;
/** Buffer to store the association response for application retrieval */
u8 assocRspBuffer[MRVDRV_ASSOC_RSP_BUF_SIZE];
/** Length of the data stored in assocRspBuffer */
int assocRspSize;
/** Generice IEEE IEs passed from the application to be inserted into the
* association request to firmware
*/
u8 genIeBuffer[MRVDRV_GENIE_BUF_SIZE];
/** Length of the data stored in genIeBuffer */
u8 genIeBufferLen;
BOOLEAN IsGTK_SET;
/** Encryption Key*/
u8 Wpa_ie[256];
u8 Wpa_ie_len;
HostCmd_DS_802_11_KEY_MATERIAL aeskey;
/* Advanced Encryption Standard */
BOOLEAN AdhocAESEnabled;
struct rt_event cmd_EncKey;
u16 RxAntennaMode;
u16 TxAntennaMode;
/** Requested Signal Strength*/
u16 bcn_avg_factor;
u16 data_avg_factor;
u16 SNR[MAX_TYPE_B][MAX_TYPE_AVG];
u16 NF[MAX_TYPE_B][MAX_TYPE_AVG];
u8 RSSI[MAX_TYPE_B][MAX_TYPE_AVG];
u8 rawSNR[DEFAULT_DATA_AVG_FACTOR];
u8 rawNF[DEFAULT_DATA_AVG_FACTOR];
u16 nextSNRNF;
u16 numSNRNF;
u32 RxPDAge;
u16 RxPDRate;
BOOLEAN RadioOn;
/** Blue Tooth Co-existence Arbitration */
HostCmd_DS_802_11_BCA_TIMESHARE bca_ts;
/** sleep_params */
SleepParams sp;
/** sleep_period (Enhanced Power Save) */
SleepPeriod sleep_period;
#define MAX_REGION_CHANNEL_NUM 2
/** Region Channel data */
REGION_CHANNEL region_channel[MAX_REGION_CHANNEL_NUM];
REGION_CHANNEL universal_channel[MAX_REGION_CHANNEL_NUM];
/** 11D and Domain Regulatory Data */
wlan_802_11d_domain_reg_t DomainReg;
parsed_region_chan_11d_t parsed_region_chan;
/** FSM variable for 11d support */
wlan_802_11d_state_t State11D;
u8 beaconBuffer[MAX_SCAN_BEACON_BUFFER];
u8 *pBeaconBufEnd;
HostCmd_DS_802_11_GET_LOG LogMsg;
u16 ScanProbes;
u32 PktTxCtrl;
u8 *helper;
u32 helper_len;
u8 *fmimage;
u32 fmimage_len;
u16 TxRate;
wps_t wps;
wlan_dbg dbg;
wlan_subscribe_event subevent;
u32 num_cmd_timeout;
};
#endif /* _WLAN_DEV_H_ */

471
wifi/wlan/wlan_fw.c Normal file
View File

@ -0,0 +1,471 @@
/** @file wlan_fw.c
* @brief This file contains the initialization for FW
* and HW
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
09/28/05: Add Doxygen format comments
01/05/06: Add kernel 2.6.x support
01/11/06: Conditionalize new scan/join functions.
Cleanup association response handler initialization.
01/06/05: Add FW file read
05/08/06: Remove the 2nd GET_HW_SPEC command and TempAddr/PermanentAddr
06/30/06: replaced MODULE_PARM(name, type) with module_param(name, type, perm)
********************************************************/
#include "include.h"
#include "gspibin.h"
#include "helper_gspi.h"
#include "wlan_debug.h"
//#include <linux/vmalloc.h>
/********************************************************
Local Variables
********************************************************/
char *helper_name = NULL;
char *fw_name = NULL;
/********************************************************
Global Variables
********************************************************/
/********************************************************
Local Functions
********************************************************/
/**
* @brief This function downloads firmware image, gets
* HW spec from firmware and set basic parameters to
* firmware.
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
wlan_download_firmware(wlan_private * priv)
{
int ret = WLAN_STATUS_SUCCESS;
wlan_adapter *adapter = priv->adapter;
u8 *ptr = NULL;
u8* temp1;
u32 len = 0;
HostCmd_DS_CMD_GSPI_BUS_CONFIG bus_config;
ENTER();
sbi_disable_host_int(priv);
adapter->fmimage = NULL;
adapter->fmimage_len = 0;
adapter->helper = NULL;
adapter->helper_len = 0;
ptr=(u8*)helpgspibin;
len=sizeof(helpgspibin);
adapter->helper = ptr;
adapter->helper_len = len;
wlan_debug2("helper read success, len=%x\n", len);
ptr=(u8*)gspi8686bin;
len=sizeof(gspi8686bin);
adapter->fmimage = ptr;
adapter->fmimage_len = len;
/* Download the helper */
ret = sbi_prog_helper(priv);
if (ret) {
wlan_debug1("down load helper failed!\n");
ret = WLAN_STATUS_FAILURE;
goto done;
}
/* Download firmware */
if (sbi_prog_firmware_w_helper(priv)) {
wlan_debug1("down load firmware unsuccessful\n");
ret = WLAN_STATUS_FAILURE;
goto done;
}
/* check if the fimware is downloaded successfully or not */
if (sbi_verify_fw_download(priv)) {
wlan_debug1( "FW failed to be active in time!\n");
ret = WLAN_STATUS_FAILURE;
goto done;
}
wlan_debug3(" fw has been load to board\n ");
#define RF_REG_OFFSET 0x07
#define RF_REG_VALUE 0xc8
sbi_enable_host_int(priv);
#define SPI_BMR_DELAY_METHOD B_BIT_2
#define SPI_BMR_BUSMODE_16_16 0x02 //16bit address and 16bit data
g_bus_mode_reg = SPI_BMR_BUSMODE_16_16 | SPI_BMR_DELAY_METHOD;
g_dummy_clk_ioport = 1;
g_dummy_clk_reg = 1;
bus_config.BusDelayMode = g_bus_mode_reg;
bus_config.HostTimeDelayToReadPort = g_dummy_clk_ioport * 16;
bus_config.HostTimeDelayToReadregister = g_dummy_clk_reg * 16;
wlan_debug3 ("Setting for %d %d\n", g_dummy_clk_ioport,
g_dummy_clk_reg);
ret =PrepareAndSendCommand(priv, HostCmd_CMD_GSPI_BUS_CONFIG,
HostCmd_ACT_GEN_SET,
HostCmd_OPTION_WAITFORRSP, 0, &bus_config);
if (ret) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
wlan_debug3("Hostcmd_CMD_GSPI_BUS_CONFIG OK\n ");
/*
* Read MAC address from HW
*/
memset(adapter->CurrentAddr, 0xff, MRVDRV_ETH_ADDR_LEN);
ret = PrepareAndSendCommand(priv, HostCmd_CMD_GET_HW_SPEC,
0, HostCmd_OPTION_WAITFORRSP, 0, NULL);
if (ret) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
temp1=adapter->CurrentAddr;
wlan_debug3 ("Hostcmd_CMD_GET_HW_SPEC OK:%x,%x,%x,%x,%x,%x,%x,%x\n",
temp1[0],temp1[1],temp1[2],temp1[3],temp1[4],temp1[5],temp1[6],temp1[7]);
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_MAC_CONTROL,
0, HostCmd_OPTION_WAITFORRSP, 0,
&adapter->CurrentPacketFilter);
if (ret) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
wlan_debug2("Hostcmd_CMD_MAC_CONTROL OK\n");
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_FW_WAKE_METHOD,
HostCmd_ACT_GET,
HostCmd_OPTION_WAITFORRSP, 0,
&priv->adapter->fwWakeupMethod);
if (ret) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_RATE_ADAPT_RATESET,
HostCmd_ACT_GEN_GET,
HostCmd_OPTION_WAITFORRSP, 0, NULL);
if (ret) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
priv->adapter->DataRate = 0;
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_RF_TX_POWER,
HostCmd_ACT_GEN_GET,
HostCmd_OPTION_WAITFORRSP, 0, NULL);
if (ret) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
wlan_debug3("Hostcmd_CMD_802_11_RF_TX_POWER OK\n ");
ret = WLAN_STATUS_SUCCESS;
done:
LEAVE();
return (ret);
}
/**
* @brief This function initializes timers.
*
* @param priv A pointer to wlan_private structure
* @return n/a
*/
static void init_sync_objects(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
InitializeTimer(&Adapter->MrvDrvCommandTimer,
MrvDrvCommandTimerFunction, priv,"cmdtimer");
Adapter->CommandTimerIsSet = FALSE;
return;
}
/**
* @brief This function allocates buffer for the member of adapter
* structure like command buffer and BSSID list.
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int
wlan_allocate_adapter(wlan_private * priv)
{
u32 ulBufSize;
wlan_adapter *Adapter = priv->adapter;
BSSDescriptor_t *pTempScanTable;
/* Allocate buffer to store the BSSID list */
ulBufSize = sizeof(BSSDescriptor_t) * MRVDRV_MAX_BSSID_LIST;
pTempScanTable = (BSSDescriptor_t *)rt_malloc(ulBufSize);
if (!pTempScanTable) {
return WLAN_STATUS_FAILURE;
}
Adapter->ScanTable = pTempScanTable;
memset(Adapter->ScanTable, 0, ulBufSize);
Adapter->bgScanConfig =(HostCmd_DS_802_11_BG_SCAN_CONFIG *)rt_malloc(sizeof(HostCmd_DS_802_11_BG_SCAN_CONFIG));
if (!Adapter->bgScanConfig) {
return WLAN_STATUS_FAILURE;
}
Adapter->bgScanConfigSize = sizeof(HostCmd_DS_802_11_BG_SCAN_CONFIG);
memset(Adapter->bgScanConfig, 0, Adapter->bgScanConfigSize);
/* Allocate the command buffers */
if (AllocateCmdBuffer(priv) != WLAN_STATUS_SUCCESS) {
return WLAN_STATUS_FAILURE;
}
memset(&Adapter->PSConfirmSleep, 0, sizeof(PS_CMD_ConfirmSleep));
Adapter->PSConfirmSleep.SeqNum = (++Adapter->SeqNum);
Adapter->PSConfirmSleep.Command =(HostCmd_CMD_802_11_PS_MODE);
Adapter->PSConfirmSleep.Size =(sizeof(PS_CMD_ConfirmSleep));
Adapter->PSConfirmSleep.Result = 0;
Adapter->PSConfirmSleep.Action =(HostCmd_SubCmd_Sleep_Confirmed);
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function initializes the adapter structure
* and set default value to the member of adapter.
*
* @param priv A pointer to wlan_private structure
* @return n/a
*/
static void
wlan_init_adapter(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
int i;
Adapter->ScanProbes = 0;
Adapter->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
Adapter->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
/* ATIM params */
Adapter->AtimWindow = 0;
Adapter->ATIMEnabled = FALSE;
Adapter->MediaConnectStatus = WlanMediaStateDisconnected;
memset(Adapter->CurrentAddr, 0xff, MRVDRV_ETH_ADDR_LEN);
/* Status variables */
Adapter->HardwareStatus = WlanHardwareStatusInitializing;
/* scan type */
Adapter->ScanType = HostCmd_SCAN_TYPE_ACTIVE;
/* scan mode */
Adapter->ScanMode = HostCmd_BSS_TYPE_ANY;
/* scan time */
Adapter->SpecificScanTime = MRVDRV_SPECIFIC_SCAN_CHAN_TIME;
Adapter->ActiveScanTime = MRVDRV_ACTIVE_SCAN_CHAN_TIME;
Adapter->PassiveScanTime = MRVDRV_PASSIVE_SCAN_CHAN_TIME;
/* 802.11 specific */
Adapter->SecInfo.WEPStatus = Wlan802_11WEPDisabled;
for (i = 0; i < sizeof(Adapter->WepKey) / sizeof(Adapter->WepKey[0]); i++)
memset(&Adapter->WepKey[i], 0, sizeof(MRVL_WEP_KEY));
Adapter->CurrentWepKeyIndex = 0;
Adapter->SecInfo.AuthenticationMode = Wlan802_11AuthModeOpen;
Adapter->SecInfo.EncryptionMode = CIPHER_NONE;
///////ADD FOR WEP TEST//////////
Adapter->SecInfo.WPAEnabled = FALSE;
Adapter->SecInfo.WPA2Enabled= FALSE;
Adapter->mrvlAssocTlvBufferLen=0;
///////ADD FOR WEP TEST//////////
Adapter->AdhocAESEnabled = FALSE;
Adapter->InfrastructureMode = Wlan802_11Infrastructure;
Adapter->NumInScanTable = 0;
Adapter->pAttemptedBSSDesc = NULL;
Adapter->pBeaconBufEnd = Adapter->beaconBuffer;
Adapter->HisRegCpy |= HIS_TxDnLdRdy;
memset(&Adapter->CurBssParams, 0, sizeof(Adapter->CurBssParams));
/* PnP and power profile */
Adapter->SurpriseRemoved = FALSE;
Adapter->CurrentPacketFilter =
HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON;
Adapter->RadioOn = RADIO_ON;
Adapter->TxAntenna = RF_ANTENNA_2;
Adapter->RxAntenna = RF_ANTENNA_AUTO;
Adapter->HWRateDropMode = HW_TABLE_RATE_DROP;
Adapter->Is_DataRate_Auto = TRUE;
Adapter->BeaconPeriod = MRVDRV_BEACON_INTERVAL;
Adapter->AdhocChannel = DEFAULT_AD_HOC_CHANNEL;
Adapter->PSMode = Wlan802_11PowerModeCAM;
Adapter->MultipleDtim = MRVDRV_DEFAULT_MULTIPLE_DTIM;
Adapter->ListenInterval = MRVDRV_DEFAULT_LISTEN_INTERVAL;
Adapter->PSState = PS_STATE_FULL_POWER;
Adapter->NeedToWakeup = FALSE;
Adapter->LocalListenInterval = 0; /* default value in firmware will be used */
Adapter->fwWakeupMethod = WAKEUP_FW_UNCHANGED;
Adapter->IsDeepSleep = FALSE;
Adapter->bWakeupDevRequired = FALSE;
Adapter->WakeupTries = 0;
Adapter->bHostSleepConfigured = FALSE;
Adapter->HSCfg.conditions = HOST_SLEEP_CFG_CANCEL;
Adapter->HSCfg.gpio = 0;
Adapter->HSCfg.gap = 0;
Adapter->DataRate = 0; // Initially indicate the rate as auto
Adapter->adhoc_grate_enabled = FALSE;
Adapter->IntCounter = Adapter->IntCounterSaved = 0;
INIT_LIST_HEAD((struct list_head *) &Adapter->RxSkbQ);
Adapter->gen_null_pkg = TRUE; /*Enable NULL Pkg generation */
rt_event_init(&Adapter->cmd_EncKey, "EncKeyevt", RT_IPC_FLAG_FIFO); //which thread wait on this queue
Adapter->CurrentTxSkb = NULL;
Adapter->PktTxCtrl = 0;
return;
}
/********************************************************
Global Functions
********************************************************/
/**
* @brief This function initializes firmware
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
wlan_init_fw(wlan_private * priv)
{
int ret = WLAN_STATUS_SUCCESS;
wlan_adapter *Adapter = priv->adapter;
ENTER();
/* Allocate adapter structure */
if ((ret = wlan_allocate_adapter(priv)) != WLAN_STATUS_SUCCESS) {
goto done;
}
/* init adapter structure */
wlan_init_adapter(priv);
/* init timer etc. */
init_sync_objects(priv);
/* download fimrware etc. */
if ((ret = wlan_download_firmware(priv)) != WLAN_STATUS_SUCCESS) {
Adapter->HardwareStatus = WlanHardwareStatusNotReady;
ret = WLAN_STATUS_FAILURE;
goto done;
}
/* init 802.11d */
wlan_init_11d(priv);
Adapter->HardwareStatus = WlanHardwareStatusReady;
ret = WLAN_STATUS_SUCCESS;
done:
LEAVE();
return ret;
}
/**
* @brief This function frees the structure of adapter
*
* @param priv A pointer to wlan_private structure
* @return n/a
*/
void
wlan_free_adapter(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
ENTER();
if (!Adapter) {
wlan_debug1( "Why double free adapter?:)\n");
return;
}
wlan_debug3("Free Command buffer\n");
FreeCmdBuffer(priv);
wlan_debug2("Free CommandTimer\n");
if (Adapter->CommandTimerIsSet) {
CancelTimer(&Adapter->MrvDrvCommandTimer);
Adapter->CommandTimerIsSet = FALSE;
}
FreeTimer(&Adapter->MrvDrvCommandTimer);
if (Adapter->bgScanConfig) {
rt_free(Adapter->bgScanConfig);
Adapter->bgScanConfig = NULL;
}
wlan_debug3("Free ScanTable\n");
if (Adapter->ScanTable) {
rt_free(Adapter->ScanTable);
Adapter->ScanTable = NULL;
}
wlan_debug3("Free Adapter\n");
/* Free the adapter object itself */
rt_free(Adapter);
priv->adapter = NULL;
LEAVE();
}

955
wifi/wlan/wlan_join.c Normal file
View File

@ -0,0 +1,955 @@
/** @file wlan_join.c
*
* @brief Functions implementing wlan infrastructure and adhoc join routines
*
* IOCTL handlers as well as command preperation and response routines
* for sending adhoc start, adhoc join, and association commands
* to the firmware.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*
* @sa wlan_join.h
*/
/*************************************************************
Change Log:
01/11/06: Initial revision. Match new scan code, relocate related functions
01/19/06: Fix failure to save adhoc ssid as current after adhoc start
03/16/06: Add a semaphore to protect reassociation thread
************************************************************/
#include "include.h"
#include "rt_wlan_dev.h"
#define EBUSY 1000
#define ENOTSUPP 1001
BOOLEAN
Is_Command_Allowed(wlan_private * priv)
{
BOOLEAN ret = TRUE;
{
if ((priv->adapter->IsDeepSleep == TRUE)) {
wlan_debug3("IOCTLS called when station is in DeepSleep\n");
ret = FALSE;
}
}
return ret;
}
/**
* @brief This function finds out the common rates between rate1 and rate2.
*
* It will fill common rates in rate1 as output if found.
*
* NOTE: Setting the MSB of the basic rates need to be taken
* care, either before or after calling this function
*
* @param Adapter A pointer to wlan_adapter structure
* @param rate1 the buffer which keeps input and output
* @param rate1_size the size of rate1 buffer
* @param rate2 the buffer which keeps rate2
* @param rate2_size the size of rate2 buffer.
*
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int
get_common_rates(wlan_adapter * Adapter, u8 * rate1,
int rate1_size, u8 * rate2, int rate2_size)
{
u8 *ptr = rate1;
int ret = WLAN_STATUS_SUCCESS;
u8 *tmp = NULL;
int i, j;
if (!(tmp = (u8*)malloc(rate1_size))) {
wlan_debug3("Allocate buffer for common rates failed\n");
return -ENOMEM;
}
memcpy(tmp, rate1, rate1_size);
memset(rate1, 0, rate1_size);
for (i = 0; rate2[i] && i < rate2_size; i++) {
for (j = 0; tmp[j] && j < rate1_size; j++) {
/* Check common rate, excluding the bit for basic rate */
if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
*rate1++ = tmp[j];
break;
}
}
}
if (!Adapter->Is_DataRate_Auto) {
while (*ptr) {
if ((*ptr & 0x7f) == Adapter->DataRate) {
ret = WLAN_STATUS_SUCCESS;
goto done;
}
ptr++;
}
wlan_debug3("Previously set fixed data rate %#x isn't "
"compatible with the network.\n", Adapter->DataRate);
ret = WLAN_STATUS_FAILURE;
goto done;
}
ret = WLAN_STATUS_SUCCESS;
done:
free(tmp);
return ret;
}
/**
* @brief Create the intersection of the rates supported by a target BSS and
* our Adapter settings for use in an assoc/join command.
*
* @param Adapter A pointer to wlan_adapter structure
* @param pBSSDesc BSS Descriptor whose rates are used in the setup
* @param pOutRates Output: Octet array of rates common between the BSS
* and the Adapter supported rates settings
* @param pOutRatesSize Output: Number of rates/octets set in pOutRates
*
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*
*/
static int
setup_rates_from_bssdesc(wlan_adapter * Adapter,
BSSDescriptor_t * pBSSDesc,
u8 * pOutRates, int *pOutRatesSize)
{
u8 *card_rates;
int card_rates_size;
ENTER();
memcpy(pOutRates, pBSSDesc->SupportedRates, WLAN_SUPPORTED_RATES);
card_rates = SupportedRates;
card_rates_size = sizeof(SupportedRates);
if (get_common_rates(Adapter, pOutRates, WLAN_SUPPORTED_RATES,
card_rates, card_rates_size)) {
*pOutRatesSize = 0;
wlan_debug2( "get_common_rates failed\n");
LEAVE();
return WLAN_STATUS_FAILURE;
}
*pOutRatesSize = MIN(strlen(pOutRates), WLAN_SUPPORTED_RATES);
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief Connect to the AP or Ad-hoc Network with specific bssid
*
* NOTE: Scan should be issued by application before this function is called
*
* @param dev A pointer to net_device structure
* @param info A pointer to iw_request_info structure
* @param awrq A pointer to iw_param structure
* @param extra A pointer to extra data buf
* @return WLAN_STATUS_SUCCESS --success, otherwise fail
*/
int wlan_set_wap (struct rt_wlan_dev *dev, char * dstbssid,int len)
{
wlan_private *priv = dev->priv;
wlan_adapter *Adapter = priv->adapter;
int ret = WLAN_STATUS_SUCCESS;
const u8 bcast[ETH_ALEN] = { 255, 255, 255, 255, 255, 255 };
u8 reqBSSID[ETH_ALEN];
int i;
ENTER();
if(len!=ETH_ALEN)
return -WLANEPARAMETER;
if (!Is_Command_Allowed(priv)) {
wlan_debug1( "%s: not allowed\n", __FUNCTION__);
return -EBUSY;
}
/* Clear any past association response stored for application retrieval */
Adapter->assocRspSize = 0;
wlan_debug3("ASSOC: WAP: sa_data: %02x:%02x:%02x:%02x:%02x:%02x\n",
(u8) dstbssid[0], (u8) dstbssid[1],
(u8) dstbssid[2], (u8) dstbssid[3],
(u8) dstbssid[4], (u8) dstbssid[5]);
#ifdef REASSOCIATION
// cancel re-association timer if there's one
if (Adapter->ReassocTimerIsSet == TRUE) {
CancelTimer(&Adapter->MrvDrvTimer);
Adapter->ReassocTimerIsSet = FALSE;
}
#endif /* REASSOCIATION */
if (!memcmp(bcast, dstbssid, ETH_ALEN)) {
i = FindBestSSIDInList(Adapter);
} else {
memcpy(reqBSSID, dstbssid, ETH_ALEN);
wlan_debug3( "ASSOC: WAP: Bssid = %02x:%02x:%02x:%02x:%02x:%02x\n",
dstbssid[0], dstbssid[1], dstbssid[2],
dstbssid[3], dstbssid[4], dstbssid[5]);
/* Search for index position in list for requested MAC */
i = FindBSSIDInList(Adapter, reqBSSID, Adapter->InfrastructureMode);
}
if (i < 0) {
wlan_debug1( "ASSOC: WAP: MAC address not found in BSSID List\n");
return -ENETUNREACH;
}
if (Adapter->InfrastructureMode == Wlan802_11Infrastructure) {
ret = wlan_associate(priv, &Adapter->ScanTable[i]);
if (ret) {
LEAVE();
return ret;
}
}
/* Check to see if we successfully connected */
if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
ret = WLAN_STATUS_SUCCESS;
} else {
ret = -ENETDOWN;
}
LEAVE();
return ret;
}
/**
* @brief Associated to a specific BSS discovered in a scan
*
* @param priv A pointer to wlan_private structure
* @param pBSSDesc Pointer to the BSS descriptor to associate with.
*
* @return WLAN_STATUS_SUCCESS-success, otherwise fail
*/
int
wlan_associate(wlan_private * priv, BSSDescriptor_t * pBSSDesc)
{
wlan_adapter *Adapter = priv->adapter;
int enableData = TRUE;
// union iwreq_data wrqu;
int ret;
IEEEtypes_AssocRsp_t *pAssocRsp;
u8 currentBSSID[MRVDRV_ETH_ADDR_LEN];
int reassocAttempt = FALSE;
ENTER();
/* Return error if the Adapter or table entry is not marked as infra */
if ((Adapter->InfrastructureMode != Wlan802_11Infrastructure)
|| (pBSSDesc->InfrastructureMode != Wlan802_11Infrastructure)) {
LEAVE();
return -EINVAL;
}
memcpy(&currentBSSID,
&Adapter->CurBssParams.BSSDescriptor.MacAddress,
sizeof(currentBSSID));
if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
reassocAttempt = TRUE;
wlan_debug3( "Attempting reassociation, stopping wmm queues\n");
wmm_stop_queue(priv);
}
/* Clear any past association response stored for application retrieval */
Adapter->assocRspSize = 0;
ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_ASSOCIATE,
0, HostCmd_OPTION_WAITFORRSP, 0, pBSSDesc);
if (Adapter->wmm.enabled) {
/* Don't re-enable carrier until we get the WMM_GET_STATUS event */
enableData = FALSE;
} else {
/* Since WMM is not enabled, setup the queues with the defaults */
wmm_setup_queues(priv);
}
if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
if (reassocAttempt
&& (memcmp(&currentBSSID,
&Adapter->CurBssParams.BSSDescriptor.MacAddress,
sizeof(currentBSSID)) == 0)) {
/* Reassociation attempt failed, still associated to old AP,
** no need to wait for WMM notification to restart data
*/
enableData = TRUE;
}
if (enableData) {
wlan_debug2( "Post association, re-enabling data flow\n");
wmm_start_queue(priv);
}
} else {
wlan_debug2( "Post association, stopping data flow\n");
}
// memcpy(wrqu.ap_addr.sa_data,
// &Adapter->CurBssParams.BSSDescriptor.MacAddress, ETH_ALEN);
// wrqu.ap_addr.sa_family = ARPHRD_ETHER;
// wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL);
pAssocRsp = (IEEEtypes_AssocRsp_t *) Adapter->assocRspBuffer;
if (ret || pAssocRsp->StatusCode) {
ret = -ENETUNREACH;
}
LEAVE();
return ret;
}
/**
* @brief Associated to a specific indexed entry in the ScanTable
*
* @param priv A pointer to wlan_private structure
* @param tableIdx Index into the ScanTable to associate to, index parameter
* base value is 1. No scanning is done before the
* association attempt.
*
* @return WLAN_STATUS_SUCCESS-success, otherwise fail
*/
int
wlan_associate_to_table_idx(wlan_private * priv, int tableIdx)
{
wlan_adapter *Adapter = priv->adapter;
int ret;
ENTER();
wlan_debug3("ASSOC: iwpriv: Index = %d, NumInScanTable = %d\n",
tableIdx, Adapter->NumInScanTable);
/* Check index in table, subtract 1 if within range and call association
* sub-function. ScanTable[] is 0 based, parameter is 1 based to
* conform with IW_ENCODE_INDEX flag parameter passing in iwconfig/iwlist
*/
if (tableIdx && (tableIdx <= Adapter->NumInScanTable)) {
ret = wlan_associate(priv, &Adapter->ScanTable[tableIdx - 1]);
} else {
ret = -EINVAL;
}
LEAVE();
return ret;
}
/**
* @brief Send Deauthentication Request
*
* @param priv A pointer to wlan_private structure
* @return WLAN_STATUS_SUCCESS--success, WLAN_STATUS_FAILURE--fail
*/
int
SendDeauthentication(wlan_private * priv)
{
return PrepareAndSendCommand(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
0, HostCmd_OPTION_WAITFORRSP, 0, NULL);
}
/**
* @brief Append a generic IE as a passthrough TLV to a TLV buffer.
*
* This function is called from the network join command prep. routine.
* If the IE buffer has been setup by the application, this routine appends
* the buffer as a passthrough TLV type to the request.
*
* @param priv A pointer to wlan_private structure
* @param ppBuffer pointer to command buffer pointer
*
* @return bytes added to the buffer
*/
static int
wlan_cmd_append_generic_ie(wlan_private * priv, u8 ** ppBuffer)
{
wlan_adapter *Adapter = priv->adapter;
int retLen = 0;
MrvlIEtypesHeader_t ieHeader;
/* Null Checks */
if (ppBuffer == 0)
return 0;
if (*ppBuffer == 0)
return 0;
/*
* If there is a generic ie buffer setup, append it to the return
* parameter buffer pointer.
*/
if (Adapter->genIeBufferLen) {
wlan_debug3("append generic %d to %p\n", Adapter->genIeBufferLen,
*ppBuffer);
/* Wrap the generic IE buffer with a passthrough TLV type */
ieHeader.Type = wlan_cpu_to_le16(TLV_TYPE_PASSTHROUGH);
ieHeader.Len = wlan_cpu_to_le16(Adapter->genIeBufferLen);
memcpy(*ppBuffer, &ieHeader, sizeof(ieHeader));
/* Increment the return size and the return buffer pointer param */
*ppBuffer += sizeof(ieHeader);
retLen += sizeof(ieHeader);
/* Copy the generic IE buffer to the output buffer, advance pointer */
memcpy(*ppBuffer, Adapter->genIeBuffer, Adapter->genIeBufferLen);
/* Increment the return size and the return buffer pointer param */
*ppBuffer += Adapter->genIeBufferLen;
retLen += Adapter->genIeBufferLen;
/* Reset the generic IE buffer */
Adapter->genIeBufferLen = 0;
}
/* return the length appended to the buffer */
return retLen;
}
/**
* @brief Append any application provided Marvell TLVs to a TLV buffer.
*
* This function is called from the network join command prep. routine.
* If the Marvell TLV buffer has been setup by the application, this routine
* appends the buffer to the request.
*
* @param priv A pointer to wlan_private structure
* @param ppBuffer pointer to command buffer pointer
*
* @return bytes added to the buffer
*/
static int
wlan_cmd_append_marvell_tlv(wlan_private * priv, u8 ** ppBuffer)
{
wlan_adapter *Adapter = priv->adapter;
int retLen = 0;
/* Null Checks */
if (ppBuffer == 0)
return 0;
if (*ppBuffer == 0)
return 0;
/*
* If there is a Marvell TLV buffer setup, append it to the return
* parameter buffer pointer.
*/
if (Adapter->mrvlAssocTlvBufferLen) {
wlan_debug3("append tlv %d to %p\n",
Adapter->mrvlAssocTlvBufferLen, *ppBuffer);
/* Copy the TLV buffer to the output buffer, advance pointer */
memcpy(*ppBuffer,
Adapter->mrvlAssocTlvBuffer, Adapter->mrvlAssocTlvBufferLen);
/* Increment the return size and the return buffer pointer param */
*ppBuffer += Adapter->mrvlAssocTlvBufferLen;
retLen += Adapter->mrvlAssocTlvBufferLen;
/* Reset the Marvell TLV buffer */
Adapter->mrvlAssocTlvBufferLen = 0;
}
/* return the length appended to the buffer */
return retLen;
}
/**
* @brief Append TSF tracking info from the scan table for the target AP
*
* This function is called from the network join command prep. routine.
* The TSF table TSF sent to the firmware contians two TSF values:
* - the TSF of the target AP from its previous beacon/probe response
* - the TSF timestamp of our local MAC at the time we observed the
* beacon/probe response.
*
* The firmware uses the timestamp values to set an initial TSF value
* in the MAC for the new association after a reassociation attempt.
*
* @param priv A pointer to wlan_private structure
* @param ppBuffer A pointer to command buffer pointer
* @param pBSSDesc A pointer to the BSS Descriptor from the scan table of
* the AP we are trying to join
*
* @return bytes added to the buffer
*/
static int
wlan_cmd_append_tsf_tlv(wlan_private * priv, u8 ** ppBuffer,
BSSDescriptor_t * pBSSDesc)
{
MrvlIEtypes_TsfTimestamp_t tsfTlv;
u64 tsfVal;
/* Null Checks */
if (ppBuffer == 0)
return 0;
if (*ppBuffer == 0)
return 0;
tsfTlv.Header.Type = wlan_cpu_to_le16(TLV_TYPE_TSFTIMESTAMP);
tsfTlv.Header.Len = wlan_cpu_to_le16(2 * sizeof(tsfVal));
memcpy(*ppBuffer, &tsfTlv, sizeof(tsfTlv.Header));
*ppBuffer += sizeof(tsfTlv.Header);
/* TSF timestamp from the firmware TSF when the bcn/prb rsp was received */
tsfVal = wlan_cpu_to_le64(pBSSDesc->networkTSF);
memcpy(*ppBuffer, &tsfVal, sizeof(tsfVal));
*ppBuffer += sizeof(tsfVal);
memcpy(&tsfVal, pBSSDesc->TimeStamp, sizeof(tsfVal));
wlan_debug3( "ASSOC: TSF offset calc: %016llx - %016llx\n",
tsfVal, pBSSDesc->networkTSF);
tsfVal = wlan_cpu_to_le64(tsfVal);
memcpy(*ppBuffer, &tsfVal, sizeof(tsfVal));
*ppBuffer += sizeof(tsfVal);
return (sizeof(tsfTlv.Header) + (2 * sizeof(tsfVal)));
}
/**
* @brief This function prepares command of deauthenticate.
*
* @param priv A pointer to wlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
wlan_cmd_802_11_deauthenticate(wlan_private * priv, HostCmd_DS_COMMAND * cmd)
{
wlan_adapter *Adapter = priv->adapter;
HostCmd_DS_802_11_DEAUTHENTICATE *dauth = &cmd->params.deauth;
ENTER();
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
cmd->Size =
wlan_cpu_to_le16(sizeof(HostCmd_DS_802_11_DEAUTHENTICATE) + S_DS_GEN);
/* set AP MAC address */
memcpy(dauth->MacAddr,
&Adapter->CurBssParams.BSSDescriptor.MacAddress, ETH_ALEN);
/* Reason code 3 = Station is leaving */
#define REASON_CODE_STA_LEAVING 3
dauth->ReasonCode = wlan_cpu_to_le16(REASON_CODE_STA_LEAVING);
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function prepares command of association.
*
* @param priv A pointer to wlan_private structure
* @param cmd A pointer to HostCmd_DS_COMMAND structure
* @param pdata_buf Void cast of BSSDescriptor_t from the scan table to assoc
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static char parabuf[256];
int
wlan_cmd_802_11_associate(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, void *pdata_buf)
{
wlan_adapter *Adapter = priv->adapter;
HostCmd_DS_802_11_ASSOCIATE *pAsso = &cmd->params.associate;
int ret = WLAN_STATUS_SUCCESS;
BSSDescriptor_t *pBSSDesc;
WLAN_802_11_RATES rates;
int ratesSize;
u8 *pos;
u16 TmpCap;
u8* tempuf;
u32 temlen=0;
MrvlIEtypes_SsIdParamSet_t *pSsidTlv;
MrvlIEtypes_PhyParamSet_t *pPhyTlv;
MrvlIEtypes_SsParamSet_t *pSsTlv;
MrvlIEtypes_RatesParamSet_t *pRatesTlv;
MrvlIEtypes_AuthType_t *pAuthTlv;
MrvlIEtypes_RsnParamSet_t *pRsnTlv;
ENTER();
tempuf=rt_malloc(256);
if(tempuf==RT_NULL)
{
wlan_debug1("wlan_cmd_802_11_associate fail to get mem\r\n ");
goto done;
}
rt_memset(tempuf,0x00,256);
pBSSDesc = (BSSDescriptor_t *) pdata_buf;
pos = (u8 *) pAsso;
cmd->Command = wlan_cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
/* Save so we know which BSS Desc to use in the response handler */
Adapter->pAttemptedBSSDesc = pBSSDesc;
rt_memcpy(pAsso->PeerStaAddr,
pBSSDesc->MacAddress, sizeof(pAsso->PeerStaAddr));
pos += sizeof(pAsso->PeerStaAddr);
/* set the listen interval */
pAsso->ListenInterval = wlan_cpu_to_le16(Adapter->ListenInterval);
pos += sizeof(pAsso->CapInfo);
pos += sizeof(pAsso->ListenInterval);
pos += sizeof(pAsso->Reserved1);
pSsidTlv=(MrvlIEtypes_SsIdParamSet_t *)tempuf;
//pSsidTlv = (MrvlIEtypes_SsIdParamSet_t *) pos;
pSsidTlv->Header.Type = wlan_cpu_to_le16(TLV_TYPE_SSID);
pSsidTlv->Header.Len = pBSSDesc->Ssid.SsidLength;
rt_memcpy(pSsidTlv->SsId, pBSSDesc->Ssid.Ssid, pSsidTlv->Header.Len);
temlen+=sizeof(pSsidTlv->Header) + pSsidTlv->Header.Len;
rt_memcpy(pos, (u8*)pSsidTlv, temlen);
pos += sizeof(pSsidTlv->Header) + pSsidTlv->Header.Len;
rt_memset(tempuf,0x00,256);
temlen=0;
pPhyTlv=(MrvlIEtypes_PhyParamSet_t *)tempuf;
// pPhyTlv = (MrvlIEtypes_PhyParamSet_t *) pos;
pPhyTlv->Header.Type = wlan_cpu_to_le16(TLV_TYPE_PHY_DS);
pPhyTlv->Header.Len = sizeof(pPhyTlv->fh_ds.DsParamSet);
rt_memcpy(&pPhyTlv->fh_ds.DsParamSet,
&pBSSDesc->PhyParamSet.DsParamSet.CurrentChan,
sizeof(pPhyTlv->fh_ds.DsParamSet));
temlen=sizeof(pPhyTlv->Header) + pPhyTlv->Header.Len;
rt_memcpy(pos, (u8*)pPhyTlv, temlen);
pos += sizeof(pPhyTlv->Header) + pPhyTlv->Header.Len;
// pPhyTlv->Header.Len = wlan_cpu_to_le16(pPhyTlv->Header.Len);
rt_memset(tempuf,0x00,256);
temlen=0;
pSsTlv=(MrvlIEtypes_SsParamSet_t *)tempuf;
// pSsTlv = (MrvlIEtypes_SsParamSet_t *) pos;
pSsTlv->Header.Type = wlan_cpu_to_le16(TLV_TYPE_CF);
pSsTlv->Header.Len = sizeof(pSsTlv->cf_ibss.CfParamSet);
temlen=sizeof(pSsTlv->Header) + pSsTlv->Header.Len;
rt_memcpy(pos, (u8*)pSsTlv, temlen);
pos += sizeof(pSsTlv->Header) + pSsTlv->Header.Len;
// pSsTlv->Header.Len = wlan_cpu_to_le16(pSsTlv->Header.Len);
/* Get the common rates supported between the driver and the BSS Desc */
if (setup_rates_from_bssdesc(Adapter, pBSSDesc, rates, &ratesSize)) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
/* Setup the Rates TLV in the association command */
rt_memset(tempuf,0x00,256);
temlen=0;
pRatesTlv=(MrvlIEtypes_RatesParamSet_t *)tempuf;
//pRatesTlv = (MrvlIEtypes_RatesParamSet_t *) pos;
pRatesTlv->Header.Type = wlan_cpu_to_le16(TLV_TYPE_RATES);
pRatesTlv->Header.Len = wlan_cpu_to_le16(ratesSize);
rt_memcpy(pRatesTlv->Rates, rates, ratesSize);
temlen=sizeof(pRatesTlv->Header) + ratesSize;
rt_memcpy(pos, (u8*)pRatesTlv, temlen);
pos += sizeof(pRatesTlv->Header) + ratesSize;
wlan_debug3( "ASSOC_CMD: Rates size = %d\n", ratesSize);
/* Add the Authentication type to be used for Auth frames if needed */
rt_memset(tempuf,0x00,256);
temlen=0;
pAuthTlv=(MrvlIEtypes_AuthType_t *)tempuf;
// pAuthTlv = (MrvlIEtypes_AuthType_t *) pos;
pAuthTlv->Header.Type = wlan_cpu_to_le16(TLV_TYPE_AUTH_TYPE);
pAuthTlv->Header.Len = sizeof(pAuthTlv->AuthType);
pAuthTlv->AuthType = Adapter->SecInfo.AuthenticationMode;
temlen=sizeof(pAuthTlv->Header) + pAuthTlv->Header.Len;
rt_memcpy(pos, (u8*)pAuthTlv, temlen);
pos += sizeof(pAuthTlv->Header) + pAuthTlv->Header.Len;
// pAuthTlv->Header.Len = wlan_cpu_to_le16(pAuthTlv->Header.Len);
rt_memset(tempuf,0x00,256);
temlen=0;
if (!Adapter->wps.SessionEnable) {
if (Adapter->SecInfo.WPAEnabled || Adapter->SecInfo.WPA2Enabled) {
pRsnTlv=(MrvlIEtypes_RsnParamSet_t *)tempuf;
// pRsnTlv = (MrvlIEtypes_RsnParamSet_t *) pos;
pRsnTlv->Header.Type = (u16) Adapter->Wpa_ie[0]; /* WPA_IE or WPA2_IE */
pRsnTlv->Header.Type = pRsnTlv->Header.Type & 0x00FF;
pRsnTlv->Header.Type = wlan_cpu_to_le16(pRsnTlv->Header.Type);
pRsnTlv->Header.Len = (u16) Adapter->Wpa_ie[1];
pRsnTlv->Header.Len = pRsnTlv->Header.Len & 0x00FF;
rt_memcpy(pRsnTlv->RsnIE, &Adapter->Wpa_ie[2], pRsnTlv->Header.Len);
temlen+=sizeof(pRsnTlv->Header) + pRsnTlv->Header.Len;
rt_memcpy(pos, (u8*)pRsnTlv, temlen);
// HEXDUMP("ASSOC_CMD: RSN IE", (u8 *) pRsnTlv,
// sizeof(pRsnTlv->Header) + pRsnTlv->Header.Len);
pos += sizeof(pRsnTlv->Header) + pRsnTlv->Header.Len;
// pRsnTlv->Header.Len = wlan_cpu_to_le16(pRsnTlv->Header.Len);
}
}
rt_free(tempuf);
wlan_wmm_process_association_req(priv, &pos, &pBSSDesc->wmmIE);
wlan_cmd_append_generic_ie(priv, &pos);
wlan_cmd_append_marvell_tlv(priv, &pos);
wlan_cmd_append_tsf_tlv(priv, &pos, pBSSDesc);
if (wlan_parse_dnld_countryinfo_11d(priv)) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
cmd->Size = wlan_cpu_to_le16((u16) (pos - (u8 *) pAsso) + S_DS_GEN);
/* set the Capability info at last */
rt_memcpy(&TmpCap, &pBSSDesc->Cap, sizeof(pAsso->CapInfo));
TmpCap &= CAPINFO_MASK;
wlan_debug3( "ASSOC_CMD: TmpCap=%4X CAPINFO_MASK=%4X\n",
TmpCap, CAPINFO_MASK);
TmpCap = wlan_cpu_to_le16(TmpCap);
rt_memcpy(&pAsso->CapInfo, &TmpCap, sizeof(pAsso->CapInfo));
done:
LEAVE();
return ret;
}
/**
* @brief Association firmware command response handler
*
* The response buffer for the association command has the following
* memory layout.
*
* For cases where an association response was not received (indicated
* by the CapInfo and AId field):
*
* .------------------------------------------------------------.
* | Header(4 * sizeof(u16)): Standard command response hdr |
* .------------------------------------------------------------.
* | CapInfo/Error Return(u16): |
* | 0xFFFF(-1): Internal error |
* | 0xFFFE(-2): Authentication unhandled message |
* | 0xFFFD(-3): Authentication refused |
* .------------------------------------------------------------.
* | StatusCode(u16): |
* | If CapInfo is -1: |
* | (1) Internal processing failure |
* | (2) Timeout waiting for AP response |
* | |
* | If CapInfo is -2: |
* | An authentication frame was received but was |
* | not handled by the firmware. IEEE Status |
* | code for the failure is returned. |
* | |
* | If CapInfo is -3: |
* | An authentication frame was received and the |
* | StatusCode is the IEEE Status reported in the |
* | response. |
* .------------------------------------------------------------.
* | AId(u16): 0xFFFF |
* .------------------------------------------------------------.
*
*
* For cases where an association response was received, the IEEE
* standard association response frame is returned:
*
* .------------------------------------------------------------.
* | Header(4 * sizeof(u16)): Standard command response hdr |
* .------------------------------------------------------------.
* | CapInfo(u16): IEEE Capability |
* .------------------------------------------------------------.
* | StatusCode(u16): IEEE Status Code |
* .------------------------------------------------------------.
* | AId(u16): IEEE Association ID |
* .------------------------------------------------------------.
* | IEEE IEs(variable): Any received IEs comprising the |
* | remaining portion of a received |
* | association response frame. |
* .------------------------------------------------------------.
*
* For simplistic handling, the StatusCode field can be used to determine
* an association success (0) or failure (non-zero).
*
* @param priv A pointer to wlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
wlan_ret_802_11_associate(wlan_private * priv, HostCmd_DS_COMMAND * resp)
{
wlan_adapter *Adapter = priv->adapter;
int ret = WLAN_STATUS_SUCCESS;
IEEEtypes_AssocRsp_t *pAssocRsp;
BSSDescriptor_t *pBSSDesc;
WLAN_802_11_RATES rates;
int ratesSize;
ENTER();
pAssocRsp = (IEEEtypes_AssocRsp_t *) & resp->params;
// HEXDUMP("ASSOC_RESP:", (void *) &resp->params,
// wlan_le16_to_cpu(resp->Size) - S_DS_GEN);
Adapter->assocRspSize = MIN(wlan_le16_to_cpu(resp->Size) - S_DS_GEN,
sizeof(Adapter->assocRspBuffer));
memcpy(Adapter->assocRspBuffer, &resp->params, Adapter->assocRspSize);
if (pAssocRsp->StatusCode) {
priv->adapter->dbg.num_cmd_assoc_failure++;
wlan_debug3("ASSOC_RESP: Association Failed, status code = %d\n",
pAssocRsp->StatusCode);
ret = WLAN_STATUS_FAILURE;
goto done;
}
/* Send a Media Connected event, according to the Spec */
Adapter->MediaConnectStatus = WlanMediaStateConnected;
/* Set the attempted BSSID Index to current */
pBSSDesc = Adapter->pAttemptedBSSDesc;
wlan_debug3("ASSOC_RESP: %s\n", pBSSDesc->Ssid.Ssid);
/* Make a copy of current BSSID descriptor */
memcpy(&Adapter->CurBssParams.BSSDescriptor,
pBSSDesc, sizeof(BSSDescriptor_t));
/* update CurBssParams */
Adapter->CurBssParams.BSSDescriptor.Channel
= pBSSDesc->PhyParamSet.DsParamSet.CurrentChan;
if (setup_rates_from_bssdesc(Adapter, pBSSDesc, rates, &ratesSize)) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
/* Copy the infra. association rates into Current BSS state structure */
Adapter->CurBssParams.NumOfRates = ratesSize;
memcpy(&Adapter->CurBssParams.DataRates, rates, ratesSize);
/* Adjust the timestamps in the scan table to be relative to the newly
* associated AP's TSF
*/
wlan_scan_update_tsf_timestamps(priv, pBSSDesc);
if (pBSSDesc->wmmIE.VendHdr.ElementId == WMM_IE) {
Adapter->CurBssParams.wmm_enabled = TRUE;
} else {
Adapter->CurBssParams.wmm_enabled = FALSE;
}
if (Adapter->wmm.required && Adapter->CurBssParams.wmm_enabled) {
Adapter->wmm.enabled = TRUE;
} else {
Adapter->wmm.enabled = FALSE;
}
Adapter->CurBssParams.wmm_uapsd_enabled = FALSE;
if (Adapter->wmm.enabled == TRUE) {
Adapter->CurBssParams.wmm_uapsd_enabled
= pBSSDesc->wmmIE.QoSInfo.QosUAPSD;
}
wlan_debug3("ASSOC_RESP: CurrentPacketFilter is %x\n",
Adapter->CurrentPacketFilter);
if (Adapter->SecInfo.WPAEnabled || Adapter->SecInfo.WPA2Enabled)
Adapter->IsGTK_SET = FALSE;
Adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0;
Adapter->NF[TYPE_RXPD][TYPE_AVG] = 0;
memset(Adapter->rawSNR, 0x00, sizeof(Adapter->rawSNR));
memset(Adapter->rawNF, 0x00, sizeof(Adapter->rawNF));
Adapter->nextSNRNF = 0;
Adapter->numSNRNF = 0;
priv->adapter->dbg.num_cmd_assoc_success++;
wlan_debug3("ASSOC_RESP: Associated \n");
done:
LEAVE();
return ret;
}
/**
* @brief This function handles the command response of disassociate
*
* @param priv A pointer to wlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
wlan_ret_802_11_disassociate(wlan_private * priv, HostCmd_DS_COMMAND * resp)
{
ENTER();
priv->adapter->dbg.num_cmd_deauth++;
MacEventDisconnected(priv);
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the command response of ad_hoc_start and
* ad_hoc_join
*
* @param priv A pointer to wlan_private structure
* @param resp A pointer to HostCmd_DS_COMMAND
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
#ifdef REASSOCIATION
/**
* @brief This function triggers re-association by waking up
* re-assoc thread.
*
* @param FunctionContext A pointer to FunctionContext
* @return n/a
*/
void
MrvDrvReassocTimerFunction(void *FunctionContext)
{
wlan_private *priv = (wlan_private *) FunctionContext;
wlan_adapter *Adapter = priv->adapter;
ENTER();
PRINTM(INFO, "MrvDrvReassocTimer fired.\n");
Adapter->ReassocTimerIsSet = FALSE;
if (Adapter->PSState != PS_STATE_FULL_POWER) {
/* wait until Exit_PS command returns */
Adapter->ReassocTimerIsSet = TRUE;
ModTimer(&Adapter->MrvDrvTimer, MRVDRV_TIMER_1S);
PRINTM(INFO, "MrvDrvTimerFunction(PSState=%d) waiting"
"for Exit_PS done\n", Adapter->PSState);
LEAVE();
return;
}
PRINTM(INFO, "Waking Up the Reassoc Thread\n");
// wake_up_interruptible(&priv->ReassocThread.waitQ);
rt_event_send(&priv->ReassocThread.waitQ, WakeUpReassociationThread);
LEAVE();
return;
}
#endif /* REASSOCIATION */

57
wifi/wlan/wlan_join.h Normal file
View File

@ -0,0 +1,57 @@
/** @file wlan_join.h
*
* @brief Interface for the wlan infrastructure and adhoc join routines
*
* Driver interface functions and type declarations for the join module
* implemented in wlan_join.c. Process all start/join requests for
* both adhoc and infrastructure networks
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*
* @sa wlan_join.c
*/
/*************************************************************
Change Log:
01/11/06: Initial revision. Match new scan code, relocate related functions
************************************************************/
#ifndef _WLAN_JOIN_H
#define _WLAN_JOIN_H
//! Size of buffer allocated to store the association response from firmware
#define MRVDRV_ASSOC_RSP_BUF_SIZE 500
//! Size of buffer allocated to store IEs passed to firmware in the assoc req
#define MRVDRV_GENIE_BUF_SIZE 256
//! Size of buffer allocated to store TLVs passed to firmware in the assoc req
#define MRVDRV_ASSOC_TLV_BUF_SIZE 256
extern int wlan_cmd_802_11_authenticate(wlan_private * priv,
HostCmd_DS_COMMAND * cmd,
void *pdata_buf);
extern int wlan_cmd_802_11_deauthenticate(wlan_private * priv,
HostCmd_DS_COMMAND * cmd);
extern int wlan_cmd_802_11_associate(wlan_private * priv,
HostCmd_DS_COMMAND * cmd,
void *pdata_buf);
extern int wlan_ret_802_11_authenticate(wlan_private * priv,
HostCmd_DS_COMMAND * resp);
extern int wlan_ret_802_11_disassociate(wlan_private * priv,
HostCmd_DS_COMMAND * resp);
extern int wlan_ret_802_11_associate(wlan_private * priv,
HostCmd_DS_COMMAND * resp);
extern int wlan_associate(wlan_private * priv, BSSDescriptor_t * pBSSDesc);
extern int wlan_associate_to_table_idx(wlan_private * priv, int tableIdx);
extern int wlanidle_off(wlan_private * priv);
extern int SendDeauthentication(wlan_private * priv);
#endif

921
wifi/wlan/wlan_main.c Normal file
View File

@ -0,0 +1,921 @@
/* @file wlan_main.c
*
* @brief This file contains the major functions in WLAN
* driver. It includes init, exit, open, close and main
* thread etc..
*
*/
/**
* @mainpage M-WLAN Linux Driver
*
* @section overview_sec Overview
*
* The M-WLAN is a Linux reference driver for Marvell
* 802.11 (a/b/g) WLAN chipset.
*
* @section copyright_sec Copyright
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*
*/
/********************************************************
Change log:
09/30/05: Add Doxygen format comments
12/09/05: Add TX_QUEUE support
01/05/06: Add kernel 2.6.x support
01/11/06: Conditionalize new scan/join functions.
01/12/06: Add TxLockFlag for UAPSD power save mode
and Proprietary Periodic sleep support
********************************************************/
#include "include.h"
#include "wlan_debug.h"
#include <netif/ethernetif.h>
#include <rtdef.h>
/********************************************************
Local Variables
********************************************************/
static struct rt_semaphore tx_sem_lock;
struct rt_event wlan_tx_event;
u32 driver_flags;
#define WLAN_TX_PWR_DEFAULT 20 /*100mW */
#define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */
#define WLAN_TX_PWR_JP_DEFAULT 16 /*50mW */
#define WLAN_TX_PWR_FR_100MW 20 /*100mW */
#define WLAN_TX_PWR_EMEA_DEFAULT 20 /*100mW */
/* Format { Channel, Frequency (MHz), MaxTxPower } */
/* Band: 'B/G', Region: USA FCC/Canada IC */
static CHANNEL_FREQ_POWER channel_freq_power_US_BG[] = {
{1, 2412, WLAN_TX_PWR_US_DEFAULT},
{2, 2417, WLAN_TX_PWR_US_DEFAULT},
{3, 2422, WLAN_TX_PWR_US_DEFAULT},
{4, 2427, WLAN_TX_PWR_US_DEFAULT},
{5, 2432, WLAN_TX_PWR_US_DEFAULT},
{6, 2437, WLAN_TX_PWR_US_DEFAULT},
{7, 2442, WLAN_TX_PWR_US_DEFAULT},
{8, 2447, WLAN_TX_PWR_US_DEFAULT},
{9, 2452, WLAN_TX_PWR_US_DEFAULT},
{10, 2457, WLAN_TX_PWR_US_DEFAULT},
{11, 2462, WLAN_TX_PWR_US_DEFAULT}
};
/* Band: 'B/G', Region: Europe ETSI */
static CHANNEL_FREQ_POWER channel_freq_power_EU_BG[] = {
{1, 2412, WLAN_TX_PWR_EMEA_DEFAULT},
{2, 2417, WLAN_TX_PWR_EMEA_DEFAULT},
{3, 2422, WLAN_TX_PWR_EMEA_DEFAULT},
{4, 2427, WLAN_TX_PWR_EMEA_DEFAULT},
{5, 2432, WLAN_TX_PWR_EMEA_DEFAULT},
{6, 2437, WLAN_TX_PWR_EMEA_DEFAULT},
{7, 2442, WLAN_TX_PWR_EMEA_DEFAULT},
{8, 2447, WLAN_TX_PWR_EMEA_DEFAULT},
{9, 2452, WLAN_TX_PWR_EMEA_DEFAULT},
{10, 2457, WLAN_TX_PWR_EMEA_DEFAULT},
{11, 2462, WLAN_TX_PWR_EMEA_DEFAULT},
{12, 2467, WLAN_TX_PWR_EMEA_DEFAULT},
{13, 2472, WLAN_TX_PWR_EMEA_DEFAULT}
};
/* Band: 'B/G', Region: Spain */
static CHANNEL_FREQ_POWER channel_freq_power_SPN_BG[] = {
{10, 2457, WLAN_TX_PWR_DEFAULT},
{11, 2462, WLAN_TX_PWR_DEFAULT}
};
/* Band: 'B/G', Region: France */
static CHANNEL_FREQ_POWER channel_freq_power_FR_BG[] = {
{10, 2457, WLAN_TX_PWR_FR_100MW},
{11, 2462, WLAN_TX_PWR_FR_100MW},
{12, 2467, WLAN_TX_PWR_FR_100MW},
{13, 2472, WLAN_TX_PWR_FR_100MW}
};
/* Band: 'B/G', Region: Japan */
static CHANNEL_FREQ_POWER channel_freq_power_JPN41_BG[] = {
{1, 2412, WLAN_TX_PWR_JP_DEFAULT},
{2, 2417, WLAN_TX_PWR_JP_DEFAULT},
{3, 2422, WLAN_TX_PWR_JP_DEFAULT},
{4, 2427, WLAN_TX_PWR_JP_DEFAULT},
{5, 2432, WLAN_TX_PWR_JP_DEFAULT},
{6, 2437, WLAN_TX_PWR_JP_DEFAULT},
{7, 2442, WLAN_TX_PWR_JP_DEFAULT},
{8, 2447, WLAN_TX_PWR_JP_DEFAULT},
{9, 2452, WLAN_TX_PWR_JP_DEFAULT},
{10, 2457, WLAN_TX_PWR_JP_DEFAULT},
{11, 2462, WLAN_TX_PWR_JP_DEFAULT},
{12, 2467, WLAN_TX_PWR_JP_DEFAULT},
{13, 2472, WLAN_TX_PWR_JP_DEFAULT}
};
/* Band: 'B/G', Region: Japan */
static CHANNEL_FREQ_POWER channel_freq_power_JPN40_BG[] = {
{14, 2484, WLAN_TX_PWR_JP_DEFAULT}
};
/********************************************************
Global Variables
********************************************************/
struct rt_wlan_dev *wlan_eth = NULL;
struct rt_semaphore driver_sem;
/**
* the structure for channel, frequency and power
*/
typedef struct _region_cfp_table
{
u8 region;
CHANNEL_FREQ_POWER *cfp_BG;
int cfp_no_BG;
} region_cfp_table_t;
/**
* the structure for the mapping between region and CFP
*/
region_cfp_table_t region_cfp_table[] = {
{0x10, /*US FCC */
channel_freq_power_US_BG,
sizeof(channel_freq_power_US_BG) / sizeof(CHANNEL_FREQ_POWER),
}
,
{0x20, /*CANADA IC */
channel_freq_power_US_BG,
sizeof(channel_freq_power_US_BG) / sizeof(CHANNEL_FREQ_POWER),
}
,
{0x30, /*EU*/ channel_freq_power_EU_BG,
sizeof(channel_freq_power_EU_BG) / sizeof(CHANNEL_FREQ_POWER),
}
,
{0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
sizeof(channel_freq_power_SPN_BG) / sizeof(CHANNEL_FREQ_POWER),
}
,
{0x32, /*FRANCE*/ channel_freq_power_FR_BG,
sizeof(channel_freq_power_FR_BG) / sizeof(CHANNEL_FREQ_POWER),
}
,
{0x40, /*JAPAN*/ channel_freq_power_JPN40_BG,
sizeof(channel_freq_power_JPN40_BG) / sizeof(CHANNEL_FREQ_POWER),
}
,
{0x41, /*JAPAN*/ channel_freq_power_JPN41_BG,
sizeof(channel_freq_power_JPN41_BG) / sizeof(CHANNEL_FREQ_POWER),
}
,
/*Add new region here */
};
/**
* the rates supported by the card
*/
u8 WlanDataRates[WLAN_SUPPORTED_RATES] =
{ 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00
};
/**
* the rates supported
*/
u8 SupportedRates[G_SUPPORTED_RATES] =
{ 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48,
0x60, 0x6c, 0
};
/**
* the global variable of a pointer to wlan_private
* structure variable
*/
wlan_private *wlanpriv = NULL;
u32 DSFreqList[15] = {
0, 2412000, 2417000, 2422000, 2427000, 2432000, 2437000, 2442000,
2447000, 2452000, 2457000, 2462000, 2467000, 2472000, 2484000
};
/**
* the table to keep region code
*/
u16 RegionCodeToIndex[MRVDRV_MAX_REGION_CODE] =
{ 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41 };
char main_thread_stack[2048];
char assciation_thread_stack[2048];
/********************************************************
Local Functions
********************************************************/
/**
* @brief This function opens the network device
*
* @param dev A pointer to net_device structure
* @return WLAN_STATUS_SUCCESS
*/
static int
wlan_open(struct rt_wlan_dev *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
priv->open = TRUE;
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function closes the network device
*
* @param dev A pointer to net_device structure
* @return WLAN_STATUS_SUCCESS
*/
static int
wlan_close(struct rt_wlan_dev *dev)
{
wlan_private *priv = dev->priv;
ENTER();
wlan_clean_txrx(priv);
priv->open = FALSE;
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles packet transmission
*
* @param skb A pointer to sk_buff structure
* @param dev A pointer to net_device structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
rt_err_t rt_wlan_dev_tx( rt_device_t dev, struct pbuf* packet)
{
int ret;
struct rt_wlan_dev *wlandev=dev->user_data;
wlan_private *priv = wlandev->priv;
ret = RT_EOK;
ENTER();
wlan_debug3( "Data <= kernel\n");
rt_sem_take(&tx_sem_lock, RT_WAITING_FOREVER);
if (wlan_tx_packet(priv, packet)) {
rt_sem_release(&tx_sem_lock);
/* Transmit failed */
ret = RT_ERROR;
}
rt_sem_release(&tx_sem_lock);
LEAVE();
return ret;
}
/**
* @brief This function handles the timeout of packet
* transmission
*
* @param dev A pointer to net_device structure
* @return n/a
*/
static void
wlan_tx_timeout(struct rt_wlan_dev *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
ENTER();
wlan_debug2("wlan_tx timeout\n");
priv->adapter->dbg.num_tx_timeout++;
priv->adapter->IntCounter++;
rt_event_send(&priv->MainThread.waitQ, WakeUpMainThread);
LEAVE();
}
/**
* @brief This function returns the network statistics
*
* @param dev A pointer to wlan_private structure
* @return A pointer to net_device_stats structure
*/
static struct net_device_stats *
wlan_get_stats(struct rt_wlan_dev *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
return &priv->stats;
}
/**
* @brief This function sets the MAC address to firmware.
*
* @param priv A pointer to wlan_private structure
* @param pRxPD A pointer to RxPD structure of received packet
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int
wlan_set_mac_address(struct rt_wlan_dev *dev, char *addr)
{
int ret = WLAN_STATUS_SUCCESS;
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *Adapter = priv->adapter;
ENTER();
memset(Adapter->CurrentAddr, 0, MRVDRV_ETH_ADDR_LEN);
/* dev->dev_addr is 8 bytes */
rt_memcpy(Adapter->CurrentAddr, addr, ETH_ALEN);
ret = PrepareAndSendCommand(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
HostCmd_ACT_SET,
HostCmd_OPTION_WAITFORRSP, 0, NULL);
if (ret) {
wlan_debug1("set mac address failed.\n");
ret = WLAN_STATUS_FAILURE;
goto done;
}
rt_memcpy(dev->dev_addr, Adapter->CurrentAddr, ETH_ALEN);
done:
LEAVE();
return ret;
}
/**
* @brief This function sets multicast addresses to firmware
*
* @param dev A pointer to net_device structure
* @return n/a
*/
static void
wlan_set_multicast_list(struct rt_wlan_dev *dev)
{
wlan_private *priv = dev->priv;
wlan_adapter *Adapter = priv->adapter;
int OldPacketFilter;
ENTER();
OldPacketFilter = Adapter->CurrentPacketFilter;
#if 0
if (dev->flags & IFF_PROMISC) {
wlan_debug3("Enable Promiscuous mode\n");
Adapter->CurrentPacketFilter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
Adapter->CurrentPacketFilter &= ~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
} else {
/* Multicast */
Adapter->CurrentPacketFilter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
if (dev->flags & IFF_ALLMULTI || dev->mc_count >
MRVDRV_MAX_MULTICAST_LIST_SIZE) {
wlan_debug3("Enabling All Multicast!\n");
Adapter->CurrentPacketFilter |=
HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
} else {
Adapter->CurrentPacketFilter &=
~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
if (!dev->mc_count) {
wlan_debug3("No multicast addresses - "
"disabling multicast!\n");
} else {
int i;
Adapter->NumOfMulticastMACAddr =
CopyMulticastAddrs(Adapter, dev);
PRINTM(INFO, "Multicast addresses: %d\n", dev->mc_count);
for (i = 0; i < dev->mc_count; i++) {
wlan_debug3("Multicast address %d:"
"%x %x %x %x %x %x\n", i,
Adapter->MulticastList[i][0],
Adapter->MulticastList[i][1],
Adapter->MulticastList[i][2],
Adapter->MulticastList[i][3],
Adapter->MulticastList[i][4],
Adapter->MulticastList[i][5]);
}
/* set multicast addresses to firmware */
PrepareAndSendCommand(priv, HostCmd_CMD_MAC_MULTICAST_ADR,
HostCmd_ACT_GEN_SET, 0, 0, NULL);
}
}
}
if (Adapter->CurrentPacketFilter != OldPacketFilter) {
PrepareAndSendCommand(priv,
HostCmd_CMD_MAC_CONTROL,
0, 0, 0, &Adapter->CurrentPacketFilter);
}
#endif
LEAVE();
}
/**
* @brief This function pops rx_skb from the rx queue.
*
* @param RxSkbQ A pointer to rx_skb queue
* @return A pointer to skb
*/
static struct sk_buff * wlan_pop_rx_skb(struct sk_buff *RxSkbQ)
{
struct sk_buff *skb_data = NULL;
if (!list_empty((struct list_head *) RxSkbQ)) {
skb_data = RxSkbQ->next;
list_del((struct list_head *) RxSkbQ->next);
}
return skb_data;
}
/**
* @brief This function hanldes the major job in WLAN driver.
* it handles the event generated by firmware, rx data received
* from firmware and tx data sent from kernel.
*
* @param data A pointer to wlan_thread structure
* @return WLAN_STATUS_SUCCESS
*/
static void wlan_service_main_thread(void *data)
{
wlan_thread *thread = data;
wlan_private *priv = thread->priv;
wlan_adapter *Adapter = priv->adapter;
u8 ireg = 0;
rt_uint32_t e;
ENTER();
if (rt_sem_init(&driver_sem, "wlansem", 1, RT_IPC_FLAG_FIFO)!=RT_EOK)
{
wlan_debug2("init driver_sem failed/r/n");
return ;
}
wlan_activate_thread(thread);
wmm_init(priv);
for (;;) {
if ((Adapter->WakeupTries) ||
(Adapter->PSState == PS_STATE_SLEEP
&& !Adapter->bWakeupDevRequired) ||
(!Adapter->IntCounter &&
Adapter->PSState == PS_STATE_PRE_SLEEP) ||
(!Adapter->IntCounter
&& (priv->wlan_dev.dnld_sent || Adapter->TxLockFlag
|| wmm_lists_empty(priv) || wmm_is_queue_stopped(priv))
&& (priv->wlan_dev.dnld_sent || !Adapter->CurrentTxSkb)
&& (priv->wlan_dev.dnld_sent || Adapter->CurCmd ||
list_empty(&Adapter->CmdPendingQ))
)
) {
wlan_debug2 ("main-thread sleeping... "
"WakeupReq=%s Conn=%s PS_Mode=%d PS_State=%d\n\r",
(Adapter->bWakeupDevRequired) ? "Y" : "N",
(Adapter->MediaConnectStatus) ? "Y" : "N",
Adapter->PSMode, Adapter->PSState);
rt_event_recv(&thread->waitQ,WakeUpMainThread,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&e);
wlan_debug2 ("main-thread waking up: IntCnt=%d ""CurCmd=%s CmdPending=%s\n\r"
"Connect=%s "
"CurTxSkb=%s dnld_sent=%d\n\r",
Adapter->IntCounter,
(Adapter->CurCmd) ? "Y" : "N",
list_empty(&Adapter->CmdPendingQ) ? "N" : "Y",
(Adapter->MediaConnectStatus) ? "Y" : "N",
(Adapter->CurrentTxSkb) ? "Y" : "N",
priv->wlan_dev.dnld_sent);
} else {
}
if (Adapter->IntCounter) {
rt_sem_take(&driver_sem, RT_WAITING_FOREVER);
Adapter->IntCounter = 0;
rt_sem_release(&driver_sem);
if (sbi_get_int_status(priv, &ireg)) {
wlan_debug1("main-thread: reading HOST_INT_STATUS_REG failed\n");
wlan_debug1("sbi_get_int_status return \n");
}
rt_sem_take(&driver_sem, RT_WAITING_FOREVER);
Adapter->HisRegCpy |= ireg;
rt_sem_release(&driver_sem);
wlan_debug1("INT: status = 0x%x\n", Adapter->HisRegCpy);
} else if (Adapter->bWakeupDevRequired
&& ((Adapter->PSState == PS_STATE_SLEEP)
)
) {
Adapter->WakeupTries++;
wlan_debug3("Wakeup device... WakeupReq=%s Conn=%s PS_Mode=%d PS_State=%d\n",
(Adapter->bWakeupDevRequired) ? "Y" : "N",
(priv->adapter->MediaConnectStatus) ? "Y" : "N",
priv->adapter->PSMode, priv->adapter->PSState);
/* Wake up device */
if (sbi_exit_deep_sleep(priv))
wlan_debug3("main-thread: wakeup dev failed\n");
continue;
}
/* Command response? */
if (Adapter->HisRegCpy & HIS_CmdUpLdRdy) {
rt_sem_take(&driver_sem, RT_WAITING_FOREVER);
Adapter->HisRegCpy &= ~HIS_CmdUpLdRdy;
rt_sem_release(&driver_sem);
wlan_process_rx_command(priv);
}
/* Any received data? */
if (Adapter->HisRegCpy & HIS_RxUpLdRdy) {
rt_sem_take(&driver_sem, RT_WAITING_FOREVER);
Adapter->HisRegCpy &= ~HIS_RxUpLdRdy;
rt_sem_release(&driver_sem);
wlan_send_rxskbQ(priv);
}
/* Any Card Event */
if (Adapter->HisRegCpy & HIS_CardEvent) {
rt_sem_take(&driver_sem, RT_WAITING_FOREVER);
Adapter->HisRegCpy &= ~HIS_CardEvent;
rt_sem_release(&driver_sem);
if (sbi_read_event_cause(priv)) {
wlan_debug1("main-thread: sbi_read_event_cause failed.\n");
continue;
}
wlan_process_event(priv);
}
/* Check if we need to confirm Sleep Request received previously */
if (Adapter->PSState == PS_STATE_PRE_SLEEP) {
if (!priv->wlan_dev.dnld_sent && !Adapter->CurCmd) {
wlan_debug1("Adapter->MediaConnectStatus ==WlanMediaStateConnected");
PSConfirmSleep(priv, (u16) Adapter->PSMode);
}
}
/* The PS state is changed during processing of
* Sleep Request event above
*/
if ((Adapter->PSState == PS_STATE_SLEEP)
|| (Adapter->PSState == PS_STATE_PRE_SLEEP)) {
continue;
}
/* Execute the next command */
if (!priv->wlan_dev.dnld_sent && !Adapter->CurCmd) {
ExecuteNextCommand(priv);
}
if (!priv->wlan_dev.dnld_sent
&& !wmm_lists_empty(priv) && !wmm_is_queue_stopped(priv)) {
if ((Adapter->PSState == PS_STATE_FULL_POWER)
|| (Adapter->sleep_period.period == 0)
|| (Adapter->TxLockFlag == FALSE)) {
wmm_process_tx(priv);
}
}
}
LEAVE();
return ;
}
/**
* @brief This function adds the card. it will probe the
* card, allocate the wlan_priv and initialize the device.
*
* @param card A pointer to card
* @return A pointer to wlan_private structure
*/
static wlan_private * wlan_FW_thread_init(struct rt_wlan_dev *wlandev)
{
struct rt_wlan_dev *dev = NULL;
wlan_private *priv = NULL;
if(wlandev==NULL){
wlan_debug1( "wlan add card input error\n");
return NULL;
}
dev=wlandev;
priv = (wlan_private*)rt_malloc(sizeof(wlan_private));
if(!priv ) {
wlan_debug1( "Init ethernet device private failed!\n");
return NULL;
}
rt_memset(priv,0x00,sizeof(wlan_private));
dev->priv=priv;
wlanpriv= priv;
wlan_eth=dev;
priv->adapter =(wlan_adapter*) rt_malloc(sizeof(wlan_adapter));
if(!priv->adapter) {
wlan_debug1("Allocate buffer for wlan_adapter failed!\n");
goto err_malloc;
}
rt_memset(priv->adapter, 0, sizeof(wlan_adapter));
rt_sem_init(&priv->adapter->wmm.flowcrsem, "tx_flowcr", 0, RT_IPC_FLAG_FIFO);
priv->wlan_dev.netdev = dev;
rt_event_init(&priv->adapter->ds_awake_q, "deepsleep", RT_IPC_FLAG_FIFO);
INIT_LIST_HEAD(&priv->adapter->CmdFreeQ);
INIT_LIST_HEAD(&priv->adapter->CmdPendingQ);
priv->MainThread.priv = priv;
rt_thread_init(&priv->MainThread.task,
"wlan_men_thread",
wlan_service_main_thread,
&priv->MainThread,
&main_thread_stack[0],
sizeof(main_thread_stack), 121, 100);
rt_thread_startup(&priv->MainThread.task);
rt_sem_init(&tx_sem_lock, "wlan_tx_lock", 1, RT_IPC_FLAG_FIFO);
if (spi_register_dev(priv) < 0) {
wlan_debug1("Failed to register wlan device!\n");
goto err_registerdev;
}
wlan_debug2("%s: Marvell Wlan 802.11 Adapter "
"revision 0x%02X at IRQ %i\n", dev->name,
priv->adapter->chip_rev, dev->irq);
/* init FW and HW */
if (wlan_init_fw(priv)) {
wlan_debug1("Firmware Init Failed\n");
goto err_init_fw;
}
return priv;
err_init_fw:
err_registerdev:
err_malloc:
rt_free(priv);
wlanpriv = NULL;
return NULL;
}
/**
* @brief This function removes the card.
*
* @param priv A pointer to card
* @return WLAN_STATUS_SUCCESS
*/
static int
wlan_remove_card(void *card)
{
wlan_private *priv = wlanpriv;
wlan_adapter *Adapter;
struct rt_wlan_dev *dev;
ENTER();
if (!priv) {
LEAVE();
return WLAN_STATUS_SUCCESS;
}
Adapter = priv->adapter;
if (!Adapter) {
LEAVE();
return WLAN_STATUS_SUCCESS;
}
dev = priv->wlan_dev.netdev;
rt_event_send(&Adapter->ds_awake_q, 0x01);
if (Adapter->CurCmd) {
rt_kprintf("Wake up current cmdwait_q\n");
rt_event_send(&Adapter->CurCmd->cmdwait, CmdWaitQWoken);
}
Adapter->CurCmd = NULL;
if (Adapter->MediaConnectStatus == WlanMediaStateConnected) {
wlan_clean_txrx(priv);
Adapter->MediaConnectStatus = WlanMediaStateDisconnected;
}
if (Adapter->PSMode == Wlan802_11PowerModeMAX_PSP) {
Adapter->PSMode = Wlan802_11PowerModeCAM;
PSWakeup(priv, HostCmd_OPTION_WAITFORRSP);
}
if (Adapter->IsDeepSleep == TRUE) {
Adapter->IsDeepSleep = FALSE;
}
PrepareAndSendCommand(priv, HostCmd_CMD_802_11_RESET, 0, 0, 0, NULL);
wlan_clean_txrx(priv);
Adapter->SurpriseRemoved = TRUE;
/* Stop the thread servicing the interrupts */
rt_event_send(&priv->MainThread.waitQ, WakeUpMainThread);
wlan_free_adapter(priv);
/* Last reference is our one */
wlan_debug3("Unregister finish\n");
priv->wlan_dev.netdev = NULL;
wlanpriv = NULL;
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/********************************************************
Global Functions
********************************************************/
/**
* @brief This function sends the rx packets to the os from the skb queue
*
* @param priv A pointer to wlan_private structure
* @return n/a
*/
void
wlan_send_rxskbQ(wlan_private * priv)
{
struct rt_wlan_dev* netdev=priv->wlan_dev.netdev;
rt_err_t result;
ENTER();
result = eth_device_ready(&(netdev->parent));
if(result!=RT_EOK)
wlan_debug1("wlan_send_rxskbQ %d",result);
RT_ASSERT(result == RT_EOK);
LEAVE();
}
/* reception packet. */
struct pbuf *rt_wlan_dev_rx(rt_device_t dev)
{
struct rt_wlan_dev*netdev=(struct rt_wlan_dev*)(dev->user_data);
wlan_private * priv=netdev->priv;
struct pbuf* p= RT_NULL;
struct sk_buff *skb=RT_NULL;
rt_err_t result;
if (priv->adapter) {
skb = wlan_pop_rx_skb(&priv->adapter->RxSkbQ);
if(skb==RT_NULL)
{
return RT_NULL;
}
p=ProcessRxedPacket(priv, skb);
wlan_debug3("free skb %x,data %x",(u32)skb,(u32)skb->data);
if(skb!=RT_NULL)
{
if(skb->head!=RT_NULL)
rt_free(skb->head);
rt_free(skb);
}
if (!list_empty((struct list_head *) (&priv->adapter->RxSkbQ))) {
result = eth_device_ready(&(priv->wlan_dev.netdev->parent));
if(result!=RT_EOK)
wlan_debug1("rt_wlan_dev_rx %d",result);
RT_ASSERT(result == RT_EOK);
}
}
return p;
}
/**
* @brief This function finds the CFP in
* region_cfp_table based on region and band parameter.
*
* @param region The region code
* @param band The band
* @param cfp_no A pointer to CFP number
* @return A pointer to CFP
*/
CHANNEL_FREQ_POWER *
wlan_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
{
int i;
ENTER();
for (i = 0; i < sizeof(region_cfp_table) / sizeof(region_cfp_table_t);
i++) {
wlan_debug3( "region_cfp_table[i].region=%d\n",
region_cfp_table[i].region);
if (region_cfp_table[i].region == region) {
{
*cfp_no = region_cfp_table[i].cfp_no_BG;
LEAVE();
return region_cfp_table[i].cfp_BG;
}
}
}
LEAVE();
return NULL;
}
/**
* @brief This function sets region table.
*
* @param priv A pointer to wlan_private structure
* @param region The region code
* @param band The band
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int
wlan_set_regiontable(wlan_private * priv, u8 region, u8 band)
{
wlan_adapter *Adapter = priv->adapter;
int i = 0;
CHANNEL_FREQ_POWER *cfp;
int cfp_no;
ENTER();
memset(Adapter->region_channel, 0, sizeof(Adapter->region_channel));
{
cfp = wlan_get_region_cfp_table(region, band, &cfp_no);
if (cfp != NULL) {
Adapter->region_channel[i].NrCFP = cfp_no;
Adapter->region_channel[i].CFP = cfp;
} else {
wlan_debug3("wrong region code %#x in Band B-G\n", region);
return WLAN_STATUS_FAILURE;
}
Adapter->region_channel[i].Valid = TRUE;
Adapter->region_channel[i].Region = region;
Adapter->region_channel[i].Band = band;
i++;
}
LEAVE();
return WLAN_STATUS_SUCCESS;
}
/**
* @brief This function handles the interrupt. it will change PS
* state if applicable. it will wake up main_thread to handle
* the interrupt event as well.
*
*/
void
wlan_interrupt(struct rt_wlan_dev *dev)
{
wlan_private *priv=wlanpriv;
priv->adapter->IntCounter++;
wlan_debug3 ("*\n");
priv->adapter->WakeupTries = 0;
if (priv->adapter->PSState == PS_STATE_SLEEP) {
priv->adapter->PSState = PS_STATE_AWAKE;
}
rt_event_send(&priv->MainThread.waitQ, WakeUpMainThread);
}
/**
* @brief This function initializes module.
*
* @param n/a A pointer to rt_wlan_dev structure
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int wlan_init_module(struct rt_wlan_dev * wlan_dev)
{
int ret = WLAN_STATUS_SUCCESS;
wlan_private * prv=RT_NULL;
wlan_debug3("start wlan device init..... \r\n");
if(wlan_dev==NULL)
{
ret = WLAN_STATUS_FAILURE;
goto done;
}
rt_event_init(&wlan_tx_event, "wlantx", RT_IPC_FLAG_FIFO);
prv=wlan_FW_thread_init(wlan_dev);
if(prv==NULL){
ret = WLAN_STATUS_FAILURE;
goto done;
}
done:
return ret;
}

355
wifi/wlan/wlan_rx.c Normal file
View File

@ -0,0 +1,355 @@
/** @file wlan_rx.c
* @brief This file contains the handling of RX in wlan
* driver.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
09/28/05: Add Doxygen format comments
12/09/05: ADD Sliding window SNR/NF Average Calculation support
********************************************************/
#include "include.h"
/********************************************************
Local Variables
********************************************************/
typedef struct
{
u8 dest_addr[6];
u8 src_addr[6];
u16 h803_len;
}Eth803Hdr_t;
typedef struct
{
u8 llc_dsap;
u8 llc_ssap;
u8 llc_ctrl;
u8 snap_oui[3];
u16 snap_type;
}Rfc1042Hdr_t;
typedef struct
{
Eth803Hdr_t eth803_hdr;
Rfc1042Hdr_t rfc1042_hdr;
}RxPacketHdr_t;
typedef struct
{
u8 dest_addr[6];
u8 src_addr[6];
u16 ethertype;
} EthII_Hdr_t;
/********************************************************
Global Variables
********************************************************/
/********************************************************
Local Functions
********************************************************/
/**
* @brief This function computes the AvgSNR .
*
* @param priv A pointer to wlan_private structure
* @return AvgSNR
*/
static u8
wlan_getAvgSNR(wlan_private * priv)
{
u8 i;
u16 temp = 0;
wlan_adapter *Adapter = priv->adapter;
if (Adapter->numSNRNF == 0)
return 0;
for (i = 0; i < Adapter->numSNRNF; i++)
temp += Adapter->rawSNR[i];
return (u8) (temp / Adapter->numSNRNF);
}
/**
* @brief This function computes the AvgNF
*
* @param priv A pointer to wlan_private structure
* @return AvgNF
*/
static u8
wlan_getAvgNF(wlan_private * priv)
{
u8 i;
u16 temp = 0;
wlan_adapter *Adapter = priv->adapter;
if (Adapter->numSNRNF == 0)
return 0;
for (i = 0; i < Adapter->numSNRNF; i++)
temp += Adapter->rawNF[i];
return (u8) (temp / Adapter->numSNRNF);
}
/**
* @brief This function save the raw SNR/NF to our internel buffer
*
* @param priv A pointer to wlan_private structure
* @param pRxPD A pointer to RxPD structure of received packet
* @return n/a
*/
static void
wlan_save_rawSNRNF(wlan_private * priv, RxPD * pRxPD)
{
wlan_adapter *Adapter = priv->adapter;
if (Adapter->numSNRNF < Adapter->data_avg_factor)
Adapter->numSNRNF++;
Adapter->rawSNR[Adapter->nextSNRNF] = pRxPD->SNR;
Adapter->rawNF[Adapter->nextSNRNF] = pRxPD->NF;
Adapter->nextSNRNF++;
if (Adapter->nextSNRNF >= Adapter->data_avg_factor)
Adapter->nextSNRNF = 0;
return;
}
#define DATA_RSSI_LOW_BIT 0x01
#define DATA_SNR_LOW_BIT 0x02
#define DATA_RSSI_HIGH_BIT 0x04
#define DATA_SNR_HIGH_BIT 0x08
/**
* @brief This function computes the RSSI in received packet.
*
* @param priv A pointer to wlan_private structure
* @return n/a
*/
static void
wlan_check_subscribe_event(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
int temp;
if (Adapter->subevent.EventsBitmap == 0)
return;
if ((Adapter->subevent.EventsBitmap & DATA_RSSI_LOW_BIT) ||
(Adapter->subevent.EventsBitmap & DATA_RSSI_HIGH_BIT)) {
temp =
-CAL_RSSI(Adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
Adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
if (Adapter->subevent.EventsBitmap & DATA_RSSI_LOW_BIT) {
if (temp > Adapter->subevent.Rssi_low.value) {
if (!Adapter->subevent.Rssi_low.Freq)
Adapter->subevent.EventsBitmap &= ~DATA_RSSI_LOW_BIT;
if (Adapter->subevent.Rssi_low.Freq > 1) {
Adapter->subevent.Rssi_low.Freq--;
if (Adapter->subevent.Rssi_low.Freq == 1)
Adapter->subevent.Rssi_low.Freq = 0;
}
}
}
if (Adapter->subevent.EventsBitmap & DATA_RSSI_HIGH_BIT) {
if (temp < Adapter->subevent.Rssi_high.value) {
if (!Adapter->subevent.Rssi_high.Freq)
Adapter->subevent.EventsBitmap &= ~DATA_RSSI_HIGH_BIT;
if (Adapter->subevent.Rssi_high.Freq > 1) {
Adapter->subevent.Rssi_high.Freq--;
if (Adapter->subevent.Rssi_high.Freq == 1)
Adapter->subevent.Rssi_high.Freq = 0;
}
}
}
}
if ((Adapter->subevent.EventsBitmap & DATA_SNR_LOW_BIT) ||
(Adapter->subevent.EventsBitmap & DATA_SNR_HIGH_BIT)) {
temp = Adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
if (Adapter->subevent.EventsBitmap & DATA_SNR_LOW_BIT) {
if (temp < Adapter->subevent.Snr_low.value) {
if (!Adapter->subevent.Snr_low.Freq)
Adapter->subevent.EventsBitmap &= ~DATA_SNR_LOW_BIT;
if (Adapter->subevent.Snr_low.Freq > 1) {
Adapter->subevent.Snr_low.Freq--;
if (Adapter->subevent.Snr_low.Freq == 1)
Adapter->subevent.Snr_low.Freq = 0;
}
}
}
if (Adapter->subevent.EventsBitmap & DATA_SNR_HIGH_BIT) {
if (temp > Adapter->subevent.Snr_high.value) {
if (!Adapter->subevent.Snr_high.Freq)
Adapter->subevent.EventsBitmap &= ~DATA_SNR_HIGH_BIT;
if (Adapter->subevent.Snr_high.Freq > 1) {
Adapter->subevent.Snr_high.Freq--;
if (Adapter->subevent.Snr_high.Freq == 1)
Adapter->subevent.Snr_high.Freq = 0;
}
}
}
}
return;
}
/**
* @brief This function computes the RSSI in received packet.
*
* @param priv A pointer to wlan_private structure
* @param pRxPD A pointer to RxPD structure of received packet
* @return n/a
*/
static void
wlan_compute_rssi(wlan_private * priv, RxPD * pRxPD)
{
wlan_adapter *Adapter = priv->adapter;
static int timer=0;
ENTER();
wlan_debug3("RxPD: SNR = %d, NF = %d\n", pRxPD->SNR, pRxPD->NF);
Adapter->SNR[TYPE_RXPD][TYPE_NOAVG] = pRxPD->SNR;
Adapter->NF[TYPE_RXPD][TYPE_NOAVG] = pRxPD->NF;
wlan_save_rawSNRNF(priv, pRxPD);
Adapter->RxPDAge =timer++;
Adapter->RxPDRate = pRxPD->RxRate;
Adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getAvgSNR(priv) * AVG_SCALE;
Adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getAvgNF(priv) * AVG_SCALE;
wlan_debug3("SNR-avg = %d, NF-avg = %d\n",
Adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
Adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
Adapter->RSSI[TYPE_RXPD][TYPE_NOAVG] =
CAL_RSSI(Adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
Adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
Adapter->RSSI[TYPE_RXPD][TYPE_AVG] =
CAL_RSSI(Adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
Adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
wlan_check_subscribe_event(priv);
LEAVE();
}
/********************************************************
Global functions
********************************************************/
/**
* @brief This function processes received packet and forwards it
* to kernel/upper layer
*
* @param priv A pointer to wlan_private
* @param skb A pointer to skb which includes the received packet
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
struct pbuf* ProcessRxedPacket(wlan_private * priv, struct sk_buff *skb)
{
int ret = WLAN_STATUS_SUCCESS;
struct pbuf* p=RT_NULL;
RxPacketHdr_t *pRxPkt;
RxPD *pRxPD;
u32 pbuflen;
int hdrChop;
int minlen;
EthII_Hdr_t *pEthHdr;
const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
ENTER();
pRxPD = (RxPD *) skb->data;
pRxPkt = (RxPacketHdr_t *) ((u8 *) pRxPD + pRxPD->PktOffset);
/*mac source address :6byte .mac destination address :6byte. length 2 bytes =14*/
minlen=(8+4+(pRxPD->PktOffset));
if (skb->len < minlen) {
wlan_debug1( "RX Error: FRAME RECEIVED WITH BAD LENGTH\n");
priv->stats.rx_length_errors++;
goto done;
}
wlan_debug3( "RX Data: skb->len - pRxPD->PktOffset = %d - %d = %d\n",
skb->len, pRxPD->PktOffset, skb->len - pRxPD->PktOffset);
wlan_debug3("RX Data: Dest %x,%x,%x,%x,%x,%x", pRxPkt->eth803_hdr.dest_addr[0],
pRxPkt->eth803_hdr.dest_addr[1],
pRxPkt->eth803_hdr.dest_addr[2],
pRxPkt->eth803_hdr.dest_addr[3],
pRxPkt->eth803_hdr.dest_addr[4],
pRxPkt->eth803_hdr.dest_addr[5]);
wlan_debug3("RX Data: Src %x,%x,%x,%x,%x,%x", pRxPkt->eth803_hdr.src_addr[0],
pRxPkt->eth803_hdr.src_addr[1],
pRxPkt->eth803_hdr.src_addr[2],
pRxPkt->eth803_hdr.src_addr[3],
pRxPkt->eth803_hdr.src_addr[4],
pRxPkt->eth803_hdr.src_addr[5]);
if (memcmp(&pRxPkt->rfc1042_hdr,
rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) {
/*
* Replace the 803 header and rfc1042 header (llc/snap) with an
* EthernetII header, keep the src/dst and snap_type (ethertype)
*
* The firmware only passes up SNAP frames converting
* all RX Data from 802.11 to 802.2/LLC/SNAP frames.
*
* To create the Ethernet II, just move the src, dst address right
* before the snap_type.
*/
pEthHdr = (EthII_Hdr_t *)
((u8 *) & pRxPkt->eth803_hdr
+ sizeof(pRxPkt->eth803_hdr) + sizeof(pRxPkt->rfc1042_hdr)
- sizeof(pRxPkt->eth803_hdr.dest_addr)
- sizeof(pRxPkt->eth803_hdr.src_addr)
- sizeof(pRxPkt->rfc1042_hdr.snap_type));
rt_memcpy(pEthHdr->src_addr, pRxPkt->eth803_hdr.src_addr,
sizeof(pEthHdr->src_addr));
rt_memcpy(pEthHdr->dest_addr, pRxPkt->eth803_hdr.dest_addr,
sizeof(pEthHdr->dest_addr));
/* Chop off the RxPD + the excess memory from the 802.2/llc/snap header
* that was removed
*/
hdrChop = (u8 *) pEthHdr - (u8 *) pRxPD;
} else {
HEXDUMP("RX Data: LLC/SNAP",
(u8 *) & pRxPkt->rfc1042_hdr, sizeof(pRxPkt->rfc1042_hdr));
/* Chop off the RxPD */
hdrChop = (u8 *) & pRxPkt->eth803_hdr - (u8 *) pRxPD;
}
/* Chop off the leading header bytes so the skb points to the start of
* either the reconstructed EthII frame or the 802.2/llc/snap frame
*/
wlan_compute_rssi(priv, pRxPD);
pbuflen=(skb->len-hdrChop);
wlan_debug1("pbuflen= %d",pbuflen);
p = pbuf_alloc(PBUF_LINK, pbuflen, PBUF_RAM);
if(p==RT_NULL)
{
wlan_debug1("alloc pbuf failed length %d",pbuflen);
return RT_NULL;
}
rt_memcpy(p->payload,(u8*)((u32)pRxPD+hdrChop),pbuflen);
priv->stats.rx_bytes += skb->len;
priv->stats.rx_packets++;
wlan_debug3("Data => kernel\n");
done:
LEAVE();
return (p);
}

2897
wifi/wlan/wlan_scan.c Normal file

File diff suppressed because it is too large Load Diff

375
wifi/wlan/wlan_scan.h Normal file
View File

@ -0,0 +1,375 @@
/** @file wlan_scan.h
*
* @brief Interface for the wlan network scan routines
*
* Driver interface functions and type declarations for the scan module
* implemented in wlan_scan.c.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*
* @sa wlan_scan.c
*/
/*************************************************************
Change Log:
01/11/06: Initial revision. New scan code, relocate related functions
************************************************************/
#ifndef _WLAN_SCAN_H
#define _WLAN_SCAN_H
/**
* @brief Maximum number of channels that can be sent in a setuserscan ioctl
*
* @sa wlan_ioctl_user_scan_cfg
*/
#define WLAN_IOCTL_USER_SCAN_CHAN_MAX 50
//! Infrastructure BSS scan type in wlan_scan_cmd_config
#define WLAN_SCAN_BSS_TYPE_BSS 1
//! Adhoc BSS scan type in wlan_scan_cmd_config
#define WLAN_SCAN_BSS_TYPE_IBSS 2
//! Adhoc or Infrastructure BSS scan type in wlan_scan_cmd_config, no filter
#define WLAN_SCAN_BSS_TYPE_ANY 3
/** @brief Maximum buffer space for beacons retrieved from scan responses
* 4000 has successfully stored up to 40 beacons
* 6000 has successfully stored the max scan results (max 64)
*/
#define MAX_SCAN_BEACON_BUFFER 6000
/**
* @brief Buffer pad space for newly allocated beacons/probe responses
*
* Beacons are typically 6 bytes longer than an equivalent probe response.
* For each scan response stored, allocate an extra byte pad at the end to
* allow easy expansion to store a beacon in the same memory a probe reponse
* previously contained
*/
#define SCAN_BEACON_ENTRY_PAD 6
//! Scan time specified in the channel TLV for each channel for passive scans
#define MRVDRV_PASSIVE_SCAN_CHAN_TIME 100
//! Scan time specified in the channel TLV for each channel for active scans
#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
//! Scan time specified in the channel TLV for each channel for specific scans
#define MRVDRV_SPECIFIC_SCAN_CHAN_TIME 100
//! Max passive scan time for each channel in milliseconds
#define MRVDRV_MAX_PASSIVE_SCAN_CHAN_TIME 2000
//! Max active scan time for each channel in milliseconds
#define MRVDRV_MAX_ACTIVE_SCAN_CHAN_TIME 500
/**
* Max total scan time in milliseconds
* The total scan time should be less than scan command timeout value (10s)
*/
#define MRVDRV_MAX_TOTAL_SCAN_TIME (MRVDRV_TIMER_10S - MRVDRV_TIMER_1S)
/**
* @brief Structure used internally in the wlan driver to configure a scan.
*
* Sent to the command processing module to configure the firmware
* scan command prepared by wlan_cmd_802_11_scan.
*
* @sa wlan_scan_networks
*
*/
typedef struct
{
/**
* @brief BSS Type to be sent in the firmware command
*
* Field can be used to restrict the types of networks returned in the
* scan. Valid settings are:
*
* - WLAN_SCAN_BSS_TYPE_BSS (infrastructure)
* - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
* - WLAN_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure)
*/
u8 bssType;
/**
* @brief Specific BSSID used to filter scan results in the firmware
*/
u8 specificBSSID[MRVDRV_ETH_ADDR_LEN];
/**
* @brief Length of TLVs sent in command starting at tlvBuffer
*/
int tlvBufferLen;
/**
* @brief SSID TLV(s) and ChanList TLVs to be sent in the firmware command
*
* @sa TLV_TYPE_CHANLIST, MrvlIEtypes_ChanListParamSet_t
* @sa TLV_TYPE_SSID, MrvlIEtypes_SsIdParamSet_t
*/
u8 tlvBuffer[1]; //!< SSID TLV(s) and ChanList TLVs are stored here
} wlan_scan_cmd_config;
/**
* @brief IOCTL channel sub-structure sent in wlan_ioctl_user_scan_cfg
*
* Multiple instances of this structure are included in the IOCTL command
* to configure a instance of a scan on the specific channel.
*/
typedef struct
{
u8 chanNumber; //!< Channel Number to scan
u8 radioType; //!< Radio type: 'B/G' Band = 0, 'A' Band = 1
u8 scanType; //!< Scan type: Active = 0, Passive = 1
u8 reserved;
u16 scanTime; //!< Scan duration in milliseconds; if 0 default used
} __ATTRIB_PACK__ wlan_ioctl_user_scan_chan;
/**
* @brief IOCTL SSID List sub-structure sent in wlan_ioctl_user_scan_cfg
*
* Used to specify SSID specific filters as well as SSID pattern matching
* filters for scan result processing in firmware.
*/
typedef struct
{
char ssid[MRVDRV_MAX_SSID_LENGTH + 1];
u8 maxLen;
} __ATTRIB_PACK__ wlan_ioctl_user_scan_ssid;
/**
* @brief IOCTL input structure to configure an immediate scan cmd to firmware
*
* Used in the setuserscan (WLAN_SET_USER_SCAN) private ioctl. Specifies
* a number of parameters to be used in general for the scan as well
* as a channel list (wlan_ioctl_user_scan_chan) for each scan period
* desired.
*
* @sa wlan_set_user_scan_ioctl
*/
typedef struct
{
/**
* @brief Flag set to keep the previous scan table intact
*
* If set, the scan results will accumulate, replacing any previous
* matched entries for a BSS with the new scan data
*/
u8 keepPreviousScan; //!< Do not erase the existing scan results
/**
* @brief BSS Type to be sent in the firmware command
*
* Field can be used to restrict the types of networks returned in the
* scan. Valid settings are:
*
* - WLAN_SCAN_BSS_TYPE_BSS (infrastructure)
* - WLAN_SCAN_BSS_TYPE_IBSS (adhoc)
* - WLAN_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure)
*/
u8 bssType;
/**
* @brief Configure the number of probe requests for active chan scans
*/
u8 numProbes;
u8 reserved;
/**
* @brief BSSID filter sent in the firmware command to limit the results
*/
u8 specificBSSID[MRVDRV_ETH_ADDR_LEN];
/**
* @brief SSID filter list used in the to limit the scan results
*/
wlan_ioctl_user_scan_ssid ssidList[MRVDRV_MAX_SSID_LIST_LENGTH];
/**
* @brief Variable number (fixed maximum) of channels to scan up
*/
wlan_ioctl_user_scan_chan chanList[WLAN_IOCTL_USER_SCAN_CHAN_MAX];
} __ATTRIB_PACK__ wlan_ioctl_user_scan_cfg;
/**
* @brief Sub-structure passed in wlan_ioctl_get_scan_table_entry for each BSS
*
* Fixed field information returned for the scan response in the IOCTL
* response.
*/
typedef struct
{
u8 bssid[6]; //!< BSSID of this network
u8 channel; //!< Channel this beacon/probe response was detected
u8 rssi; //!< RSSI for the received packet
u64 networkTSF; //!< TSF value from the firmware at packet reception
} __ATTRIB_PACK__ wlan_ioctl_get_scan_table_fixed;
/**
* @brief Structure passed in the wlan_ioctl_get_scan_table_info for each
* BSS returned in the WLAN_GET_SCAN_RESP IOCTL
*
* @sa wlan_get_scan_table_ioctl
*/
typedef struct
{
/**
* @brief Fixed field length included in the response.
*
* Length value is included so future fixed fields can be added to the
* response without breaking backwards compatibility. Use the length
* to find the offset for the bssInfoLength field, not a sizeof() calc.
*/
u32 fixedFieldLength;
/**
* @brief Always present, fixed length data fields for the BSS
*/
wlan_ioctl_get_scan_table_fixed fixedFields;
/**
* @brief Length of the BSS Information (probe resp or beacon) that
* follows starting at bssInfoBuffer
*/
u32 bssInfoLength;
/**
* @brief Probe response or beacon scanned for the BSS.
*
* Field layout:
* - TSF 8 octets
* - Beacon Interval 2 octets
* - Capability Info 2 octets
*
* - IEEE Infomation Elements; variable number & length per 802.11 spec
*/
u8 bssInfoBuffer[1];
} __ATTRIB_PACK__ wlan_ioctl_get_scan_table_entry;
/**
* @brief WLAN_GET_SCAN_RESP private IOCTL struct to retrieve the scan table
*
* @sa wlan_get_scan_table_ioctl
*/
typedef struct
{
/**
* - Zero based scan entry to start retrieval in command request
* - Number of scans entires returned in command response
*/
u32 scanNumber;
/**
* Buffer marker for multiple wlan_ioctl_get_scan_table_entry structures.
* Each struct is padded to the nearest 32 bit boundary.
*/
u8 scan_table_entry_buffer[1];
} __ATTRIB_PACK__ wlan_ioctl_get_scan_table_info;
/**
* @brief Structure used to store information for each beacon/probe response
*/
typedef struct
{
WLAN_802_11_MAC_ADDRESS MacAddress;
WLAN_802_11_SSID Ssid;
/* WEP encryption requirement */
u32 Privacy;
/* receive signal strength in dBm */
WLAN_802_11_RSSI Rssi;
u32 Channel;
u16 BeaconPeriod;
u32 ATIMWindow;
u8 ERPFlags;
WLAN_802_11_NETWORK_TYPE NetworkTypeInUse;
WLAN_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
WLAN_802_11_RATES SupportedRates;
IEEEtypes_WmmParameter_t wmmIE;
int extra_ie;
u8 TimeStamp[8]; //!< TSF value included in the beacon/probe response
IEEEtypes_PhyParamSet_t PhyParamSet;
IEEEtypes_SsParamSet_t SsParamSet;
IEEEtypes_CapInfo_t Cap;
u8 DataRates[WLAN_SUPPORTED_RATES];
u64 networkTSF; //!< TSF timestamp from the current firmware TSF
IEEEtypes_CountryInfoFullSet_t CountryInfo;
IEEEtypes_VendorSpecific_t wpaIE;
IEEEtypes_Generic_t rsnIE;
IEEEtypes_VendorSpecific_t wpsIE;
u8 *pBeaconBuf; //!< Pointer to the returned scan response
u32 beaconBufSize; //!< Length of the stored scan response //dennis
u32 beaconBufSizeMax; //!< Max allocated size for updated scan response //dennis
} BSSDescriptor_t;
extern int SSIDcmp(WLAN_802_11_SSID * ssid1, WLAN_802_11_SSID * ssid2);
extern int FindSSIDInList(wlan_adapter * Adapter, WLAN_802_11_SSID * ssid,
u8 * bssid, int mode);
extern int FindBestSSIDInList(wlan_adapter * Adapter);
extern int FindBSSIDInList(wlan_adapter * Adapter, u8 * bssid, int mode);
extern int FindBestNetworkSsid(wlan_private * priv, WLAN_802_11_SSID * pSSID);
extern int SendSpecificSSIDScan(wlan_private * priv,
WLAN_802_11_SSID * pRequestedSSID);
extern int SendSpecificBSSIDScan(wlan_private * priv, u8 * bssid);
extern int wlan_get_scan_table_ioctl(wlan_private * priv, void*wrq);
extern int wlan_set_user_scan_ioctl(wlan_private * priv, void *wrq);
extern int wlan_associate(wlan_private * priv, BSSDescriptor_t * pBSSDesc);
extern int wlan_cmd_802_11_scan(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, void *pdata_buf);
extern void wlan_scan_update_tsf_timestamps(wlan_private * priv,
BSSDescriptor_t * pNewBssDesc);
extern int wlan_ret_802_11_scan(wlan_private * priv,
HostCmd_DS_COMMAND * resp);
extern int wlan_extscan_ioctl(wlan_private * priv, void *req);
extern int sendBgScanQueryCmd(wlan_private * priv);
extern int wlan_bg_scan_enable(wlan_private * priv, BOOLEAN enable);
//extern int wlan_do_bg_scan_config_ioctl(wlan_private * priv,
// void *req);
extern int wlan_cmd_802_11_bg_scan_config(wlan_private * priv,
HostCmd_DS_COMMAND * cmd,
int cmd_action, void *pdata_buf);
extern int wlan_cmd_802_11_bg_scan_query(wlan_private * priv,
HostCmd_DS_COMMAND * cmd);
#ifdef __KERNEL__
extern int wlan_get_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_point *dwrq, char *extra);
extern int wlan_set_scan(struct net_device *dev, struct iw_request_info *info,
struct iw_param *vwrq, char *extra);
#endif
#endif /* _WLAN_SCAN_H */

40
wifi/wlan/wlan_thread.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
#ifndef __WLAN_THREAD_H_
#define __WLAN_THREAD_H_
#include <rtthread.h>
#define WakeUpMainThread (0x01)
#define WakeUpReassociationThread (0x02)
typedef struct
{
struct rt_thread task; //wait for modified
struct rt_event waitQ;
int priority;
void *priv;
} wlan_thread;
static void wlan_activate_thread(wlan_thread * thr)
{
/** Record the thread pid */
rt_event_init(&thr->waitQ, "threadevt", RT_IPC_FLAG_FIFO);
}
static void wlan_deactivate_thread(wlan_thread * thr)
{
}
static void wlan_create_thread(int (*wlanfunc) (void *), wlan_thread * thr, char *name)
{
// thr->task = kthread_run(wlanfunc, thr, "%s", name);
}
static int wlan_terminate_thread(wlan_thread * thr)
{
return 0;
}
#endif

332
wifi/wlan/wlan_tx.c Normal file
View File

@ -0,0 +1,332 @@
/** @file wlan_tx.c
* @brief This file contains the handling of TX in wlan
* driver.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
09/28/05: Add Doxygen format comments
12/13/05: Add Proprietary periodic sleep support
01/05/06: Add kernel 2.6.x support
04/06/06: Add TSPEC, queue metrics, and MSDU expiry support
********************************************************/
#include "include.h"
#include <netif/ethernetif.h>
#define TX_QUEUED_PACKET_LOWER_LIMIT 40
#define TX_QUEUED_PACKET_UPPER_LIMIT 50
/********************************************************
Local Variables
********************************************************/
/********************************************************
Global Variables
********************************************************/
extern struct rt_event wlan_tx_event;
/********************************************************
Local Functions
********************************************************/
/**
* @brief This function processes a single packet and sends
* to IF layer
*
* @param priv A pointer to wlan_private structure
* @param skb A pointer to skb which includes TX packet
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
static int
SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
{
wlan_adapter *Adapter = priv->adapter;
int ret = WLAN_STATUS_SUCCESS;
TxPD LocalTxPD;
TxPD *pLocalTxPD = &LocalTxPD;
u8 *ptr = Adapter->TmpTxBuf;
struct pbuf *phead;
int curlen;
rt_base_t level;
ENTER();
if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
wlan_debug1( "Tx Error: Bad skb length %d : %d\n",
skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
ret = WLAN_STATUS_FAILURE;
goto done;
}
memset(pLocalTxPD, 0, sizeof(TxPD));
pLocalTxPD->TxPacketLength = skb->len;
if (Adapter->PSState != PS_STATE_FULL_POWER) {
if (TRUE == CheckLastPacketIndication(priv)) {
Adapter->TxLockFlag = TRUE;
pLocalTxPD->Flags = MRVDRV_TxPD_POWER_MGMT_LAST_PACKET;
}
}
/* offset of actual data */
pLocalTxPD->TxPacketLocation = sizeof(TxPD);
if (pLocalTxPD->TxControl == 0) {
/* TxCtrl set by user or default */
pLocalTxPD->TxControl = Adapter->PktTxCtrl;
}
endian_convert_TxPD(pLocalTxPD);
memcpy(pLocalTxPD->TxDestAddrHigh, skb->data, MRVDRV_ETH_ADDR_LEN);
memcpy(ptr, pLocalTxPD, sizeof(TxPD));
ptr += sizeof(TxPD);
phead=(struct pbuf*)skb->head;
curlen=0;
if(phead ->tot_len>=2048)
{
wlan_debug1("tx too long\r\n");
goto done;
}
while(phead!=RT_NULL&&curlen<phead ->tot_len)
{
rt_memcpy(ptr+curlen, phead->payload,phead->len);
curlen+=phead->len;
phead=phead->next;
}
// memcpy(ptr, skb->data, skb->len);
ret = sbi_host_to_card(priv, MVMS_DAT, Adapter->TmpTxBuf,
skb->len + sizeof(TxPD));
if (ret) {
wlan_debug1("SendSinglePacket Error: sbi_host_to_card failed: 0x%X\n",
ret);
Adapter->dbg.num_tx_host_to_card_failure++;
goto done;
}
wlan_debug3("Data => FW\n");
//wmm_process_fw_iface_tx_xfer_start(priv);
if (--Adapter->wmm.packetsQueued < TX_QUEUED_PACKET_LOWER_LIMIT) {
wlan_debug2( "WMM: FW OS+: %d\n", Adapter->wmm.packetsQueued);
if(Adapter->wmm.downlinkblock==TRUE)
{
level = rt_hw_interrupt_disable();
Adapter->wmm.downlinkblock=FALSE;
rt_hw_interrupt_enable(level);
rt_sem_release(&Adapter->wmm.flowcrsem);
}
}
done:
if (!ret) {
priv->stats.tx_packets++;
priv->stats.tx_bytes += skb->len;
} else {
priv->stats.tx_dropped++;
priv->stats.tx_errors++;
}
/* need to be freed in all cases */
// if(skb->head!=NULL)
{
//rt_free(skb->head);
rt_free(skb);
}
level = rt_hw_interrupt_disable();
priv->adapter->CurrentTxSkb = NULL;
rt_hw_interrupt_enable(level);
rt_event_send(&wlan_tx_event, 0x01);
LEAVE();
return ret;
}
/********************************************************
Global functions
********************************************************/
/**
* @brief This function checks the conditions and sends packet to IF
* layer if everything is ok.
*
* @param priv A pointer to wlan_private structure
* @return n/a
*/
extern struct rt_semaphore driver_sem;
void wlan_process_tx(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
ENTER();
if (priv->wlan_dev.dnld_sent) {
wlan_debug1 ("TX Error: dnld_sent = %d, not sending\n",priv->wlan_dev.dnld_sent);
goto done;
}
SendSinglePacket(priv, Adapter->CurrentTxSkb);
rt_sem_take(&driver_sem, RT_WAITING_FOREVER);
priv->adapter->HisRegCpy &= ~HIS_TxDnLdRdy;
rt_sem_release(&driver_sem);
done:
LEAVE();
}
/**
* @brief This function queues the packet received from
* kernel/upper layer and wake up the main thread to handle it.
*
* @param priv A pointer to wlan_private structure
* @param skb A pointer to skb which includes TX packet
* @return WLAN_STATUS_SUCCESS or WLAN_STATUS_FAILURE
*/
int wlan_tx_packet(wlan_private * priv, struct pbuf *packet)
{
u32 flags;
wlan_adapter *Adapter = priv->adapter;
int ret = WLAN_STATUS_SUCCESS;
rt_base_t level;
struct sk_buff *skb=RT_NULL;
struct pbuf* p;
int datalen=0;
rt_uint32_t e;
ENTER();
skb=rt_malloc(sizeof(struct sk_buff));
if(skb==RT_NULL)
{
wlan_debug1("tx skb malloc failed\r\n");
return WLAN_STATUS_FAILURE;
}
skb->head = (char*)packet;
wlan_debug3("tx buf %d,%x\n",packet->tot_len, skb->head);
if (!(skb->head )) {
wlan_debug1("No free skb data buf\n");
ret = WLAN_STATUS_FAILURE;
rt_free(skb);
return ret;
}
skb->data=(char *)packet->payload;
/* p=packet;
while(p!=RT_NULL&&datalen< packet->tot_len)
{
rt_memcpy(skb->data+datalen, p->payload,p->len);
datalen+=p->len;
p=p->next;
}
*/
skb->len=packet->tot_len;
level = rt_hw_interrupt_disable();
list_add_tail((struct list_head *) skb,
(struct list_head *) &Adapter->wmm.txSkbQ);
Adapter->wmm.packetsQueued++;
if (!priv->wlan_dev.dnld_sent
|| (Adapter->wmm.packetsQueued >= TX_QUEUED_PACKET_UPPER_LIMIT)) {
wlan_debug1( "WMM: APP OS-: %d\n", Adapter->wmm.packetsQueued);
Adapter->wmm.downlinkblock=TRUE;
}
rt_hw_interrupt_enable(level);
rt_event_send(&priv->MainThread.waitQ, WakeUpMainThread);
if(Adapter->wmm.downlinkblock==TRUE)
{
rt_sem_take(&Adapter->wmm.flowcrsem, RT_WAITING_FOREVER);
}
rt_event_recv(&wlan_tx_event,0x1,RT_EVENT_FLAG_OR|RT_EVENT_FLAG_CLEAR,RT_WAITING_FOREVER,&e);
LEAVE();
return ret;
}
/**
* @brief This function tells firmware to send a NULL data packet.
*
* @param priv A pointer to wlan_private structure
* @param flags Trasnit Pkt Flags
* @return n/a
*/
int
SendNullPacket(wlan_private * priv, u8 flags)
{
wlan_adapter *Adapter = priv->adapter;
TxPD txpd;
int ret = WLAN_STATUS_SUCCESS;
u8 *ptr = Adapter->TmpTxBuf;
ENTER();
if (Adapter->SurpriseRemoved == TRUE) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
if (Adapter->MediaConnectStatus == WlanMediaStateDisconnected) {
ret = WLAN_STATUS_FAILURE;
goto done;
}
memset(&txpd, 0, sizeof(TxPD));
txpd.TxControl = Adapter->PktTxCtrl;
txpd.Flags = flags;
txpd.Priority = WMM_HIGHEST_PRIORITY;
txpd.TxPacketLocation = sizeof(TxPD);
endian_convert_TxPD(&txpd);
memcpy(ptr, &txpd, sizeof(TxPD));
ret = sbi_host_to_card(priv, MVMS_DAT, Adapter->TmpTxBuf, sizeof(TxPD));
if (ret != 0) {
wlan_debug1( "TX Error: SendNullPacket failed!\n");
Adapter->dbg.num_tx_host_to_card_failure++;
goto done;
}
wlan_debug3("Null data => FW\n");
done:
LEAVE();
return ret;
}
/**
* @brief This function check if we need send last packet indication.
*
* @param priv A pointer to wlan_private structure
*
* @return TRUE or FALSE
*/
BOOLEAN
CheckLastPacketIndication(wlan_private * priv)
{
wlan_adapter *Adapter = priv->adapter;
BOOLEAN ret = FALSE;
BOOLEAN prop_ps = TRUE;
ENTER();
if (Adapter->sleep_period.period == 0 || Adapter->gen_null_pkg == FALSE /* for UPSD certification tests */
) {
LEAVE();
return ret;
}
if (wmm_lists_empty(priv)) {
// if (((Adapter->CurBssParams.wmm_uapsd_enabled == TRUE)
// && (Adapter->wmm.qosinfo != 0)) || prop_ps) {
ret = TRUE;
// }
}
LEAVE();
return ret;
}

1041
wifi/wlan/wlan_types.h Normal file

File diff suppressed because it is too large Load Diff

67
wifi/wlan/wlan_utilites.c Normal file
View File

@ -0,0 +1,67 @@
#include "wlan_defs.h"
#include "stdio.h"
void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
static void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
int list_empty(const struct list_head *head)
{
return head->next == head;
}
static void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = NULL;
entry->prev = NULL;
}
/**
* memmove - Copy one area of memory to another
* @dest: Where to copy to
* @src: Where to copy from
* @count: The size of the area.
*
* Unlike memcpy(), memmove() copes with overlapping areas.
*/
void *memmove(void *dest, const void *src, unsigned int count)
{
char *tmp;
const char *s;
if (dest <= src) {
tmp = dest;
s = src;
while (count--)
*tmp++ = *s++;
} else {
tmp = dest;
tmp += count;
s = src;
s += count;
while (count--)
*--tmp = *--s;
}
return dest;
}

18
wifi/wlan/wlan_version.h Normal file
View File

@ -0,0 +1,18 @@
/** @file wlan_version.h
* @brief This file contains wlan driver version number.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/********************************************************
Change log:
10/04/05: Add Doxygen format comments
********************************************************/
//#include "../release_version.h"
const char driver_version[] =
// "gspi8686-%s-" DRIVER_RELEASE_VERSION "-(" "FP" FPNUM ")"
//#ifdef DEBUG_LEVEL2
"-dbg"
//#endif
" ";

221
wifi/wlan/wlan_wext.c Normal file
View File

@ -0,0 +1,221 @@
/** @file wlan_wext.c
* @brief This file contains ioctl functions
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/********************************************************
Change log:
10/10/05: Add Doxygen format comments
12/23/05: Modify FindBSSIDInList to search entire table for
duplicate BSSIDs when earlier matches are not compatible
12/26/05: Remove errant memcpy in wlanidle_off; overwriting stack space
01/05/06: Add kernel 2.6.x support
01/11/06: Conditionalize new scan/join functions.
Update statics/externs. Move forward decl. from wlan_decl.h
04/06/06: Add TSPEC, queue metrics, and MSDU expiry support
04/10/06: Add hostcmd generic API
04/18/06: Remove old Subscrive Event and add new Subscribe Event
implementation through generic hostcmd API
05/04/06: Add IBSS coalescing related new iwpriv command
08/29/06: Add ledgpio private command
10/23/06: Validate setbcnavg/setdataavg command parameters and
return error if out of range
********************************************************/
#include "include.h"
#include "wlan_version.h"
#include "wlan_dev.h"
#include "wlan_debug.h"
#include "wlan_wext.h"
extern struct rt_wlan_dev *wlan_eth ;
extern wlan_private *wlanpriv;
/**
* @brief Find the channel frequency power info with specific channel
*
* @param adapter A pointer to wlan_adapter structure
* @param band it can be BAND_A, BAND_G or BAND_B
* @param channel the channel for looking
* @return A pointer to CHANNEL_FREQ_POWER structure or NULL if not find.
*/
CHANNEL_FREQ_POWER *
find_cfp_by_band_and_channel(wlan_adapter * adapter, u8 band, u16 channel)
{
CHANNEL_FREQ_POWER *cfp = NULL;
REGION_CHANNEL *rc;
int count = sizeof(adapter->region_channel) /
sizeof(adapter->region_channel[0]);
int i, j;
for (j = 0; !cfp && (j < count); j++) {
rc = &adapter->region_channel[j];
if (adapter->State11D.Enable11D == ENABLE_11D) {
rc = &adapter->universal_channel[j];
}
if (!rc->Valid || !rc->CFP)
continue;
if (rc->Band != band)
continue;
for (i = 0; i < rc->NrCFP; i++) {
if (rc->CFP[i].Channel == channel) {
cfp = &rc->CFP[i];
break;
}
}
}
if (!cfp && channel)
wlan_debug1("find_cfp_by_band_and_channel(): cannot find "
"cfp by band %d & channel %d\n", band, channel);
return cfp;
}
int wlan_scan_network_for_AP(void)
{
if(wlan_eth==NULL)
return -1;
if(wlan_set_scan(wlan_eth, NULL,NULL,NULL)!=0)
wlan_debug1("wlan_set_scan sucess\n");
return 0;
}
int wlan_associate_AP(char *dstbssid,int len)
{
char * ssid[6];
if(dstbssid==RT_NULL)
rt_memset(ssid,0xff,6);
else{
rt_memcpy(ssid,dstbssid,6);
}
wlan_set_wap (wlan_eth, ssid,6);
}
static _wep_key_set_arg keyset;
int set_wlan_wep_key_char(char *key,int len)
{
int keylen=len;
wlan_debug1( "set wep key %s\n",key);
rt_memset((u8*)&keyset,0x00,sizeof(Wep_Key_Set_Arg));
rt_memcpy((u8*)(&keyset.Key_value[0]),key,len);
keyset.KeyLength[0]=len;
keyset.defaut_key_index=0;
keyset.wepkeyaction=SETWEPKEY;
wlan_set_wep_key(&keyset);
}
int wlan_set_wep_key(Wep_Key_Set_Arg key_set_arg)
{
int ret = WLAN_STATUS_SUCCESS;
wlan_private *priv = wlan_eth->priv;
wlan_adapter *Adapter = priv->adapter;
MRVL_WEP_KEY *pWep;
int index, PrevAuthMode,i=0;
ENTER();
if (!Is_Command_Allowed(priv)) {
wlan_debug1( "%s: not allowed\n", __FUNCTION__);
return -EBUSY;
}
if(key_set_arg->defaut_key_index>=MRVL_NUM_WEP_KEY)
{ return -WLANEPARAMETER;}
else{index=key_set_arg->defaut_key_index;}
if(key_set_arg->KeyLength[index]==0||key_set_arg->KeyLength[index]>MAX_WEP_KEY_SIZE)
return -WLANEPARAMETER;
if(key_set_arg->wepkeyaction==SETWEPKEY)
{
Adapter->CurrentWepKeyIndex = index;
for(i=0;i<MRVL_NUM_WEP_KEY;i++)
{
pWep = &Adapter->WepKey[i];
if((key_set_arg->KeyLength[i]!=0)&&(key_set_arg->KeyLength[i]<=MAX_WEP_KEY_SIZE))
{
rt_memcpy(pWep->KeyMaterial,&key_set_arg->Key_value[i][0],key_set_arg->KeyLength[i]);
if (key_set_arg->KeyLength[i]>MIN_WEP_KEY_SIZE) {
pWep->KeyLength = MAX_WEP_KEY_SIZE;
} else {
if (key_set_arg->KeyLength[i] > 0) {
pWep->KeyLength = MIN_WEP_KEY_SIZE;
}
}
}else{
pWep->KeyLength = 0;
rt_memset(pWep->KeyMaterial,0x00,MAX_WEP_KEY_SIZE);
}
}
Adapter->SecInfo.WEPStatus = Wlan802_11WEPEnabled;
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_SET_WEP,
0, HostCmd_OPTION_WAITFORRSP,
OID_802_11_ADD_WEP, NULL);
if (ret) {
LEAVE();
return ret;
}
}else if(key_set_arg->wepkeyaction==NOWEPKEY)
{
Adapter->SecInfo.WEPStatus = Wlan802_11WEPDisabled;
}
wlan_debug3("act %d, Length=%d Index=%d CurrentWepKeyIndex=%d\n",
key_set_arg->wepkeyaction, key_set_arg->KeyLength[index], Adapter->CurrentWepKeyIndex);
if (Adapter->SecInfo.WEPStatus == Wlan802_11WEPEnabled) {
Adapter->CurrentPacketFilter |= HostCmd_ACT_MAC_WEP_ENABLE;
} else {
Adapter->CurrentPacketFilter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
}
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_MAC_CONTROL,
0, HostCmd_OPTION_WAITFORRSP,
0, &Adapter->CurrentPacketFilter);
LEAVE();
return WLAN_STATUS_SUCCESS;
}
int wlan_set_wpa_psk(WLAN_802_11_KEY* wpa_psk_arg)
{
int ret = WLAN_STATUS_SUCCESS;
wlan_private *priv = wlan_eth->priv;
WLAN_802_11_KEY *pKey;
ENTER();
if (!Is_Command_Allowed(priv)) {
wlan_debug1("%s: not allowed\n", __FUNCTION__);
return -EBUSY;
}
pKey = wpa_psk_arg;
wlan_debug3("Key buffer: %s", pKey->KeyMaterial);
// current driver only supports key length of up to 32 bytes
if (pKey->KeyLength > MRVL_MAX_WPA_KEY_LENGTH) {
wlan_debug1( " Error in key length \n");
return WLAN_STATUS_FAILURE;
}
ret = PrepareAndSendCommand(priv,
HostCmd_CMD_802_11_KEY_MATERIAL,
HostCmd_ACT_SET,
HostCmd_OPTION_WAITFORRSP,
KEY_INFO_ENABLED, pKey);
if (ret) {
LEAVE();
return ret;
}
LEAVE();
return ret;
}

318
wifi/wlan/wlan_wext.h Normal file
View File

@ -0,0 +1,318 @@
/** @file wlan_wext.h
* @brief This file contains definition for IOCTL call.
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2007
*/
/********************************************************
Change log:
10/11/05: Add Doxygen format comments
12/19/05: Correct a typo in structure _wlan_ioctl_wmm_tspec
01/11/06: Conditionalize new scan/join ioctls
04/10/06: Add hostcmd generic API
04/18/06: Remove old Subscrive Event and add new Subscribe Event
implementation through generic hostcmd API
06/08/06: Add definitions of custom events
08/29/06: Add ledgpio private command
********************************************************/
#ifndef _WLAN_WEXT_H_
#define _WLAN_WEXT_H_
#include "wlan_defs.h"
#define SUBCMD_OFFSET 4
/** PRIVATE CMD ID */
#define WLANIOCTL 0x8BE0
#define WLANSETWPAIE (WLANIOCTL + 0)
#ifdef MFG_CMD_SUPPORT
#define WLANMANFCMD (WLANIOCTL + 2)
#endif
#define WLANREGRDWR (WLANIOCTL + 3)
#define MAX_EEPROM_DATA 256
#define WLANHOSTCMD (WLANIOCTL + 4)
#define WLANHOSTSLEEPCFG (WLANIOCTL + 5)
#define WLANARPFILTER (WLANIOCTL + 6)
#define WLAN_SETINT_GETINT (WLANIOCTL + 7)
#define WLANNF 1
#define WLANRSSI 2
#define WLANBGSCAN 4
#define WLANENABLE11D 5
#define WLANADHOCGRATE 6
#define WLANWMM_ENABLE 8
#define WLANNULLGEN 10
#define WLANADHOCCSET 11
#define WLAN_ADHOC_G_PROT 12
#define WLAN_SETNONE_GETNONE (WLANIOCTL + 8)
#define WLANDEAUTH 1
#define WLANRADIOON 2
#define WLANRADIOOFF 3
#define WLANREMOVEADHOCAES 4
#define WLANADHOCSTOP 5
#define WLANCRYPTOTEST 7
#ifdef REASSOCIATION
#define WLANREASSOCIATIONAUTO 8
#define WLANREASSOCIATIONUSER 9
#endif /* REASSOCIATION */
#define WLANWLANIDLEON 10
#define WLANWLANIDLEOFF 11
#define WLANGETLOG (WLANIOCTL + 9)
#define WLAN_SETCONF_GETCONF (WLANIOCTL + 10)
#define BG_SCAN_CONFIG 1
#define CAL_DATA_EXT_CONFIG 2
#define WLANSCAN_TYPE (WLANIOCTL + 11)
#define WLAN_SET_GET_2K (WLANIOCTL + 13)
#define WLAN_SET_USER_SCAN 1
#define WLAN_GET_SCAN_TABLE 2
#define WLAN_SET_MRVL_TLV 3
#define WLAN_GET_ASSOC_RSP 4
#define WLAN_ADDTS_REQ 5
#define WLAN_DELTS_REQ 6
#define WLAN_QUEUE_CONFIG 7
#define WLAN_QUEUE_STATS 8
#define WLAN_GET_CFP_TABLE 9
#define WLAN_TX_PKT_STATS 12
#define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15)
#define WLANGETREGION 1
#define WLAN_GET_LISTEN_INTERVAL 2
#define WLAN_GET_MULTIPLE_DTIM 3
#define WLAN_GET_TX_RATE 4
#define WLANGETBCNAVG 5
#define WLANGETDATAAVG 6
#define WLAN_SETNONE_GETTWELVE_CHAR (WLANIOCTL + 19)
#define WLAN_SUBCMD_GETRXANTENNA 1
#define WLAN_SUBCMD_GETTXANTENNA 2
#define WLAN_GET_TSF 3
#define WLAN_WPS_SESSION 4
#define WLAN_SETWORDCHAR_GETNONE (WLANIOCTL + 20)
#define WLANSETADHOCAES 1
#define WLAN_SETONEINT_GETWORDCHAR (WLANIOCTL + 21)
#define WLANGETADHOCAES 1
#define WLANVERSION 2
#define WLANVEREXT 3
#define WLAN_SETONEINT_GETONEINT (WLANIOCTL + 23)
#define WLAN_WMM_QOSINFO 2
#define WLAN_LISTENINTRVL 3
#define WLAN_FW_WAKEUP_METHOD 4
#define WAKEUP_FW_UNCHANGED 0
#define WAKEUP_FW_THRU_INTERFACE 1
#define WAKEUP_FW_THRU_GPIO 2
#define WLAN_NULLPKTINTERVAL 5
#define WLAN_BCN_MISS_TIMEOUT 6
#define WLAN_ADHOC_AWAKE_PERIOD 7
#define WLAN_LDO 8
#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24)
#define WLAN_SUBCMD_SETRXANTENNA 1
#define WLAN_SUBCMD_SETTXANTENNA 2
#define WLANSETAUTHALG 4
#define WLANSETENCRYPTIONMODE 5
#define WLANSETREGION 6
#define WLAN_SET_LISTEN_INTERVAL 7
#define WLAN_SET_MULTIPLE_DTIM 8
#define WLANSETBCNAVG 9
#define WLANSETDATAAVG 10
#define WLANASSOCIATE 11
#define WLAN_SET64CHAR_GET64CHAR (WLANIOCTL + 25)
#define WLANSLEEPPARAMS 2
#define WLAN_BCA_TIMESHARE 3
#define WLANSCAN_MODE 6
#define WLAN_GET_ADHOC_STATUS 9
#if (WIRELESS_EXT < 18)
#define WLAN_SET_GEN_IE 10
#define WLAN_GET_GEN_IE 11
#endif
#define WLAN_WMM_QUEUE_STATUS 13
#define WLANEXTSCAN (WLANIOCTL + 26)
#define WLANDEEPSLEEP (WLANIOCTL + 27)
#define DEEP_SLEEP_ENABLE 1
#define DEEP_SLEEP_DISABLE 0
#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29)
#define WLAN_TPCCFG 1
#define WLAN_LED_GPIO_CTRL 5
#define WLAN_SCANPROBES 6
#define WLAN_SLEEP_PERIOD 7
#define WLAN_ADAPT_RATESET 8
#define WLAN_INACTIVITY_TIMEOUT 9
#define WLANSNR 10
#define WLAN_GET_RATE 11
#define WLAN_GET_RXINFO 12
#define WLAN_SET_ATIM_WINDOW 13
#define WLAN_BEACON_INTERVAL 14
#define WLAN_SCAN_TIME 16
#define WLAN_DATA_SUBSCRIBE_EVENT 18
#define WLAN_TXCONTROL 19
#define WLAN_GSPI_REG_RW 20
#define WLANHSCFG 21
#ifdef DEBUG_LEVEL1
#define WLAN_DRV_DBG 24
#endif
#define REG_MAC 0x19
#define REG_BBP 0x1a
#define REG_RF 0x1b
#define REG_EEPROM 0x59
#define CMD_DISABLED 0
#define CMD_ENABLED 1
#define CMD_GET 2
#define SKIP_CMDNUM 4
#define SKIP_TYPE 1
#define SKIP_SIZE 2
#define SKIP_ACTION 2
#define SKIP_TYPE_SIZE (SKIP_TYPE + SKIP_SIZE)
#define SKIP_TYPE_ACTION (SKIP_TYPE + SKIP_ACTION)
/* define custom events */
#define CUS_EVT_HWM_CFG_DONE "HWM_CFG_DONE.indication "
#define CUS_EVT_BEACON_RSSI_LOW "EVENT=BEACON_RSSI_LOW"
#define CUS_EVT_BEACON_SNR_LOW "EVENT=BEACON_SNR_LOW"
#define CUS_EVT_BEACON_RSSI_HIGH "EVENT=BEACON_RSSI_HIGH"
#define CUS_EVT_BEACON_SNR_HIGH "EVENT=BEACON_SNR_HIGH"
#define CUS_EVT_MAX_FAIL "EVENT=MAX_FAIL"
#define CUS_EVT_MLME_MIC_ERR_UNI "MLME-MICHAELMICFAILURE.indication unicast "
#define CUS_EVT_MLME_MIC_ERR_MUL "MLME-MICHAELMICFAILURE.indication multicast "
#define CUS_EVT_DATA_RSSI_LOW "EVENT=DATA_RSSI_LOW"
#define CUS_EVT_DATA_SNR_LOW "EVENT=DATA_SNR_LOW"
#define CUS_EVT_DATA_RSSI_HIGH "EVENT=DATA_RSSI_HIGH"
#define CUS_EVT_DATA_SNR_HIGH "EVENT=DATA_SNR_HIGH"
#define CUS_EVT_DEEP_SLEEP_AWAKE "EVENT=DS_AWAKE"
#define CUS_EVT_ADHOC_LINK_SENSED "EVENT=ADHOC_LINK_SENSED"
#define CUS_EVT_ADHOC_BCN_LOST "EVENT=ADHOC_BCN_LOST"
/** wlan_ioctl */
typedef struct _wlan_ioctl
{
/** Command ID */
u16 command;
/** data length */
u16 len;
/** data pointer */
u8 *data;
} wlan_ioctl;
/** wlan_ioctl_rfantenna */
typedef struct _wlan_ioctl_rfantenna
{
u16 Action;
u16 AntennaMode;
} wlan_ioctl_rfantenna;
/** wlan_ioctl_regrdwr */
typedef struct _wlan_ioctl_regrdwr
{
/** Which register to access */
u16 WhichReg;
/** Read or Write */
u16 Action;
u32 Offset;
u16 NOB;
u32 Value;
} wlan_ioctl_regrdwr;
/** wlan_ioctl_cfregrdwr */
typedef struct _wlan_ioctl_cfregrdwr
{
/** Read or Write */
u8 Action;
/** register address */
u16 Offset;
/** register value */
u16 Value;
} wlan_ioctl_cfregrdwr;
/** wlan_ioctl_adhoc_key_info */
typedef struct _wlan_ioctl_adhoc_key_info
{
u16 action;
u8 key[16];
u8 tkiptxmickey[16];
u8 tkiprxmickey[16];
} wlan_ioctl_adhoc_key_info;
/** sleep_params */
typedef struct _wlan_ioctl_sleep_params_config
{
u16 Action;
u16 Error;
u16 Offset;
u16 StableTime;
u8 CalControl;
u8 ExtSleepClk;
u16 Reserved;
} __ATTRIB_PACK__ wlan_ioctl_sleep_params_config,
*pwlan_ioctl_sleep_params_config;
/** BCA TIME SHARE */
typedef struct _wlan_ioctl_bca_timeshare_config
{
/** ACT_GET/ACT_SET */
u16 Action;
/** Type: WLAN, BT */
u16 TrafficType;
/** Interval: 20msec - 60000msec */
u32 TimeShareInterval;
/** PTA arbiter time in msec */
u32 BTTime;
} __ATTRIB_PACK__ wlan_ioctl_bca_timeshare_config,
*pwlan_ioctl_bca_timeshare_config;
#define MAX_CFP_LIST_NUM 64
/** wlan_ioctl_cfp_table */
typedef struct _wlan_ioctl_cfp_table
{
u32 region;
u32 cfp_no;
struct
{
u16 Channel;
u32 Freq;
u16 MaxTxPower;
BOOLEAN Unsupported;
} cfp[MAX_CFP_LIST_NUM];
} __ATTRIB_PACK__ wlan_ioctl_cfp_table, *pwlan_ioctl_cfp_table;
/** WLAN_802_11_AUTHENTICATION_MODE */
typedef enum Key_Actiond
{
READWEPKEY= 0x00,
SETWEPKEY= 0x01,
NOWEPKEY= 0x3,
} WEP_Key_Actiond;
typedef struct _wep_key_set_arg{
u8 Key_value[MRVL_NUM_WEP_KEY][16];
u8 KeyLength[4]; /* each element key corresponds to the key_value with the same index*/
u8 defaut_key_index; /*valide range from 0 to 3*/
WLAN_802_11_WEP_STATUS wepstatus;
WLAN_802_11_AUTHENTICATION_MODE AuMode;
WEP_Key_Actiond wepkeyaction;
}_wep_key_set_arg,*Wep_Key_Set_Arg;
typedef struct _Wlan_WPA_PSK
{
u32 KeyLength;
u8 BSSID[6]; /*AP MAC address*/
u8 KeyMaterial[MRVL_MAX_KEY_WPA_KEY_LENGTH];
} WLAN_WPA_PSK_ARG,*WLAN_WPA_PSK_PTR;;
#endif /* _WLAN_WEXT_H_ */

1556
wifi/wlan/wlan_wmm.c Normal file

File diff suppressed because it is too large Load Diff

113
wifi/wlan/wlan_wmm.h Normal file
View File

@ -0,0 +1,113 @@
/** @file wlan_wmm.h
* @brief This file contains related macros, enum, and struct
* of wmm functionalities
*
* Copyright © Marvell International Ltd. and/or its affiliates, 2003-2006
*/
/****************************************************
Change log:
09/26/05: add Doxygen format comments
04/06/06: Add TSPEC, queue metrics, and MSDU expiry support
****************************************************/
#ifndef __WLAN_WMM_H
#define __WLAN_WMM_H
#include "wlan_types.h"
#include "wlan_defs.h"
/** Custom indiciation message sent to the application layer for WMM changes */
#define WMM_CONFIG_CHANGE_INDICATION "WMM_CONFIG_CHANGE.indication"
/** Highest priority setting for a packet (uses voice AC) */
#define WMM_HIGHEST_PRIORITY 7
/** struct of WMM DESC */
struct sk_buff {
/* These two members must be first. */
struct sk_buff *next;
struct sk_buff *prev;
unsigned int len;
unsigned char *head,*data;
};
typedef struct
{
u8 required;
u8 enabled;
u8 packetsQueued;
u8 queueStopped;
u8 downlinkblock;
struct rt_semaphore flowcrsem;
struct sk_buff txSkbQ;
// WmmAcStatus_t acStatus[MAX_AC_QUEUES];
// wlan_wmm_ac_e acDowngradedVals[MAX_AC_QUEUES];
/** wmm queue priority table*/
//u8 queuePriority[MAX_AC_QUEUES];
// u8 qosinfo;
} __ATTRIB_PACK__ WMM_DESC;
#ifdef __KERNEL__
extern u8 wmm_compute_driver_packet_delay(const struct sk_buff *skb);
#endif
extern int sendWMMStatusChangeCmd(wlan_private * priv);
extern int wmm_lists_empty(wlan_private * priv);
extern void wmm_process_tx(wlan_private * priv);
extern void wmm_init(wlan_private * priv);
extern void wmm_setup_queues(wlan_private * priv);
extern void wmm_start_queue(wlan_private * priv);
extern void wmm_stop_queue(wlan_private * priv);
extern int wmm_is_queue_stopped(wlan_private * priv);
extern void wmm_process_fw_iface_tx_xfer_start(wlan_private * priv);
extern void wmm_process_fw_iface_tx_xfer_end(wlan_private * priv);
extern void wmm_process_app_iface_tx(wlan_private * priv);
extern wlan_wmm_ac_e wmm_convert_tos_to_ac(int tos);
extern wlan_wmm_ac_e wmm_downgrade_ac(wlan_private * priv,wlan_wmm_ac_e acVal);
extern u32 wlan_wmm_process_association_req(wlan_private * priv,
u8 ** ppAssocBuf,
IEEEtypes_WmmParameter_t *
pWmmIE);
/*
* Functions used in the cmd handling routine
*/
extern int wlan_cmd_wmm_get_status(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, void *InfoBuf);
extern int wlan_cmd_wmm_addts_req(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, void *InfoBuf);
extern int wlan_cmd_wmm_delts_req(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, void *InfoBuf);
extern int wlan_cmd_wmm_queue_config(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, void *InfoBuf);
extern int wlan_cmd_wmm_queue_stats(wlan_private * priv,
HostCmd_DS_COMMAND * cmd, void *InfoBuf);
/*
* Functions used in the cmdresp handling routine
*/
extern int wlan_cmdresp_wmm_get_status(wlan_private * priv,
const HostCmd_DS_COMMAND * resp);
extern int wlan_cmdresp_wmm_addts_req(wlan_private * priv,
const HostCmd_DS_COMMAND * resp);
extern int wlan_cmdresp_wmm_delts_req(wlan_private * priv,
const HostCmd_DS_COMMAND * resp);
extern int wlan_cmdresp_wmm_queue_config(wlan_private * priv,
const HostCmd_DS_COMMAND * resp);
extern int wlan_cmdresp_wmm_queue_stats(wlan_private * priv,
const HostCmd_DS_COMMAND * resp);
/*
* IOCTLs
*/
//extern int wlan_wmm_enable_ioctl(wlan_private * priv, struct iwreq *wrq);
//extern int wlan_wmm_queue_status_ioctl(wlan_private * priv,struct iwreq *wrq);
//extern int wlan_wmm_addts_req_ioctl(wlan_private * priv, struct iwreq *wrq);
//extern int wlan_wmm_delts_req_ioctl(wlan_private * priv, struct iwreq *wrq);
//extern int wlan_wmm_queue_config_ioctl(wlan_private * priv,struct iwreq *wrq);
//extern int wlan_wmm_queue_stats_ioctl(wlan_private * priv, struct iwreq *wrq);
#endif /* __WLAN_WMM_H */