M7350v7_en_gpl
This commit is contained in:
1413
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio.c
Executable file
1413
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio.c
Executable file
File diff suppressed because it is too large
Load Diff
171
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio.h
Executable file
171
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio.h
Executable file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Header files defines some SDIO inline routines
|
||||
*
|
||||
* $Id: 8188e_sdio.h,v 1.4.4.5 2010/12/10 06:11:55 family Exp $
|
||||
*
|
||||
* Copyright (c) 2009 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _8188E_SDIO_H_
|
||||
#define _8188E_SDIO_H_
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <asm/bitops.h>
|
||||
#endif
|
||||
|
||||
#include "8192cd.h"
|
||||
#include "sdio/sdio_io.h"
|
||||
#include "8188e_sdio_hw.h"
|
||||
#include "8188e_sdio_recv.h"
|
||||
#include "8188e_sdio_cmd.h"
|
||||
#include "hal_intf_xmit.h"
|
||||
|
||||
typedef __kernel_size_t SIZE_T;
|
||||
typedef __kernel_ssize_t SSIZE_T;
|
||||
|
||||
#define SIZE_PTR SIZE_T
|
||||
#define SSIZE_PTR SSIZE_T
|
||||
|
||||
#define TX_SELE_HQ BIT(0) // High Queue
|
||||
#define TX_SELE_LQ BIT(1) // Low Queue
|
||||
#define TX_SELE_NQ BIT(2) // Normal Queue
|
||||
|
||||
// Note: We will divide number of page equally for each queue other than public queue!
|
||||
#define TX_TOTAL_PAGE_NUMBER 0xF8
|
||||
#define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1)
|
||||
|
||||
// For Normal Chip Setting
|
||||
// (HPQ + LPQ + NPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER
|
||||
#define NORMAL_PAGE_NUM_PUBQ 0xE7
|
||||
#define NORMAL_PAGE_NUM_HPQ 0x0C
|
||||
#define NORMAL_PAGE_NUM_LPQ 0x02
|
||||
#define NORMAL_PAGE_NUM_NPQ 0x02
|
||||
|
||||
// For Test Chip Setting
|
||||
// (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER
|
||||
#define TEST_PAGE_NUM_PUBQ 0x7E
|
||||
|
||||
// For Test Chip Setting
|
||||
#define WMM_TEST_TX_TOTAL_PAGE_NUMBER 0xF5
|
||||
#define WMM_TEST_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) //F6
|
||||
|
||||
#define WMM_TEST_PAGE_NUM_PUBQ 0xA3
|
||||
#define WMM_TEST_PAGE_NUM_HPQ 0x29
|
||||
#define WMM_TEST_PAGE_NUM_LPQ 0x29
|
||||
|
||||
//Note: For Normal Chip Setting ,modify later
|
||||
#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER 0xF5
|
||||
#define WMM_NORMAL_TX_PAGE_BOUNDARY (WMM_TEST_TX_TOTAL_PAGE_NUMBER + 1) //F6
|
||||
|
||||
#define WMM_NORMAL_PAGE_NUM_PUBQ 0xB0
|
||||
#define WMM_NORMAL_PAGE_NUM_HPQ 0x29
|
||||
#define WMM_NORMAL_PAGE_NUM_LPQ 0x1C
|
||||
#define WMM_NORMAL_PAGE_NUM_NPQ 0x1C
|
||||
|
||||
// Note: We will divide number of page equally for each queue other than public queue!
|
||||
// 22k = 22528 bytes = 176 pages (@page = 128 bytes)
|
||||
// must reserved about 7 pages for LPS => 176-7 = 169 (0xA9)
|
||||
// 2*BCN / 1*ps-poll / 1*null-data /1*prob_rsp /1*QOS null-data /1*BT QOS null-data
|
||||
|
||||
#ifdef SDIO_AP_OFFLOAD
|
||||
#define TX_TOTAL_PAGE_NUMBER_88E 0xA0
|
||||
#else
|
||||
#define TX_TOTAL_PAGE_NUMBER_88E 0xA9 // 169 (21632=> 21k)
|
||||
#endif
|
||||
|
||||
#define TX_PAGE_BOUNDARY_88E (TX_TOTAL_PAGE_NUMBER_88E + 1)
|
||||
|
||||
//Note: For Normal Chip Setting ,modify later
|
||||
#define WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_88E TX_TOTAL_PAGE_NUMBER_88E //0xA9 , 0xb0=>176=>22k
|
||||
#define WMM_NORMAL_TX_PAGE_BOUNDARY_88E (WMM_NORMAL_TX_TOTAL_PAGE_NUMBER_88E + 1) //0xA9
|
||||
|
||||
#define MAX_HW_TX_QUEUE 8
|
||||
#define MAX_STA_TX_SERV_QUEUE 5 // must <= MAX_HW_TX_QUEUE
|
||||
|
||||
enum SDIO_TX_INT_STATUS {
|
||||
SDIO_TX_INT_SETUP_TH = 0,
|
||||
SDIO_TX_INT_WORKING,
|
||||
};
|
||||
|
||||
enum {
|
||||
ENQUEUE_TO_HEAD = 0,
|
||||
ENQUEUE_TO_TAIL =1,
|
||||
};
|
||||
|
||||
extern const u32 reg_freepage_thres[SDIO_TX_FREE_PG_QUEUE];
|
||||
|
||||
struct hal_data_8188e
|
||||
{
|
||||
//In /Out Pipe information
|
||||
int RtInPipe[2];
|
||||
int RtOutPipe[3];
|
||||
u8 Queue2Pipe[8];//for out pipe mapping
|
||||
// Add for dual MAC 0--Mac0 1--Mac1
|
||||
u32 interfaceIndex;
|
||||
|
||||
u8 OutEpQueueSel;
|
||||
u8 OutEpNumber;
|
||||
|
||||
// Auto FSM to Turn On, include clock, isolation, power control for MAC only
|
||||
u8 bMacPwrCtrlOn;
|
||||
|
||||
//
|
||||
// SDIO ISR Related
|
||||
//
|
||||
u32 sdio_himr;
|
||||
u32 sdio_hisr;
|
||||
unsigned long SdioTxIntStatus;
|
||||
volatile u8 SdioTxIntQIdx;
|
||||
|
||||
//
|
||||
// SDIO Tx FIFO related.
|
||||
//
|
||||
// HIQ, MID, LOW, PUB free pages; padapter->xmitpriv.free_txpg
|
||||
u8 SdioTxFIFOFreePage[SDIO_TX_FREE_PG_QUEUE];
|
||||
u8 SdioTxFIFOFreePage_prev[SDIO_TX_FREE_PG_QUEUE];
|
||||
u8 SdioTxOQTFreeSpace;
|
||||
|
||||
int WaitSdioTxOQT;
|
||||
u8 WaitSdioTxOQTSpace;
|
||||
|
||||
//
|
||||
// SDIO Rx FIFO related.
|
||||
//
|
||||
u8 SdioRxFIFOCnt;
|
||||
u16 SdioRxFIFOSize;
|
||||
};
|
||||
|
||||
typedef struct hal_data_8188e HAL_INTF_DATA_TYPE, *PHAL_INTF_DATA_TYPE;
|
||||
|
||||
void InitSdioInterrupt(struct rtl8192cd_priv *priv);
|
||||
void EnableSdioInterrupt(struct rtl8192cd_priv *priv);
|
||||
void DisableSdioInterrupt(struct rtl8192cd_priv *priv);
|
||||
|
||||
int sdio_dvobj_init(struct rtl8192cd_priv *priv);
|
||||
void sdio_dvobj_deinit(struct rtl8192cd_priv *priv);
|
||||
|
||||
int sdio_alloc_irq(struct rtl8192cd_priv *priv);
|
||||
int sdio_free_irq(struct rtl8192cd_priv *priv);
|
||||
|
||||
void rtw_dev_unload(struct rtl8192cd_priv *priv);
|
||||
|
||||
u8 rtw_init_drv_sw(struct rtl8192cd_priv *priv);
|
||||
u8 rtw_free_drv_sw(struct rtl8192cd_priv *priv);
|
||||
|
||||
void rtl8188es_interface_configure(struct rtl8192cd_priv *priv);
|
||||
void _InitQueueReservedPage(struct rtl8192cd_priv *priv);
|
||||
void _InitQueuePriority(struct rtl8192cd_priv *priv);
|
||||
void _initSdioAggregationSetting(struct rtl8192cd_priv *priv);
|
||||
|
||||
u8 sdio_query_txbuf_status(struct rtl8192cd_priv *priv);
|
||||
#ifdef CONFIG_SDIO_TX_IN_INTERRUPT
|
||||
u8 sdio_query_txbuf_status_locksafe(struct rtl8192cd_priv *priv);
|
||||
#endif
|
||||
u8 sdio_query_txoqt_status(struct rtl8192cd_priv *priv);
|
||||
|
||||
#endif // _8188E_SDIO_H_
|
||||
|
1630
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_cmd.c
Executable file
1630
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_cmd.c
Executable file
File diff suppressed because it is too large
Load Diff
125
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_cmd.h
Executable file
125
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_cmd.h
Executable file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Header files defines some SDIO CMD inline routines
|
||||
*
|
||||
* $Id: 8188e_sdio_cmd.h,v 1.4.4.5 2010/12/10 06:11:55 family Exp $
|
||||
*
|
||||
* Copyright (c) 2009 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _8188E_SDIO_CMD_H_
|
||||
#define _8188E_SDIO_CMD_H_
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/kthread.h> // for kthread_run()
|
||||
#endif
|
||||
|
||||
#include "./osdep_service.h"
|
||||
|
||||
struct timer_event_entry {
|
||||
_list list;
|
||||
void (*function)(unsigned long);
|
||||
unsigned long data;
|
||||
};
|
||||
|
||||
#define INIT_TIMER_EVENT_ENTRY(_entry, _func, _data) \
|
||||
do { \
|
||||
_rtw_init_listhead(&(_entry)->list); \
|
||||
(_entry)->data = (_data); \
|
||||
(_entry)->function = (_func); \
|
||||
} while (0)
|
||||
|
||||
int _rtw_init_cmd_priv(struct rtl8192cd_priv *priv);
|
||||
void _rtw_free_cmd_priv(struct rtl8192cd_priv *priv);
|
||||
|
||||
int rtw_enqueue_timer_event(struct rtl8192cd_priv *priv, struct timer_event_entry *entry, int insert_tail);
|
||||
void timer_event_timer_fn(unsigned long __data);
|
||||
|
||||
void rtw_flush_cmd_queue(struct rtl8192cd_priv *priv, struct stat_info *pstat);
|
||||
void rtw_flush_rx_mgt_queue(struct rtl8192cd_priv *priv);
|
||||
|
||||
int rtw_cmd_thread(void *context);
|
||||
|
||||
void notify_update_sta_RATid(struct rtl8192cd_priv *priv, struct stat_info *pstat);
|
||||
void notify_del_sta(struct rtl8192cd_priv *priv, struct stat_info *pstat);
|
||||
|
||||
void notify_40M_RRSR_SC_change(struct rtl8192cd_priv *priv);
|
||||
void notify_NAV_prot_len_change(struct rtl8192cd_priv *priv);
|
||||
void notify_slot_time_change(struct rtl8192cd_priv *priv, int use_short);
|
||||
#ifdef SW_ANT_SWITCH
|
||||
void notify_antenna_switch(struct rtl8192cd_priv *priv, u8 nextAntenna);
|
||||
#endif
|
||||
void notify_mp_ctx_background(struct rtl8192cd_priv *priv);
|
||||
void notify_IOT_EDCA_switch(struct rtl8192cd_priv *priv, u32 be_edca, u32 vi_edca);
|
||||
void notify_set_key(struct net_device *dev, DOT11_SET_KEY *pSetKey, unsigned char *pKey);
|
||||
void notify_disconnect_sta(struct net_device *dev, DOT11_DISCONNECT_REQ *pReq);
|
||||
void notify_indicate_MIC_failure(struct net_device *dev, struct stat_info *pstat);
|
||||
void notify_indicate_MIC_failure_clnt(struct rtl8192cd_priv *priv, unsigned char *sa);
|
||||
#ifdef RTK_BR_EXT
|
||||
void notify_mac_clone(struct rtl8192cd_priv *priv, unsigned char *addr);
|
||||
#endif
|
||||
void notify_recv_mgnt_frame(struct rtl8192cd_priv *priv, struct rx_frinfo *pfrinfo);
|
||||
#ifdef CONFIG_RTL_WAPI_SUPPORT
|
||||
void notify_recv_wai_frame(struct rtl8192cd_priv *priv, struct rx_frinfo *pfrinfo);
|
||||
#endif
|
||||
void notify_tx_report_change(struct rtl8192cd_priv *priv);
|
||||
void notify_tx_report_interval_change(struct rtl8192cd_priv *priv, u16 interval);
|
||||
void notify_macid_pause_change(struct rtl8192cd_priv *priv, u16 macid, u16 pause);
|
||||
void notify_macid_no_link_change(struct rtl8192cd_priv *priv, u16 macid, u16 nolink);
|
||||
|
||||
#ifdef SDIO_AP_OFFLOAD
|
||||
void cmd_set_ap_offload(struct rtl8192cd_priv *priv, u8 en);
|
||||
void rtw_offload_reinit_timer(struct rtl8192cd_priv *priv);
|
||||
void ap_offload_exit(struct rtl8192cd_priv *priv);
|
||||
void handle_ap_cmd(struct work_struct *work);
|
||||
#endif
|
||||
#if defined(WIFI_WPAS_CLI) || defined(RTK_NL80211)
|
||||
void notify_wpas_join(struct rtl8192cd_priv *priv);
|
||||
#endif
|
||||
|
||||
enum rtw_cmd_code
|
||||
{
|
||||
_CMD_UPDATE_STA_RATID = 0,
|
||||
_CMD_DEL_STA,
|
||||
|
||||
_CMD_40M_RRSR_SC_CHANGE,
|
||||
_CMD_NAV_PROT_LEN_CHANGE,
|
||||
_CMD_SLOT_TIME_CHANGE,
|
||||
#ifdef SW_ANT_SWITCH
|
||||
_CMD_ANTENNA_SWITCH,
|
||||
#endif
|
||||
_CMD_MP_CTX_BACKGROUND,
|
||||
_CMD_IOT_EDCA_SWITCH,
|
||||
_CMD_SET_KEY,
|
||||
_CMD_DISCONNECT_STA,
|
||||
_CMD_INDICATE_MIC_FAILURE,
|
||||
_CMD_INDICATE_MIC_FAILURE_CLNT,
|
||||
#ifdef RTK_BR_EXT
|
||||
_CMD_MAC_CLONE,
|
||||
#endif
|
||||
_CMD_RECV_MGNT_FRAME,
|
||||
#ifdef CONFIG_RTL_WAPI_SUPPORT
|
||||
_CMD_RECV_WAI_FRAME,
|
||||
#endif
|
||||
_CMD_TX_REPORT_CHANGE,
|
||||
_CMD_TX_REPORT_INTERVAL_CHANGE,
|
||||
_CMD_MACID_PAUSE_CHANGE,
|
||||
_CMD_MACID_NO_LINK_CHANGE,
|
||||
#ifdef SDIO_AP_OFFLOAD
|
||||
_CMD_AP_OFFLOAD,
|
||||
_CMD_AP_UNOFFLOAD,
|
||||
#endif
|
||||
#if defined(WIFI_WPAS_CLI) || defined(RTK_NL80211)
|
||||
_CMD_WPAS_JOIN,
|
||||
#endif
|
||||
#ifdef RTK_NL80211
|
||||
_CMD_CFG_IND,
|
||||
#endif
|
||||
MAX_RTW_CMD_CODE
|
||||
};
|
||||
|
||||
#endif // _8188E_SDIO_CMD_H_
|
||||
|
844
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_hw.c
Executable file
844
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_hw.c
Executable file
@ -0,0 +1,844 @@
|
||||
/*
|
||||
* SDIO core routines
|
||||
*
|
||||
* $Id: 8188e_sdio_hw.c,v 1.27.2.31 2010/12/31 08:37:43 family Exp $
|
||||
*
|
||||
* Copyright (c) 2009 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define _8188E_SDIO_HW_C_
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#endif
|
||||
|
||||
#include "8192cd.h"
|
||||
#include "8192cd_headers.h"
|
||||
#include "8192cd_debug.h"
|
||||
#include "Hal8188EPwrSeq.h"
|
||||
|
||||
|
||||
extern struct _device_info_ wlan_device[];
|
||||
extern int drv_registered;
|
||||
|
||||
|
||||
extern int MDL_DEVINIT rtl8192cd_init_one(struct sdio_func *psdio_func,
|
||||
const struct sdio_device_id *ent, struct _device_info_ *wdev, int vap_idx);
|
||||
extern void rtl8192cd_deinit_one(struct rtl8192cd_priv *priv);
|
||||
|
||||
|
||||
static int MDL_DEVINIT rtw_drv_init(struct sdio_func *psdio_func, const struct sdio_device_id *pdid)
|
||||
{
|
||||
int ret;
|
||||
#ifdef MBSSID
|
||||
int i;
|
||||
#endif
|
||||
printk("%s: sdio_func_id is \"%s\"\n", __func__, sdio_func_id(psdio_func));
|
||||
|
||||
ret = rtl8192cd_init_one(psdio_func, pdid, &wlan_device[0], -1);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
#ifdef UNIVERSAL_REPEATER
|
||||
ret = rtl8192cd_init_one(psdio_func, pdid, &wlan_device[0], -1);
|
||||
if (ret)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
#ifdef MBSSID
|
||||
for (i = 0; i < RTL8192CD_NUM_VWLAN; i++) {
|
||||
ret = rtl8192cd_init_one(psdio_func, pdid, &wlan_device[0], i);
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
if(usb_dvobj_init(wlan_device[wlan_index].priv) != SUCCESS) {
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
*/
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (NULL != wlan_device[0].priv) {
|
||||
rtl8192cd_deinit_one(wlan_device[0].priv);
|
||||
wlan_device[0].priv = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void MDL_DEVEXIT rtw_dev_remove(struct sdio_func *psdio_func)
|
||||
{
|
||||
struct net_device *dev = sdio_get_drvdata(psdio_func);
|
||||
struct rtl8192cd_priv *priv = GET_DEV_PRIV(dev);
|
||||
|
||||
printk("%s: sdio_func_id is \"%s\"\n", __func__, sdio_func_id(psdio_func));
|
||||
|
||||
sdio_set_drvdata(psdio_func, NULL);
|
||||
|
||||
if (priv) {
|
||||
priv->pshare->bDriverStopped = TRUE;
|
||||
if (TRUE == drv_registered)
|
||||
priv->pshare->bSurpriseRemoved = TRUE;
|
||||
|
||||
if (priv == wlan_device[0].priv) {
|
||||
wlan_device[0].priv = NULL;
|
||||
rtl8192cd_deinit_one(priv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct sdio_device_id rtw_sdio_id_tbl[] = {
|
||||
#ifdef CONFIG_RTL_88E_SUPPORT
|
||||
{ SDIO_DEVICE(0x024c, 0x8179) },
|
||||
#endif
|
||||
#ifdef CONFIG_WLAN_HAL_8192EE
|
||||
{ SDIO_DEVICE(0x024c, 0x818b) },
|
||||
#endif
|
||||
{} /* Terminating entry */
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(sdio, rtw_sdio_id_tbl);
|
||||
|
||||
#ifdef CONFIG_POWER_SAVE
|
||||
static const struct dev_pm_ops rtw_sdio_pm_ops = {
|
||||
.prepare = rtw_sdio_prepare,
|
||||
.complete = rtw_sdio_complete,
|
||||
.suspend = rtw_sdio_suspend,
|
||||
.resume = rtw_sdio_resume,
|
||||
};
|
||||
#endif
|
||||
|
||||
struct sdio_driver rtl8192cd_sdio_driver = {
|
||||
.name = (char*)DRV_NAME,
|
||||
.id_table = rtw_sdio_id_tbl,
|
||||
.probe = rtw_drv_init,
|
||||
.remove = rtw_dev_remove,
|
||||
#ifdef CONFIG_POWER_SAVE
|
||||
.drv = {
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &rtw_sdio_pm_ops,
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_RTL_88E_SUPPORT
|
||||
#define FW_8188E_SIZE 0x4000 //16384,16k
|
||||
#define FW_8188E_START_ADDRESS 0x1000
|
||||
#define FW_8188E_END_ADDRESS 0x1FFF //0x5FFF
|
||||
|
||||
#define MAX_PAGE_SIZE 4096 // @ page : 4k bytes
|
||||
#define MAX_REG_BOLCK_SIZE 196
|
||||
|
||||
static int _BlockWrite(struct rtl8192cd_priv *priv, void *buffer, u32 buffSize)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
u32 blockSize_p1 = 4; // (Default) Phase #1 : PCI muse use 4-byte write to download FW
|
||||
u32 blockCount_p1 = 0;
|
||||
u32 remainSize_p1 = 0;
|
||||
u8 *bufferPtr = (u8*)buffer;
|
||||
u32 i=0;
|
||||
|
||||
#ifdef CONFIG_PCI_HCI
|
||||
u8 remainFW[4] = {0, 0, 0, 0};
|
||||
u8 *p = NULL;
|
||||
|
||||
blockCount_p1 = buffSize / blockSize_p1;
|
||||
remainSize_p1 = buffSize % blockSize_p1;
|
||||
|
||||
for (i = 0; i < blockCount_p1; i++) {
|
||||
RTL_W32((FW_8188E_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
|
||||
}
|
||||
|
||||
p = (u8*)((u32*)(bufferPtr + blockCount_p1 * blockSize_p1));
|
||||
if (remainSize_p1) {
|
||||
switch (remainSize_p1) {
|
||||
case 3:
|
||||
remainFW[2]=*(p+2);
|
||||
case 2:
|
||||
remainFW[1]=*(p+1);
|
||||
case 1:
|
||||
remainFW[0]=*(p);
|
||||
RTL_W32((FW_8188E_START_ADDRESS + blockCount_p1 * blockSize_p1),
|
||||
le32_to_cpu(*(u32*)remainFW));
|
||||
}
|
||||
}
|
||||
|
||||
#else // !CONFIG_PCI_HCI
|
||||
u32 blockSize_p2 = 8; // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
|
||||
u32 blockSize_p3 = 1; // Phase #3 : Use 1-byte, the remnant of FW image.
|
||||
u32 blockCount_p2 = 0, blockCount_p3 = 0;
|
||||
u32 remainSize_p2 = 0;
|
||||
u32 offset=0;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
blockSize_p1 = MAX_REG_BOLCK_SIZE;
|
||||
#endif
|
||||
|
||||
//3 Phase #1
|
||||
blockCount_p1 = buffSize / blockSize_p1;
|
||||
remainSize_p1 = buffSize % blockSize_p1;
|
||||
|
||||
for (i = 0; i < blockCount_p1; i++)
|
||||
{
|
||||
#ifdef CONFIG_USB_HCI
|
||||
ret = RTL_Wn((FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
|
||||
#else
|
||||
ret = RTL_W32((FW_8188E_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
|
||||
#endif
|
||||
if (IS_ERR_VALUE(ret))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
//3 Phase #2
|
||||
if (remainSize_p1)
|
||||
{
|
||||
offset = blockCount_p1 * blockSize_p1;
|
||||
|
||||
blockCount_p2 = remainSize_p1/blockSize_p2;
|
||||
remainSize_p2 = remainSize_p1%blockSize_p2;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
for (i = 0; i < blockCount_p2; i++) {
|
||||
ret = RTL_Wn((FW_8188E_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
|
||||
if (IS_ERR_VALUE(ret))
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//3 Phase #3
|
||||
if (remainSize_p2)
|
||||
{
|
||||
offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
|
||||
|
||||
blockCount_p3 = remainSize_p2 / blockSize_p3;
|
||||
|
||||
for(i = 0 ; i < blockCount_p3 ; i++){
|
||||
ret = RTL_W8((FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
|
||||
if (IS_ERR_VALUE(ret))
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
#endif // CONFIG_PCI_HCI
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _PageWrite(struct rtl8192cd_priv *priv, u32 page, void *buffer, u32 size)
|
||||
{
|
||||
u8 value8;
|
||||
u8 u8Page = (u8) (page & 0x07) ;
|
||||
|
||||
value8 = (RTL_R8(REG_MCUFWDL+2)&0xF8) | u8Page ;
|
||||
RTL_W8(REG_MCUFWDL+2,value8);
|
||||
return _BlockWrite(priv, buffer, size);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_HCI
|
||||
static void _FillDummy(u8 *pFwBuf, u32 *pFwLen)
|
||||
{
|
||||
u32 FwLen = *pFwLen;
|
||||
u8 remain = (u8)(FwLen%4);
|
||||
|
||||
if (remain) {
|
||||
remain = 4 - remain;
|
||||
|
||||
do {
|
||||
pFwBuf[FwLen] = 0;
|
||||
FwLen++;
|
||||
remain--;
|
||||
} while (remain > 0);
|
||||
}
|
||||
|
||||
*pFwLen = FwLen;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _WriteFW(struct rtl8192cd_priv *priv, void *buffer, u32 size)
|
||||
{
|
||||
// Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
|
||||
// We can remove _ReadChipVersion from ReadpadapterInfo8192C later.
|
||||
int ret = 0;
|
||||
u32 pageNums,remainSize ;
|
||||
u32 page, offset;
|
||||
u8 *bufferPtr = (u8*)buffer;
|
||||
|
||||
#ifdef CONFIG_PCI_HCI
|
||||
// 20100120 Joseph: Add for 88CE normal chip.
|
||||
// Fill in zero to make firmware image to dword alignment.
|
||||
// _FillDummy(bufferPtr, &size);
|
||||
#endif
|
||||
|
||||
pageNums = size / MAX_PAGE_SIZE ;
|
||||
//RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n"));
|
||||
remainSize = size % MAX_PAGE_SIZE;
|
||||
|
||||
for (page = 0; page < pageNums; page++) {
|
||||
offset = page * MAX_PAGE_SIZE;
|
||||
|
||||
ret = _PageWrite(priv, page, bufferPtr+offset, MAX_PAGE_SIZE);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
goto exit;
|
||||
}
|
||||
if (remainSize) {
|
||||
offset = pageNums * MAX_PAGE_SIZE;
|
||||
page = pageNums;
|
||||
|
||||
ret = _PageWrite(priv, page, bufferPtr+offset, remainSize);
|
||||
if (IS_ERR_VALUE(ret))
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _8051Reset88E(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
u8 u1bTmp;
|
||||
|
||||
u1bTmp = RTL_R8(REG_SYS_FUNC_EN+1);
|
||||
RTL_W8(REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
|
||||
RTL_W8(REG_SYS_FUNC_EN+1, u1bTmp|(BIT2));
|
||||
}
|
||||
|
||||
int Load_88E_Firmware(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
int fw_len, wait_cnt=0;
|
||||
#ifdef CONFIG_PCI_HCI
|
||||
unsigned int CurPtr=0;
|
||||
unsigned int WriteAddr;
|
||||
unsigned int Temp;
|
||||
#endif
|
||||
unsigned char *ptmp;
|
||||
u8 value8;
|
||||
int ret = TRUE;
|
||||
|
||||
#ifdef CONFIG_RTL8672
|
||||
printk("val=%x\n", RTL_R8(0x80));
|
||||
#endif
|
||||
|
||||
#ifdef MP_TEST
|
||||
if (priv->pshare->rf_ft_var.mp_specific)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
printk("===> %s\n", __FUNCTION__);
|
||||
|
||||
if (RTL_R16(0xF0) >= 0x8000) {
|
||||
ptmp = Array_8188E_FW_AP_S + 32;
|
||||
fw_len = ArrayLength_8188E_FW_AP_T - 32;
|
||||
} else {
|
||||
ptmp = Array_8188E_FW_AP_T + 32;
|
||||
fw_len = ArrayLength_8188E_FW_AP_S - 32;
|
||||
}
|
||||
|
||||
// Disable SIC
|
||||
RTL_W8(0x41, 0x40);
|
||||
delay_ms(1);
|
||||
|
||||
#ifdef CONFIG_RTL8672
|
||||
RTL_W8(0x04, RTL_R8(0x04) | 0x02);
|
||||
delay_ms(1); //czyao
|
||||
#endif
|
||||
|
||||
// Load SRAM
|
||||
RTL_W8(MCUFWDL, RTL_R8(MCUFWDL) | MCUFWDL_EN);
|
||||
delay_ms(1);
|
||||
|
||||
RTL_W32(MCUFWDL, RTL_R32(MCUFWDL) & 0xfff0ffff);
|
||||
delay_ms(1);
|
||||
|
||||
#ifdef CONFIG_PCI_HCI
|
||||
WriteAddr = 0x1000;
|
||||
while (CurPtr < fw_len) {
|
||||
if ((CurPtr+4) > fw_len) {
|
||||
// Reach the end of file.
|
||||
while (CurPtr < fw_len) {
|
||||
Temp = *(ptmp + CurPtr);
|
||||
RTL_W8(WriteAddr, (unsigned char)Temp);
|
||||
WriteAddr++;
|
||||
CurPtr++;
|
||||
}
|
||||
} else {
|
||||
// Write FW content to memory.
|
||||
Temp = *((unsigned int *)(ptmp + CurPtr));
|
||||
Temp = cpu_to_le32(Temp);
|
||||
RTL_W32(WriteAddr, Temp);
|
||||
WriteAddr += 4;
|
||||
|
||||
if((IS_TEST_CHIP(priv)==0) && (WriteAddr == 0x2000)) {
|
||||
unsigned char tmp = RTL_R8(MCUFWDL+2);
|
||||
tmp += 1;
|
||||
WriteAddr = 0x1000;
|
||||
RTL_W8(MCUFWDL+2, tmp) ;
|
||||
delay_ms(10);
|
||||
// printk("\n[CurPtr=%x, 0x82=%x]\n", CurPtr, RTL_R8(0x82));
|
||||
}
|
||||
CurPtr += 4;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (IS_ERR_VALUE(_WriteFW(priv, ptmp, fw_len))) {
|
||||
printk("WriteFW FAIL !\n");
|
||||
ret = FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// MCU firmware download disable.
|
||||
RTL_W8(MCUFWDL, RTL_R8(MCUFWDL) & 0xfe);
|
||||
delay_ms(1);
|
||||
// Reserved for fw extension.
|
||||
RTL_W8(0x81, 0x00);
|
||||
|
||||
if (FALSE == ret)
|
||||
return FALSE;
|
||||
|
||||
value8 = RTL_R8(MCUFWDL);
|
||||
value8 |= MCUFWDL_RDY;
|
||||
value8 &= ~WINTINI_RDY;
|
||||
RTL_W8(MCUFWDL, value8);
|
||||
|
||||
// Enable MCU
|
||||
value8 = RTL_R8(REG_SYS_FUNC_EN+1);
|
||||
RTL_W8(REG_SYS_FUNC_EN+1, value8 & (~BIT2));
|
||||
RTL_W8(REG_SYS_FUNC_EN+1, value8|BIT2);
|
||||
|
||||
printk("<=== %s\n", __FUNCTION__);
|
||||
|
||||
// check if firmware is ready
|
||||
while (!(RTL_R8(MCUFWDL) & WINTINI_RDY)) {
|
||||
if (++wait_cnt > 10) {
|
||||
printk("8188e firmware not ready\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
delay_ms(1);
|
||||
}
|
||||
#ifdef CONFIG_RTL8672
|
||||
printk("val=%x\n",RTL_R8(MCUFWDL));
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif // CONFIG_RTL_88E_SUPPORT
|
||||
|
||||
|
||||
int rtl8192cd_stop_hw(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
#ifdef TXREPORT
|
||||
RTL8188E_DisableTxReport(priv);
|
||||
#endif
|
||||
|
||||
RTL_W8(RCR, 0);
|
||||
RTL_W8(TXPAUSE, 0xff); // Pause MAC TX queue
|
||||
RTL_W8(CR, 0x0);
|
||||
|
||||
// Run LPS WL RFOFF flow
|
||||
if (FALSE == HalPwrSeqCmdParsing(priv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
|
||||
PWR_INTF_SDIO_MSK, rtl8188E_enter_lps_flow)) {
|
||||
DEBUG_ERR("[%s %d] run RF OFF flow fail!\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
if (RTL_R8(MCUFWDL) & BIT(7)) { //8051 RAM code
|
||||
// Reset MCU 0x2[10]=0.
|
||||
RTL_W8(SYS_FUNC_EN+1, RTL_R8(SYS_FUNC_EN+1) & ~ BIT(2));
|
||||
}
|
||||
|
||||
// MCUFWDL 0x80[1:0]=0
|
||||
// reset MCU ready status
|
||||
RTL_W8(MCUFWDL, 0);
|
||||
|
||||
// Disable CMD53 R/W
|
||||
GET_HAL_INTF_DATA(priv)->bMacPwrCtrlOn = FALSE;
|
||||
|
||||
// Card disable power action flow
|
||||
if (FALSE == HalPwrSeqCmdParsing(priv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
|
||||
PWR_INTF_SDIO_MSK, rtl8188E_card_disable_flow)) {
|
||||
DEBUG_ERR("[%s %d] run CARD DISABLE flow fail!\n", __FUNCTION__, __LINE__);
|
||||
}
|
||||
|
||||
// lock ISO/CLK/Power control register
|
||||
RTL_W8(RSV_CTRL0, 0x0e);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_EXT_CLK_26M
|
||||
#define REG_APE_PLL_CTRL_EXT 0x002c
|
||||
void _InitClockTo26MHz(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
u8 u1temp = 0;
|
||||
|
||||
// EnableGpio5ClockReq(priv, FALSE, 1);
|
||||
|
||||
u1temp = RTL_R8(REG_APE_PLL_CTRL_EXT);
|
||||
u1temp = (u1temp & 0xF0) | 0x05;
|
||||
RTL_W8(REG_APE_PLL_CTRL_EXT, u1temp);
|
||||
|
||||
printk("acli: set 26M\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* Call power on sequence to enable card
|
||||
*/
|
||||
u8 _CardEnable(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
HAL_INTF_DATA_TYPE *pHalData = GET_HAL_INTF_DATA(priv);
|
||||
|
||||
#ifdef CONFIG_EXT_CLK_26M
|
||||
u8 val8;
|
||||
#endif
|
||||
|
||||
if (FALSE == pHalData->bMacPwrCtrlOn)
|
||||
{
|
||||
// RSV_CTRL 0x1C[7:0] = 0x00
|
||||
// unlock ISO/CLK/Power control register
|
||||
RTL_W8(REG_RSV_CTRL, 0x0);
|
||||
|
||||
#ifdef CONFIG_EXT_CLK_26M
|
||||
// _InitClockTo26MHz(priv);
|
||||
val8 = RTL_R8(0x4); // APS_FSMCO
|
||||
val8 = val8 & ~BIT(5);
|
||||
RTL_W8(0x4, val8);
|
||||
#endif
|
||||
|
||||
if (FALSE == HalPwrSeqCmdParsing(priv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
|
||||
PWR_INTF_SDIO_MSK, rtl8188E_card_enable_flow)) {
|
||||
printk(KERN_ERR "%s: run power on flow fail\n", __func__);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
pHalData->bMacPwrCtrlOn = TRUE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int rtl8188es_InitPowerOn(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
u16 value16;
|
||||
|
||||
if (_CardEnable(priv) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// Enable power down and GPIO interrupt
|
||||
value16 = RTL_R16(REG_APS_FSMCO);
|
||||
value16 |= PDN_EN; // Enable HW power down and RF on
|
||||
RTL_W16(REG_APS_FSMCO, value16);
|
||||
|
||||
// Reset TX/RX DMA before LLT init to avoid TXDMA error "LLT_NULL_PG"
|
||||
RTL_W8(CR, 0x0);
|
||||
|
||||
// Enable MAC DMA/WMAC/SCHEDULE/SEC block
|
||||
value16 = RTL_R16(CR);
|
||||
value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN
|
||||
| PROTOCOL_EN | SCHEDULE_EN | CALTMR_EN);
|
||||
// for SDIO - Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy. Added by tynli. 2011.08.31.
|
||||
|
||||
RTL_W16(CR, value16);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
#ifdef MBSSID
|
||||
void rtl8192cd_init_mbssid(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int camData[2];
|
||||
unsigned char *macAddr = GET_MY_HWADDR;
|
||||
unsigned int inter_bcn_space;
|
||||
int nr_vap;
|
||||
_irqL irqL;
|
||||
|
||||
SMP_LOCK_MBSSID(&irqL);
|
||||
|
||||
if (IS_ROOT_INTERFACE(priv))
|
||||
{
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | MBIDCAM_VALID | (macAddr[5] << 8) | macAddr[4];
|
||||
camData[1] = (macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0];
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
|
||||
// clear the rest area of CAM
|
||||
camData[1] = 0;
|
||||
for (i=1; i<8; i++) {
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | (i&MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT;
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
}
|
||||
|
||||
priv->pshare->bcn_priv[0] = priv;
|
||||
priv->pshare->inter_bcn_space = priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod * NET80211_TU_TO_US;
|
||||
|
||||
if (priv->pmib->miscEntry.func_off) {
|
||||
priv->func_off_already = 1;
|
||||
priv->pshare->nr_bcn = 0;
|
||||
RTL_W8(REG_MBSSID_CTRL, RTL_R8(REG_MBSSID_CTRL) & ~BIT0);
|
||||
} else {
|
||||
priv->pshare->nr_bcn = 1;
|
||||
RTL_W8(REG_MBSSID_CTRL, RTL_R8(REG_MBSSID_CTRL) | BIT0);
|
||||
}
|
||||
|
||||
RTL_W32(MBSSID_BCN_SPACE,
|
||||
(priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE2_Mask)<<BCN_SPACE2_SHIFT
|
||||
|(priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE1_Mask)<<BCN_SPACE1_SHIFT);
|
||||
|
||||
RTL_W8(BCN_CTRL, 0);
|
||||
RTL_W8(DUAL_TSF_RST, 1);
|
||||
RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N|EN_TXBCN_RPT);
|
||||
|
||||
RTL_W32(RCR, RTL_R32(RCR) | RCR_MBID_EN); // MBSSID enable
|
||||
}
|
||||
else if (IS_VAP_INTERFACE(priv))
|
||||
{
|
||||
if (priv->pmib->miscEntry.func_off) {
|
||||
priv->func_off_already = 1;
|
||||
priv->vap_init_seq = 0;
|
||||
SMP_UNLOCK_MBSSID(&irqL);
|
||||
return;
|
||||
}
|
||||
|
||||
nr_vap = priv->pshare->nr_bcn;
|
||||
priv->vap_init_seq = nr_vap;
|
||||
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | MBIDCAM_VALID |
|
||||
(priv->vap_init_seq & MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT |
|
||||
(macAddr[5] << 8) | macAddr[4];
|
||||
camData[1] = (macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0];
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
|
||||
inter_bcn_space = priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod-
|
||||
((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod*nr_vap)/(nr_vap+1))-1;
|
||||
if (inter_bcn_space > 200)
|
||||
inter_bcn_space = 200;
|
||||
|
||||
priv->pshare->bcn_priv[nr_vap] = priv;
|
||||
priv->pshare->nr_bcn++;
|
||||
priv->pshare->inter_bcn_space = priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod*NET80211_TU_TO_US/(nr_vap+1);
|
||||
|
||||
RTL_W8(REG_MBSSID_CTRL, RTL_R8(REG_MBSSID_CTRL) | BIT(priv->vap_init_seq));
|
||||
|
||||
RTL_W32(MBSSID_BCN_SPACE, (inter_bcn_space & BCN_SPACE2_Mask)<<BCN_SPACE2_SHIFT
|
||||
|(priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE1_Mask)<<BCN_SPACE1_SHIFT);
|
||||
|
||||
RTL_W8(BCN_CTRL, 0);
|
||||
RTL_W8(DUAL_TSF_RST, 1);
|
||||
RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N|EN_TXBCN_RPT);
|
||||
RTL_W8(MBID_NUM, (RTL_R8(MBID_NUM) & ~MBID_BCN_NUM_Mask) | (nr_vap & MBID_BCN_NUM_Mask));
|
||||
|
||||
RTL_W32(RCR, RTL_R32(RCR) & ~RCR_MBID_EN);
|
||||
RTL_W32(RCR, RTL_R32(RCR) | RCR_MBID_EN); // MBSSID enable
|
||||
}
|
||||
|
||||
SMP_UNLOCK_MBSSID(&irqL);
|
||||
}
|
||||
|
||||
void __rtl8192cd_sort_mbssid_bcn(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
struct rtl8192cd_priv *priv_root, *priv_vap;
|
||||
unsigned char *macAddr;
|
||||
unsigned char mbssid_ctrl;
|
||||
int nr_bcn, nr_vap;
|
||||
|
||||
int i, j;
|
||||
unsigned int camData[2];
|
||||
unsigned int inter_bcn_space;
|
||||
|
||||
camData[1] = 0;
|
||||
|
||||
for (i = 0; i <= priv->pshare->nr_bcn; ++i) {
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | (i&MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT;
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
}
|
||||
|
||||
nr_bcn = 0;
|
||||
mbssid_ctrl = 0x0FF;
|
||||
priv_root = GET_ROOT(priv);
|
||||
|
||||
macAddr = priv_root->pmib->dot11OperationEntry.hwaddr;
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | MBIDCAM_VALID |
|
||||
(priv_root->vap_init_seq & MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT |
|
||||
(macAddr[5] << 8) | macAddr[4];
|
||||
camData[1] = (macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0];
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
|
||||
if (!priv_root->pmib->miscEntry.func_off) {
|
||||
priv_root->func_off_already = 0;
|
||||
priv->pshare->bcn_priv[nr_bcn++] = priv_root;
|
||||
} else {
|
||||
priv_root->func_off_already = 1;
|
||||
priv->pshare->bcn_priv[0] = priv_root;
|
||||
mbssid_ctrl &= ~BIT0;
|
||||
}
|
||||
|
||||
for (i = 0; i < RTL8192CD_NUM_VWLAN; ++i) {
|
||||
priv_vap = priv_root->pvap_priv[i];
|
||||
if (!IS_DRV_OPEN(priv_vap))
|
||||
continue;
|
||||
|
||||
if (priv_vap->pmib->miscEntry.func_off) {
|
||||
priv_vap->func_off_already = 1;
|
||||
continue;
|
||||
}
|
||||
priv_vap->func_off_already = 0;
|
||||
|
||||
priv_vap->vap_init_seq = nr_bcn;
|
||||
priv->pshare->bcn_priv[nr_bcn++] = priv_vap;
|
||||
|
||||
macAddr = priv_vap->pmib->dot11OperationEntry.hwaddr;
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | MBIDCAM_VALID |
|
||||
(priv_vap->vap_init_seq & MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT |
|
||||
(macAddr[5] << 8) | macAddr[4];
|
||||
camData[1] = (macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0];
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
|
||||
mbssid_ctrl |= BIT(priv_vap->vap_init_seq);
|
||||
}
|
||||
|
||||
priv->pshare->nr_bcn = nr_bcn;
|
||||
nr_vap = (nr_bcn > 1) ? (nr_bcn - 1) : 0;
|
||||
|
||||
inter_bcn_space = priv_root->pmib->dot11StationConfigEntry.dot11BeaconPeriod-
|
||||
((priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod*nr_vap)/(nr_vap+1))-1;
|
||||
if (inter_bcn_space > 200)
|
||||
inter_bcn_space = 200;
|
||||
priv->pshare->inter_bcn_space = priv_root->pmib->dot11StationConfigEntry.dot11BeaconPeriod*NET80211_TU_TO_US/(nr_vap+1);
|
||||
|
||||
RTL_W8(MBID_NUM, (RTL_R8(MBID_NUM) & ~MBID_BCN_NUM_Mask) | (nr_vap & MBID_BCN_NUM_Mask));
|
||||
RTL_W8(REG_MBSSID_CTRL, mbssid_ctrl);
|
||||
|
||||
RTL_W32(MBSSID_BCN_SPACE, (inter_bcn_space & BCN_SPACE2_Mask)<<BCN_SPACE2_SHIFT
|
||||
|(priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE1_Mask)<<BCN_SPACE1_SHIFT);
|
||||
|
||||
RTL_W8(BCN_CTRL, 0);
|
||||
//RTL_W8(DUAL_TSF_RST, 1);
|
||||
RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N|EN_TXBCN_RPT);
|
||||
|
||||
// update TBTT prohibit hold time according to current beacon settings
|
||||
if (0 == nr_bcn)
|
||||
RTL_W32(TBTT_PROHIBIT, (RTL_R32(TBTT_PROHIBIT)&0xfff000ff) | 0x100);
|
||||
else if (inter_bcn_space <= 40)
|
||||
RTL_W32(TBTT_PROHIBIT, (RTL_R32(TBTT_PROHIBIT)&0xfff000ff) | 0x1df00);
|
||||
else if (1 == nr_bcn)
|
||||
RTL_W32(TBTT_PROHIBIT, (RTL_R32(TBTT_PROHIBIT)&0xfff000ff) | 0x40000);
|
||||
else
|
||||
RTL_W32(TBTT_PROHIBIT, (RTL_R32(TBTT_PROHIBIT)&0xfff000ff) | 0x1df00);
|
||||
|
||||
RTL_W32(RCR, RTL_R32(RCR) & ~RCR_MBID_EN);
|
||||
RTL_W32(RCR, RTL_R32(RCR) | RCR_MBID_EN); // MBSSID enable
|
||||
}
|
||||
|
||||
void rtl8192cd_sort_mbssid_bcn(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
_irqL irqL;
|
||||
|
||||
SMP_LOCK_MBSSID(&irqL);
|
||||
|
||||
__rtl8192cd_sort_mbssid_bcn(priv);
|
||||
|
||||
SMP_UNLOCK_MBSSID(&irqL);
|
||||
}
|
||||
|
||||
void rtl8192cd_stop_mbssid(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
int i, j;
|
||||
unsigned int camData[2];
|
||||
_irqL irqL;
|
||||
|
||||
camData[1] = 0;
|
||||
|
||||
SMP_LOCK_MBSSID(&irqL);
|
||||
|
||||
if (IS_ROOT_INTERFACE(priv))
|
||||
{
|
||||
// clear the rest area of CAM
|
||||
for (i=0; i<8; i++) {
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | (i&MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT;
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
}
|
||||
|
||||
priv->pshare->nr_bcn = 1;
|
||||
priv->pshare->bcn_priv[0] = priv;
|
||||
priv->pshare->inter_bcn_space = priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod * NET80211_TU_TO_US;
|
||||
|
||||
RTL_W32(RCR, RTL_R32(RCR) & ~RCR_MBID_EN); // MBSSID disable
|
||||
RTL_W32(MBSSID_BCN_SPACE,
|
||||
(priv->pmib->dot11StationConfigEntry.dot11BeaconPeriod & BCN_SPACE1_Mask)<<BCN_SPACE1_SHIFT);
|
||||
|
||||
RTL_W8(BCN_CTRL, 0);
|
||||
//RTL_W8(DUAL_TSF_RST, 1);
|
||||
RTL_W8(BCN_CTRL, EN_BCN_FUNCTION | DIS_SUB_STATE_N | DIS_TSF_UPDATE_N| EN_TXBCN_RPT);
|
||||
}
|
||||
else if (IS_VAP_INTERFACE(priv) && (priv->vap_init_seq >= 0))
|
||||
{
|
||||
if (priv->func_off_already) {
|
||||
priv->vap_init_seq = -1;
|
||||
SMP_UNLOCK_MBSSID(&irqL);
|
||||
return;
|
||||
}
|
||||
|
||||
__rtl8192cd_sort_mbssid_bcn(priv);
|
||||
priv->vap_init_seq = -1;
|
||||
}
|
||||
|
||||
SMP_UNLOCK_MBSSID(&irqL);
|
||||
}
|
||||
|
||||
void rtl8192cd_set_mbidcam(struct rtl8192cd_priv *priv, unsigned char *macAddr, unsigned char index)
|
||||
{
|
||||
int j;
|
||||
unsigned int camData[2];
|
||||
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | MBIDCAM_VALID |
|
||||
(index & MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT |
|
||||
(macAddr[5] << 8) | macAddr[4];
|
||||
camData[1] = (macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0];
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
}
|
||||
|
||||
void rtl8192cd_clear_mbidcam(struct rtl8192cd_priv *priv, unsigned char index)
|
||||
{
|
||||
int j;
|
||||
unsigned int camData[2];
|
||||
|
||||
camData[0] = MBIDCAM_POLL | MBIDWRITE_EN | (index &MBIDCAM_ADDR_Mask)<<MBIDCAM_ADDR_SHIFT;
|
||||
camData[1] = 0;
|
||||
for (j=1; j>=0; j--) {
|
||||
RTL_W32((MBIDCAMCFG+4)-4*j, camData[j]);
|
||||
}
|
||||
}
|
||||
#endif // MBSSID
|
||||
|
36
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_hw.h
Executable file
36
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_hw.h
Executable file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Header files defines some SDIO TX inline routines
|
||||
*
|
||||
* $Id: 8188e_sdio_hw.h,v 1.4.4.5 2010/12/10 06:11:55 family Exp $
|
||||
*
|
||||
* Copyright (c) 2009 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _8188E_SDIO_HW_H_
|
||||
#define _8188E_SDIO_HW_H_
|
||||
|
||||
extern struct sdio_driver rtl8192cd_sdio_driver;
|
||||
|
||||
extern int Load_88E_Firmware(struct rtl8192cd_priv *priv);
|
||||
extern u8 _CardEnable(struct rtl8192cd_priv *priv);
|
||||
extern int rtl8188es_InitPowerOn(struct rtl8192cd_priv *priv);
|
||||
|
||||
#ifdef CONFIG_EXT_CLK_26M
|
||||
extern void _InitClockTo26MHz(struct rtl8192cd_priv *priv);
|
||||
#endif
|
||||
|
||||
#ifdef MBSSID
|
||||
void rtl8192cd_init_mbssid(struct rtl8192cd_priv *priv);
|
||||
void rtl8192cd_stop_mbssid(struct rtl8192cd_priv *priv);
|
||||
void rtl8192cd_sort_mbssid_bcn(struct rtl8192cd_priv *priv);
|
||||
|
||||
void rtl8192cd_set_mbidcam(struct rtl8192cd_priv *priv, unsigned char *macAddr, unsigned char index);
|
||||
void rtl8192cd_clear_mbidcam(struct rtl8192cd_priv *priv, unsigned char index);
|
||||
#endif
|
||||
|
||||
#endif // _8188E_SDIO_HW_H_
|
||||
|
839
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_recv.c
Executable file
839
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_recv.c
Executable file
@ -0,0 +1,839 @@
|
||||
/*
|
||||
* SDIO RX handle routines
|
||||
*
|
||||
* $Id: 8188e_sdio_recv.c,v 1.27.2.31 2010/12/31 08:37:43 family Exp $
|
||||
*
|
||||
* Copyright (c) 2009 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define _8188E_SDIO_RECV_C_
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#endif
|
||||
|
||||
#include "8192cd.h"
|
||||
#include "8192cd_headers.h"
|
||||
#include "8192cd_debug.h"
|
||||
#include "8192cd_rx.h"
|
||||
|
||||
|
||||
int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue)
|
||||
{
|
||||
_irqL irqL;
|
||||
|
||||
_enter_critical(&queue->lock, &irqL);
|
||||
|
||||
rtw_list_insert_tail(&precvbuf->list, get_list_head(queue));
|
||||
|
||||
++queue->qlen;
|
||||
|
||||
_exit_critical(&queue->lock, &irqL);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
struct recv_buf *rtw_dequeue_recvbuf(_queue *queue)
|
||||
{
|
||||
_irqL irqL;
|
||||
struct recv_buf *precvbuf = NULL;
|
||||
_list *plist, *phead;
|
||||
|
||||
plist = NULL;
|
||||
|
||||
phead = get_list_head(queue);
|
||||
|
||||
_enter_critical(&queue->lock, &irqL);
|
||||
|
||||
if (rtw_is_list_empty(phead) == FALSE) {
|
||||
|
||||
plist = get_next(phead);
|
||||
|
||||
rtw_list_delete(plist);
|
||||
|
||||
--queue->qlen;
|
||||
}
|
||||
|
||||
_exit_critical(&queue->lock, &irqL);
|
||||
|
||||
if (NULL != plist) {
|
||||
precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
|
||||
}
|
||||
|
||||
return precvbuf;
|
||||
}
|
||||
|
||||
union recv_frame *rtw_alloc_recvframe(_queue *pfree_recv_queue)
|
||||
{
|
||||
_irqL irqL;
|
||||
union recv_frame *precvframe = NULL;
|
||||
_list *plist, *phead;
|
||||
|
||||
plist = NULL;
|
||||
|
||||
phead = get_list_head(pfree_recv_queue);
|
||||
|
||||
_enter_critical_bh(&pfree_recv_queue->lock, &irqL);
|
||||
|
||||
if (rtw_is_list_empty(phead) == FALSE) {
|
||||
|
||||
plist = get_next(phead);
|
||||
|
||||
rtw_list_delete(plist);
|
||||
|
||||
--pfree_recv_queue->qlen;
|
||||
}
|
||||
|
||||
_exit_critical_bh(&pfree_recv_queue->lock, &irqL);
|
||||
|
||||
if (NULL != plist) {
|
||||
precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
|
||||
}
|
||||
|
||||
return precvframe;
|
||||
}
|
||||
|
||||
int rtw_free_recvframe(struct rtl8192cd_priv *priv, union recv_frame *precvframe, _queue *pfree_recv_queue)
|
||||
{
|
||||
_irqL irqL;
|
||||
|
||||
if(precvframe->u.hdr.pkt)
|
||||
{
|
||||
rtl_kfree_skb(priv, precvframe->u.hdr.pkt, _SKB_RX_);
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
}
|
||||
|
||||
_enter_critical_bh(&pfree_recv_queue->lock, &irqL);
|
||||
|
||||
rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
|
||||
|
||||
++pfree_recv_queue->qlen;
|
||||
|
||||
_exit_critical_bh(&pfree_recv_queue->lock, &irqL);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int recv_func(struct rtl8192cd_priv *priv, void *pcontext, struct recv_stat *prxstat, struct phy_stat *pphy_info)
|
||||
{
|
||||
union recv_frame *precvframe = (union recv_frame *)pcontext;
|
||||
int retval = FAIL;
|
||||
struct rx_desc *pdesc = (struct rx_desc *)prxstat;
|
||||
struct rx_frinfo *pfrinfo;
|
||||
struct sk_buff *pskb;
|
||||
unsigned int cmd;
|
||||
unsigned int rtl8192cd_ICV, privacy;
|
||||
unsigned char rx_rate;
|
||||
struct stat_info *pstat;
|
||||
unsigned char *pframe;
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
|
||||
pskb = (struct sk_buff *)(precvframe->u.hdr.pkt);
|
||||
|
||||
cmd = get_desc(pdesc->Dword0);
|
||||
pfrinfo = get_pfrinfo(pskb);
|
||||
|
||||
init_frinfo(pfrinfo);
|
||||
#if defined(UNIVERSAL_REPEATER) || defined(MBSSID)
|
||||
pfrinfo->is_br_mgnt = 0;
|
||||
#endif
|
||||
|
||||
if (cmd & RX_CRC32) {
|
||||
/*printk("CRC32 happens~!!\n");*/
|
||||
rx_pkt_exception(priv, cmd);
|
||||
goto _exit_recv_func;
|
||||
}
|
||||
|
||||
if (!IS_DRV_OPEN(priv)) {
|
||||
goto _exit_recv_func;
|
||||
}
|
||||
|
||||
if (cmd & RX_ICVERR) {
|
||||
rtl8192cd_ICV = privacy = 0;
|
||||
pstat = NULL;
|
||||
|
||||
pframe = get_pframe(pfrinfo);
|
||||
#if defined(WDS) || defined(CONFIG_RTK_MESH) || defined(A4_STA)
|
||||
if (get_tofr_ds(pframe) == 3) {
|
||||
pstat = get_stainfo(priv, GetAddr2Ptr(pframe));
|
||||
} else
|
||||
#endif
|
||||
{pstat = get_stainfo(priv, get_sa(pframe));}
|
||||
|
||||
if (!pstat) {
|
||||
rtl8192cd_ICV++;
|
||||
} else {
|
||||
if (OPMODE & WIFI_AP_STATE) {
|
||||
#if defined(WDS) || defined(CONFIG_RTK_MESH)
|
||||
if (get_tofr_ds(pframe) == 3){
|
||||
#if defined(CONFIG_RTK_MESH)
|
||||
if(priv->pmib->dot1180211sInfo.mesh_enable) {
|
||||
privacy = (IS_MCAST(GetAddr1Ptr(pframe))) ? _NO_PRIVACY_ : priv->pmib->dot11sKeysTable.dot11Privacy;
|
||||
} else
|
||||
#endif
|
||||
{privacy = priv->pmib->dot11WdsInfo.wdsPrivacy;}
|
||||
}
|
||||
else
|
||||
#endif /* defined(WDS) || defined(CONFIG_RTK_MESH) */
|
||||
{privacy = get_sta_encrypt_algthm(priv, pstat);}
|
||||
}
|
||||
#if defined(CLIENT_MODE)
|
||||
else {
|
||||
privacy = get_sta_encrypt_algthm(priv, pstat);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (privacy != _CCMP_PRIVACY_)
|
||||
rtl8192cd_ICV++;
|
||||
}
|
||||
|
||||
if (rtl8192cd_ICV) {
|
||||
rx_pkt_exception(priv, cmd);
|
||||
goto _exit_recv_func;
|
||||
}
|
||||
}
|
||||
|
||||
pfrinfo->pktlen = (cmd & RX_PktLenMask) - _CRCLNG_;
|
||||
pfrinfo->driver_info_size = ((cmd >> RX_DrvInfoSizeSHIFT) & RX_DrvInfoSizeMask)<<3;
|
||||
pfrinfo->rxbuf_shift = (cmd & (RX_ShiftMask << RX_ShiftSHIFT)) >> RX_ShiftSHIFT;
|
||||
pfrinfo->sw_dec = (cmd & RX_SwDec) >> 27;
|
||||
|
||||
// pfrinfo->pktlen -= pfrinfo->rxbuf_shift;
|
||||
if ((pfrinfo->pktlen > 0x2000) || (pfrinfo->pktlen < 16)) {
|
||||
printk("pfrinfo->pktlen=%d, goto rx_reuse\n",pfrinfo->pktlen);
|
||||
goto _exit_recv_func;
|
||||
}
|
||||
|
||||
pfrinfo->driver_info = (struct RxFWInfo *)pphy_info;
|
||||
pfrinfo->physt = (get_desc(pdesc->Dword0) & RX_PHYST)? 1:0;
|
||||
pfrinfo->faggr = (get_desc(pdesc->Dword1) & RX_FAGGR)? 1:0;
|
||||
pfrinfo->paggr = (get_desc(pdesc->Dword1) & RX_PAGGR)? 1:0;
|
||||
pfrinfo->rx_bw = (get_desc(pdesc->Dword3) & RX_BW)? 1:0;
|
||||
pfrinfo->rx_splcp = (get_desc(pdesc->Dword3) & RX_SPLCP)? 1:0;
|
||||
|
||||
rx_rate = get_desc(pdesc->Dword3) & RX_RxMcsMask;
|
||||
if (rx_rate < 12) {
|
||||
pfrinfo->rx_rate = dot11_rate_table[rx_rate];
|
||||
} else {
|
||||
pfrinfo->rx_rate = HT_RATE_ID + (rx_rate - 12);
|
||||
}
|
||||
|
||||
if (!pfrinfo->physt) {
|
||||
pfrinfo->rssi = 0;
|
||||
} else {
|
||||
#ifdef USE_OUT_SRC
|
||||
#ifdef _OUTSRC_COEXIST
|
||||
if (IS_OUTSRC_CHIP(priv))
|
||||
#endif
|
||||
{
|
||||
translate_rssi_sq_outsrc(priv, pfrinfo, rx_rate);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(USE_OUT_SRC) || defined(_OUTSRC_COEXIST)
|
||||
#ifdef _OUTSRC_COEXIST
|
||||
if (!IS_OUTSRC_CHIP(priv))
|
||||
#endif
|
||||
{
|
||||
translate_rssi_sq(priv, pfrinfo);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MP_TEST
|
||||
if (OPMODE & WIFI_MP_STATE) {
|
||||
unsigned char *sa,*da,*bssid;
|
||||
unsigned int find_flag = 1;
|
||||
|
||||
pframe = get_pframe(pfrinfo);
|
||||
if ((OPMODE & WIFI_MP_ARX_FILTER ) && (OPMODE & WIFI_MP_RX ))
|
||||
{
|
||||
sa = get_sa(pframe);
|
||||
da = get_da(pframe);
|
||||
bssid = get_bssid_mp(pframe);
|
||||
|
||||
if ((priv->pshare->mp_filter_flag & 0x1)
|
||||
&& memcmp(priv->pshare->mp_filter_SA, sa, MACADDRLEN))
|
||||
{
|
||||
find_flag = 0;
|
||||
}
|
||||
if (find_flag)
|
||||
{
|
||||
if ((priv->pshare->mp_filter_flag & 0x2)
|
||||
&& memcmp(priv->pshare->mp_filter_DA, da, MACADDRLEN))
|
||||
{
|
||||
find_flag = 0;
|
||||
}
|
||||
}
|
||||
if (find_flag)
|
||||
{
|
||||
if ((priv->pshare->mp_filter_flag & 0x4)
|
||||
&& memcmp(priv->pshare->mp_filter_BSSID, bssid, MACADDRLEN))
|
||||
{
|
||||
find_flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (find_flag)
|
||||
{
|
||||
rx_sum_up(priv, NULL, pfrinfo->pktlen, GetRetry(pframe));
|
||||
if (priv->pshare->rf_ft_var.rssi_dump)
|
||||
update_sta_rssi(priv, NULL, pfrinfo);
|
||||
}
|
||||
|
||||
retval = SUCCESS;
|
||||
goto _exit_recv_func;
|
||||
}
|
||||
#endif // MP_TEST
|
||||
|
||||
SNMP_MIB_INC(dot11ReceivedFragmentCount, 1);
|
||||
|
||||
#if defined(SW_ANT_SWITCH)
|
||||
if (priv->pshare->rf_ft_var.antSw_enable) {
|
||||
dm_SWAW_RSSI_Check(priv, pfrinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!validate_mpdu(priv, pfrinfo)) {
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
}
|
||||
|
||||
retval = SUCCESS;
|
||||
|
||||
_exit_recv_func:
|
||||
rtw_free_recvframe(priv, precvframe, &precvpriv->free_recv_queue);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
s32 rtw_recv_entry(struct rtl8192cd_priv *priv, union recv_frame *precvframe, struct recv_stat *prxstat, struct phy_stat *pphy_info)
|
||||
{
|
||||
return recv_func(priv, precvframe, prxstat, pphy_info);
|
||||
}
|
||||
|
||||
void rtl8188es_free_recv_priv(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
|
||||
_rtw_spinlock_free(&precvpriv->free_recv_buf_queue.lock);
|
||||
_rtw_spinlock_free(&precvpriv->recv_buf_pending_queue.lock);
|
||||
|
||||
if (precvpriv->pallocated_recv_buf)
|
||||
{
|
||||
rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF * sizeof(struct recv_buf) + 4);
|
||||
precvpriv->pallocated_recv_buf = NULL;
|
||||
precvpriv->precv_buf = NULL;
|
||||
}
|
||||
|
||||
if (precvpriv->recvbuf_mem) {
|
||||
#ifdef USE_PREALLOC_MODULE
|
||||
rtw_pre_free(precvpriv->recvbuf_mem);
|
||||
#else
|
||||
rtw_mfree(precvpriv->recvbuf_mem, MAX_RECVBUF_MEM_SZ);
|
||||
#endif
|
||||
precvpriv->recvbuf_mem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int rtl8188es_init_recv_priv(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
struct recv_buf *precvbuf;
|
||||
int i;
|
||||
|
||||
//init recv_buf
|
||||
_rtw_init_queue(&precvpriv->free_recv_buf_queue);
|
||||
_rtw_init_queue(&precvpriv->recv_buf_pending_queue);
|
||||
|
||||
#ifdef USE_PREALLOC_MODULE
|
||||
precvpriv->recvbuf_mem = rtw_pre_malloc(PREALLOC_TYPE_RECVMEM, MAX_RECVBUF_MEM_SZ);
|
||||
#else
|
||||
precvpriv->recvbuf_mem = rtw_malloc(MAX_RECVBUF_MEM_SZ);
|
||||
#endif
|
||||
if (NULL == precvpriv->recvbuf_mem) {
|
||||
printk("alloc recvbuf_mem fail!(size %d)\n", MAX_RECVBUF_MEM_SZ);
|
||||
return FAIL;
|
||||
}
|
||||
precvpriv->recvbuf_mem_head = PTR_ALIGN(precvpriv->recvbuf_mem, RECVBUFF_ALIGN_SZ);
|
||||
precvpriv->recvbuf_mem_data = precvpriv->recvbuf_mem_tail = precvpriv->recvbuf_mem_head;
|
||||
#ifdef RECVBUF_DEBUG
|
||||
precvpriv->recvbuf_mem_end = PTR_ALIGN(precvpriv->recvbuf_mem +MAX_RECVBUF_MEM_SZ-RECVBUFF_ALIGN_SZ, RECVBUFF_ALIGN_SZ);
|
||||
*precvpriv->recvbuf_mem_end = RECVBUF_POISON_END;
|
||||
#else
|
||||
precvpriv->recvbuf_mem_end = precvpriv->recvbuf_mem + MAX_RECVBUF_MEM_SZ;
|
||||
#endif
|
||||
|
||||
precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF *sizeof(struct recv_buf) + 4);
|
||||
|
||||
if (precvpriv->pallocated_recv_buf == NULL) {
|
||||
printk("alloc recv_buf fail!(size %d)\n", (NR_RECVBUFF *sizeof(struct recv_buf) + 4));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
|
||||
|
||||
precvbuf = (struct recv_buf*)precvpriv->precv_buf;
|
||||
|
||||
for (i=0 ; i < NR_RECVBUFF ; i++)
|
||||
{
|
||||
_rtw_init_listhead(&precvbuf->list);
|
||||
rtw_list_insert_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue));
|
||||
precvbuf++;
|
||||
}
|
||||
|
||||
precvpriv->free_recv_buf_queue.qlen = NR_RECVBUFF;
|
||||
|
||||
//init tasklet
|
||||
tasklet_init(&precvpriv->recv_tasklet,
|
||||
(void(*)(unsigned long))rtl8188es_recv_tasklet,
|
||||
(unsigned long)priv);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
exit:
|
||||
rtl8188es_free_recv_priv(priv);
|
||||
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
void update_recvframe_attrib_88e(union recv_frame *precvframe, struct recv_stat *prxstat)
|
||||
{
|
||||
struct rx_pkt_attrib *pattrib;
|
||||
struct recv_stat report;
|
||||
|
||||
report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
|
||||
report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
|
||||
report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
|
||||
report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
|
||||
report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
|
||||
report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
|
||||
|
||||
pattrib = &precvframe->u.hdr.attrib;
|
||||
memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
|
||||
|
||||
pattrib->crc_err = (u8)((report.rxdw0 >> 14) & 0x1);;//(u8)prxreport->crc32;
|
||||
|
||||
// update rx report to recv_frame attribute
|
||||
pattrib->pkt_rpt_type = (u8)((report.rxdw3 >> 14) & 0x3);//prxreport->rpt_sel;
|
||||
|
||||
if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet
|
||||
{
|
||||
pattrib->pkt_len = (u16)(report.rxdw0 &0x00003fff);//(u16)prxreport->pktlen;
|
||||
pattrib->drvinfo_sz = (u8)((report.rxdw0 >> 16) & 0xf) * 8;//(u8)(prxreport->drvinfosize << 3);
|
||||
|
||||
pattrib->physt = (u8)((report.rxdw0 >> 26) & 0x1);//(u8)prxreport->physt;
|
||||
|
||||
pattrib->bdecrypted = (report.rxdw0 & BIT(27))? 0:1;//(u8)(prxreport->swdec ? 0 : 1);
|
||||
pattrib->encrypt = (u8)((report.rxdw0 >> 20) & 0x7);//(u8)prxreport->security;
|
||||
|
||||
pattrib->qos = (u8)((report.rxdw0 >> 23) & 0x1);//(u8)prxreport->qos;
|
||||
pattrib->priority = (u8)((report.rxdw1 >> 8) & 0xf);//(u8)prxreport->tid;
|
||||
|
||||
pattrib->amsdu = (u8)((report.rxdw1 >> 13) & 0x1);//(u8)prxreport->amsdu;
|
||||
|
||||
pattrib->seq_num = (u16)(report.rxdw2 & 0x00000fff);//(u16)prxreport->seq;
|
||||
pattrib->frag_num = (u8)((report.rxdw2 >> 12) & 0xf);//(u8)prxreport->frag;
|
||||
pattrib->mfrag = (u8)((report.rxdw1 >> 27) & 0x1);//(u8)prxreport->mf;
|
||||
pattrib->mdata = (u8)((report.rxdw1 >> 26) & 0x1);//(u8)prxreport->md;
|
||||
|
||||
pattrib->icv_err = (u8)((report.rxdw0 >> 15) & 0x1);//(u8)prxreport->icverr;
|
||||
//pattrib->shift_sz = (u8)prxreport->shift;
|
||||
//pattrib->shift_sz = (u8)((report.rxdw0 >> 24) & 0x3);
|
||||
|
||||
}
|
||||
else if(pattrib->pkt_rpt_type == TX_REPORT2)// TX RPT
|
||||
{
|
||||
pattrib->pkt_len =(u16)(report.rxdw0 & 0x3FF);//Rx length[9:0]
|
||||
pattrib->drvinfo_sz = 0;
|
||||
|
||||
//
|
||||
// Get TX report MAC ID valid.
|
||||
//
|
||||
pattrib->MacIDValidEntry[0] = report.rxdw4;
|
||||
pattrib->MacIDValidEntry[1] = report.rxdw5;
|
||||
|
||||
}
|
||||
else if(pattrib->pkt_rpt_type == HIS_REPORT)// USB HISR RPT
|
||||
{
|
||||
pattrib->pkt_len = (u16)(report.rxdw0 &0x00003fff);//(u16)prxreport->pktlen;
|
||||
}
|
||||
else if(pattrib->pkt_rpt_type == TX_REPORT1)//CCX
|
||||
{
|
||||
pattrib->pkt_len = TX_RPT1_PKT_LEN;
|
||||
pattrib->drvinfo_sz = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int recvbuf2recvframe(struct rtl8192cd_priv *priv, struct recv_buf *precvbuf)
|
||||
{
|
||||
u8 *pbuf;
|
||||
u8 shift_sz = 0;
|
||||
u32 pkt_offset, skb_len, alloc_sz;
|
||||
struct recv_stat *prxstat;
|
||||
struct phy_stat *pphy_info = NULL;
|
||||
_pkt *pkt_copy = NULL;
|
||||
union recv_frame *precvframe = NULL;
|
||||
struct rx_pkt_attrib *pattrib = NULL;
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
_queue *pfree_recv_queue = &precvpriv->free_recv_queue;
|
||||
int nr_recvframe = 0;
|
||||
|
||||
pbuf = precvbuf->pdata;
|
||||
|
||||
do {
|
||||
prxstat = (struct recv_stat *)pbuf;
|
||||
|
||||
precvframe = rtw_alloc_recvframe(pfree_recv_queue);
|
||||
if (precvframe == NULL)
|
||||
{
|
||||
printk("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __FUNCTION__, __LINE__);
|
||||
precvpriv->nr_out_of_recvframe++;
|
||||
goto _exit_recvbuf2recvframe;
|
||||
}
|
||||
|
||||
update_recvframe_attrib_88e(precvframe, prxstat);
|
||||
|
||||
pattrib = &precvframe->u.hdr.attrib;
|
||||
|
||||
if (pattrib->physt
|
||||
#ifdef CONFIG_RTL_88E_SUPPORT
|
||||
&& (pattrib->pkt_rpt_type == NORMAL_RX)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
pphy_info = (struct phy_stat *)(pbuf + RXDESC_OFFSET);
|
||||
}
|
||||
|
||||
pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
|
||||
|
||||
if ((pbuf + pkt_offset) > precvbuf->ptail)
|
||||
{
|
||||
printk("%s()-%d: RX Warning! next pkt len exceed ptail!\n", __FUNCTION__, __LINE__);
|
||||
rtw_free_recvframe(priv, precvframe, pfree_recv_queue);
|
||||
goto _exit_recvbuf2recvframe;
|
||||
}
|
||||
|
||||
// Modified by Albert 20101213
|
||||
// For 8 bytes IP header alignment.
|
||||
if (pattrib->qos) // Qos data, wireless lan header length is 26
|
||||
{
|
||||
shift_sz = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift_sz = 0;
|
||||
}
|
||||
|
||||
skb_len = pattrib->pkt_len;
|
||||
|
||||
// for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
|
||||
// modify alloc_sz for recvive crc error packet by thomas 2011-06-02
|
||||
if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
|
||||
//alloc_sz = 1664; //1664 is 128 alignment.
|
||||
if(skb_len <= 1650)
|
||||
alloc_sz = 1664;
|
||||
else
|
||||
alloc_sz = skb_len + 14;
|
||||
}
|
||||
else {
|
||||
alloc_sz = skb_len;
|
||||
// 6 is for IP header 8 bytes alignment in QoS packet case.
|
||||
// 8 is for skb->data 4 bytes alignment.
|
||||
alloc_sz += 14;
|
||||
}
|
||||
|
||||
// Make IP header in AMSDU subframe 4 bytes alignment
|
||||
if (pattrib->amsdu) {
|
||||
shift_sz += 2;
|
||||
alloc_sz += 2;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RTL_WAPI_SUPPORT
|
||||
alloc_sz += sizeof(struct rx_frinfo) + SMS4_MIC_LEN;
|
||||
#else
|
||||
alloc_sz += sizeof(struct rx_frinfo) + 8; // 8 is for TKIP Michael padding
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
|
||||
pkt_copy = dev_alloc_skb(alloc_sz);
|
||||
#else
|
||||
pkt_copy = netdev_alloc_skb(priv->dev, alloc_sz);
|
||||
#endif
|
||||
if (pkt_copy)
|
||||
{
|
||||
pkt_copy->dev = priv->dev;
|
||||
precvframe->u.hdr.pkt = pkt_copy;
|
||||
skb_reserve( pkt_copy, sizeof(struct rx_frinfo));
|
||||
skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
|
||||
skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
|
||||
memcpy(pkt_copy->data, (pbuf + RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz), skb_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("recvbuf2recvframe:can not allocate memory for skb copy\n");
|
||||
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
rtw_free_recvframe(priv, precvframe, pfree_recv_queue);
|
||||
|
||||
goto _exit_recvbuf2recvframe;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RTL_SKB_STATS
|
||||
rtl_atomic_inc(&priv->rtl_rx_skb_cnt);
|
||||
#endif
|
||||
|
||||
if (pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet
|
||||
{
|
||||
nr_recvframe++;
|
||||
if (rtw_recv_entry(priv, precvframe, prxstat, pphy_info) != SUCCESS)
|
||||
{
|
||||
//printk("recvbuf2recvframe: rtw_recv_entry(precvframe) != SUCCESS\n");
|
||||
}
|
||||
}
|
||||
else { // pkt_rpt_type == TX_REPORT1-CCX, TX_REPORT2-TX RTP, HIS_REPORT-USB HISR RTP
|
||||
|
||||
//enqueue recvframe to txrtp queue
|
||||
if (unlikely(pattrib->pkt_rpt_type == TX_REPORT1)) {
|
||||
printk("rx CCX\n");
|
||||
}
|
||||
else if (pattrib->pkt_rpt_type == TX_REPORT2) {
|
||||
//printk("rx TX RPT\n");
|
||||
#ifdef TXREPORT
|
||||
#ifdef RATEADAPTIVE_BY_ODM
|
||||
ODM_RA_TxRPT2Handle_8188E(
|
||||
ODMPTR,
|
||||
pkt_copy->data, //precvframe->u.hdr.rx_data,
|
||||
pattrib->pkt_len,
|
||||
pattrib->MacIDValidEntry[0],
|
||||
pattrib->MacIDValidEntry[1]
|
||||
);
|
||||
#else
|
||||
{
|
||||
struct rx_frinfo *pfrinfo = get_pfrinfo(pkt_copy);
|
||||
pfrinfo->pktlen = pattrib->pkt_len;
|
||||
|
||||
RTL8188E_TxReportHandler(priv, pkt_copy, pattrib->MacIDValidEntry[0],
|
||||
pattrib->MacIDValidEntry[1], (struct rx_desc *)prxstat);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
rtw_free_recvframe(priv, precvframe, pfree_recv_queue);
|
||||
}
|
||||
|
||||
// Page size of receive package is 128 bytes alignment => DMA AGG
|
||||
// refer to _InitTransferPageSize()
|
||||
pkt_offset = _RND128(pkt_offset);
|
||||
precvbuf->pdata += pkt_offset;
|
||||
pbuf = precvbuf->pdata;
|
||||
precvframe = NULL;
|
||||
pkt_copy = NULL;
|
||||
|
||||
} while(pbuf < precvbuf->ptail);
|
||||
|
||||
priv->pshare->nr_recvframe_in_recvbuf = nr_recvframe;
|
||||
|
||||
_exit_recvbuf2recvframe:
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void rtw_flush_recvbuf_pending_queue(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
struct recv_buf *precvbuf;
|
||||
|
||||
while (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue))) {
|
||||
precvpriv->recvbuf_mem_data = precvbuf->pend;
|
||||
rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
|
||||
}
|
||||
}
|
||||
|
||||
void rtl8188es_recv_tasklet(void *p)
|
||||
{
|
||||
struct rtl8192cd_priv *priv = (struct rtl8192cd_priv *)p;
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
struct recv_buf *precvbuf;
|
||||
int nr_recvbuf = 0;
|
||||
|
||||
do {
|
||||
if ((priv->pshare->bDriverStopped == TRUE) || (priv->pshare->bSurpriseRemoved == TRUE))
|
||||
{
|
||||
printk("[%s] bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
|
||||
__FUNCTION__, priv->pshare->bDriverStopped, priv->pshare->bSurpriseRemoved);
|
||||
break;
|
||||
}
|
||||
|
||||
precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
|
||||
if (NULL == precvbuf)
|
||||
break;
|
||||
|
||||
nr_recvbuf++;
|
||||
recvbuf2recvframe(priv, precvbuf);
|
||||
|
||||
precvpriv->recvbuf_mem_data = precvbuf->pend;
|
||||
rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
|
||||
} while (1);
|
||||
|
||||
priv->pshare->nr_recvbuf_handled_in_tasklet = nr_recvbuf;
|
||||
}
|
||||
|
||||
struct recv_buf* sd_recv_rxfifo(struct rtl8192cd_priv *priv, u32 size)
|
||||
{
|
||||
int err;
|
||||
u8 *preadbuf;
|
||||
u32 allocsize;
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
struct recv_buf *precvbuf = NULL;
|
||||
|
||||
BUG_ON(size > MAX_RECVBUF_SZ);
|
||||
|
||||
precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
|
||||
if (NULL == precvbuf) {
|
||||
DEBUG_INFO("%s: alloc recvbuf FAIL!\n", __FUNCTION__);
|
||||
precvpriv->nr_out_of_recvbuf++;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
// prepare buffer size to meet sdio_read_port() requirement
|
||||
allocsize = _RND(size, priv->pshare->block_transfer_len);
|
||||
|
||||
// assign buffer memory to recvbuf
|
||||
preadbuf = NULL;
|
||||
if (precvpriv->recvbuf_mem_tail >= precvpriv->recvbuf_mem_data) {
|
||||
if ((unsigned long)(precvpriv->recvbuf_mem_end - precvpriv->recvbuf_mem_tail) >= allocsize)
|
||||
preadbuf = precvpriv->recvbuf_mem_tail;
|
||||
else if ((unsigned long)(precvpriv->recvbuf_mem_data - precvpriv->recvbuf_mem_head) > allocsize)
|
||||
preadbuf = precvpriv->recvbuf_mem_head;
|
||||
} else {
|
||||
if ((unsigned long)(precvpriv->recvbuf_mem_data - precvpriv->recvbuf_mem_tail) > allocsize)
|
||||
preadbuf = precvpriv->recvbuf_mem_tail;
|
||||
}
|
||||
if (NULL == preadbuf) {
|
||||
DEBUG_INFO("%s: alloc recvbuf mem FAIL!\n", __FUNCTION__);
|
||||
precvpriv->nr_out_of_recvbuf_mem++;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
BUG_ON((unsigned long)preadbuf & (RECVBUFF_ALIGN_SZ - 1));
|
||||
|
||||
err = sdio_read_port(priv, WLAN_RX0FF_DEVICE_ID, size, preadbuf);
|
||||
if (0 != err) {
|
||||
printk("%s: read port FAIL! (err=%d)\n", __FUNCTION__, err);
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
#ifdef RECVBUF_DEBUG
|
||||
if (*precvpriv->recvbuf_mem_end != RECVBUF_POISON_END) {
|
||||
printk("[%s] BUG!! recvbuf_mem overwritten!!\n", __FUNCTION__);
|
||||
*precvpriv->recvbuf_mem_end = RECVBUF_POISON_END;
|
||||
}
|
||||
#endif
|
||||
|
||||
precvbuf->phead = preadbuf;
|
||||
precvbuf->pdata = preadbuf;
|
||||
precvbuf->ptail = preadbuf + size;
|
||||
precvbuf->pend = PTR_ALIGN(precvbuf->ptail, RECVBUFF_ALIGN_SZ);
|
||||
if (precvbuf->pend > precvpriv->recvbuf_mem_end)
|
||||
precvbuf->pend = precvpriv->recvbuf_mem_end;
|
||||
|
||||
precvpriv->recvbuf_mem_tail = precvbuf->pend;
|
||||
|
||||
return precvbuf;
|
||||
|
||||
err_exit:
|
||||
|
||||
if (precvbuf) {
|
||||
rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sd_rxhandler(struct rtl8192cd_priv *priv, struct recv_buf *precvbuf)
|
||||
{
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
|
||||
rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue);
|
||||
|
||||
// Considering TP, do every one without checking if recv_buf_pending_queue.qlen == 1
|
||||
tasklet_schedule(&precvpriv->recv_tasklet);
|
||||
}
|
||||
|
||||
int _rtw_init_recv_priv(struct rtl8192cd_priv *priv)
|
||||
{
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
union recv_frame *precvframe;
|
||||
int i;
|
||||
|
||||
_rtw_spinlock_init(&precvpriv->lock);
|
||||
|
||||
//init recv_frame
|
||||
_rtw_init_queue(&precvpriv->free_recv_queue);
|
||||
_rtw_init_queue(&precvpriv->recv_pending_queue);
|
||||
|
||||
precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
|
||||
|
||||
if (NULL == precvpriv->pallocated_frame_buf) {
|
||||
printk("alloc recv_frame fail!(size %d)\n", (NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
|
||||
|
||||
precvframe = (union recv_frame*) precvpriv->precv_frame_buf;
|
||||
|
||||
for (i=0; i < NR_RECVFRAME ; i++)
|
||||
{
|
||||
_rtw_init_listhead(&(precvframe->u.list));
|
||||
|
||||
rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
|
||||
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
|
||||
precvframe++;
|
||||
}
|
||||
|
||||
precvpriv->free_recv_queue.qlen = NR_RECVFRAME;
|
||||
|
||||
if (FAIL == rtl8188es_init_recv_priv(priv)) {
|
||||
rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
|
||||
|
||||
precvpriv->pallocated_frame_buf = NULL;
|
||||
precvpriv->precv_frame_buf = NULL;
|
||||
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void _rtw_free_recv_priv (struct rtl8192cd_priv *priv)
|
||||
{
|
||||
struct recv_priv *precvpriv = &priv->recvpriv;
|
||||
|
||||
_rtw_spinlock_free(&precvpriv->lock);
|
||||
|
||||
_rtw_spinlock_free(&precvpriv->free_recv_queue.lock);
|
||||
_rtw_spinlock_free(&precvpriv->recv_pending_queue.lock);
|
||||
|
||||
if (precvpriv->pallocated_frame_buf) {
|
||||
rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
|
||||
|
||||
precvpriv->pallocated_frame_buf = NULL;
|
||||
precvpriv->precv_frame_buf = NULL;
|
||||
}
|
||||
|
||||
rtl8188es_free_recv_priv(priv);
|
||||
}
|
||||
|
158
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_recv.h
Executable file
158
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_recv.h
Executable file
@ -0,0 +1,158 @@
|
||||
#ifndef _8188E_SDIO_RECV_H_
|
||||
#define _8188E_SDIO_RECV_H_
|
||||
|
||||
#define MAX_RECVBUF_MEM_SZ (65536) // 64K=4*16K > 4*10K
|
||||
#define MAX_RECVBUF_SZ (10240)
|
||||
#define NR_RECVBUFF (8)
|
||||
#define NR_PREALLOC_RECV_SKB (8)
|
||||
#define RECVBUFF_ALIGN_SZ (8)
|
||||
|
||||
#define NR_RECVFRAME 256
|
||||
#define RXFRAME_ALIGN 8
|
||||
#define RXFRAME_ALIGN_SZ (1<<RXFRAME_ALIGN)
|
||||
|
||||
#define RXDESC_SIZE 24
|
||||
#define RXDESC_OFFSET RXDESC_SIZE
|
||||
|
||||
#define RECVBUF_POISON_END 0x5a
|
||||
|
||||
|
||||
#define RECVBUF_DEBUG
|
||||
|
||||
#define TX_RPT1_PKT_LEN 8
|
||||
|
||||
typedef enum _RX_PACKET_TYPE{
|
||||
NORMAL_RX,//Normal rx packet
|
||||
TX_REPORT1,//CCX
|
||||
TX_REPORT2,//TX RPT
|
||||
HIS_REPORT,// USB HISR RPT
|
||||
}RX_PACKET_TYPE, *PRX_PACKET_TYPE;
|
||||
|
||||
struct recv_priv
|
||||
{
|
||||
spinlock_t lock;
|
||||
|
||||
u8 *pallocated_frame_buf;
|
||||
u8 *precv_frame_buf;
|
||||
_queue free_recv_queue;
|
||||
_queue recv_pending_queue;
|
||||
|
||||
struct tasklet_struct recv_tasklet;
|
||||
|
||||
u8 *recvbuf_mem;
|
||||
u8 *recvbuf_mem_head;
|
||||
u8 *recvbuf_mem_data;
|
||||
u8 *recvbuf_mem_tail;
|
||||
u8 *recvbuf_mem_end;
|
||||
|
||||
u8 *pallocated_recv_buf;
|
||||
u8 *precv_buf; // 4 alignment
|
||||
_queue free_recv_buf_queue;
|
||||
_queue recv_buf_pending_queue;
|
||||
|
||||
unsigned int nr_out_of_recvbuf;
|
||||
unsigned int nr_out_of_recvbuf_mem;
|
||||
unsigned int nr_out_of_recvframe;
|
||||
};
|
||||
|
||||
struct recv_buf
|
||||
{
|
||||
struct list_head list;
|
||||
u8 *phead;
|
||||
u8 *pdata;
|
||||
u8 *ptail;
|
||||
u8 *pend;
|
||||
};
|
||||
|
||||
struct rx_pkt_attrib
|
||||
{
|
||||
u16 pkt_len;
|
||||
u8 physt;
|
||||
u8 drvinfo_sz;
|
||||
u8 shift_sz;
|
||||
u8 hdrlen; //the WLAN Header Len
|
||||
u8 amsdu;
|
||||
u8 qos;
|
||||
u8 priority;
|
||||
u8 pw_save;
|
||||
u8 mdata;
|
||||
u16 seq_num;
|
||||
u8 frag_num;
|
||||
u8 mfrag;
|
||||
u8 order;
|
||||
u8 privacy; //in frame_ctrl field
|
||||
u8 bdecrypted;
|
||||
u8 encrypt; //when 0 indicate no encrypt. when non-zero, indicate the encrypt algorith
|
||||
u8 iv_len;
|
||||
u8 icv_len;
|
||||
u8 crc_err;
|
||||
u8 icv_err;
|
||||
|
||||
#ifdef CONFIG_RTL_88E_SUPPORT
|
||||
u8 pkt_rpt_type;
|
||||
u32 MacIDValidEntry[2];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct recv_frame_hdr
|
||||
{
|
||||
struct list_head list;
|
||||
|
||||
struct sk_buff *pkt;
|
||||
|
||||
struct rx_pkt_attrib attrib;
|
||||
};
|
||||
|
||||
struct recv_stat
|
||||
{
|
||||
unsigned int rxdw0;
|
||||
unsigned int rxdw1;
|
||||
unsigned int rxdw2;
|
||||
unsigned int rxdw3;
|
||||
unsigned int rxdw4;
|
||||
unsigned int rxdw5;
|
||||
};
|
||||
|
||||
struct phy_stat
|
||||
{
|
||||
unsigned int phydw0;
|
||||
unsigned int phydw1;
|
||||
unsigned int phydw2;
|
||||
unsigned int phydw3;
|
||||
unsigned int phydw4;
|
||||
unsigned int phydw5;
|
||||
unsigned int phydw6;
|
||||
unsigned int phydw7;
|
||||
};
|
||||
|
||||
union recv_frame{
|
||||
union{
|
||||
struct list_head list;
|
||||
struct recv_frame_hdr hdr;
|
||||
//unsigned int mem[/*RECVFRAME_HDR_ALIGN*/128>>2];
|
||||
}u;
|
||||
|
||||
//uint mem[MAX_RXSZ>>2];
|
||||
};
|
||||
|
||||
__inline static s32 translate_percentage_to_dbm(u32 SignalStrengthIndex)
|
||||
{
|
||||
s32 SignalPower; // in dBm.
|
||||
|
||||
// Translate to dBm (x=0.5y-95).
|
||||
SignalPower = (s32)((SignalStrengthIndex + 1) >> 1);
|
||||
SignalPower -= 95;
|
||||
|
||||
return SignalPower;
|
||||
}
|
||||
|
||||
|
||||
void rtl8188es_recv_tasklet(void *priv);
|
||||
int _rtw_init_recv_priv(struct rtl8192cd_priv *priv);
|
||||
void _rtw_free_recv_priv (struct rtl8192cd_priv *priv);
|
||||
void rtw_flush_recvbuf_pending_queue(struct rtl8192cd_priv *priv);
|
||||
|
||||
struct recv_buf* sd_recv_rxfifo(struct rtl8192cd_priv *priv, u32 size);
|
||||
void sd_rxhandler(struct rtl8192cd_priv *priv, struct recv_buf *precvbuf);
|
||||
|
||||
#endif
|
3946
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_xmit.c
Executable file
3946
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_xmit.c
Executable file
File diff suppressed because it is too large
Load Diff
205
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_xmit.h
Executable file
205
wlan/8192es/DriverSrcPkg/Driver/rtl8192cd_92es/sdio/8189es/8188e_sdio_xmit.h
Executable file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Header files defines some SDIO TX inline routines
|
||||
*
|
||||
* $Id: 8188e_sdio_xmit.h,v 1.4.4.5 2010/12/10 06:11:55 family Exp $
|
||||
*
|
||||
* Copyright (c) 2009 Realtek Semiconductor Corp.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef _8188E_SDIO_XMIT_H_
|
||||
#define _8188E_SDIO_XMIT_H_
|
||||
|
||||
#include "./8188e_sdio.h"
|
||||
|
||||
#define NR_XMITFRAME (512)
|
||||
// stop netdev tx queue if the remaining amount of xmitframe is equal to threshold when allocating xmitframe
|
||||
#define STOP_NETIF_TX_QUEUE_THRESH 40
|
||||
// restart netdev tx queue if the available amount of xmitframe is equal to threshold when recycling xmitframe
|
||||
#define WAKE_NETIF_TX_QUEUE_THRESH 80
|
||||
#define MAX_TX_AGG_PKT_NUM (16)
|
||||
|
||||
#ifdef CONFIG_SDIO_TX_AGGREGATION
|
||||
#define MAX_XMITBUF_PKT 5
|
||||
#define MAX_XMITBUF_SZ (1536*MAX_XMITBUF_PKT) // 7.5k 1536*5
|
||||
#else
|
||||
#define MAX_XMITBUF_SZ (2048)
|
||||
#endif
|
||||
#define NR_XMITBUFF (16)
|
||||
|
||||
#define MAX_XMIT_EXTBUF_SZ (1536)
|
||||
#define NR_XMIT_EXTBUFF (32)
|
||||
|
||||
#define NR_URG_XMITBUFF (16)
|
||||
|
||||
#ifdef SDIO_AP_OFFLOAD
|
||||
#define MAX_BCN_XMITBUF_SZ ((RTL8192CD_NUM_VWLAN+1)*1024)
|
||||
#else
|
||||
#define MAX_BCN_XMITBUF_SZ (2048)
|
||||
#endif
|
||||
|
||||
#define NR_BCN_XMITBUFF (2)
|
||||
|
||||
#define XMITBUF_ALIGN_SZ (512)
|
||||
|
||||
#define TXDESC_SIZE (32)
|
||||
|
||||
#define PACKET_OFFSET_SZ (8)
|
||||
|
||||
#define DEFAULT_TXPKT_OFFSET (0)
|
||||
|
||||
#define TXAGG_DESC_ALIGN_SZ (8)
|
||||
|
||||
#define HIQ_NOLIMIT_CHECK_INTERVAL RTL_MILISECONDS_TO_JIFFIES(10)
|
||||
|
||||
#define STA_TS_LIMIT (16*1024) // 16*1024 us == 16 ms
|
||||
|
||||
#define MAX_TCP_ACK_AGG 10
|
||||
#define TCP_ACK_TIMEOUT msecs_to_jiffies(10)
|
||||
|
||||
//#define TXDMA_ERROR_DEBUG
|
||||
//#define TXDMA_ERROR_PAGE_DEBUG
|
||||
//#define TXDMA_ERROR_LLT_DEBUG
|
||||
|
||||
#ifndef CONFIG_SDIO_TX_INTERRUPT
|
||||
#undef TXDMA_ERROR_PAGE_DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IRQ_LEVEL_XMIT_LOCK
|
||||
#define xmit_preempt_disable(flags) local_irq_save(flags)
|
||||
#define xmit_preempt_enable(flags) local_irq_restore(flags)
|
||||
#define xmit_lock(lock, irql) _enter_critical(lock, irql)
|
||||
#define xmit_unlock(lock, irql) _exit_critical(lock, irql)
|
||||
#else
|
||||
#define xmit_preempt_disable(flags) do { local_bh_disable(); (void)(flags); } while (0)
|
||||
#define xmit_preempt_enable(flags) do { local_bh_enable(); (void)(flags); } while (0)
|
||||
#define xmit_lock(lock, irql) _enter_critical_bh(lock, irql)
|
||||
#define xmit_unlock(lock, irql) _exit_critical_bh(lock, irql)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TXPATH_HARD_START_XMIT = 0,
|
||||
TXPATH_SLOW_PATH,
|
||||
TXPATH_FIRETX
|
||||
};
|
||||
|
||||
enum {
|
||||
SDIO_TX_THREAD = 0,
|
||||
SDIO_TX_ISR,
|
||||
SDIO_RX_ISR,
|
||||
};
|
||||
|
||||
enum XMIT_BUF_FLAGS {
|
||||
XMIT_BUF_FLAG_REUSE = BIT0,
|
||||
};
|
||||
|
||||
enum XMIT_THREAD_STATE {
|
||||
XMIT_THREAD_STATE_RUNNING = BIT0,
|
||||
};
|
||||
|
||||
struct tx_desc {
|
||||
unsigned int Dword0;
|
||||
unsigned int Dword1;
|
||||
unsigned int Dword2;
|
||||
unsigned int Dword3;
|
||||
unsigned int Dword4;
|
||||
unsigned int Dword5;
|
||||
unsigned int Dword6;
|
||||
unsigned int Dword7;
|
||||
};
|
||||
|
||||
struct xmit_buf {
|
||||
_list list;
|
||||
_list tx_xmitbuf_list;
|
||||
|
||||
u16 ext_tag; // 0: Normal xmitbuf, 1: extension xmitbuf.
|
||||
|
||||
u8 *pallocated_buf;
|
||||
u8 *pkt_head;
|
||||
u8 *pkt_data;
|
||||
u8 *pkt_tail;
|
||||
u8 *pkt_end;
|
||||
|
||||
u32 len;
|
||||
u32 flags;
|
||||
s32 status;
|
||||
|
||||
u8 q_num;
|
||||
u8 tx_page_idx;
|
||||
u8 pg_num;
|
||||
u8 agg_num;
|
||||
void *agg_start_with;
|
||||
|
||||
struct tx_desc_info txdesc_info[MAX_TX_AGG_PKT_NUM];
|
||||
|
||||
u8 pkt_offset; // indicate the num of 8-byte dummy data between TX descriptor and TX packet
|
||||
u8 use_hw_queue; // indicate whether got the ownership to use HW queue
|
||||
};
|
||||
|
||||
struct xmit_frame {
|
||||
_list list;
|
||||
|
||||
struct tx_insn txinsn;
|
||||
struct rtl8192cd_priv *priv;
|
||||
};
|
||||
|
||||
|
||||
int _rtw_init_xmit_priv(struct rtl8192cd_priv *priv);
|
||||
void _rtw_free_xmit_priv(struct rtl8192cd_priv *priv);
|
||||
|
||||
struct xmit_buf *rtw_alloc_xmitbuf(struct rtl8192cd_priv *priv, u8 q_num);
|
||||
s32 rtw_free_xmitbuf(struct rtl8192cd_priv *priv, struct xmit_buf *pxmitbuf);
|
||||
|
||||
struct xmit_buf *rtw_alloc_xmitbuf_ext(struct rtl8192cd_priv *priv, u8 q_num);
|
||||
s32 rtw_free_xmitbuf_ext(struct rtl8192cd_priv *priv, struct xmit_buf *pxmitbuf);
|
||||
|
||||
struct xmit_buf *rtw_alloc_urg_xmitbuf(struct rtl8192cd_priv *priv, u8 q_num);
|
||||
s32 rtw_free_urg_xmitbuf(struct rtl8192cd_priv *priv, struct xmit_buf *pxmitbuf);
|
||||
int rtw_enqueue_urg_xmitframe(struct rtl8192cd_priv *priv, struct xmit_frame *pxmitframe, int insert_tail);
|
||||
|
||||
struct xmit_buf *rtw_alloc_beacon_xmitbuf(struct rtl8192cd_priv *priv);
|
||||
s32 rtw_free_beacon_xmitbuf(struct rtl8192cd_priv *priv, struct xmit_buf *pxmitbuf);
|
||||
|
||||
struct xmit_frame *rtw_alloc_xmitframe(struct rtl8192cd_priv *priv);
|
||||
s32 rtw_free_xmitframe(struct rtl8192cd_priv *priv, struct xmit_frame *pxmitframe);
|
||||
void rtw_free_xmitframe_queue(struct rtl8192cd_priv *priv, _queue *pframequeue);
|
||||
|
||||
#ifdef CONFIG_TCP_ACK_TXAGG
|
||||
int rtw_xmit_enqueue_tcpack(struct rtl8192cd_priv *priv, struct tx_insn *txcfg);
|
||||
void rtw_tcpack_servq_flush(struct rtl8192cd_priv *priv, struct tcpack_servq *tcpackq);
|
||||
#endif
|
||||
|
||||
int rtw_send_xmitframe(struct xmit_frame *pxmitframe);
|
||||
|
||||
void rtw_txservq_flush(struct rtl8192cd_priv *priv, struct tx_servq *ptxservq);
|
||||
|
||||
void rtw_pspoll_sta_enqueue(struct rtl8192cd_priv *priv, struct stat_info *pstat, int insert_tail);
|
||||
void rtw_pspoll_sta_delete(struct rtl8192cd_priv *priv, struct stat_info *pstat);
|
||||
int rtw_enqueue_xmitframe(struct rtl8192cd_priv *priv, struct xmit_frame *pxmitframe, int insert_tail);
|
||||
struct xmit_frame* rtw_txservq_dequeue(struct rtl8192cd_priv *priv, struct tx_servq *ptxservq);
|
||||
struct xmit_frame* rtw_dequeue_xmitframe(struct rtl8192cd_priv *priv, int q_num);
|
||||
|
||||
void rtw_xmitbuf_aggregate(struct rtl8192cd_priv *priv, struct xmit_buf *pxmitbuf, struct stat_info *pstat, int q_num);
|
||||
|
||||
int rtl8192cd_usb_tx_recycle(struct rtl8192cd_priv *priv, struct tx_desc_info* pdescinfo);
|
||||
void rtl8192cd_usb_cal_txdesc_chksum(struct tx_desc *ptxdesc);
|
||||
|
||||
void need_sched_xmit_for_enqueue(struct rtl8192cd_priv *priv, int q_num);
|
||||
void need_sched_xmit_for_dequeue(struct rtl8192cd_priv *priv, int q_num);
|
||||
#ifdef CONFIG_SDIO_TX_AGGREGATION
|
||||
struct xmit_buf* get_usable_pending_xmitbuf(struct rtl8192cd_priv *priv, struct tx_insn* txcfg);
|
||||
#endif
|
||||
void enqueue_pending_xmitbuf(struct rtl8192cd_priv *priv, struct xmit_buf *pxmitbuf);
|
||||
#ifdef CONFIG_SDIO_TX_INTERRUPT
|
||||
s32 rtl8188es_dequeue_writeport(struct rtl8192cd_priv *priv, int from);
|
||||
#endif
|
||||
void rtw_flush_xmit_pending_queue(struct rtl8192cd_priv *priv);
|
||||
u32 sdio_submit_xmitbuf(struct rtl8192cd_priv *priv, struct xmit_buf *pxmitbuf);
|
||||
|
||||
int rtw_xmit_thread(void *context);
|
||||
|
||||
#endif // _8188E_SDIO_XMIT_H_
|
||||
|
Reference in New Issue
Block a user