Commit c5c77ba1 authored by Johnny Kim's avatar Johnny Kim Committed by Greg Kroah-Hartman

staging: wilc1000: Add SDIO/SPI 802.11 driver

This driver is for the wilc1000 which is a single chip IEEE 802.11
b/g/n device.
The driver works together with cfg80211, which is the kernel side of
configuration management for wireless devices because the wilc1000
chipset is fullmac where the MLME is managed in hardware.

The driver worked from kernel version 2.6.38 and being now ported
to several others since then.
A TODO file is included as well in this commit.
Signed-off-by: default avatarJohnny Kim <johnny.kim@atmel.com>
Signed-off-by: default avatarRachel Kim <rachel.kim@atmel.com>
Signed-off-by: default avatarDean Lee <dean.lee@atmel.com>
Signed-off-by: default avatarChris Park <chris.park@atmel.com>
Acked-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7d98c63e
......@@ -110,4 +110,6 @@ source "drivers/staging/fbtft/Kconfig"
source "drivers/staging/fsl-mc/Kconfig"
source "drivers/staging/wilc1000/Kconfig"
endif # STAGING
......@@ -47,3 +47,4 @@ obj-$(CONFIG_UNISYSSPAR) += unisys/
obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD) += clocking-wizard/
obj-$(CONFIG_FB_TFT) += fbtft/
obj-$(CONFIG_FSL_MC_BUS) += fsl-mc/
obj-$(CONFIG_WILC1000) += wilc1000/
config WILC1000
tristate "WILC1000 support (WiFi only)"
---help---
This module only support IEEE 802.11n WiFi.
choice
prompt "Memory Allocation"
depends on WILC1000
default WILC1000_PREALLOCATE_AT_LOADING_DRIVER
config WILC1000_PREALLOCATE_AT_LOADING_DRIVER
bool "Preallocate memory at loading driver"
---help---
This choice supports static allocation of the memory
for the receive buffer. The driver will allocate the RX buffer
during initial time. The driver will also free the buffer
by calling network device stop.
config WILC1000_DYNAMICALLY_ALLOCATE_MEMROY
bool "Dynamically allocate memory in real time"
---help---
This choice supports dynamic allocation of the memory
for the receive buffer. The driver will allocate the RX buffer
when it is required.
endchoice
choice
prompt "Bus Type"
depends on WILC1000
default WILC1000_SDIO
config WILC1000_SDIO
bool "SDIO support"
depends on MMC
---help---
This module adds support for the SDIO interface of adapters using
WILC chipset. Select this if your platform is using the SDIO bus.
config WILC1000_SPI
bool "SPI support"
---help---
This module adds support for the SPI interface of adapters using
WILC chipset. Select this if your platform is using the SPI bus.
endchoice
config WILC1000_HW_OOB_INTR
bool "Use out of band interrupt"
depends on WILC1000 && WILC1000_SDIO
default n
---help---
If your platform don't recognize SDIO IRQ, connect chipset external IRQ pin
and check this option. Or, Use this to get all interrupts including SDIO interrupts.
obj-$(CONFIG_WILC1000) += wilc1000.o
obj-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += wilc_exported_buf.o
ccflags-$(CONFIG_WILC1000_SDIO) += -DWILC_SDIO -DCOMPLEMENT_BOOT
ccflags-$(CONFIG_WILC1000_HW_OOB_INTR) += -DWILC_SDIO_IRQ_GPIO
ccflags-$(CONFIG_WILC1000_SPI) += -DWILC_SPI
ccflags-y += -DSTA_FIRMWARE=\"atmel/wilc1000_fw.bin\" \
-DAP_FIRMWARE=\"atmel/wilc1000_ap_fw.bin\" \
-DP2P_CONCURRENCY_FIRMWARE=\"atmel/wilc1000_p2p_fw.bin\"
ccflags-y += -I$(src)/ -DEXPORT_SYMTAB -D__CHECK_ENDIAN__ -DWILC_ASIC_A0 \
-DPLL_WORKAROUND -DCONNECT_DIRECT -DAGING_ALG \
-DWILC_PARSE_SCAN_IN_HOST -DDISABLE_PWRSAVE_AND_SCAN_DURING_IP \
-DWILC_PLATFORM=WILC_LINUXKERNEL -Wno-unused-function -DUSE_WIRELESS \
-DWILC_DEBUGFS
#ccflags-y += -DTCP_ACK_FILTER
ccflags-$(CONFIG_WILC1000_PREALLOCATE_DURING_SYSTEM_BOOT) += -DMEMORY_STATIC \
-DWILC_PREALLOC_AT_BOOT
ccflags-$(CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER) += -DMEMORY_STATIC \
-DWILC_PREALLOC_AT_INSMOD
ccflags-$(CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY) += -DWILC_NORMAL_ALLOC
wilc1000-objs := wilc_wfi_netdevice.o wilc_wfi_cfgoperations.o linux_wlan.o linux_mon.o \
wilc_memory.o wilc_msgqueue.o wilc_semaphore.o wilc_sleep.o wilc_strutils.o \
wilc_thread.o wilc_time.o wilc_timer.o coreconfigurator.o host_interface.o \
fifo_buffer.o wilc_sdio.o wilc_spi.o wilc_wlan_cfg.o wilc_debugfs.o
wilc1000-$(CONFIG_WILC1000_SDIO) += linux_wlan_sdio.o
wilc1000-$(CONFIG_WILC1000_SPI) += linux_wlan_spi.o
WILC1000_SRC_VERSION = 10.0
PATCHLEVEL = 2
WILC1000_FW_VERSION = 0
ccflags-y += -D__DRIVER_VERSION__=\"$(WILC1000_SRC_VERSION).$(PATCHLEVEL)\"
TODO:
- remove the defined feature as kernel versions
- remove OS wrapper functions
- remove custom debug and tracing functions
- rework comments and function headers(also coding style)
- remove build warnings
- support soft-ap and p2p mode
- support resume/suspend function
/*!
* @file coreconfigsimulator.h
* @brief
* @author
* @sa coreconfigsimulator.c
* @date 1 Mar 2012
* @version 1.0
*/
#ifndef CORECONFIGSIMULATOR_H
#define CORECONFIGSIMULATOR_H
extern WILC_Sint32 CoreConfigSimulatorInit (void);
extern WILC_Sint32 CoreConfigSimulatorDeInit (void);
#endif
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
#include "wilc_oswrapper.h"
#include "fifo_buffer.h"
WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer, WILC_Uint32 u32BufferLength)
{
WILC_Uint32 u32Error = 0;
tstrFifoHandler *pstrFifoHandler = WILC_MALLOC (sizeof (tstrFifoHandler));
if (pstrFifoHandler) {
WILC_memset (pstrFifoHandler, 0, sizeof (tstrFifoHandler));
pstrFifoHandler->pu8Buffer = WILC_MALLOC (u32BufferLength);
if (pstrFifoHandler->pu8Buffer) {
tstrWILC_SemaphoreAttrs strSemBufferAttrs;
pstrFifoHandler->u32BufferLength = u32BufferLength;
WILC_memset (pstrFifoHandler->pu8Buffer, 0, u32BufferLength);
/* create semaphore */
WILC_SemaphoreFillDefault (&strSemBufferAttrs);
strSemBufferAttrs.u32InitCount = 1;
WILC_SemaphoreCreate(&pstrFifoHandler->SemBuffer, &strSemBufferAttrs);
*hBuffer = pstrFifoHandler;
} else {
*hBuffer = NULL;
u32Error = 1;
}
} else {
u32Error = 1;
}
return u32Error;
}
WILC_Uint32 FIFO_DeInit(tHANDLE hFifo)
{
WILC_Uint32 u32Error = 0;
tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo;
if (pstrFifoHandler) {
if (pstrFifoHandler->pu8Buffer) {
WILC_FREE (pstrFifoHandler->pu8Buffer);
} else {
u32Error = 1;
}
WILC_SemaphoreDestroy (&pstrFifoHandler->SemBuffer, WILC_NULL);
WILC_FREE (pstrFifoHandler);
} else {
u32Error = 1;
}
return u32Error;
}
WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead)
{
WILC_Uint32 u32Error = 0;
tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo;
if (pstrFifoHandler && pu32BytesRead) {
if (pstrFifoHandler->u32TotalBytes) {
if (WILC_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, WILC_NULL) == WILC_SUCCESS) {
if (u32BytesToRead > pstrFifoHandler->u32TotalBytes) {
*pu32BytesRead = pstrFifoHandler->u32TotalBytes;
} else {
*pu32BytesRead = u32BytesToRead;
}
if ((pstrFifoHandler->u32ReadOffset + u32BytesToRead) <= pstrFifoHandler->u32BufferLength) {
WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset,
*pu32BytesRead);
/* update read offset and total bytes */
pstrFifoHandler->u32ReadOffset += u32BytesToRead;
pstrFifoHandler->u32TotalBytes -= u32BytesToRead;
} else {
WILC_Uint32 u32FirstPart =
pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32ReadOffset;
WILC_memcpy(pu8Buffer, pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32ReadOffset,
u32FirstPart);
WILC_memcpy(pu8Buffer + u32FirstPart, pstrFifoHandler->pu8Buffer,
u32BytesToRead - u32FirstPart);
/* update read offset and total bytes */
pstrFifoHandler->u32ReadOffset = u32BytesToRead - u32FirstPart;
pstrFifoHandler->u32TotalBytes -= u32BytesToRead;
}
WILC_SemaphoreRelease (&pstrFifoHandler->SemBuffer, WILC_NULL);
} else {
u32Error = 1;
}
} else {
u32Error = 1;
}
} else {
u32Error = 1;
}
return u32Error;
}
WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer, WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite)
{
WILC_Uint32 u32Error = 0;
tstrFifoHandler *pstrFifoHandler = (tstrFifoHandler *) hFifo;
if (pstrFifoHandler) {
if (u32BytesToWrite < pstrFifoHandler->u32BufferLength) {
if ((pstrFifoHandler->u32TotalBytes + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength ||
bForceOverWrite) {
if (WILC_SemaphoreAcquire(&pstrFifoHandler->SemBuffer, WILC_NULL) == WILC_SUCCESS) {
if ((pstrFifoHandler->u32WriteOffset + u32BytesToWrite) <= pstrFifoHandler->u32BufferLength) {
WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer,
u32BytesToWrite);
/* update read offset and total bytes */
pstrFifoHandler->u32WriteOffset += u32BytesToWrite;
pstrFifoHandler->u32TotalBytes += u32BytesToWrite;
} else {
WILC_Uint32 u32FirstPart =
pstrFifoHandler->u32BufferLength - pstrFifoHandler->u32WriteOffset;
WILC_memcpy(pstrFifoHandler->pu8Buffer + pstrFifoHandler->u32WriteOffset, pu8Buffer,
u32FirstPart);
WILC_memcpy(pstrFifoHandler->pu8Buffer, pu8Buffer + u32FirstPart,
u32BytesToWrite - u32FirstPart);
/* update read offset and total bytes */
pstrFifoHandler->u32WriteOffset = u32BytesToWrite - u32FirstPart;
pstrFifoHandler->u32TotalBytes += u32BytesToWrite;
}
/* if data overwriten */
if (pstrFifoHandler->u32TotalBytes > pstrFifoHandler->u32BufferLength) {
/* adjust read offset to the oldest data available */
pstrFifoHandler->u32ReadOffset = pstrFifoHandler->u32WriteOffset;
/* data availabe is the buffer length */
pstrFifoHandler->u32TotalBytes = pstrFifoHandler->u32BufferLength;
}
WILC_SemaphoreRelease(&pstrFifoHandler->SemBuffer, WILC_NULL);
}
} else {
u32Error = 1;
}
} else {
u32Error = 1;
}
} else {
u32Error = 1;
}
return u32Error;
}
\ No newline at end of file
#include "wilc_oswrapper.h"
#define tHANDLE void *
typedef struct {
WILC_Uint8 *pu8Buffer;
WILC_Uint32 u32BufferLength;
WILC_Uint32 u32WriteOffset;
WILC_Uint32 u32ReadOffset;
WILC_Uint32 u32TotalBytes;
WILC_SemaphoreHandle SemBuffer;
} tstrFifoHandler;
extern WILC_Uint32 FIFO_InitBuffer(tHANDLE *hBuffer,
WILC_Uint32 u32BufferLength);
extern WILC_Uint32 FIFO_DeInit(tHANDLE hFifo);
extern WILC_Uint32 FIFO_ReadBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer,
WILC_Uint32 u32BytesToRead, WILC_Uint32 *pu32BytesRead);
extern WILC_Uint32 FIFO_WriteBytes(tHANDLE hFifo, WILC_Uint8 *pu8Buffer,
WILC_Uint32 u32BytesToWrite, WILC_Bool bForceOverWrite);
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
/*****************************************************************************/
/* */
/* Ittiam 802.11 MAC SOFTWARE */
/* */
/* ITTIAM SYSTEMS PVT LTD, BANGALORE */
/* COPYRIGHT(C) 2005 */
/* */
/* This program is proprietary to Ittiam Systems Private Limited and */
/* is protected under Indian Copyright Law as an unpublished work. Its use */
/* and disclosure is limited by the terms and conditions of a license */
/* agreement. It may not be copied or otherwise reproduced or disclosed to */
/* persons outside the licensee's organization except in accordance with the*/
/* terms and conditions of such an agreement. All copies and */
/* reproductions shall be the property of Ittiam Systems Private Limited and*/
/* must bear this notice in its entirety. */
/* */
/*****************************************************************************/
/*****************************************************************************/
/* */
/* File Name : itypes.h */
/* */
/* Description : This file contains all the data type definitions for */
/* MAC implementation. */
/* */
/* List of Functions : None */
/* Issues / Problems : None */
/* */
/* Revision History : */
/* */
/* DD MM YYYY Author(s) Changes */
/* 01 05 2005 Ittiam Draft */
/* */
/*****************************************************************************/
#ifndef ITYPES_H
#define ITYPES_H
/*****************************************************************************/
/* Data Types */
/*****************************************************************************/
typedef int WORD32;
typedef short WORD16;
typedef char WORD8;
typedef unsigned int UWORD32;
typedef unsigned short UWORD16;
typedef unsigned char UWORD8;
/*****************************************************************************/
/* Enums */
/*****************************************************************************/
typedef enum {
BFALSE = 0,
BTRUE = 1
} BOOL_T;
#endif /* ITYPES_H */
This diff is collapsed.
This diff is collapsed.
#ifndef LINUX_WLAN_COMMON_H
#define LINUX_WLAN_COMMON_H
enum debug_region {
Generic_debug = 0,
Hostapd_debug,
Hostinf_debug,
CFG80211_debug,
Coreconfig_debug,
Interrupt_debug,
TX_debug,
RX_debug,
Lock_debug,
Tcp_enhance,
/*Added by amr - BugID_4720*/
Spin_debug,
Init_debug,
Bus_debug,
Mem_debug,
Firmware_debug,
COMP = 0xFFFFFFFF,
};
#define GENERIC_DBG (1 << Generic_debug)
#define HOSTAPD_DBG (1 << Hostapd_debug)
#define HOSTINF_DBG (1 << Hostinf_debug)
#define CORECONFIG_DBG (1 << Coreconfig_debug)
#define CFG80211_DBG (1 << CFG80211_debug)
#define INT_DBG (1 << Interrupt_debug)
#define TX_DBG (1 << TX_debug)
#define RX_DBG (1 << RX_debug)
#define LOCK_DBG (1 << Lock_debug)
#define TCP_ENH (1 << Tcp_enhance)
/*Added by Amr - BugID_4720*/
#define SPIN_DEBUG (1 << Spin_debug)
#define INIT_DBG (1 << Init_debug)
#define BUS_DBG (1 << Bus_debug)
#define MEM_DBG (1 << Mem_debug)
#define FIRM_DBG (1 << Firmware_debug)
#if defined (WILC_DEBUGFS)
extern int wilc_debugfs_init(void);
extern void wilc_debugfs_remove(void);
extern atomic_t REGION;
extern atomic_t DEBUG_LEVEL;
#define DEBUG (1 << 0)
#define INFO (1 << 1)
#define WRN (1 << 2)
#define ERR (1 << 3)
#define PRINT_D(region, ...) do { \
if ((atomic_read(&DEBUG_LEVEL) & DEBUG) && ((atomic_read(&REGION)) & (region))) { \
printk("DBG [%s: %d]", __FUNCTION__, __LINE__); \
printk(__VA_ARGS__); \
} \
} while (0)
#define PRINT_INFO(region, ...) do { \
if ((atomic_read(&DEBUG_LEVEL) & INFO) && ((atomic_read(&REGION)) & (region))) { \
printk("INFO [%s]", __FUNCTION__); \
printk(__VA_ARGS__); \
} \
} while (0)
#define PRINT_WRN(region, ...) do { \
if ((atomic_read(&DEBUG_LEVEL) & WRN) && ((atomic_read(&REGION)) & (region))) { \
printk("WRN [%s: %d]", __FUNCTION__, __LINE__); \
printk(__VA_ARGS__); \
} \
} while (0)
#define PRINT_ER(...) do { \
if ((atomic_read(&DEBUG_LEVEL) & ERR)) { \
printk("ERR [%s: %d]", __FUNCTION__, __LINE__); \
printk(__VA_ARGS__); \
} \
} while (0)
#else
#define REGION (INIT_DBG | GENERIC_DBG | CFG80211_DBG | FIRM_DBG | HOSTAPD_DBG)
#define DEBUG 1
#define INFO 0
#define WRN 0
#define PRINT_D(region, ...) do { if (DEBUG == 1 && ((REGION)&(region))) { \
printk("DBG [%s: %d]", __FUNCTION__, __LINE__); \
printk(__VA_ARGS__); \
} \
} while (0)
#define PRINT_INFO(region, ...) do { if (INFO == 1 && ((REGION)&(region))) { \
printk("INFO [%s]", __FUNCTION__); \
printk(__VA_ARGS__); \
} \
} while (0)
#define PRINT_WRN(region, ...) do { if (WRN == 1 && ((REGION)&(region))) { \
printk("WRN [%s: %d]", __FUNCTION__, __LINE__); \
printk(__VA_ARGS__); \
} \
} while (0)
#define PRINT_ER(...) do { printk("ERR [%s: %d]", __FUNCTION__, __LINE__); \
printk(__VA_ARGS__); \
} while (0)
#endif
#define FN_IN /* PRINT_D(">>> \n") */
#define FN_OUT /* PRINT_D("<<<\n") */
#ifdef MEMORY_STATIC
#define LINUX_RX_SIZE (96 * 1024)
#endif
#define LINUX_TX_SIZE (64 * 1024)
#define WILC_MULTICAST_TABLE_SIZE 8
#if defined (NM73131_0_BOARD)
#define MODALIAS "wilc_spi"
#define GPIO_NUM IRQ_WILC1000_GPIO
#elif defined (BEAGLE_BOARD)
#define SPI_CHANNEL 4
#if SPI_CHANNEL == 4
#define MODALIAS "wilc_spi4"
#define GPIO_NUM 162
#else
#define MODALIAS "wilc_spi3"
#define GPIO_NUM 133
#endif
#elif defined(PANDA_BOARD)
#define MODALIAS "WILC_SPI"
#define GPIO_NUM 139
#elif defined(PLAT_WMS8304) /* rachel */
#define MODALIAS "wilc_spi"
#define GPIO_NUM 139
#elif defined (PLAT_RKXXXX)
#define MODALIAS "WILC_IRQ"
#define GPIO_NUM RK30_PIN3_PD2 /* RK30_PIN3_PA1 */
/* RK30_PIN3_PD2 */
/* RK2928_PIN1_PA7 */
#elif defined(CUSTOMER_PLATFORM)
/*
TODO : specify MODALIAS name and GPIO number. This is certainly necessary for SPI interface.
*
* ex)
* #define MODALIAS "WILC_SPI"
* #define GPIO_NUM 139
*/
#else
/* base on SAMA5D3_Xplained Board */
#define MODALIAS "WILC_SPI"
#define GPIO_NUM 0x44
#endif
void linux_wlan_enable_irq(void);
#endif
#include "wilc_wfi_netdevice.h"
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/host.h>
#if defined (NM73131_0_BOARD)
#define SDIO_MODALIAS "wilc_sdio"
#else
#define SDIO_MODALIAS "wilc1000_sdio"
#endif
#if defined (NM73131_0_BOARD)
#define MAX_SPEED 50000000
#elif defined(CUSTOMER_PLATFORM)
/* TODO : User have to stable bus clock as user's environment. */
#ifdef MAX_BUS_SPEED
#define MAX_SPEED MAX_BUS_SPEED
#else
#define MAX_SPEED 50000000
#endif
#else
#define MAX_SPEED (6 * 1000000) /* Max 50M */
#endif
struct sdio_func *local_sdio_func;
extern linux_wlan_t *g_linux_wlan;
extern int wilc_netdev_init(void);
extern int sdio_clear_int(void);
extern void wilc_handle_isr(void);
static unsigned int sdio_default_speed;
#define SDIO_VENDOR_ID_WILC 0x0296
#define SDIO_DEVICE_ID_WILC 0x5347
static const struct sdio_device_id wilc_sdio_ids[] = {
{ SDIO_DEVICE(SDIO_VENDOR_ID_WILC, SDIO_DEVICE_ID_WILC) },
};
static void wilc_sdio_interrupt(struct sdio_func *func)
{
#ifndef WILC_SDIO_IRQ_GPIO
sdio_release_host(func);
wilc_handle_isr();
sdio_claim_host(func);
#endif
}
int linux_sdio_cmd52(sdio_cmd52_t *cmd)
{
struct sdio_func *func = g_linux_wlan->wilc_sdio_func;
int ret;
u8 data;
sdio_claim_host(func);
func->num = cmd->function;
if (cmd->read_write) { /* write */
if (cmd->raw) {
sdio_writeb(func, cmd->data, cmd->address, &ret);
data = sdio_readb(func, cmd->address, &ret);
cmd->data = data;
} else {
sdio_writeb(func, cmd->data, cmd->address, &ret);
}
} else { /* read */
data = sdio_readb(func, cmd->address, &ret);
cmd->data = data;
}
sdio_release_host(func);
if (ret < 0) {
PRINT_ER("wilc_sdio_cmd52..failed, err(%d)\n", ret);
return 0;
}
return 1;
}
int linux_sdio_cmd53(sdio_cmd53_t *cmd)
{
struct sdio_func *func = g_linux_wlan->wilc_sdio_func;
int size, ret;
sdio_claim_host(func);
func->num = cmd->function;
func->cur_blksize = cmd->block_size;
if (cmd->block_mode)
size = cmd->count * cmd->block_size;
else
size = cmd->count;
if (cmd->read_write) { /* write */
ret = sdio_memcpy_toio(func, cmd->address, (void *)cmd->buffer, size);
} else { /* read */
ret = sdio_memcpy_fromio(func, (void *)cmd->buffer, cmd->address, size);
}
sdio_release_host(func);
if (ret < 0) {
PRINT_ER("wilc_sdio_cmd53..failed, err(%d)\n", ret);
return 0;
}
return 1;
}
volatile int probe; /* COMPLEMENT_BOOT */
static int linux_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
{
PRINT_D(INIT_DBG, "probe function\n");
#ifdef COMPLEMENT_BOOT
if (local_sdio_func != NULL) {
local_sdio_func = func;
probe = 1;
PRINT_D(INIT_DBG, "local_sdio_func isn't NULL\n");
return 0;
}
#endif
PRINT_D(INIT_DBG, "Initializing netdev\n");
local_sdio_func = func;
if (wilc_netdev_init()) {
PRINT_ER("Couldn't initialize netdev\n");
return -1;
}
printk("Driver Initializing success\n");
return 0;
}
static void linux_sdio_remove(struct sdio_func *func)
{
/**
* TODO
**/
}
struct sdio_driver wilc_bus = {
.name = SDIO_MODALIAS,
.id_table = wilc_sdio_ids,
.probe = linux_sdio_probe,
.remove = linux_sdio_remove,
};
int enable_sdio_interrupt(void)
{
int ret = 0;
#ifndef WILC_SDIO_IRQ_GPIO
sdio_claim_host(local_sdio_func);
ret = sdio_claim_irq(local_sdio_func, wilc_sdio_interrupt);
sdio_release_host(local_sdio_func);
if (ret < 0) {
PRINT_ER("can't claim sdio_irq, err(%d)\n", ret);
ret = -EIO;
}
#endif
return ret;
}
void disable_sdio_interrupt(void)
{
#ifndef WILC_SDIO_IRQ_GPIO
int ret;
PRINT_D(INIT_DBG, "disable_sdio_interrupt IN\n");
sdio_claim_host(local_sdio_func);
ret = sdio_release_irq(local_sdio_func);
if (ret < 0) {
PRINT_ER("can't release sdio_irq, err(%d)\n", ret);
}
sdio_release_host(local_sdio_func);
PRINT_D(INIT_DBG, "disable_sdio_interrupt OUT\n");
#endif
}
static int linux_sdio_set_speed(int speed)
{
struct mmc_ios ios;
sdio_claim_host(local_sdio_func);
memcpy((void *)&ios, (void *)&local_sdio_func->card->host->ios, sizeof(struct mmc_ios));
local_sdio_func->card->host->ios.clock = speed;
ios.clock = speed;
local_sdio_func->card->host->ops->set_ios(local_sdio_func->card->host, &ios);
sdio_release_host(local_sdio_func);
PRINT_INFO(INIT_DBG, "@@@@@@@@@@@@ change SDIO speed to %d @@@@@@@@@\n", speed);
return 1;
}
static int linux_sdio_get_speed(void)
{
return local_sdio_func->card->host->ios.clock;
}
int linux_sdio_init(void *pv)
{
/**
* TODO :
**/
sdio_default_speed = linux_sdio_get_speed();
return 1;
}
void linux_sdio_deinit(void *pv)
{
/**
* TODO :
**/
sdio_unregister_driver(&wilc_bus);
}
int linux_sdio_set_max_speed(void)
{
return linux_sdio_set_speed(MAX_SPEED);
}
int linux_sdio_set_default_speed(void)
{
return linux_sdio_set_speed(sdio_default_speed);
}
extern struct sdio_func *local_sdio_func;
extern struct sdio_driver wilc_bus;
#include <linux/mmc/sdio_func.h>
int linux_sdio_init(void *);
void linux_sdio_deinit(void *);
int linux_sdio_cmd52(sdio_cmd52_t *cmd);
int linux_sdio_cmd53(sdio_cmd53_t *cmd);
int enable_sdio_interrupt(void);
void disable_sdio_interrupt(void);
int linux_sdio_set_max_speed(void);
int linux_sdio_set_default_speed(void);
This diff is collapsed.
#ifndef LINUX_WLAN_SPI_H
#define LINUX_WLAN_SPI_H
#include <linux/spi/spi.h>
extern struct spi_device *wilc_spi_dev;
extern struct spi_driver wilc_bus;
int linux_spi_init(void *vp);
void linux_spi_deinit(void *vp);
int linux_spi_write(uint8_t *b, uint32_t len);
int linux_spi_read(uint8_t *rb, uint32_t rlen);
int linux_spi_write_read(unsigned char *wb, unsigned char *rb, unsigned int rlen);
int linux_spi_set_max_speed(void);
#endif
This diff is collapsed.
#ifndef __WILC_ERRORSUPPORT_H__
#define __WILC_ERRORSUPPORT_H__
/*!
* @file wilc_errorsupport.h
* @brief Error reporting and handling support
* @author syounan
* @sa wilc_oswrapper.h top level OS wrapper file
* @date 10 Aug 2010
* @version 1.0
*/
#include "linux_wlan_common.h"
/* Psitive Numbers to indicate sucess with special status */
#define WILC_ALREADY_EXSIT (+100) /** The requested object already exists */
/* Generic success will return 0 */
#define WILC_SUCCESS 0 /** Generic success */
/* Negative numbers to indicate failures */
#define WILC_FAIL -100 /** Generic Fail */
#define WILC_BUSY -101 /** Busy with another operation*/
#define WILC_INVALID_ARGUMENT -102 /** A given argument is invalid*/
#define WILC_INVALID_STATE -103 /** An API request would violate the Driver state machine (i.e. to start PID while not camped)*/
#define WILC_BUFFER_OVERFLOW -104 /** In copy operations if the copied data is larger than the allocated buffer*/
#define WILC_NULL_PTR -105 /** null pointer is passed or used */
#define WILC_EMPTY -107
#define WILC_FULL -108
#define WILC_TIMEOUT -109
#define WILC_CANCELED -110 /** The required operation have been canceled by the user*/
#define WILC_INVALID_FILE -112 /** The Loaded file is corruped or having an invalid format */
#define WILC_NOT_FOUND -113 /** Cant find the file to load */
#define WILC_NO_MEM -114
#define WILC_UNSUPPORTED_VERSION -115
#define WILC_FILE_EOF -116
/* Error type */
typedef WILC_Sint32 WILC_ErrNo;
#define WILC_IS_ERR(__status__) (__status__ < WILC_SUCCESS)
#define WILC_ERRORCHECK(__status__) do { \
if (WILC_IS_ERR(__status__)) { \
PRINT_ER("PRINT_ER(%d)\n", __status__); \
goto ERRORHANDLER; \
} \
} while (0)
#define WILC_ERRORREPORT(__status__, __err__) do { \
PRINT_ER("PRINT_ER(%d)\n", __err__); \
__status__ = __err__; \
goto ERRORHANDLER; \
} while (0)
#define WILC_NULLCHECK(__status__, __ptr__) do { \
if (__ptr__ == WILC_NULL) { \
WILC_ERRORREPORT(__status__, WILC_NULL_PTR); \
} \
} while (0)
#define WILC_CATCH(__status__) \
ERRORHANDLER: \
if (WILC_IS_ERR(__status__)) \
#ifdef CONFIG_WILC_ASSERTION_SUPPORT
/**
* @brief prints a diagnostic message and aborts the program
* @param[in] pcExpression The expression that triggered the assertion
* @param[in] pcFileName The name of the current source file.
* @param[in] u32LineNumber The line number in the current source file.
* @warning DO NOT CALL DIRECTLY. USE EQUIVALENT MACRO FUNCTION INSTEAD.
*/
void WILC_assert_INTERNAL(WILC_Char *pcExpression, WILC_Char *pcFileName, WILC_Uint32 u32LineNumber);
#define WILC_assert(__expression__) (void)(!!(__expression__) || (WILC_assert_INTERNAL((# __expression__), __WILC_FILE__, __WILC_LINE__), 0))
#else
#define WILC_assert(__expression__) ((void)0)
#endif
#endif
This diff is collapsed.
This diff is collapsed.
#ifndef __WILC_LOG_H__
#define __WILC_LOG_H__
/* Errors will always get printed */
#define WILC_ERROR(...) do { WILC_PRINTF("(ERR)(%s:%d) ", __WILC_FUNCTION__, __WILC_LINE__); \
WILC_PRINTF(__VA_ARGS__); \
} while (0)
/* Wraning only printed if verbosity is 1 or more */
#if (WILC_LOG_VERBOSITY_LEVEL > 0)
#define WILC_WARN(...) do { WILC_PRINTF("(WRN)"); \
WILC_PRINTF(__VA_ARGS__); \
} while (0)
#else
#define WILC_WARN(...) (0)
#endif
/* Info only printed if verbosity is 2 or more */
#if (WILC_LOG_VERBOSITY_LEVEL > 1)
#define WILC_INFO(...) do { WILC_PRINTF("(INF)"); \
WILC_PRINTF(__VA_ARGS__); \
} while (0)
#else
#define WILC_INFO(...) (0)
#endif
/* Debug is only printed if verbosity is 3 or more */
#if (WILC_LOG_VERBOSITY_LEVEL > 2)
#define WILC_DBG(...) do { WILC_PRINTF("(DBG)(%s:%d) ", __WILC_FUNCTION__, __WILC_LINE__); \
WILC_PRINTF(__VA_ARGS__); \
} while (0)
#else
#define WILC_DBG(...) (0)
#endif
/* Function In/Out is only printed if verbosity is 4 or more */
#if (WILC_LOG_VERBOSITY_LEVEL > 3)
#define WILC_FN_IN do { WILC_PRINTF("(FIN) (%s:%d) \n", __WILC_FUNCTION__, __WILC_LINE__); } while (0)
#define WILC_FN_OUT(ret) do { WILC_PRINTF("(FOUT) (%s:%d) %d.\n", __WILC_FUNCTION__, __WILC_LINE__, (ret)); } while (0)
#else
#define WILC_FN_IN (0)
#define WILC_FN_OUT(ret) (0)
#endif
#endif
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment