mirror of
https://github.com/lwfinger/rtl8188eu.git
synced 2025-05-08 14:33:05 +00:00
rtl8188EUS: Initial addition of files in branch v5.2.2.4
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
This commit is contained in:
parent
77471b4361
commit
6fa9ed423c
541 changed files with 393757 additions and 85553 deletions
File diff suppressed because it is too large
Load diff
9936
os_dep/ioctl_linux.c
9936
os_dep/ioctl_linux.c
File diff suppressed because it is too large
Load diff
346
os_dep/linux/custom_gpio_linux.c
Normal file
346
os_dep/linux/custom_gpio_linux.c
Normal file
|
@ -0,0 +1,346 @@
|
|||
/******************************************************************************
|
||||
* Customer code to add GPIO control during WLAN start/stop
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "drv_types.h"
|
||||
|
||||
#ifdef CONFIG_PLATFORM_SPRD
|
||||
|
||||
/* gspi func & GPIO define */
|
||||
#include <mach/gpio.h>/* 0915 */
|
||||
#include <mach/board.h>
|
||||
|
||||
#if !(defined ANDROID_2X)
|
||||
|
||||
#ifdef CONFIG_RTL8188E
|
||||
#include <mach/regulator.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#endif /* CONFIG_RTL8188E */
|
||||
|
||||
#ifndef GPIO_WIFI_POWER
|
||||
#define GPIO_WIFI_POWER -1
|
||||
#endif /* !GPIO_WIFI_POWER */
|
||||
|
||||
#ifndef GPIO_WIFI_RESET
|
||||
#define GPIO_WIFI_RESET -1
|
||||
#endif /* !GPIO_WIFI_RESET */
|
||||
|
||||
#ifndef GPIO_WIFI_PWDN
|
||||
#define GPIO_WIFI_PWDN -1
|
||||
#endif /* !GPIO_WIFI_RESET */
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
extern unsigned int oob_irq;
|
||||
#endif /* CONFIG_GSPI_HCI */
|
||||
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
extern int rtw_mp_mode;
|
||||
#else /* !CONFIG_SDIO_HCI */
|
||||
#endif /* !CONFIG_SDIO_HCI */
|
||||
|
||||
int rtw_wifi_gpio_init(void)
|
||||
{
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
if (GPIO_WIFI_IRQ > 0) {
|
||||
gpio_request(GPIO_WIFI_IRQ, "oob_irq");
|
||||
gpio_direction_input(GPIO_WIFI_IRQ);
|
||||
|
||||
oob_irq = gpio_to_irq(GPIO_WIFI_IRQ);
|
||||
|
||||
RTW_INFO("%s oob_irq:%d\n", __func__, oob_irq);
|
||||
}
|
||||
#endif
|
||||
if (GPIO_WIFI_RESET > 0)
|
||||
gpio_request(GPIO_WIFI_RESET , "wifi_rst");
|
||||
if (GPIO_WIFI_POWER > 0)
|
||||
gpio_request(GPIO_WIFI_POWER, "wifi_power");
|
||||
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
#if (defined(CONFIG_RTL8723B)) && (MP_DRIVER == 1)
|
||||
if (rtw_mp_mode == 1) {
|
||||
RTW_INFO("%s GPIO_BT_RESET pin special for mp_test\n", __func__);
|
||||
if (GPIO_BT_RESET > 0)
|
||||
gpio_request(GPIO_BT_RESET , "bt_rst");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw_wifi_gpio_deinit(void)
|
||||
{
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
if (GPIO_WIFI_IRQ > 0)
|
||||
gpio_free(GPIO_WIFI_IRQ);
|
||||
#endif
|
||||
if (GPIO_WIFI_RESET > 0)
|
||||
gpio_free(GPIO_WIFI_RESET);
|
||||
if (GPIO_WIFI_POWER > 0)
|
||||
gpio_free(GPIO_WIFI_POWER);
|
||||
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
#if (defined(CONFIG_RTL8723B)) && (MP_DRIVER == 1)
|
||||
if (rtw_mp_mode == 1) {
|
||||
RTW_INFO("%s GPIO_BT_RESET pin special for mp_test\n", __func__);
|
||||
if (GPIO_BT_RESET > 0)
|
||||
gpio_free(GPIO_BT_RESET);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Customer function to control hw specific wlan gpios */
|
||||
void rtw_wifi_gpio_wlan_ctrl(int onoff)
|
||||
{
|
||||
switch (onoff) {
|
||||
case WLAN_PWDN_OFF:
|
||||
RTW_INFO("%s: call customer specific GPIO(%d) to set wifi power down pin to 0\n",
|
||||
__FUNCTION__, GPIO_WIFI_RESET);
|
||||
|
||||
#ifndef CONFIG_DONT_BUS_SCAN
|
||||
if (GPIO_WIFI_RESET > 0)
|
||||
gpio_direction_output(GPIO_WIFI_RESET , 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WLAN_PWDN_ON:
|
||||
RTW_INFO("%s: callc customer specific GPIO(%d) to set wifi power down pin to 1\n",
|
||||
__FUNCTION__, GPIO_WIFI_RESET);
|
||||
|
||||
if (GPIO_WIFI_RESET > 0)
|
||||
gpio_direction_output(GPIO_WIFI_RESET , 1);
|
||||
break;
|
||||
|
||||
case WLAN_POWER_OFF:
|
||||
break;
|
||||
|
||||
case WLAN_POWER_ON:
|
||||
break;
|
||||
#ifdef CONFIG_SDIO_HCI
|
||||
#if (defined(CONFIG_RTL8723B)) && (MP_DRIVER == 1)
|
||||
case WLAN_BT_PWDN_OFF:
|
||||
if (rtw_mp_mode == 1) {
|
||||
RTW_INFO("%s: call customer specific GPIO to set wifi power down pin to 0\n",
|
||||
__FUNCTION__);
|
||||
if (GPIO_BT_RESET > 0)
|
||||
gpio_direction_output(GPIO_BT_RESET , 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WLAN_BT_PWDN_ON:
|
||||
if (rtw_mp_mode == 1) {
|
||||
RTW_INFO("%s: callc customer specific GPIO to set wifi power down pin to 1 %x\n",
|
||||
__FUNCTION__, GPIO_BT_RESET);
|
||||
|
||||
if (GPIO_BT_RESET > 0)
|
||||
gpio_direction_output(GPIO_BT_RESET , 1);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#else /* ANDROID_2X */
|
||||
|
||||
#include <mach/ldo.h>
|
||||
|
||||
#ifdef CONFIG_RTL8188E
|
||||
extern int sprd_3rdparty_gpio_wifi_power;
|
||||
#endif
|
||||
extern int sprd_3rdparty_gpio_wifi_pwd;
|
||||
#if defined(CONFIG_RTL8723B)
|
||||
extern int sprd_3rdparty_gpio_bt_reset;
|
||||
#endif
|
||||
|
||||
int rtw_wifi_gpio_init(void)
|
||||
{
|
||||
#if defined(CONFIG_RTL8723B)
|
||||
if (sprd_3rdparty_gpio_bt_reset > 0)
|
||||
gpio_direction_output(sprd_3rdparty_gpio_bt_reset, 1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw_wifi_gpio_deinit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Customer function to control hw specific wlan gpios */
|
||||
void rtw_wifi_gpio_wlan_ctrl(int onoff)
|
||||
{
|
||||
switch (onoff) {
|
||||
case WLAN_PWDN_OFF:
|
||||
RTW_INFO("%s: call customer specific GPIO to set wifi power down pin to 0\n",
|
||||
__FUNCTION__);
|
||||
if (sprd_3rdparty_gpio_wifi_pwd > 0)
|
||||
gpio_set_value(sprd_3rdparty_gpio_wifi_pwd, 0);
|
||||
|
||||
if (sprd_3rdparty_gpio_wifi_pwd == 60) {
|
||||
RTW_INFO("%s: turn off VSIM2 2.8V\n", __func__);
|
||||
LDO_TurnOffLDO(LDO_LDO_SIM2);
|
||||
}
|
||||
break;
|
||||
|
||||
case WLAN_PWDN_ON:
|
||||
RTW_INFO("%s: callc customer specific GPIO to set wifi power down pin to 1\n",
|
||||
__FUNCTION__);
|
||||
if (sprd_3rdparty_gpio_wifi_pwd == 60) {
|
||||
RTW_INFO("%s: turn on VSIM2 2.8V\n", __func__);
|
||||
LDO_SetVoltLevel(LDO_LDO_SIM2, LDO_VOLT_LEVEL0);
|
||||
LDO_TurnOnLDO(LDO_LDO_SIM2);
|
||||
}
|
||||
if (sprd_3rdparty_gpio_wifi_pwd > 0)
|
||||
gpio_set_value(sprd_3rdparty_gpio_wifi_pwd, 1);
|
||||
break;
|
||||
|
||||
case WLAN_POWER_OFF:
|
||||
#ifdef CONFIG_RTL8188E
|
||||
#ifdef CONFIG_WIF1_LDO
|
||||
RTW_INFO("%s: turn off VDD-WIFI0 1.2V\n", __FUNCTION__);
|
||||
LDO_TurnOffLDO(LDO_LDO_WIF1);
|
||||
#endif /* CONFIG_WIF1_LDO */
|
||||
|
||||
RTW_INFO("%s: turn off VDD-WIFI0 3.3V\n", __FUNCTION__);
|
||||
LDO_TurnOffLDO(LDO_LDO_WIF0);
|
||||
|
||||
RTW_INFO("%s: call customer specific GPIO(%d) to turn off wifi power\n",
|
||||
__FUNCTION__, sprd_3rdparty_gpio_wifi_power);
|
||||
if (sprd_3rdparty_gpio_wifi_power != 65535)
|
||||
gpio_set_value(sprd_3rdparty_gpio_wifi_power, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WLAN_POWER_ON:
|
||||
#ifdef CONFIG_RTL8188E
|
||||
RTW_INFO("%s: call customer specific GPIO(%d) to turn on wifi power\n",
|
||||
__FUNCTION__, sprd_3rdparty_gpio_wifi_power);
|
||||
if (sprd_3rdparty_gpio_wifi_power != 65535)
|
||||
gpio_set_value(sprd_3rdparty_gpio_wifi_power, 1);
|
||||
|
||||
RTW_INFO("%s: turn on VDD-WIFI0 3.3V\n", __FUNCTION__);
|
||||
LDO_TurnOnLDO(LDO_LDO_WIF0);
|
||||
LDO_SetVoltLevel(LDO_LDO_WIF0, LDO_VOLT_LEVEL1);
|
||||
|
||||
#ifdef CONFIG_WIF1_LDO
|
||||
RTW_INFO("%s: turn on VDD-WIFI1 1.2V\n", __func__);
|
||||
LDO_TurnOnLDO(LDO_LDO_WIF1);
|
||||
LDO_SetVoltLevel(LDO_LDO_WIF1, LDO_VOLT_LEVEL3);
|
||||
#endif /* CONFIG_WIF1_LDO */
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WLAN_BT_PWDN_OFF:
|
||||
RTW_INFO("%s: call customer specific GPIO to set bt power down pin to 0\n",
|
||||
__FUNCTION__);
|
||||
#if defined(CONFIG_RTL8723B)
|
||||
if (sprd_3rdparty_gpio_bt_reset > 0)
|
||||
gpio_set_value(sprd_3rdparty_gpio_bt_reset, 0);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case WLAN_BT_PWDN_ON:
|
||||
RTW_INFO("%s: callc customer specific GPIO to set bt power down pin to 1\n",
|
||||
__FUNCTION__);
|
||||
#if defined(CONFIG_RTL8723B)
|
||||
if (sprd_3rdparty_gpio_bt_reset > 0)
|
||||
gpio_set_value(sprd_3rdparty_gpio_bt_reset, 1);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ANDROID_2X */
|
||||
|
||||
#elif defined(CONFIG_PLATFORM_ARM_RK3066)
|
||||
#include <mach/iomux.h>
|
||||
|
||||
#define GPIO_WIFI_IRQ RK30_PIN2_PC2
|
||||
extern unsigned int oob_irq;
|
||||
int rtw_wifi_gpio_init(void)
|
||||
{
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
if (GPIO_WIFI_IRQ > 0) {
|
||||
rk30_mux_api_set(GPIO2C2_LCDC1DATA18_SMCBLSN1_HSADCDATA5_NAME, GPIO2C_GPIO2C2);/* jacky_test */
|
||||
gpio_request(GPIO_WIFI_IRQ, "oob_irq");
|
||||
gpio_direction_input(GPIO_WIFI_IRQ);
|
||||
|
||||
oob_irq = gpio_to_irq(GPIO_WIFI_IRQ);
|
||||
|
||||
RTW_INFO("%s oob_irq:%d\n", __func__, oob_irq);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int rtw_wifi_gpio_deinit(void)
|
||||
{
|
||||
#ifdef CONFIG_GSPI_HCI
|
||||
if (GPIO_WIFI_IRQ > 0)
|
||||
gpio_free(GPIO_WIFI_IRQ);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtw_wifi_gpio_wlan_ctrl(int onoff)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GPIO_API
|
||||
/* this is a demo for extending GPIO pin[7] as interrupt mode */
|
||||
struct net_device *rtl_net;
|
||||
extern int rtw_register_gpio_interrupt(struct net_device *netdev, int gpio_num, void(*callback)(u8 level));
|
||||
extern int rtw_disable_gpio_interrupt(struct net_device *netdev, int gpio_num);
|
||||
void gpio_int(u8 is_high)
|
||||
{
|
||||
RTW_INFO("%s level=%d\n", __func__, is_high);
|
||||
}
|
||||
int register_net_gpio_init(void)
|
||||
{
|
||||
rtl_net = dev_get_by_name(&init_net, "wlan0");
|
||||
if (!rtl_net) {
|
||||
RTW_PRINT("rtl_net init fail!\n");
|
||||
return -1;
|
||||
}
|
||||
return rtw_register_gpio_interrupt(rtl_net, 7, gpio_int);
|
||||
}
|
||||
int unregister_net_gpio_init(void)
|
||||
{
|
||||
rtl_net = dev_get_by_name(&init_net, "wlan0");
|
||||
if (!rtl_net) {
|
||||
RTW_PRINT("rtl_net init fail!\n");
|
||||
return -1;
|
||||
}
|
||||
return rtw_disable_gpio_interrupt(rtl_net, 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
int rtw_wifi_gpio_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rtw_wifi_gpio_wlan_ctrl(int onoff)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_PLATFORM_SPRD */
|
7280
os_dep/linux/ioctl_cfg80211.c
Normal file
7280
os_dep/linux/ioctl_cfg80211.c
Normal file
File diff suppressed because it is too large
Load diff
323
os_dep/linux/ioctl_cfg80211.h
Normal file
323
os_dep/linux/ioctl_cfg80211.h
Normal file
|
@ -0,0 +1,323 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __IOCTL_CFG80211_H__
|
||||
#define __IOCTL_CFG80211_H__
|
||||
|
||||
|
||||
#if defined(RTW_USE_CFG80211_STA_EVENT)
|
||||
#undef CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER
|
||||
#endif
|
||||
|
||||
#ifndef RTW_P2P_GROUP_INTERFACE
|
||||
#define RTW_P2P_GROUP_INTERFACE 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* (RTW_P2P_GROUP_INTERFACE, RTW_DEDICATED_P2P_DEVICE)
|
||||
* (0, 0): wlan0 + p2p0(PD+PG)
|
||||
* (1, 0): wlan0(with PD) + dynamic PGs
|
||||
* (1, 1): wlan0 (with dynamic PD wdev) + dynamic PGs
|
||||
*/
|
||||
|
||||
#if RTW_P2P_GROUP_INTERFACE
|
||||
#ifndef CONFIG_RTW_DYNAMIC_NDEV
|
||||
#define CONFIG_RTW_DYNAMIC_NDEV
|
||||
#endif
|
||||
#ifndef RTW_SINGLE_WIPHY
|
||||
#define RTW_SINGLE_WIPHY
|
||||
#endif
|
||||
#ifndef CONFIG_RADIO_WORK
|
||||
#define CONFIG_RADIO_WORK
|
||||
#endif
|
||||
#ifndef RTW_DEDICATED_P2P_DEVICE
|
||||
#define RTW_DEDICATED_P2P_DEVICE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_P2P) && RTW_P2P_GROUP_INTERFACE
|
||||
#error "RTW_P2P_GROUP_INTERFACE can't be enabled when CONFIG_P2P is disabled\n"
|
||||
#endif
|
||||
|
||||
#if !RTW_P2P_GROUP_INTERFACE && defined(RTW_DEDICATED_P2P_DEVICE)
|
||||
#error "RTW_DEDICATED_P2P_DEVICE can't be enabled when RTW_P2P_GROUP_INTERFACE is disabled\n"
|
||||
#endif
|
||||
|
||||
#if defined(RTW_DEDICATED_P2P_DEVICE) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
|
||||
#error "RTW_DEDICATED_P2P_DEVICE can't be enabled when kernel < 3.7.0\n"
|
||||
#endif
|
||||
|
||||
struct rtw_wdev_invit_info {
|
||||
u8 state; /* 0: req, 1:rep */
|
||||
u8 peer_mac[ETH_ALEN];
|
||||
u8 group_bssid[ETH_ALEN];
|
||||
u8 active;
|
||||
u8 token;
|
||||
u8 flags;
|
||||
u8 status;
|
||||
u8 req_op_ch;
|
||||
u8 rsp_op_ch;
|
||||
};
|
||||
|
||||
#define rtw_wdev_invit_info_init(invit_info) \
|
||||
do { \
|
||||
(invit_info)->state = 0xff; \
|
||||
_rtw_memset((invit_info)->peer_mac, 0, ETH_ALEN); \
|
||||
_rtw_memset((invit_info)->group_bssid, 0, ETH_ALEN); \
|
||||
(invit_info)->active = 0xff; \
|
||||
(invit_info)->token = 0; \
|
||||
(invit_info)->flags = 0x00; \
|
||||
(invit_info)->status = 0xff; \
|
||||
(invit_info)->req_op_ch = 0; \
|
||||
(invit_info)->rsp_op_ch = 0; \
|
||||
} while (0)
|
||||
|
||||
struct rtw_wdev_nego_info {
|
||||
u8 state; /* 0: req, 1:rep, 2:conf */
|
||||
u8 iface_addr[ETH_ALEN];
|
||||
u8 peer_mac[ETH_ALEN];
|
||||
u8 peer_iface_addr[ETH_ALEN];
|
||||
u8 active;
|
||||
u8 token;
|
||||
u8 status;
|
||||
u8 req_intent;
|
||||
u8 req_op_ch;
|
||||
u8 req_listen_ch;
|
||||
u8 rsp_intent;
|
||||
u8 rsp_op_ch;
|
||||
u8 conf_op_ch;
|
||||
};
|
||||
|
||||
#define rtw_wdev_nego_info_init(nego_info) \
|
||||
do { \
|
||||
(nego_info)->state = 0xff; \
|
||||
_rtw_memset((nego_info)->iface_addr, 0, ETH_ALEN); \
|
||||
_rtw_memset((nego_info)->peer_mac, 0, ETH_ALEN); \
|
||||
_rtw_memset((nego_info)->peer_iface_addr, 0, ETH_ALEN); \
|
||||
(nego_info)->active = 0xff; \
|
||||
(nego_info)->token = 0; \
|
||||
(nego_info)->status = 0xff; \
|
||||
(nego_info)->req_intent = 0xff; \
|
||||
(nego_info)->req_op_ch = 0; \
|
||||
(nego_info)->req_listen_ch = 0; \
|
||||
(nego_info)->rsp_intent = 0xff; \
|
||||
(nego_info)->rsp_op_ch = 0; \
|
||||
(nego_info)->conf_op_ch = 0; \
|
||||
} while (0)
|
||||
|
||||
struct rtw_wdev_priv {
|
||||
struct wireless_dev *rtw_wdev;
|
||||
|
||||
_adapter *padapter;
|
||||
|
||||
struct cfg80211_scan_request *scan_request;
|
||||
_lock scan_req_lock;
|
||||
|
||||
struct net_device *pmon_ndev;/* for monitor interface */
|
||||
char ifname_mon[IFNAMSIZ + 1]; /* interface name for monitor interface */
|
||||
|
||||
u8 p2p_enabled;
|
||||
u32 probe_resp_ie_update_time;
|
||||
|
||||
u8 provdisc_req_issued;
|
||||
|
||||
struct rtw_wdev_invit_info invit_info;
|
||||
struct rtw_wdev_nego_info nego_info;
|
||||
|
||||
u8 bandroid_scan;
|
||||
bool block;
|
||||
bool block_scan;
|
||||
bool power_mgmt;
|
||||
|
||||
/* report mgmt_frame registered */
|
||||
u16 report_mgmt;
|
||||
|
||||
u8 is_mgmt_tx;
|
||||
|
||||
_mutex roch_mutex;
|
||||
|
||||
#ifdef CONFIG_CONCURRENT_MODE
|
||||
ATOMIC_T switch_ch_to;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#define wdev_to_ndev(w) ((w)->netdev)
|
||||
#define wdev_to_wiphy(w) ((w)->wiphy)
|
||||
#define ndev_to_wdev(n) ((n)->ieee80211_ptr)
|
||||
|
||||
struct rtw_wiphy_data {
|
||||
struct dvobj_priv *dvobj;
|
||||
|
||||
#ifndef RTW_SINGLE_WIPHY
|
||||
_adapter *adapter;
|
||||
#endif
|
||||
|
||||
#if defined(RTW_DEDICATED_P2P_DEVICE)
|
||||
struct wireless_dev *pd_wdev; /* P2P device wdev */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define rtw_wiphy_priv(wiphy) ((struct rtw_wiphy_data *)wiphy_priv(wiphy))
|
||||
#define wiphy_to_dvobj(wiphy) (((struct rtw_wiphy_data *)wiphy_priv(wiphy))->dvobj)
|
||||
#ifdef RTW_SINGLE_WIPHY
|
||||
#define wiphy_to_adapter(wiphy) (dvobj_get_primary_adapter(wiphy_to_dvobj(wiphy)))
|
||||
#else
|
||||
#define wiphy_to_adapter(wiphy) (((struct rtw_wiphy_data *)wiphy_priv(wiphy))->adapter)
|
||||
#endif
|
||||
|
||||
#if defined(RTW_DEDICATED_P2P_DEVICE)
|
||||
#define wiphy_to_pd_wdev(wiphy) (rtw_wiphy_priv(wiphy)->pd_wdev)
|
||||
#else
|
||||
#define wiphy_to_pd_wdev(wiphy) NULL
|
||||
#endif
|
||||
|
||||
#define WIPHY_FMT "%s"
|
||||
#define WIPHY_ARG(wiphy) wiphy_name(wiphy)
|
||||
#define FUNC_WIPHY_FMT "%s("WIPHY_FMT")"
|
||||
#define FUNC_WIPHY_ARG(wiphy) __func__, WIPHY_ARG(wiphy)
|
||||
|
||||
#define SET_CFG80211_REPORT_MGMT(w, t, v) (w->report_mgmt |= (v ? BIT(t >> 4) : 0))
|
||||
#define GET_CFG80211_REPORT_MGMT(w, t) ((w->report_mgmt & BIT(t >> 4)) > 0)
|
||||
|
||||
struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev);
|
||||
void rtw_wiphy_free(struct wiphy *wiphy);
|
||||
int rtw_wiphy_register(struct wiphy *wiphy);
|
||||
void rtw_wiphy_unregister(struct wiphy *wiphy);
|
||||
|
||||
int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy);
|
||||
void rtw_wdev_free(struct wireless_dev *wdev);
|
||||
void rtw_wdev_unregister(struct wireless_dev *wdev);
|
||||
|
||||
int rtw_cfg80211_ndev_res_alloc(_adapter *adapter);
|
||||
void rtw_cfg80211_ndev_res_free(_adapter *adapter);
|
||||
int rtw_cfg80211_ndev_res_register(_adapter *adapter);
|
||||
void rtw_cfg80211_ndev_res_unregister(_adapter *adapter);
|
||||
|
||||
int rtw_cfg80211_dev_res_alloc(struct dvobj_priv *dvobj);
|
||||
void rtw_cfg80211_dev_res_free(struct dvobj_priv *dvobj);
|
||||
int rtw_cfg80211_dev_res_register(struct dvobj_priv *dvobj);
|
||||
void rtw_cfg80211_dev_res_unregister(struct dvobj_priv *dvobj);
|
||||
|
||||
void rtw_cfg80211_init_wdev_data(_adapter *padapter);
|
||||
void rtw_cfg80211_init_wiphy(_adapter *padapter);
|
||||
|
||||
void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork);
|
||||
void rtw_cfg80211_surveydone_event_callback(_adapter *padapter);
|
||||
struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork);
|
||||
int rtw_cfg80211_check_bss(_adapter *padapter);
|
||||
void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter);
|
||||
void rtw_cfg80211_indicate_connect(_adapter *padapter);
|
||||
void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated);
|
||||
void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted);
|
||||
u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms);
|
||||
|
||||
#ifdef CONFIG_CONCURRENT_MODE
|
||||
u8 rtw_cfg80211_scan_via_buddy(_adapter *padapter, struct cfg80211_scan_request *request);
|
||||
void rtw_cfg80211_indicate_scan_done_for_buddy(_adapter *padapter, bool bscan_aborted);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AP_MODE
|
||||
void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len);
|
||||
void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason);
|
||||
#endif /* CONFIG_AP_MODE */
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val);
|
||||
bool rtw_cfg80211_get_is_roch(_adapter *adapter);
|
||||
|
||||
int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter);
|
||||
int rtw_cfg80211_is_p2p_scan(_adapter *adapter);
|
||||
#if defined(RTW_DEDICATED_P2P_DEVICE)
|
||||
int rtw_cfg80211_redirect_pd_wdev(struct wiphy *wiphy, u8 *ra, struct wireless_dev **wdev);
|
||||
int rtw_cfg80211_is_scan_by_pd_wdev(_adapter *adapter);
|
||||
int rtw_pd_iface_alloc(struct wiphy *wiphy, const char *name, struct wireless_dev **pd_wdev);
|
||||
void rtw_pd_iface_free(struct wiphy *wiphy);
|
||||
#endif
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
void rtw_cfg80211_set_is_mgmt_tx(_adapter *adapter, u8 val);
|
||||
u8 rtw_cfg80211_get_is_mgmt_tx(_adapter *adapter);
|
||||
|
||||
void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len);
|
||||
|
||||
void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, union recv_frame *rframe);
|
||||
void rtw_cfg80211_rx_action_p2p(_adapter *padapter, union recv_frame *rframe);
|
||||
void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const char *msg);
|
||||
void rtw_cfg80211_rx_probe_request(_adapter *padapter, union recv_frame *rframe);
|
||||
|
||||
int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len, int type);
|
||||
|
||||
bool rtw_cfg80211_pwr_mgmt(_adapter *adapter);
|
||||
|
||||
#ifdef CONFIG_RFKILL_POLL
|
||||
void rtw_cfg80211_init_rfkill(struct wiphy *wiphy);
|
||||
void rtw_cfg80211_deinit_rfkill(struct wiphy *wiphy);
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
|
||||
#define rtw_cfg80211_rx_mgmt(wdev, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt(wdev_to_ndev(wdev), freq, buf, len, gfp)
|
||||
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
|
||||
#define rtw_cfg80211_rx_mgmt(wdev, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt(wdev_to_ndev(wdev), freq, sig_dbm, buf, len, gfp)
|
||||
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0))
|
||||
#define rtw_cfg80211_rx_mgmt(wdev, freq, sig_dbm, buf, len, gfp) cfg80211_rx_mgmt(wdev, freq, sig_dbm, buf, len, gfp)
|
||||
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3 , 18 , 0))
|
||||
#define rtw_cfg80211_rx_mgmt(wdev , freq , sig_dbm , buf , len , gfp) cfg80211_rx_mgmt(wdev , freq , sig_dbm , buf , len , 0 , gfp)
|
||||
#else
|
||||
#define rtw_cfg80211_rx_mgmt(wdev , freq , sig_dbm , buf , len , gfp) cfg80211_rx_mgmt(wdev , freq , sig_dbm , buf , len , 0)
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
|
||||
#define rtw_cfg80211_send_rx_assoc(adapter, bss, buf, len) cfg80211_send_rx_assoc((adapter)->pnetdev, buf, len)
|
||||
#else
|
||||
#define rtw_cfg80211_send_rx_assoc(adapter, bss, buf, len) cfg80211_send_rx_assoc((adapter)->pnetdev, bss, buf, len)
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
|
||||
#define rtw_cfg80211_mgmt_tx_status(wdev, cookie, buf, len, ack, gfp) cfg80211_mgmt_tx_status(wdev_to_ndev(wdev), cookie, buf, len, ack, gfp)
|
||||
#else
|
||||
#define rtw_cfg80211_mgmt_tx_status(wdev, cookie, buf, len, ack, gfp) cfg80211_mgmt_tx_status(wdev, cookie, buf, len, ack, gfp)
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
|
||||
#define rtw_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, duration, gfp) cfg80211_ready_on_channel(wdev_to_ndev(wdev), cookie, chan, channel_type, duration, gfp)
|
||||
#define rtw_cfg80211_remain_on_channel_expired(wdev, cookie, chan, chan_type, gfp) cfg80211_remain_on_channel_expired(wdev_to_ndev(wdev), cookie, chan, chan_type, gfp)
|
||||
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
|
||||
#define rtw_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, duration, gfp) cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, duration, gfp)
|
||||
#define rtw_cfg80211_remain_on_channel_expired(wdev, cookie, chan, chan_type, gfp) cfg80211_remain_on_channel_expired(wdev, cookie, chan, chan_type, gfp)
|
||||
#else
|
||||
#define rtw_cfg80211_ready_on_channel(wdev, cookie, chan, channel_type, duration, gfp) cfg80211_ready_on_channel(wdev, cookie, chan, duration, gfp)
|
||||
#define rtw_cfg80211_remain_on_channel_expired(wdev, cookie, chan, chan_type, gfp) cfg80211_remain_on_channel_expired(wdev, cookie, chan, gfp)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTW_80211R
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
|
||||
#define rtw_cfg80211_ft_event(adapter, parm) cfg80211_ft_event((adapter)->pnetdev, parm)
|
||||
#else
|
||||
#error "Cannot support FT for KERNEL_VERSION < 3.10\n"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (KERNEL_VERSION(4, 7, 0) >= LINUX_VERSION_CODE)
|
||||
#define NUM_NL80211_BANDS IEEE80211_NUM_BANDS
|
||||
#endif
|
||||
|
||||
#include "rtw_cfgvendor.h"
|
||||
|
||||
#endif /* __IOCTL_CFG80211_H__ */
|
13390
os_dep/linux/ioctl_linux.c
Normal file
13390
os_dep/linux/ioctl_linux.c
Normal file
File diff suppressed because it is too large
Load diff
2412
os_dep/linux/ioctl_mp.c
Normal file
2412
os_dep/linux/ioctl_mp.c
Normal file
File diff suppressed because it is too large
Load diff
604
os_dep/linux/mlme_linux.c
Normal file
604
os_dep/linux/mlme_linux.c
Normal file
|
@ -0,0 +1,604 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#define _MLME_OSDEP_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
void Linkup_workitem_callback(struct work_struct *work)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkup_workitem);
|
||||
_adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
|
||||
|
||||
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))
|
||||
kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKUP);
|
||||
#else
|
||||
kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKUP);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void Linkdown_workitem_callback(struct work_struct *work)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = container_of(work, struct mlme_priv, Linkdown_workitem);
|
||||
_adapter *padapter = container_of(pmlmepriv, _adapter, mlmepriv);
|
||||
|
||||
|
||||
|
||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))
|
||||
kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_LINKDOWN);
|
||||
#else
|
||||
kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_LINKDOWN);
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
void sitesurvey_ctrl_handler(void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
|
||||
_sitesurvey_ctrl_handler(adapter);
|
||||
|
||||
_set_timer(&adapter->mlmepriv.sitesurveyctrl.sitesurvey_ctrl_timer, 3000);
|
||||
}
|
||||
*/
|
||||
|
||||
void rtw_join_timeout_handler(void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
_rtw_join_timeout_handler(adapter);
|
||||
}
|
||||
|
||||
|
||||
void _rtw_scan_timeout_handler(void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
rtw_scan_timeout_handler(adapter);
|
||||
}
|
||||
|
||||
|
||||
void _dynamic_check_timer_handlder(void *FunctionContext)
|
||||
{
|
||||
struct dvobj_priv *pdvobj = (struct dvobj_priv *)FunctionContext;
|
||||
_adapter *adapter = dvobj_get_primary_adapter(pdvobj);
|
||||
|
||||
#if (MP_DRIVER == 1)
|
||||
if (adapter->registrypriv.mp_mode == 1 && adapter->mppriv.mp_dm == 0) { /* for MP ODM dynamic Tx power tracking */
|
||||
/* RTW_INFO("_dynamic_check_timer_handlder mp_dm =0 return\n"); */
|
||||
_set_timer(&pdvobj->dynamic_chk_timer, 2000);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
rtw_dynamic_check_timer_handlder(adapter);
|
||||
|
||||
_set_timer(&pdvobj->dynamic_chk_timer, 2000);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SET_SCAN_DENY_TIMER
|
||||
void _rtw_set_scan_deny_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *adapter = (_adapter *)FunctionContext;
|
||||
rtw_set_scan_deny_timer_hdl(adapter);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void rtw_init_mlme_timer(_adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
_init_timer(&(pmlmepriv->assoc_timer), padapter->pnetdev, rtw_join_timeout_handler, padapter);
|
||||
/* _init_timer(&(pmlmepriv->sitesurveyctrl.sitesurvey_ctrl_timer), padapter->pnetdev, sitesurvey_ctrl_handler, padapter); */
|
||||
_init_timer(&(pmlmepriv->scan_to_timer), padapter->pnetdev, _rtw_scan_timeout_handler, padapter);
|
||||
|
||||
#ifdef CONFIG_DFS_MASTER
|
||||
_init_timer(&(pmlmepriv->dfs_master_timer), padapter->pnetdev, rtw_dfs_master_timer_hdl, padapter);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SET_SCAN_DENY_TIMER
|
||||
_init_timer(&(pmlmepriv->set_scan_deny_timer), padapter->pnetdev, _rtw_set_scan_deny_timer_hdl, padapter);
|
||||
#endif
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
_init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter);
|
||||
_init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
extern void rtw_indicate_wx_assoc_event(_adapter *padapter);
|
||||
extern void rtw_indicate_wx_disassoc_event(_adapter *padapter);
|
||||
|
||||
void rtw_os_indicate_connect(_adapter *adapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
|
||||
(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
|
||||
rtw_cfg80211_ibss_indicate_connect(adapter);
|
||||
else
|
||||
rtw_cfg80211_indicate_connect(adapter);
|
||||
#endif /* CONFIG_IOCTL_CFG80211 */
|
||||
|
||||
rtw_indicate_wx_assoc_event(adapter);
|
||||
netif_carrier_on(adapter->pnetdev);
|
||||
|
||||
if (adapter->pid[2] != 0)
|
||||
rtw_signal_process(adapter->pid[2], SIGALRM);
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
_set_workitem(&adapter->mlmepriv.Linkup_workitem);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
extern void indicate_wx_scan_complete_event(_adapter *padapter);
|
||||
void rtw_os_indicate_scan_done(_adapter *padapter, bool aborted)
|
||||
{
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
rtw_cfg80211_indicate_scan_done(padapter, aborted);
|
||||
#endif
|
||||
indicate_wx_scan_complete_event(padapter);
|
||||
}
|
||||
|
||||
static RT_PMKID_LIST backupPMKIDList[NUM_PMKID_CACHE];
|
||||
void rtw_reset_securitypriv(_adapter *adapter)
|
||||
{
|
||||
u8 backupPMKIDIndex = 0;
|
||||
u8 backupTKIPCountermeasure = 0x00;
|
||||
u32 backupTKIPcountermeasure_time = 0;
|
||||
/* add for CONFIG_IEEE80211W, none 11w also can use */
|
||||
_irqL irqL;
|
||||
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
|
||||
|
||||
_enter_critical_bh(&adapter->security_key_mutex, &irqL);
|
||||
|
||||
if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802.1x */
|
||||
/* Added by Albert 2009/02/18 */
|
||||
/* We have to backup the PMK information for WiFi PMK Caching test item. */
|
||||
/* */
|
||||
/* Backup the btkip_countermeasure information. */
|
||||
/* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */
|
||||
|
||||
_rtw_memset(&backupPMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
|
||||
|
||||
_rtw_memcpy(&backupPMKIDList[0], &adapter->securitypriv.PMKIDList[0], sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
|
||||
backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
|
||||
backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure;
|
||||
backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
/* reset RX BIP packet number */
|
||||
pmlmeext->mgnt_80211w_IPN_rx = 0;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
_rtw_memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv));
|
||||
/* _init_timer(&(adapter->securitypriv.tkip_timer),adapter->pnetdev, rtw_use_tkipkey_handler, adapter); */
|
||||
|
||||
/* Added by Albert 2009/02/18 */
|
||||
/* Restore the PMK information to securitypriv structure for the following connection. */
|
||||
_rtw_memcpy(&adapter->securitypriv.PMKIDList[0], &backupPMKIDList[0], sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
|
||||
adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
|
||||
adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure;
|
||||
adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time;
|
||||
|
||||
adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
|
||||
adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
|
||||
|
||||
} else { /* reset values in securitypriv */
|
||||
/* if(adapter->mlmepriv.fw_state & WIFI_STATION_STATE) */
|
||||
/* { */
|
||||
struct security_priv *psec_priv = &adapter->securitypriv;
|
||||
|
||||
psec_priv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
|
||||
psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
|
||||
psec_priv->dot11PrivacyKeyIndex = 0;
|
||||
|
||||
psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_;
|
||||
psec_priv->dot118021XGrpKeyid = 1;
|
||||
|
||||
psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
|
||||
psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
|
||||
/* } */
|
||||
}
|
||||
/* add for CONFIG_IEEE80211W, none 11w also can use */
|
||||
_exit_critical_bh(&adapter->security_key_mutex, &irqL);
|
||||
|
||||
RTW_INFO(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(adapter));
|
||||
}
|
||||
|
||||
void rtw_os_indicate_disconnect(_adapter *adapter, u16 reason, u8 locally_generated)
|
||||
{
|
||||
/* RT_PMKID_LIST backupPMKIDList[NUM_PMKID_CACHE]; */
|
||||
|
||||
|
||||
netif_carrier_off(adapter->pnetdev); /* Do it first for tx broadcast pkt after disconnection issue! */
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
rtw_cfg80211_indicate_disconnect(adapter, reason, locally_generated);
|
||||
#endif /* CONFIG_IOCTL_CFG80211 */
|
||||
|
||||
rtw_indicate_wx_disassoc_event(adapter);
|
||||
|
||||
#ifdef RTK_DMP_PLATFORM
|
||||
_set_workitem(&adapter->mlmepriv.Linkdown_workitem);
|
||||
#endif
|
||||
/* modify for CONFIG_IEEE80211W, none 11w also can use the same command */
|
||||
rtw_reset_securitypriv_cmd(adapter);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void rtw_report_sec_ie(_adapter *adapter, u8 authmode, u8 *sec_ie)
|
||||
{
|
||||
uint len;
|
||||
u8 *buff, *p, i;
|
||||
union iwreq_data wrqu;
|
||||
|
||||
|
||||
|
||||
buff = NULL;
|
||||
if (authmode == _WPA_IE_ID_) {
|
||||
|
||||
buff = rtw_zmalloc(IW_CUSTOM_MAX);
|
||||
if (NULL == buff) {
|
||||
RTW_INFO(FUNC_ADPT_FMT ": alloc memory FAIL!!\n",
|
||||
FUNC_ADPT_ARG(adapter));
|
||||
return;
|
||||
}
|
||||
p = buff;
|
||||
|
||||
p += sprintf(p, "ASSOCINFO(ReqIEs=");
|
||||
|
||||
len = sec_ie[1] + 2;
|
||||
len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
p += sprintf(p, "%02x", sec_ie[i]);
|
||||
|
||||
p += sprintf(p, ")");
|
||||
|
||||
_rtw_memset(&wrqu, 0, sizeof(wrqu));
|
||||
|
||||
wrqu.data.length = p - buff;
|
||||
|
||||
wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length : IW_CUSTOM_MAX;
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event(adapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
|
||||
#endif
|
||||
|
||||
rtw_mfree(buff, IW_CUSTOM_MAX);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void _survey_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
|
||||
survey_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
void _link_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
link_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RTW_80211R
|
||||
void _ft_link_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
|
||||
ft_link_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
void _ft_roam_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
|
||||
ft_roam_timer_hdl(padapter);
|
||||
}
|
||||
#endif
|
||||
|
||||
void _addba_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
struct sta_info *psta = (struct sta_info *)FunctionContext;
|
||||
addba_timer_hdl(psta);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
|
||||
void _sa_query_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
struct sta_info *psta = (struct sta_info *)FunctionContext;
|
||||
|
||||
sa_query_timer_hdl(psta);
|
||||
}
|
||||
|
||||
void init_dot11w_expire_timer(_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
_init_timer(&psta->dot11w_expire_timer, padapter->pnetdev, _sa_query_timer_hdl, psta);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
void init_addba_retry_timer(_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
|
||||
_init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta);
|
||||
}
|
||||
|
||||
/*
|
||||
void _reauth_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
reauth_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
void _reassoc_timer_hdl(void *FunctionContext)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)FunctionContext;
|
||||
reassoc_timer_hdl(padapter);
|
||||
}
|
||||
*/
|
||||
|
||||
void init_mlme_ext_timer(_adapter *padapter)
|
||||
{
|
||||
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
|
||||
|
||||
_init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter);
|
||||
_init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter);
|
||||
#ifdef CONFIG_RTW_80211R
|
||||
_init_timer(&pmlmeext->ft_link_timer, padapter->pnetdev, _ft_link_timer_hdl, padapter);
|
||||
_init_timer(&pmlmeext->ft_roam_timer, padapter->pnetdev, _ft_roam_timer_hdl, padapter);
|
||||
#endif
|
||||
|
||||
/* _init_timer(&pmlmeext->ADDBA_timer, padapter->pnetdev, _addba_timer_hdl, padapter); */
|
||||
|
||||
/* _init_timer(&pmlmeext->reauth_timer, padapter->pnetdev, _reauth_timer_hdl, padapter); */
|
||||
/* _init_timer(&pmlmeext->reassoc_timer, padapter->pnetdev, _reassoc_timer_hdl, padapter); */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AP_MODE
|
||||
|
||||
void rtw_indicate_sta_assoc_event(_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
union iwreq_data wrqu;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
|
||||
if (psta == NULL)
|
||||
return;
|
||||
|
||||
if (psta->aid > NUM_STA)
|
||||
return;
|
||||
|
||||
if (pstapriv->sta_aid[psta->aid - 1] != psta)
|
||||
return;
|
||||
|
||||
|
||||
wrqu.addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
_rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
|
||||
|
||||
RTW_INFO("+rtw_indicate_sta_assoc_event\n");
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event(padapter->pnetdev, IWEVREGISTERED, &wrqu, NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void rtw_indicate_sta_disassoc_event(_adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
union iwreq_data wrqu;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
|
||||
if (psta == NULL)
|
||||
return;
|
||||
|
||||
if (psta->aid > NUM_STA)
|
||||
return;
|
||||
|
||||
if (pstapriv->sta_aid[psta->aid - 1] != psta)
|
||||
return;
|
||||
|
||||
|
||||
wrqu.addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
_rtw_memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
|
||||
|
||||
RTW_INFO("+rtw_indicate_sta_disassoc_event\n");
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event(padapter->pnetdev, IWEVEXPIRED, &wrqu, NULL);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_HOSTAPD_MLME
|
||||
|
||||
static int mgnt_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
_adapter *padapter = (_adapter *)phostapdpriv->padapter;
|
||||
|
||||
/* RTW_INFO("%s\n", __FUNCTION__); */
|
||||
|
||||
return rtw_hal_hostap_mgnt_xmit_entry(padapter, skb);
|
||||
}
|
||||
|
||||
static int mgnt_netdev_open(struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
|
||||
RTW_INFO("mgnt_netdev_open: MAC Address:" MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr));
|
||||
|
||||
|
||||
init_usb_anchor(&phostapdpriv->anchored);
|
||||
|
||||
rtw_netif_wake_queue(pnetdev);
|
||||
|
||||
netif_carrier_on(pnetdev);
|
||||
|
||||
/* rtw_write16(phostapdpriv->padapter, 0x0116, 0x0100); */ /* only excluding beacon */
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int mgnt_netdev_close(struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
|
||||
RTW_INFO("%s\n", __FUNCTION__);
|
||||
|
||||
usb_kill_anchored_urbs(&phostapdpriv->anchored);
|
||||
|
||||
netif_carrier_off(pnetdev);
|
||||
|
||||
rtw_netif_stop_queue(pnetdev);
|
||||
|
||||
/* rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
|
||||
static const struct net_device_ops rtl871x_mgnt_netdev_ops = {
|
||||
.ndo_open = mgnt_netdev_open,
|
||||
.ndo_stop = mgnt_netdev_close,
|
||||
.ndo_start_xmit = mgnt_xmit_entry,
|
||||
#if 0
|
||||
.ndo_set_mac_address = r871x_net_set_mac_address,
|
||||
.ndo_get_stats = r871x_net_get_stats,
|
||||
.ndo_do_ioctl = r871x_mp_ioctl,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
int hostapd_mode_init(_adapter *padapter)
|
||||
{
|
||||
unsigned char mac[ETH_ALEN];
|
||||
struct hostapd_priv *phostapdpriv;
|
||||
struct net_device *pnetdev;
|
||||
|
||||
pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv));
|
||||
if (!pnetdev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* SET_MODULE_OWNER(pnetdev); */
|
||||
ether_setup(pnetdev);
|
||||
|
||||
/* pnetdev->type = ARPHRD_IEEE80211; */
|
||||
|
||||
phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
phostapdpriv->pmgnt_netdev = pnetdev;
|
||||
phostapdpriv->padapter = padapter;
|
||||
padapter->phostapdpriv = phostapdpriv;
|
||||
|
||||
/* pnetdev->init = NULL; */
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
|
||||
|
||||
RTW_INFO("register rtl871x_mgnt_netdev_ops to netdev_ops\n");
|
||||
|
||||
pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops;
|
||||
|
||||
#else
|
||||
|
||||
pnetdev->open = mgnt_netdev_open;
|
||||
|
||||
pnetdev->stop = mgnt_netdev_close;
|
||||
|
||||
pnetdev->hard_start_xmit = mgnt_xmit_entry;
|
||||
|
||||
/* pnetdev->set_mac_address = r871x_net_set_mac_address; */
|
||||
|
||||
/* pnetdev->get_stats = r871x_net_get_stats; */
|
||||
|
||||
/* pnetdev->do_ioctl = r871x_mp_ioctl; */
|
||||
|
||||
#endif
|
||||
|
||||
pnetdev->watchdog_timeo = HZ; /* 1 second timeout */
|
||||
|
||||
/* pnetdev->wireless_handlers = NULL; */
|
||||
|
||||
#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
|
||||
pnetdev->features |= NETIF_F_IP_CSUM;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (dev_alloc_name(pnetdev, "mgnt.wlan%d") < 0)
|
||||
RTW_INFO("hostapd_mode_init(): dev_alloc_name, fail!\n");
|
||||
|
||||
|
||||
/* SET_NETDEV_DEV(pnetdev, pintfpriv->udev); */
|
||||
|
||||
|
||||
mac[0] = 0x00;
|
||||
mac[1] = 0xe0;
|
||||
mac[2] = 0x4c;
|
||||
mac[3] = 0x87;
|
||||
mac[4] = 0x11;
|
||||
mac[5] = 0x12;
|
||||
|
||||
_rtw_memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
|
||||
|
||||
|
||||
netif_carrier_off(pnetdev);
|
||||
|
||||
|
||||
/* Tell the network stack we exist */
|
||||
if (register_netdev(pnetdev) != 0) {
|
||||
RTW_INFO("hostapd_mode_init(): register_netdev fail!\n");
|
||||
|
||||
if (pnetdev)
|
||||
rtw_free_netdev(pnetdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void hostapd_mode_unload(_adapter *padapter)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
|
||||
struct net_device *pnetdev = phostapdpriv->pmgnt_netdev;
|
||||
|
||||
unregister_netdev(pnetdev);
|
||||
rtw_free_netdev(pnetdev);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
4483
os_dep/linux/os_intfs.c
Normal file
4483
os_dep/linux/os_intfs.c
Normal file
File diff suppressed because it is too large
Load diff
885
os_dep/linux/recv_linux.c
Normal file
885
os_dep/linux/recv_linux.c
Normal file
|
@ -0,0 +1,885 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _RECV_OSDEP_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
int rtw_os_recvframe_duplicate_skb(_adapter *padapter, union recv_frame *pcloneframe, _pkt *pskb)
|
||||
{
|
||||
int res = _SUCCESS;
|
||||
_pkt *pkt_copy = NULL;
|
||||
struct rx_pkt_attrib *pattrib = &pcloneframe->u.hdr.attrib;
|
||||
|
||||
if (pskb == NULL) {
|
||||
RTW_INFO("%s [WARN] skb == NULL, drop frag frame\n", __func__);
|
||||
return _FAIL;
|
||||
}
|
||||
#if 1
|
||||
pkt_copy = rtw_skb_copy(pskb);
|
||||
|
||||
if (pkt_copy == NULL) {
|
||||
RTW_INFO("%s [WARN] rtw_skb_copy fail , drop frag frame\n", __func__);
|
||||
return _FAIL;
|
||||
}
|
||||
#else
|
||||
pkt_copy = rtw_skb_clone(pskb);
|
||||
|
||||
if (pkt_copy == NULL) {
|
||||
RTW_INFO("%s [WARN] rtw_skb_clone fail , drop frag frame\n", __func__);
|
||||
return _FAIL;
|
||||
}
|
||||
#endif
|
||||
pkt_copy->dev = padapter->pnetdev;
|
||||
|
||||
pcloneframe->u.hdr.pkt = pkt_copy;
|
||||
pcloneframe->u.hdr.rx_head = pkt_copy->head;
|
||||
pcloneframe->u.hdr.rx_data = pkt_copy->data;
|
||||
pcloneframe->u.hdr.rx_end = skb_end_pointer(pkt_copy);
|
||||
pcloneframe->u.hdr.rx_tail = skb_tail_pointer(pkt_copy);
|
||||
pcloneframe->u.hdr.len = pkt_copy->len;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int rtw_os_alloc_recvframe(_adapter *padapter, union recv_frame *precvframe, u8 *pdata, _pkt *pskb)
|
||||
{
|
||||
int res = _SUCCESS;
|
||||
u8 shift_sz = 0;
|
||||
u32 skb_len, alloc_sz;
|
||||
_pkt *pkt_copy = NULL;
|
||||
struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
|
||||
|
||||
|
||||
if (pdata == NULL) {
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
res = _FAIL;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* Modified by Albert 20101213 */
|
||||
/* For 8 bytes IP header alignment. */
|
||||
shift_sz = pattrib->qos ? 6 : 0; /* Qos data, wireless lan header length is 26 */
|
||||
|
||||
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. */
|
||||
alloc_sz = (skb_len <= 1650) ? 1664 : (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;
|
||||
}
|
||||
|
||||
pkt_copy = rtw_skb_alloc(alloc_sz);
|
||||
|
||||
if (pkt_copy) {
|
||||
pkt_copy->dev = padapter->pnetdev;
|
||||
pkt_copy->len = skb_len;
|
||||
precvframe->u.hdr.pkt = pkt_copy;
|
||||
precvframe->u.hdr.rx_head = pkt_copy->head;
|
||||
precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz;
|
||||
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. */
|
||||
_rtw_memcpy(pkt_copy->data, pdata, skb_len);
|
||||
precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
|
||||
} else {
|
||||
#if 0
|
||||
{
|
||||
rtw_free_recvframe(precvframe_if2, &precvpriv->free_recv_queue);
|
||||
rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
|
||||
|
||||
/* The case of can't allocate skb is serious and may never be recovered,
|
||||
once bDriverStopped is enable, this task should be stopped.*/
|
||||
if (!rtw_is_drv_stopped(secondary_padapter))
|
||||
#ifdef PLATFORM_LINUX
|
||||
tasklet_schedule(&precvpriv->recv_tasklet);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
|
||||
RTW_INFO("%s:can not allocate memory for skb copy\n", __func__);
|
||||
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
|
||||
/* rtw_free_recvframe(precvframe, pfree_recv_queue); */
|
||||
/*exit_rtw_os_recv_resource_alloc;*/
|
||||
|
||||
res = _FAIL;
|
||||
#else
|
||||
if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
|
||||
RTW_INFO("%s: alloc_skb fail , drop frag frame\n", __FUNCTION__);
|
||||
/* rtw_free_recvframe(precvframe, pfree_recv_queue); */
|
||||
res = _FAIL;
|
||||
goto exit_rtw_os_recv_resource_alloc;
|
||||
}
|
||||
|
||||
if (pskb == NULL) {
|
||||
res = _FAIL;
|
||||
goto exit_rtw_os_recv_resource_alloc;
|
||||
}
|
||||
|
||||
precvframe->u.hdr.pkt = rtw_skb_clone(pskb);
|
||||
if (precvframe->u.hdr.pkt) {
|
||||
precvframe->u.hdr.pkt->dev = padapter->pnetdev;
|
||||
precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pdata;
|
||||
precvframe->u.hdr.rx_end = pdata + alloc_sz;
|
||||
} else {
|
||||
RTW_INFO("%s: rtw_skb_clone fail\n", __FUNCTION__);
|
||||
/* rtw_free_recvframe(precvframe, pfree_recv_queue); */
|
||||
/*exit_rtw_os_recv_resource_alloc;*/
|
||||
res = _FAIL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
exit_rtw_os_recv_resource_alloc:
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
void rtw_os_free_recvframe(union recv_frame *precvframe)
|
||||
{
|
||||
if (precvframe->u.hdr.pkt) {
|
||||
rtw_skb_free(precvframe->u.hdr.pkt);/* free skb by driver */
|
||||
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* init os related resource in struct recv_priv */
|
||||
int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter)
|
||||
{
|
||||
int res = _SUCCESS;
|
||||
|
||||
|
||||
#ifdef CONFIG_RTW_NAPI
|
||||
skb_queue_head_init(&precvpriv->rx_napi_skb_queue);
|
||||
#endif /* CONFIG_RTW_NAPI */
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* alloc os related resource in union recv_frame */
|
||||
int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe)
|
||||
{
|
||||
int res = _SUCCESS;
|
||||
|
||||
precvframe->u.hdr.pkt_newalloc = precvframe->u.hdr.pkt = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* free os related resource in union recv_frame */
|
||||
void rtw_os_recv_resource_free(struct recv_priv *precvpriv)
|
||||
{
|
||||
sint i;
|
||||
union recv_frame *precvframe;
|
||||
precvframe = (union recv_frame *) precvpriv->precv_frame_buf;
|
||||
|
||||
|
||||
#ifdef CONFIG_RTW_NAPI
|
||||
if (skb_queue_len(&precvpriv->rx_napi_skb_queue))
|
||||
RTW_WARN("rx_napi_skb_queue not empty\n");
|
||||
rtw_skb_queue_purge(&precvpriv->rx_napi_skb_queue);
|
||||
#endif /* CONFIG_RTW_NAPI */
|
||||
|
||||
for (i = 0; i < NR_RECVFRAME; i++) {
|
||||
if (precvframe->u.hdr.pkt) {
|
||||
rtw_skb_free(precvframe->u.hdr.pkt);/* free skb by driver */
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
}
|
||||
precvframe++;
|
||||
}
|
||||
}
|
||||
|
||||
/* alloc os related resource in struct recv_buf */
|
||||
int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
int res = _SUCCESS;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
precvbuf->irp_pending = _FALSE;
|
||||
precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (precvbuf->purb == NULL)
|
||||
res = _FAIL;
|
||||
|
||||
precvbuf->pskb = NULL;
|
||||
|
||||
precvbuf->pallocated_buf = precvbuf->pbuf = NULL;
|
||||
|
||||
precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL;
|
||||
|
||||
precvbuf->transfer_len = 0;
|
||||
|
||||
precvbuf->len = 0;
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
|
||||
precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, &precvbuf->dma_transfer_addr);
|
||||
precvbuf->pbuf = precvbuf->pallocated_buf;
|
||||
if (precvbuf->pallocated_buf == NULL)
|
||||
return _FAIL;
|
||||
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
|
||||
|
||||
#endif /* CONFIG_USB_HCI */
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* free os related resource in struct recv_buf */
|
||||
int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
int ret = _SUCCESS;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
|
||||
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
rtw_usb_buffer_free(pusbd, (size_t)precvbuf->alloc_sz, precvbuf->pallocated_buf, precvbuf->dma_transfer_addr);
|
||||
precvbuf->pallocated_buf = NULL;
|
||||
precvbuf->dma_transfer_addr = 0;
|
||||
|
||||
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
|
||||
|
||||
if (precvbuf->purb) {
|
||||
/* usb_kill_urb(precvbuf->purb); */
|
||||
usb_free_urb(precvbuf->purb);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_USB_HCI */
|
||||
|
||||
|
||||
if (precvbuf->pskb) {
|
||||
#ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
|
||||
if (rtw_free_skb_premem(precvbuf->pskb) != 0)
|
||||
#endif
|
||||
rtw_skb_free(precvbuf->pskb);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
_pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 *pdata)
|
||||
{
|
||||
u16 eth_type;
|
||||
u8 *data_ptr;
|
||||
_pkt *sub_skb;
|
||||
struct rx_pkt_attrib *pattrib;
|
||||
|
||||
pattrib = &prframe->u.hdr.attrib;
|
||||
|
||||
#ifdef CONFIG_SKB_COPY
|
||||
sub_skb = rtw_skb_alloc(nSubframe_Length + 12);
|
||||
if (sub_skb) {
|
||||
skb_reserve(sub_skb, 12);
|
||||
data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
|
||||
_rtw_memcpy(data_ptr, (pdata + ETH_HLEN), nSubframe_Length);
|
||||
} else
|
||||
#endif /* CONFIG_SKB_COPY */
|
||||
{
|
||||
sub_skb = rtw_skb_clone(prframe->u.hdr.pkt);
|
||||
if (sub_skb) {
|
||||
sub_skb->data = pdata + ETH_HLEN;
|
||||
sub_skb->len = nSubframe_Length;
|
||||
skb_set_tail_pointer(sub_skb, nSubframe_Length);
|
||||
} else {
|
||||
RTW_INFO("%s(): rtw_skb_clone() Fail!!!\n", __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
eth_type = RTW_GET_BE16(&sub_skb->data[6]);
|
||||
|
||||
if (sub_skb->len >= 8 &&
|
||||
((_rtw_memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) &&
|
||||
eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
|
||||
_rtw_memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE))) {
|
||||
/* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
|
||||
skb_pull(sub_skb, SNAP_SIZE);
|
||||
_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
|
||||
_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
|
||||
} else {
|
||||
u16 len;
|
||||
/* Leave Ethernet header part of hdr and full payload */
|
||||
len = htons(sub_skb->len);
|
||||
_rtw_memcpy(skb_push(sub_skb, 2), &len, 2);
|
||||
_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
|
||||
_rtw_memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
|
||||
}
|
||||
|
||||
return sub_skb;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RTW_NAPI
|
||||
static int napi_recv(_adapter *padapter, int budget)
|
||||
{
|
||||
_pkt *pskb;
|
||||
struct recv_priv *precvpriv = &padapter->recvpriv;
|
||||
int work_done = 0;
|
||||
struct registry_priv *pregistrypriv = &padapter->registrypriv;
|
||||
u8 rx_ok;
|
||||
|
||||
|
||||
while ((work_done < budget) &&
|
||||
(!skb_queue_empty(&precvpriv->rx_napi_skb_queue))) {
|
||||
pskb = skb_dequeue(&precvpriv->rx_napi_skb_queue);
|
||||
if (!pskb)
|
||||
break;
|
||||
|
||||
rx_ok = _FALSE;
|
||||
|
||||
#ifdef CONFIG_RTW_GRO
|
||||
if (pregistrypriv->en_gro) {
|
||||
if (rtw_napi_gro_receive(&padapter->napi, pskb) != GRO_DROP)
|
||||
rx_ok = _TRUE;
|
||||
goto next;
|
||||
}
|
||||
#endif /* CONFIG_RTW_GRO */
|
||||
|
||||
if (rtw_netif_receive_skb(padapter->pnetdev, pskb) == NET_RX_SUCCESS)
|
||||
rx_ok = _TRUE;
|
||||
|
||||
next:
|
||||
if (rx_ok == _TRUE) {
|
||||
work_done++;
|
||||
DBG_COUNTER(padapter->rx_logs.os_netif_ok);
|
||||
} else {
|
||||
DBG_COUNTER(padapter->rx_logs.os_netif_err);
|
||||
}
|
||||
}
|
||||
|
||||
return work_done;
|
||||
}
|
||||
|
||||
int rtw_recv_napi_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
_adapter *padapter = container_of(napi, _adapter, napi);
|
||||
int work_done = 0;
|
||||
struct recv_priv *precvpriv = &padapter->recvpriv;
|
||||
|
||||
|
||||
work_done = napi_recv(padapter, budget);
|
||||
if (work_done < budget) {
|
||||
napi_complete(napi);
|
||||
if (!skb_queue_empty(&precvpriv->rx_napi_skb_queue))
|
||||
napi_schedule(napi);
|
||||
}
|
||||
|
||||
return work_done;
|
||||
}
|
||||
#endif /* CONFIG_RTW_NAPI */
|
||||
|
||||
#ifdef DBG_UDP_PKT_LOSE_11AC
|
||||
#define PAYLOAD_LEN_LOC_OF_IP_HDR 0x10 /*ethernet payload length location of ip header (DA + SA+eth_type+(version&hdr_len)) */
|
||||
#endif
|
||||
|
||||
void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, struct rx_pkt_attrib *pattrib)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct recv_priv *precvpriv = &(padapter->recvpriv);
|
||||
struct registry_priv *pregistrypriv = &padapter->registrypriv;
|
||||
#ifdef CONFIG_BR_EXT
|
||||
void *br_port = NULL;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* Indicat the packets to upper layer */
|
||||
if (pkt) {
|
||||
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
|
||||
_pkt *pskb2 = NULL;
|
||||
struct sta_info *psta = NULL;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
int bmcast = IS_MCAST(pattrib->dst);
|
||||
|
||||
/* RTW_INFO("bmcast=%d\n", bmcast); */
|
||||
|
||||
if (_rtw_memcmp(pattrib->dst, adapter_mac_addr(padapter), ETH_ALEN) == _FALSE) {
|
||||
/* RTW_INFO("not ap psta=%p, addr=%pM\n", psta, pattrib->dst); */
|
||||
|
||||
if (bmcast) {
|
||||
psta = rtw_get_bcmc_stainfo(padapter);
|
||||
pskb2 = rtw_skb_clone(pkt);
|
||||
} else
|
||||
psta = rtw_get_stainfo(pstapriv, pattrib->dst);
|
||||
|
||||
if (psta) {
|
||||
struct net_device *pnetdev = (struct net_device *)padapter->pnetdev;
|
||||
|
||||
/* RTW_INFO("directly forwarding to the rtw_xmit_entry\n"); */
|
||||
|
||||
/* skb->ip_summed = CHECKSUM_NONE; */
|
||||
pkt->dev = pnetdev;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt));
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) */
|
||||
|
||||
_rtw_xmit_entry(pkt, pnetdev);
|
||||
|
||||
if (bmcast && (pskb2 != NULL)) {
|
||||
pkt = pskb2;
|
||||
DBG_COUNTER(padapter->rx_logs.os_indicate_ap_mcast);
|
||||
} else {
|
||||
DBG_COUNTER(padapter->rx_logs.os_indicate_ap_forward);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else { /* to APself */
|
||||
/* RTW_INFO("to APSelf\n"); */
|
||||
DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BR_EXT
|
||||
/* Insert NAT2.5 RX here! */
|
||||
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
|
||||
br_port = padapter->pnetdev->br_port;
|
||||
#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
|
||||
rcu_read_lock();
|
||||
br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
|
||||
rcu_read_unlock();
|
||||
#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
|
||||
|
||||
|
||||
if (br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE)) {
|
||||
int nat25_handle_frame(_adapter *priv, struct sk_buff *skb);
|
||||
if (nat25_handle_frame(padapter, pkt) == -1) {
|
||||
/* priv->ext_stats.rx_data_drops++; */
|
||||
/* DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); */
|
||||
/* return FAIL; */
|
||||
|
||||
#if 1
|
||||
/* bypass this frame to upper layer!! */
|
||||
#else
|
||||
rtw_skb_free(sub_skb);
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BR_EXT */
|
||||
if (precvpriv->sink_udpport > 0)
|
||||
rtw_sink_rtp_seq_dbg(padapter, pkt);
|
||||
#ifdef DBG_UDP_PKT_LOSE_11AC
|
||||
/* After eth_type_trans process , pkt->data pointer will move from ethrnet header to ip header ,
|
||||
* we have to check ethernet type , so this debug must be print before eth_type_trans
|
||||
*/
|
||||
if (*((unsigned short *)(pkt->data + ETH_ALEN * 2)) == htons(ETH_P_ARP)) {
|
||||
/* ARP Payload length will be 42bytes or 42+18(tailer)=60bytes*/
|
||||
if (pkt->len != 42 && pkt->len != 60)
|
||||
RTW_INFO("Error !!%s,ARP Payload length %u not correct\n" , __func__ , pkt->len);
|
||||
} else if (*((unsigned short *)(pkt->data + ETH_ALEN * 2)) == htons(ETH_P_IP)) {
|
||||
if (be16_to_cpu(*((u16 *)(pkt->data + PAYLOAD_LEN_LOC_OF_IP_HDR))) != (pkt->len) - ETH_HLEN) {
|
||||
RTW_INFO("Error !!%s,Payload length not correct\n" , __func__);
|
||||
RTW_INFO("%s, IP header describe Total length=%u\n" , __func__ , be16_to_cpu(*((u16 *)(pkt->data + PAYLOAD_LEN_LOC_OF_IP_HDR))));
|
||||
RTW_INFO("%s, Pkt real length=%u\n" , __func__ , (pkt->len) - ETH_HLEN);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* After eth_type_trans process , pkt->data pointer will move from ethrnet header to ip header */
|
||||
pkt->protocol = eth_type_trans(pkt, padapter->pnetdev);
|
||||
pkt->dev = padapter->pnetdev;
|
||||
|
||||
#ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
|
||||
if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1))
|
||||
pkt->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
else
|
||||
pkt->ip_summed = CHECKSUM_NONE;
|
||||
#else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
|
||||
pkt->ip_summed = CHECKSUM_NONE;
|
||||
#endif /* CONFIG_TCP_CSUM_OFFLOAD_RX */
|
||||
|
||||
#ifdef CONFIG_RTW_NAPI
|
||||
if (pregistrypriv->en_napi) {
|
||||
skb_queue_tail(&precvpriv->rx_napi_skb_queue, pkt);
|
||||
napi_schedule(&padapter->napi);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_RTW_NAPI */
|
||||
|
||||
ret = rtw_netif_rx(padapter->pnetdev, pkt);
|
||||
if (ret == NET_RX_SUCCESS)
|
||||
DBG_COUNTER(padapter->rx_logs.os_netif_ok);
|
||||
else
|
||||
DBG_COUNTER(padapter->rx_logs.os_netif_err);
|
||||
}
|
||||
}
|
||||
|
||||
void rtw_handle_tkip_mic_err(_adapter *padapter, struct sta_info *sta, u8 bgroup)
|
||||
{
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
enum nl80211_key_type key_type = 0;
|
||||
#endif
|
||||
union iwreq_data wrqu;
|
||||
struct iw_michaelmicfailure ev;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct security_priv *psecuritypriv = &padapter->securitypriv;
|
||||
u32 cur_time = 0;
|
||||
|
||||
if (psecuritypriv->last_mic_err_time == 0)
|
||||
psecuritypriv->last_mic_err_time = rtw_get_current_time();
|
||||
else {
|
||||
cur_time = rtw_get_current_time();
|
||||
|
||||
if (cur_time - psecuritypriv->last_mic_err_time < 60 * HZ) {
|
||||
psecuritypriv->btkip_countermeasure = _TRUE;
|
||||
psecuritypriv->last_mic_err_time = 0;
|
||||
psecuritypriv->btkip_countermeasure_time = cur_time;
|
||||
} else
|
||||
psecuritypriv->last_mic_err_time = rtw_get_current_time();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
if (bgroup)
|
||||
key_type |= NL80211_KEYTYPE_GROUP;
|
||||
else
|
||||
key_type |= NL80211_KEYTYPE_PAIRWISE;
|
||||
|
||||
cfg80211_michael_mic_failure(padapter->pnetdev, sta->hwaddr, key_type, -1, NULL, GFP_ATOMIC);
|
||||
#endif
|
||||
|
||||
_rtw_memset(&ev, 0x00, sizeof(ev));
|
||||
if (bgroup)
|
||||
ev.flags |= IW_MICFAILURE_GROUP;
|
||||
else
|
||||
ev.flags |= IW_MICFAILURE_PAIRWISE;
|
||||
|
||||
ev.src_addr.sa_family = ARPHRD_ETHER;
|
||||
_rtw_memcpy(ev.src_addr.sa_data, sta->hwaddr, ETH_ALEN);
|
||||
|
||||
_rtw_memset(&wrqu, 0x00, sizeof(wrqu));
|
||||
wrqu.data.length = sizeof(ev);
|
||||
|
||||
#ifndef CONFIG_IOCTL_CFG80211
|
||||
wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
#ifdef CONFIG_HOSTAPD_MLME
|
||||
_pkt *skb;
|
||||
struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
|
||||
struct net_device *pmgnt_netdev = phostapdpriv->pmgnt_netdev;
|
||||
|
||||
|
||||
skb = precv_frame->u.hdr.pkt;
|
||||
|
||||
if (skb == NULL)
|
||||
return;
|
||||
|
||||
skb->data = precv_frame->u.hdr.rx_data;
|
||||
skb->tail = precv_frame->u.hdr.rx_tail;
|
||||
skb->len = precv_frame->u.hdr.len;
|
||||
|
||||
/* pskb_copy = rtw_skb_copy(skb);
|
||||
* if(skb == NULL) goto _exit; */
|
||||
|
||||
skb->dev = pmgnt_netdev;
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
/* skb->protocol = __constant_htons(0x0019); ETH_P_80211_RAW */
|
||||
skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/
|
||||
|
||||
/* RTW_INFO("(1)data=0x%x, head=0x%x, tail=0x%x, mac_header=0x%x, len=%d\n", skb->data, skb->head, skb->tail, skb->mac_header, skb->len); */
|
||||
|
||||
/* skb->mac.raw = skb->data; */
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
/* skb_pull(skb, 24); */
|
||||
_rtw_memset(skb->cb, 0, sizeof(skb->cb));
|
||||
|
||||
rtw_netif_rx(pmgnt_netdev, skb);
|
||||
|
||||
precv_frame->u.hdr.pkt = NULL; /* set pointer to NULL before rtw_free_recvframe() if call rtw_netif_rx() */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AUTO_AP_MODE
|
||||
static void rtw_os_ksocket_send(_adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
_pkt *skb = precv_frame->u.hdr.pkt;
|
||||
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
|
||||
struct sta_info *psta = precv_frame->u.hdr.psta;
|
||||
|
||||
RTW_INFO("eth rx: got eth_type=0x%x\n", pattrib->eth_type);
|
||||
|
||||
if (psta && psta->isrc && psta->pid > 0) {
|
||||
u16 rx_pid;
|
||||
|
||||
rx_pid = *(u16 *)(skb->data + ETH_HLEN);
|
||||
|
||||
RTW_INFO("eth rx(pid=0x%x): sta("MAC_FMT") pid=0x%x\n",
|
||||
rx_pid, MAC_ARG(psta->hwaddr), psta->pid);
|
||||
|
||||
if (rx_pid == psta->pid) {
|
||||
int i;
|
||||
u16 len = *(u16 *)(skb->data + ETH_HLEN + 2);
|
||||
/* u16 ctrl_type = *(u16*)(skb->data+ETH_HLEN+4); */
|
||||
|
||||
/* RTW_INFO("eth, RC: len=0x%x, ctrl_type=0x%x\n", len, ctrl_type); */
|
||||
RTW_INFO("eth, RC: len=0x%x\n", len);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
RTW_INFO("0x%x\n", *(skb->data + ETH_HLEN + 4 + i));
|
||||
/* RTW_INFO("0x%x\n", *(skb->data+ETH_HLEN+6+i)); */
|
||||
|
||||
RTW_INFO("eth, RC-end\n");
|
||||
|
||||
#if 0
|
||||
/* send_sz = ksocket_send(padapter->ksock_send, &padapter->kaddr_send, (skb->data+ETH_HLEN+2), len); */
|
||||
rtw_recv_ksocket_send_cmd(padapter, (skb->data + ETH_HLEN + 2), len);
|
||||
|
||||
/* RTW_INFO("ksocket_send size=%d\n", send_sz); */
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* CONFIG_AUTO_AP_MODE */
|
||||
|
||||
int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
int ret = _FAIL;
|
||||
struct recv_priv *precvpriv;
|
||||
_queue *pfree_recv_queue;
|
||||
_pkt *skb;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct rx_pkt_attrib *pattrib;
|
||||
|
||||
if (NULL == precv_frame)
|
||||
goto _recv_drop;
|
||||
|
||||
pattrib = &precv_frame->u.hdr.attrib;
|
||||
precvpriv = &(padapter->recvpriv);
|
||||
pfree_recv_queue = &(precvpriv->free_recv_queue);
|
||||
|
||||
skb = precv_frame->u.hdr.pkt;
|
||||
if (skb == NULL) {
|
||||
RTW_INFO("%s :skb==NULL something wrong!!!!\n", __func__);
|
||||
goto _recv_drop;
|
||||
}
|
||||
|
||||
skb->data = precv_frame->u.hdr.rx_data;
|
||||
skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
|
||||
skb->len = precv_frame->u.hdr.len;
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
skb->protocol = htons(0x0019); /* ETH_P_80211_RAW */
|
||||
|
||||
rtw_netif_rx(padapter->pnetdev, skb);
|
||||
|
||||
/* pointers to NULL before rtw_free_recvframe() */
|
||||
precv_frame->u.hdr.pkt = NULL;
|
||||
|
||||
ret = _SUCCESS;
|
||||
|
||||
_recv_drop:
|
||||
|
||||
/* enqueue back to free_recv_queue */
|
||||
if (precv_frame)
|
||||
rtw_free_recvframe(precv_frame, pfree_recv_queue);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
struct recv_priv *precvpriv;
|
||||
_queue *pfree_recv_queue;
|
||||
_pkt *skb;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct rx_pkt_attrib *pattrib;
|
||||
|
||||
if (NULL == precv_frame)
|
||||
goto _recv_indicatepkt_drop;
|
||||
|
||||
DBG_COUNTER(padapter->rx_logs.os_indicate);
|
||||
pattrib = &precv_frame->u.hdr.attrib;
|
||||
precvpriv = &(padapter->recvpriv);
|
||||
pfree_recv_queue = &(precvpriv->free_recv_queue);
|
||||
|
||||
#ifdef CONFIG_DRVEXT_MODULE
|
||||
if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS)
|
||||
goto _recv_indicatepkt_drop;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WAPI_SUPPORT
|
||||
if (rtw_wapi_check_for_drop(padapter, precv_frame)) {
|
||||
WAPI_TRACE(WAPI_ERR, "%s(): Rx Reorder Drop case!!\n", __FUNCTION__);
|
||||
goto _recv_indicatepkt_drop;
|
||||
}
|
||||
#endif
|
||||
|
||||
skb = precv_frame->u.hdr.pkt;
|
||||
if (skb == NULL) {
|
||||
goto _recv_indicatepkt_drop;
|
||||
}
|
||||
|
||||
|
||||
skb->data = precv_frame->u.hdr.rx_data;
|
||||
|
||||
skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
|
||||
|
||||
skb->len = precv_frame->u.hdr.len;
|
||||
|
||||
|
||||
if (pattrib->eth_type == 0x888e)
|
||||
RTW_PRINT("recv eapol packet\n");
|
||||
|
||||
#ifdef CONFIG_AUTO_AP_MODE
|
||||
#if 1 /* for testing */
|
||||
#if 1
|
||||
if (0x8899 == pattrib->eth_type) {
|
||||
rtw_os_ksocket_send(padapter, precv_frame);
|
||||
|
||||
/* goto _recv_indicatepkt_drop; */
|
||||
}
|
||||
#else
|
||||
if (0x8899 == pattrib->eth_type) {
|
||||
rtw_auto_ap_mode_rx(padapter, precv_frame);
|
||||
|
||||
goto _recv_indicatepkt_end;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CONFIG_AUTO_AP_MODE */
|
||||
|
||||
/* TODO: move to core */
|
||||
{
|
||||
_pkt *pkt = skb;
|
||||
struct ethhdr *etherhdr = (struct ethhdr *)pkt->data;
|
||||
struct sta_info *sta = precv_frame->u.hdr.psta;
|
||||
|
||||
if (!sta)
|
||||
goto bypass_session_tracker;
|
||||
|
||||
if (ntohs(etherhdr->h_proto) == ETH_P_IP) {
|
||||
u8 *ip = pkt->data + 14;
|
||||
|
||||
if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */
|
||||
&& rtw_st_ctl_chk_reg_s_proto(&sta->st_ctl, 0x06) == _TRUE
|
||||
) {
|
||||
u8 *tcp = ip + GET_IPV4_IHL(ip) * 4;
|
||||
|
||||
if (rtw_st_ctl_chk_reg_rule(&sta->st_ctl, padapter, IPV4_DST(ip), TCP_DST(tcp), IPV4_SRC(ip), TCP_SRC(tcp)) == _TRUE) {
|
||||
if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) {
|
||||
session_tracker_add_cmd(padapter, sta
|
||||
, IPV4_DST(ip), TCP_DST(tcp)
|
||||
, IPV4_SRC(ip), TCP_SRC(tcp));
|
||||
if (DBG_SESSION_TRACKER)
|
||||
RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n"
|
||||
, FUNC_ADPT_ARG(padapter)
|
||||
, IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp))
|
||||
, IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp)));
|
||||
}
|
||||
if (GET_TCP_FIN(tcp)) {
|
||||
session_tracker_del_cmd(padapter, sta
|
||||
, IPV4_DST(ip), TCP_DST(tcp)
|
||||
, IPV4_SRC(ip), TCP_SRC(tcp));
|
||||
if (DBG_SESSION_TRACKER)
|
||||
RTW_INFO(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n"
|
||||
, FUNC_ADPT_ARG(padapter)
|
||||
, IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp))
|
||||
, IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
bypass_session_tracker:
|
||||
;
|
||||
}
|
||||
|
||||
rtw_os_recv_indicate_pkt(padapter, skb, pattrib);
|
||||
|
||||
_recv_indicatepkt_end:
|
||||
|
||||
precv_frame->u.hdr.pkt = NULL; /* pointers to NULL before rtw_free_recvframe() */
|
||||
|
||||
rtw_free_recvframe(precv_frame, pfree_recv_queue);
|
||||
|
||||
|
||||
|
||||
return _SUCCESS;
|
||||
|
||||
_recv_indicatepkt_drop:
|
||||
|
||||
/* enqueue back to free_recv_queue */
|
||||
if (precv_frame)
|
||||
rtw_free_recvframe(precv_frame, pfree_recv_queue);
|
||||
|
||||
DBG_COUNTER(padapter->rx_logs.os_indicate_err);
|
||||
|
||||
return _FAIL;
|
||||
|
||||
}
|
||||
|
||||
void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
struct recv_priv *precvpriv = &padapter->recvpriv;
|
||||
|
||||
#ifdef CONFIG_USB_HCI
|
||||
|
||||
precvbuf->ref_cnt--;
|
||||
|
||||
/* free skb in recv_buf */
|
||||
rtw_skb_free(precvbuf->pskb);
|
||||
|
||||
precvbuf->pskb = NULL;
|
||||
|
||||
if (precvbuf->irp_pending == _FALSE)
|
||||
rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
|
||||
|
||||
|
||||
#endif
|
||||
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
|
||||
precvbuf->pskb = NULL;
|
||||
#endif
|
||||
|
||||
}
|
||||
void _rtw_reordering_ctrl_timeout_handler(void *FunctionContext);
|
||||
void _rtw_reordering_ctrl_timeout_handler(void *FunctionContext)
|
||||
{
|
||||
struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)FunctionContext;
|
||||
rtw_reordering_ctrl_timeout_handler(preorder_ctrl);
|
||||
}
|
||||
|
||||
void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
|
||||
{
|
||||
_adapter *padapter = preorder_ctrl->padapter;
|
||||
|
||||
_init_timer(&(preorder_ctrl->reordering_ctrl_timer), padapter->pnetdev, _rtw_reordering_ctrl_timeout_handler, preorder_ctrl);
|
||||
|
||||
}
|
1274
os_dep/linux/rtw_android.c
Normal file
1274
os_dep/linux/rtw_android.c
Normal file
File diff suppressed because it is too large
Load diff
1328
os_dep/linux/rtw_cfgvendor.c
Normal file
1328
os_dep/linux/rtw_cfgvendor.c
Normal file
File diff suppressed because it is too large
Load diff
245
os_dep/linux/rtw_cfgvendor.h
Normal file
245
os_dep/linux/rtw_cfgvendor.h
Normal file
|
@ -0,0 +1,245 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef _RTW_CFGVENDOR_H_
|
||||
#define _RTW_CFGVENDOR_H_
|
||||
|
||||
#define OUI_BRCM 0x001018
|
||||
#define OUI_GOOGLE 0x001A11
|
||||
#define BRCM_VENDOR_SUBCMD_PRIV_STR 1
|
||||
#define ATTRIBUTE_U32_LEN (NLA_HDRLEN + 4)
|
||||
#define VENDOR_ID_OVERHEAD ATTRIBUTE_U32_LEN
|
||||
#define VENDOR_SUBCMD_OVERHEAD ATTRIBUTE_U32_LEN
|
||||
#define VENDOR_DATA_OVERHEAD (NLA_HDRLEN)
|
||||
|
||||
#define SCAN_RESULTS_COMPLETE_FLAG_LEN ATTRIBUTE_U32_LEN
|
||||
#define SCAN_INDEX_HDR_LEN (NLA_HDRLEN)
|
||||
#define SCAN_ID_HDR_LEN ATTRIBUTE_U32_LEN
|
||||
#define SCAN_FLAGS_HDR_LEN ATTRIBUTE_U32_LEN
|
||||
#define GSCAN_NUM_RESULTS_HDR_LEN ATTRIBUTE_U32_LEN
|
||||
#define GSCAN_RESULTS_HDR_LEN (NLA_HDRLEN)
|
||||
#define GSCAN_BATCH_RESULT_HDR_LEN (SCAN_INDEX_HDR_LEN + SCAN_ID_HDR_LEN + \
|
||||
SCAN_FLAGS_HDR_LEN + \
|
||||
GSCAN_NUM_RESULTS_HDR_LEN + \
|
||||
GSCAN_RESULTS_HDR_LEN)
|
||||
|
||||
#define VENDOR_REPLY_OVERHEAD (VENDOR_ID_OVERHEAD + \
|
||||
VENDOR_SUBCMD_OVERHEAD + \
|
||||
VENDOR_DATA_OVERHEAD)
|
||||
typedef enum {
|
||||
/* don't use 0 as a valid subcommand */
|
||||
VENDOR_NL80211_SUBCMD_UNSPECIFIED,
|
||||
|
||||
/* define all vendor startup commands between 0x0 and 0x0FFF */
|
||||
VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
|
||||
VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF,
|
||||
|
||||
/* define all GScan related commands between 0x1000 and 0x10FF */
|
||||
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
|
||||
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF,
|
||||
|
||||
/* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */
|
||||
ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100,
|
||||
ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x11FF,
|
||||
|
||||
/* define all RTT related commands between 0x1100 and 0x11FF */
|
||||
ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
|
||||
ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF,
|
||||
|
||||
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
|
||||
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF,
|
||||
|
||||
ANDROID_NL80211_SUBCMD_TDLS_RANGE_START = 0x1300,
|
||||
ANDROID_NL80211_SUBCMD_TDLS_RANGE_END = 0x13FF,
|
||||
/* This is reserved for future usage */
|
||||
|
||||
} ANDROID_VENDOR_SUB_COMMAND;
|
||||
|
||||
enum wl_vendor_subcmd {
|
||||
BRCM_VENDOR_SCMD_UNSPEC,
|
||||
BRCM_VENDOR_SCMD_PRIV_STR,
|
||||
GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
|
||||
GSCAN_SUBCMD_SET_CONFIG,
|
||||
GSCAN_SUBCMD_SET_SCAN_CONFIG,
|
||||
GSCAN_SUBCMD_ENABLE_GSCAN,
|
||||
GSCAN_SUBCMD_GET_SCAN_RESULTS,
|
||||
GSCAN_SUBCMD_SCAN_RESULTS,
|
||||
GSCAN_SUBCMD_SET_HOTLIST,
|
||||
GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG,
|
||||
GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS,
|
||||
GSCAN_SUBCMD_GET_CHANNEL_LIST,
|
||||
ANDR_WIFI_SUBCMD_GET_FEATURE_SET,
|
||||
ANDR_WIFI_SUBCMD_GET_FEATURE_SET_MATRIX,
|
||||
RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
|
||||
RTT_SUBCMD_CANCEL_CONFIG,
|
||||
RTT_SUBCMD_GETCAPABILITY,
|
||||
/* Add more sub commands here */
|
||||
VENDOR_SUBCMD_MAX
|
||||
};
|
||||
|
||||
enum gscan_attributes {
|
||||
GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
|
||||
GSCAN_ATTRIBUTE_BASE_PERIOD,
|
||||
GSCAN_ATTRIBUTE_BUCKETS_BAND,
|
||||
GSCAN_ATTRIBUTE_BUCKET_ID,
|
||||
GSCAN_ATTRIBUTE_BUCKET_PERIOD,
|
||||
GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
|
||||
GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
|
||||
GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
|
||||
GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
|
||||
GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
|
||||
GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
|
||||
|
||||
GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
|
||||
GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE,
|
||||
GSCAN_ATTRIBUTE_FLUSH_FEATURE,
|
||||
GSCAN_ATTRIBUTE_ENABLE_FULL_SCAN_RESULTS,
|
||||
GSCAN_ATTRIBUTE_REPORT_EVENTS,
|
||||
/* remaining reserved for additional attributes */
|
||||
GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
|
||||
GSCAN_ATTRIBUTE_FLUSH_RESULTS,
|
||||
GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */
|
||||
GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */
|
||||
GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */
|
||||
GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */
|
||||
GSCAN_ATTRIBUTE_NUM_CHANNELS,
|
||||
GSCAN_ATTRIBUTE_CHANNEL_LIST,
|
||||
|
||||
/* remaining reserved for additional attributes */
|
||||
|
||||
GSCAN_ATTRIBUTE_SSID = 40,
|
||||
GSCAN_ATTRIBUTE_BSSID,
|
||||
GSCAN_ATTRIBUTE_CHANNEL,
|
||||
GSCAN_ATTRIBUTE_RSSI,
|
||||
GSCAN_ATTRIBUTE_TIMESTAMP,
|
||||
GSCAN_ATTRIBUTE_RTT,
|
||||
GSCAN_ATTRIBUTE_RTTSD,
|
||||
|
||||
/* remaining reserved for additional attributes */
|
||||
|
||||
GSCAN_ATTRIBUTE_HOTLIST_BSSIDS = 50,
|
||||
GSCAN_ATTRIBUTE_RSSI_LOW,
|
||||
GSCAN_ATTRIBUTE_RSSI_HIGH,
|
||||
GSCAN_ATTRIBUTE_HOSTLIST_BSSID_ELEM,
|
||||
GSCAN_ATTRIBUTE_HOTLIST_FLUSH,
|
||||
|
||||
/* remaining reserved for additional attributes */
|
||||
GSCAN_ATTRIBUTE_RSSI_SAMPLE_SIZE = 60,
|
||||
GSCAN_ATTRIBUTE_LOST_AP_SAMPLE_SIZE,
|
||||
GSCAN_ATTRIBUTE_MIN_BREACHING,
|
||||
GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_BSSIDS,
|
||||
GSCAN_ATTRIBUTE_SIGNIFICANT_CHANGE_FLUSH,
|
||||
GSCAN_ATTRIBUTE_MAX
|
||||
};
|
||||
|
||||
enum gscan_bucket_attributes {
|
||||
GSCAN_ATTRIBUTE_CH_BUCKET_1,
|
||||
GSCAN_ATTRIBUTE_CH_BUCKET_2,
|
||||
GSCAN_ATTRIBUTE_CH_BUCKET_3,
|
||||
GSCAN_ATTRIBUTE_CH_BUCKET_4,
|
||||
GSCAN_ATTRIBUTE_CH_BUCKET_5,
|
||||
GSCAN_ATTRIBUTE_CH_BUCKET_6,
|
||||
GSCAN_ATTRIBUTE_CH_BUCKET_7
|
||||
};
|
||||
|
||||
enum gscan_ch_attributes {
|
||||
GSCAN_ATTRIBUTE_CH_ID_1,
|
||||
GSCAN_ATTRIBUTE_CH_ID_2,
|
||||
GSCAN_ATTRIBUTE_CH_ID_3,
|
||||
GSCAN_ATTRIBUTE_CH_ID_4,
|
||||
GSCAN_ATTRIBUTE_CH_ID_5,
|
||||
GSCAN_ATTRIBUTE_CH_ID_6,
|
||||
GSCAN_ATTRIBUTE_CH_ID_7
|
||||
};
|
||||
|
||||
enum rtt_attributes {
|
||||
RTT_ATTRIBUTE_TARGET_CNT,
|
||||
RTT_ATTRIBUTE_TARGET_INFO,
|
||||
RTT_ATTRIBUTE_TARGET_MAC,
|
||||
RTT_ATTRIBUTE_TARGET_TYPE,
|
||||
RTT_ATTRIBUTE_TARGET_PEER,
|
||||
RTT_ATTRIBUTE_TARGET_CHAN,
|
||||
RTT_ATTRIBUTE_TARGET_MODE,
|
||||
RTT_ATTRIBUTE_TARGET_INTERVAL,
|
||||
RTT_ATTRIBUTE_TARGET_NUM_MEASUREMENT,
|
||||
RTT_ATTRIBUTE_TARGET_NUM_PKT,
|
||||
RTT_ATTRIBUTE_TARGET_NUM_RETRY
|
||||
};
|
||||
|
||||
typedef enum wl_vendor_event {
|
||||
BRCM_VENDOR_EVENT_UNSPEC,
|
||||
BRCM_VENDOR_EVENT_PRIV_STR,
|
||||
GOOGLE_GSCAN_SIGNIFICANT_EVENT,
|
||||
GOOGLE_GSCAN_GEOFENCE_FOUND_EVENT,
|
||||
GOOGLE_GSCAN_BATCH_SCAN_EVENT,
|
||||
GOOGLE_SCAN_FULL_RESULTS_EVENT,
|
||||
GOOGLE_RTT_COMPLETE_EVENT,
|
||||
GOOGLE_SCAN_COMPLETE_EVENT,
|
||||
GOOGLE_GSCAN_GEOFENCE_LOST_EVENT
|
||||
} wl_vendor_event_t;
|
||||
|
||||
enum andr_wifi_feature_set_attr {
|
||||
ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
|
||||
ANDR_WIFI_ATTRIBUTE_FEATURE_SET
|
||||
};
|
||||
|
||||
typedef enum wl_vendor_gscan_attribute {
|
||||
ATTR_START_GSCAN,
|
||||
ATTR_STOP_GSCAN,
|
||||
ATTR_SET_SCAN_BATCH_CFG_ID, /* set batch scan params */
|
||||
ATTR_SET_SCAN_GEOFENCE_CFG_ID, /* set list of bssids to track */
|
||||
ATTR_SET_SCAN_SIGNIFICANT_CFG_ID, /* set list of bssids, rssi threshold etc.. */
|
||||
ATTR_SET_SCAN_CFG_ID, /* set common scan config params here */
|
||||
ATTR_GET_GSCAN_CAPABILITIES_ID,
|
||||
/* Add more sub commands here */
|
||||
ATTR_GSCAN_MAX
|
||||
} wl_vendor_gscan_attribute_t;
|
||||
|
||||
typedef enum gscan_batch_attribute {
|
||||
ATTR_GSCAN_BATCH_BESTN,
|
||||
ATTR_GSCAN_BATCH_MSCAN,
|
||||
ATTR_GSCAN_BATCH_BUFFER_THRESHOLD
|
||||
} gscan_batch_attribute_t;
|
||||
|
||||
typedef enum gscan_geofence_attribute {
|
||||
ATTR_GSCAN_NUM_HOTLIST_BSSID,
|
||||
ATTR_GSCAN_HOTLIST_BSSID
|
||||
} gscan_geofence_attribute_t;
|
||||
|
||||
typedef enum gscan_complete_event {
|
||||
WIFI_SCAN_BUFFER_FULL,
|
||||
WIFI_SCAN_COMPLETE
|
||||
} gscan_complete_event_t;
|
||||
|
||||
/* Capture the BRCM_VENDOR_SUBCMD_PRIV_STRINGS* here */
|
||||
#define BRCM_VENDOR_SCMD_CAPA "cap"
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
|
||||
extern int rtw_cfgvendor_attach(struct wiphy *wiphy);
|
||||
extern int rtw_cfgvendor_detach(struct wiphy *wiphy);
|
||||
extern int rtw_cfgvendor_send_async_event(struct wiphy *wiphy,
|
||||
struct net_device *dev, int event_id, const void *data, int len);
|
||||
#if defined(GSCAN_SUPPORT) && 0
|
||||
extern int wl_cfgvendor_send_hotlist_event(struct wiphy *wiphy,
|
||||
struct net_device *dev, void *data, int len, wl_vendor_event_t event);
|
||||
#endif
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT) */
|
||||
|
||||
#endif /* _RTW_CFGVENDOR_H_ */
|
3216
os_dep/linux/rtw_proc.c
Normal file
3216
os_dep/linux/rtw_proc.c
Normal file
File diff suppressed because it is too large
Load diff
65
os_dep/linux/rtw_proc.h
Normal file
65
os_dep/linux/rtw_proc.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __RTW_PROC_H__
|
||||
#define __RTW_PROC_H__
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#define RTW_PROC_HDL_TYPE_SEQ 0
|
||||
#define RTW_PROC_HDL_TYPE_SSEQ 1
|
||||
|
||||
struct rtw_proc_hdl {
|
||||
char *name;
|
||||
u8 type;
|
||||
union {
|
||||
int (*show)(struct seq_file *, void *);
|
||||
struct seq_operations *seq_op;
|
||||
} u;
|
||||
ssize_t (*write)(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data);
|
||||
};
|
||||
|
||||
#define RTW_PROC_HDL_SEQ(_name, _seq_op, _write) \
|
||||
{ .name = _name, .type = RTW_PROC_HDL_TYPE_SEQ, .u.seq_op = _seq_op, .write = _write}
|
||||
|
||||
#define RTW_PROC_HDL_SSEQ(_name, _show, _write) \
|
||||
{ .name = _name, .type = RTW_PROC_HDL_TYPE_SSEQ, .u.show = _show, .write = _write}
|
||||
|
||||
#ifdef CONFIG_PROC_DEBUG
|
||||
|
||||
struct proc_dir_entry *get_rtw_drv_proc(void);
|
||||
int rtw_drv_proc_init(void);
|
||||
void rtw_drv_proc_deinit(void);
|
||||
struct proc_dir_entry *rtw_adapter_proc_init(struct net_device *dev);
|
||||
void rtw_adapter_proc_deinit(struct net_device *dev);
|
||||
void rtw_adapter_proc_replace(struct net_device *dev);
|
||||
|
||||
#else /* !CONFIG_PROC_DEBUG */
|
||||
|
||||
#define get_rtw_drv_proc() NULL
|
||||
#define rtw_drv_proc_init() 0
|
||||
#define rtw_drv_proc_deinit() do {} while (0)
|
||||
#define rtw_adapter_proc_init(dev) NULL
|
||||
#define rtw_adapter_proc_deinit(dev) do {} while (0)
|
||||
#define rtw_adapter_proc_replace(dev) do {} while (0)
|
||||
|
||||
#endif /* !CONFIG_PROC_DEBUG */
|
||||
|
||||
#endif /* __RTW_PROC_H__ */
|
1641
os_dep/linux/usb_intf.c
Normal file
1641
os_dep/linux/usb_intf.c
Normal file
File diff suppressed because it is too large
Load diff
1105
os_dep/linux/usb_ops_linux.c
Normal file
1105
os_dep/linux/usb_ops_linux.c
Normal file
File diff suppressed because it is too large
Load diff
549
os_dep/linux/wifi_regd.c
Normal file
549
os_dep/linux/wifi_regd.c
Normal file
|
@ -0,0 +1,549 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009-2010 Realtek Corporation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#ifdef CONFIG_IOCTL_CFG80211
|
||||
|
||||
#include <rtw_wifi_regd.h>
|
||||
|
||||
static struct country_code_to_enum_rd allCountries[] = {
|
||||
{COUNTRY_CODE_USER, "RD"},
|
||||
};
|
||||
|
||||
/*
|
||||
* REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags)
|
||||
*/
|
||||
|
||||
/*
|
||||
*Only these channels all allow active
|
||||
*scan on all world regulatory domains
|
||||
*/
|
||||
|
||||
/* 2G chan 01 - chan 11 */
|
||||
#define RTW_2GHZ_CH01_11 \
|
||||
REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
|
||||
|
||||
/*
|
||||
*We enable active scan on these a case
|
||||
*by case basis by regulatory domain
|
||||
*/
|
||||
|
||||
/* 2G chan 12 - chan 13, PASSIV SCAN */
|
||||
#define RTW_2GHZ_CH12_13 \
|
||||
REG_RULE(2467-10, 2472+10, 40, 0, 20, \
|
||||
NL80211_RRF_PASSIVE_SCAN)
|
||||
|
||||
/* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */
|
||||
#define RTW_2GHZ_CH14 \
|
||||
REG_RULE(2484-10, 2484+10, 40, 0, 20, \
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
|
||||
|
||||
/* 5G chan 36 - chan 64 */
|
||||
#define RTW_5GHZ_5150_5350 \
|
||||
REG_RULE(5150-10, 5350+10, 40, 0, 30, \
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
|
||||
|
||||
/* 5G chan 100 - chan 165 */
|
||||
#define RTW_5GHZ_5470_5850 \
|
||||
REG_RULE(5470-10, 5850+10, 40, 0, 30, \
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
|
||||
|
||||
/* 5G chan 149 - chan 165 */
|
||||
#define RTW_5GHZ_5725_5850 \
|
||||
REG_RULE(5725-10, 5850+10, 40, 0, 30, \
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
|
||||
|
||||
/* 5G chan 36 - chan 165 */
|
||||
#define RTW_5GHZ_5150_5850 \
|
||||
REG_RULE(5150-10, 5850+10, 40, 0, 30, \
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
|
||||
|
||||
static const struct ieee80211_regdomain rtw_regdom_rd = {
|
||||
.n_reg_rules = 3,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTW_2GHZ_CH01_11,
|
||||
RTW_2GHZ_CH12_13,
|
||||
RTW_5GHZ_5150_5850,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtw_regdom_11 = {
|
||||
.n_reg_rules = 1,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTW_2GHZ_CH01_11,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtw_regdom_12_13 = {
|
||||
.n_reg_rules = 2,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTW_2GHZ_CH01_11,
|
||||
RTW_2GHZ_CH12_13,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtw_regdom_no_midband = {
|
||||
.n_reg_rules = 3,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTW_2GHZ_CH01_11,
|
||||
RTW_5GHZ_5150_5350,
|
||||
RTW_5GHZ_5725_5850,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtw_regdom_60_64 = {
|
||||
.n_reg_rules = 3,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTW_2GHZ_CH01_11,
|
||||
RTW_2GHZ_CH12_13,
|
||||
RTW_5GHZ_5725_5850,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtw_regdom_14_60_64 = {
|
||||
.n_reg_rules = 4,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTW_2GHZ_CH01_11,
|
||||
RTW_2GHZ_CH12_13,
|
||||
RTW_2GHZ_CH14,
|
||||
RTW_5GHZ_5725_5850,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain rtw_regdom_14 = {
|
||||
.n_reg_rules = 3,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
RTW_2GHZ_CH01_11,
|
||||
RTW_2GHZ_CH12_13,
|
||||
RTW_2GHZ_CH14,
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
static struct rtw_regulatory *rtw_regd;
|
||||
#endif
|
||||
|
||||
static bool _rtw_is_radar_freq(u16 center_freq)
|
||||
{
|
||||
return center_freq >= 5260 && center_freq <= 5700;
|
||||
}
|
||||
|
||||
#if 0 /* not_yet */
|
||||
static void _rtw_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
enum nl80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
u32 bandwidth = 0;
|
||||
int r;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (_rtw_is_radar_freq(ch->center_freq) ||
|
||||
(ch->flags & IEEE80211_CHAN_RADAR))
|
||||
continue;
|
||||
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
r = freq_reg_info(wiphy, ch->center_freq,
|
||||
bandwidth, ®_rule);
|
||||
if (r)
|
||||
continue;
|
||||
|
||||
/*
|
||||
*If 11d had a rule for this channel ensure
|
||||
*we enable adhoc/beaconing if it allows us to
|
||||
*use it. Note that we would have disabled it
|
||||
*by applying our static world regdomain by
|
||||
*default during init, prior to calling our
|
||||
*regulatory_hint().
|
||||
*/
|
||||
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
|
||||
if (!
|
||||
(reg_rule->flags &
|
||||
NL80211_RRF_PASSIVE_SCAN))
|
||||
ch->flags &=
|
||||
~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
} else {
|
||||
if (ch->beacon_found)
|
||||
ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Allows active scan scan on Ch 12 and 13 */
|
||||
static void _rtw_reg_apply_active_scan_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator
|
||||
initiator)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
u32 bandwidth = 0;
|
||||
int r;
|
||||
|
||||
if (!wiphy->bands[NL80211_BAND_2GHZ])
|
||||
return;
|
||||
sband = wiphy->bands[NL80211_BAND_2GHZ];
|
||||
|
||||
/*
|
||||
* If no country IE has been received always enable active scan
|
||||
* on these channels. This is only done for specific regulatory SKUs
|
||||
*/
|
||||
if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a country IE has been received check its rule for this
|
||||
* channel first before enabling active scan. The passive scan
|
||||
* would have been enforced by the initial processing of our
|
||||
* custom regulatory domain.
|
||||
*/
|
||||
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule);
|
||||
if (!r) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule);
|
||||
if (!r) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Always apply Radar/DFS rules on
|
||||
* freq range 5260 MHz - 5700 MHz
|
||||
*/
|
||||
static void _rtw_reg_apply_radar_flags(struct wiphy *wiphy)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
if (!wiphy->bands[NL80211_BAND_5GHZ])
|
||||
return;
|
||||
|
||||
sband = wiphy->bands[NL80211_BAND_5GHZ];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (!_rtw_is_radar_freq(ch->center_freq))
|
||||
continue;
|
||||
#ifdef CONFIG_DFS
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED)
|
||||
#if defined(CONFIG_DFS_MASTER)
|
||||
&& rtw_odm_dfs_domain_unknown(wiphy_to_adapter(wiphy))
|
||||
#endif
|
||||
) {
|
||||
ch->flags |= IEEE80211_CHAN_RADAR;
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
|
||||
ch->flags |= (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN);
|
||||
#else
|
||||
ch->flags |= IEEE80211_CHAN_NO_IR;
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_DFS */
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* We always enable radar detection/DFS on this
|
||||
* frequency range. Additionally we also apply on
|
||||
* this frequency range:
|
||||
* - If STA mode does not yet have DFS supports disable
|
||||
* active scanning
|
||||
* - If adhoc mode does not support DFS yet then disable
|
||||
* adhoc in the frequency.
|
||||
* - If AP mode does not yet support radar detection/DFS
|
||||
* do not allow AP mode
|
||||
*/
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch->flags |= IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtw_reg_apply_flags(struct wiphy *wiphy)
|
||||
{
|
||||
#if 1 /* by channel plan */
|
||||
_adapter *padapter = wiphy_to_adapter(wiphy);
|
||||
u8 channel_plan = padapter->mlmepriv.ChannelPlan;
|
||||
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
|
||||
RT_CHANNEL_INFO *channel_set = pmlmeext->channel_set;
|
||||
u8 max_chan_nums = pmlmeext->max_chan_nums;
|
||||
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i, j;
|
||||
u16 channel;
|
||||
u32 freq;
|
||||
|
||||
/* all channels disable */
|
||||
for (i = 0; i < NUM_NL80211_BANDS; i++) {
|
||||
sband = wiphy->bands[i];
|
||||
|
||||
if (sband) {
|
||||
for (j = 0; j < sband->n_channels; j++) {
|
||||
ch = &sband->channels[j];
|
||||
|
||||
if (ch)
|
||||
ch->flags = IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* channels apply by channel plans. */
|
||||
for (i = 0; i < max_chan_nums; i++) {
|
||||
channel = channel_set[i].ChannelNum;
|
||||
freq = rtw_ch2freq(channel);
|
||||
|
||||
ch = ieee80211_get_channel(wiphy, freq);
|
||||
if (ch) {
|
||||
if (channel_set[i].ScanType == SCAN_PASSIVE
|
||||
#if defined(CONFIG_DFS_MASTER)
|
||||
&& rtw_odm_dfs_domain_unknown(wiphy_to_adapter(wiphy))
|
||||
#endif
|
||||
) {
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
|
||||
ch->flags = (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN);
|
||||
#else
|
||||
ch->flags = IEEE80211_CHAN_NO_IR;
|
||||
#endif
|
||||
} else
|
||||
ch->flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i, j;
|
||||
u16 channels[37] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56,
|
||||
60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
|
||||
149, 153,
|
||||
157, 161, 165
|
||||
};
|
||||
u16 channel;
|
||||
u32 freq;
|
||||
|
||||
for (i = 0; i < NUM_NL80211_BANDS; i++) {
|
||||
sband = wiphy->bands[i];
|
||||
|
||||
if (sband)
|
||||
for (j = 0; j < sband->n_channels; j++) {
|
||||
ch = &sband->channels[j];
|
||||
|
||||
if (ch)
|
||||
ch->flags = IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 37; i++) {
|
||||
channel = channels[i];
|
||||
freq = rtw_ch2freq(channel);
|
||||
|
||||
ch = ieee80211_get_channel(wiphy, freq);
|
||||
if (ch) {
|
||||
if (channel <= 11)
|
||||
ch->flags = 0;
|
||||
else
|
||||
ch->flags = 0; /* IEEE80211_CHAN_PASSIVE_SCAN; */
|
||||
}
|
||||
/* printk("%s: freq %d(%d) flag 0x%02X\n", __func__, freq, channel, ch->flags); */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _rtw_reg_apply_world_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator,
|
||||
struct rtw_regulatory *reg)
|
||||
{
|
||||
/* _rtw_reg_apply_beaconing_flags(wiphy, initiator); */
|
||||
/* _rtw_reg_apply_active_scan_flags(wiphy, initiator); */
|
||||
return;
|
||||
}
|
||||
|
||||
static int _rtw_reg_notifier_apply(struct wiphy *wiphy,
|
||||
struct regulatory_request *request,
|
||||
struct rtw_regulatory *reg)
|
||||
{
|
||||
|
||||
/* Hard code flags */
|
||||
_rtw_reg_apply_flags(wiphy);
|
||||
|
||||
/* We always apply this */
|
||||
_rtw_reg_apply_radar_flags(wiphy);
|
||||
|
||||
switch (request->initiator) {
|
||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||
RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_DRIVER");
|
||||
_rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER,
|
||||
reg);
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_CORE:
|
||||
RTW_INFO("%s: %s\n", __func__,
|
||||
"NL80211_REGDOM_SET_BY_CORE to DRV");
|
||||
_rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER,
|
||||
reg);
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_USER:
|
||||
RTW_INFO("%s: %s\n", __func__,
|
||||
"NL80211_REGDOM_SET_BY_USER to DRV");
|
||||
_rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER,
|
||||
reg);
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||
RTW_INFO("%s: %s\n", __func__,
|
||||
"NL80211_REGDOM_SET_BY_COUNTRY_IE");
|
||||
_rtw_reg_apply_world_flags(wiphy, request->initiator, reg);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ieee80211_regdomain *_rtw_regdomain_select(struct
|
||||
rtw_regulatory
|
||||
*reg)
|
||||
{
|
||||
#if 0
|
||||
switch (reg->country_code) {
|
||||
case COUNTRY_CODE_USER:
|
||||
default:
|
||||
return &rtw_regdom_rd;
|
||||
}
|
||||
#else
|
||||
return &rtw_regdom_rd;
|
||||
#endif
|
||||
}
|
||||
|
||||
void _rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
{
|
||||
struct rtw_regulatory *reg = NULL;
|
||||
|
||||
RTW_INFO("%s\n", __func__);
|
||||
|
||||
_rtw_reg_notifier_apply(wiphy, request, reg);
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
|
||||
int rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
#else
|
||||
void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
#endif
|
||||
{
|
||||
_rtw_reg_notifier(wiphy, request);
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtw_reg_notify_by_driver(_adapter *adapter)
|
||||
{
|
||||
if ((adapter->rtw_wdev != NULL) && (adapter->rtw_wdev->wiphy)) {
|
||||
struct regulatory_request request;
|
||||
request.initiator = NL80211_REGDOM_SET_BY_DRIVER;
|
||||
rtw_reg_notifier(adapter->rtw_wdev->wiphy, &request);
|
||||
}
|
||||
}
|
||||
|
||||
static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy)
|
||||
{
|
||||
const struct ieee80211_regdomain *regd;
|
||||
|
||||
wiphy->reg_notifier = rtw_reg_notifier;
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
|
||||
wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
|
||||
wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
|
||||
#else
|
||||
wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
|
||||
wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
|
||||
wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
|
||||
#endif
|
||||
|
||||
regd = _rtw_regdomain_select(reg);
|
||||
wiphy_apply_custom_regulatory(wiphy, regd);
|
||||
|
||||
/* Hard code flags */
|
||||
_rtw_reg_apply_flags(wiphy);
|
||||
_rtw_reg_apply_radar_flags(wiphy);
|
||||
_rtw_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
|
||||
}
|
||||
|
||||
static struct country_code_to_enum_rd *_rtw_regd_find_country(u16 countrycode)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
|
||||
if (allCountries[i].countrycode == countrycode)
|
||||
return &allCountries[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rtw_regd_init(_adapter *padapter)
|
||||
{
|
||||
struct wiphy *wiphy = padapter->rtw_wdev->wiphy;
|
||||
|
||||
#if 0
|
||||
if (rtw_regd == NULL) {
|
||||
rtw_regd = (struct rtw_regulatory *)
|
||||
rtw_malloc(sizeof(struct rtw_regulatory));
|
||||
|
||||
rtw_regd->alpha2[0] = '9';
|
||||
rtw_regd->alpha2[1] = '9';
|
||||
|
||||
rtw_regd->country_code = COUNTRY_CODE_USER;
|
||||
}
|
||||
|
||||
RTW_INFO("%s: Country alpha2 being used: %c%c\n",
|
||||
__func__, rtw_regd->alpha2[0], rtw_regd->alpha2[1]);
|
||||
#endif
|
||||
|
||||
_rtw_regd_init_wiphy(NULL, wiphy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_IOCTL_CFG80211 */
|
535
os_dep/linux/xmit_linux.c
Normal file
535
os_dep/linux/xmit_linux.c
Normal file
|
@ -0,0 +1,535 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _XMIT_OSDEP_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#define DBG_DUMP_OS_QUEUE_CTL 0
|
||||
|
||||
uint rtw_remainder_len(struct pkt_file *pfile)
|
||||
{
|
||||
return pfile->buf_len - ((SIZE_PTR)(pfile->cur_addr) - (SIZE_PTR)(pfile->buf_start));
|
||||
}
|
||||
|
||||
void _rtw_open_pktfile(_pkt *pktptr, struct pkt_file *pfile)
|
||||
{
|
||||
|
||||
pfile->pkt = pktptr;
|
||||
pfile->cur_addr = pfile->buf_start = pktptr->data;
|
||||
pfile->pkt_len = pfile->buf_len = pktptr->len;
|
||||
|
||||
pfile->cur_buffer = pfile->buf_start ;
|
||||
|
||||
}
|
||||
|
||||
uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen)
|
||||
{
|
||||
uint len = 0;
|
||||
|
||||
|
||||
len = rtw_remainder_len(pfile);
|
||||
len = (rlen > len) ? len : rlen;
|
||||
|
||||
if (rmem)
|
||||
skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, len);
|
||||
|
||||
pfile->cur_addr += len;
|
||||
pfile->pkt_len -= len;
|
||||
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
sint rtw_endofpktfile(struct pkt_file *pfile)
|
||||
{
|
||||
|
||||
if (pfile->pkt_len == 0) {
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
|
||||
return _FALSE;
|
||||
}
|
||||
|
||||
void rtw_set_tx_chksum_offload(_pkt *pkt, struct pkt_attrib *pattrib)
|
||||
{
|
||||
|
||||
#ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
|
||||
struct sk_buff *skb = (struct sk_buff *)pkt;
|
||||
pattrib->hw_tcp_csum = 0;
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
||||
if (skb_shinfo(skb)->nr_frags == 0) {
|
||||
const struct iphdr *ip = ip_hdr(skb);
|
||||
if (ip->protocol == IPPROTO_TCP) {
|
||||
/* TCP checksum offload by HW */
|
||||
RTW_INFO("CHECKSUM_PARTIAL TCP\n");
|
||||
pattrib->hw_tcp_csum = 1;
|
||||
/* skb_checksum_help(skb); */
|
||||
} else if (ip->protocol == IPPROTO_UDP) {
|
||||
/* RTW_INFO("CHECKSUM_PARTIAL UDP\n"); */
|
||||
#if 1
|
||||
skb_checksum_help(skb);
|
||||
#else
|
||||
/* Set UDP checksum = 0 to skip checksum check */
|
||||
struct udphdr *udp = skb_transport_header(skb);
|
||||
udp->check = 0;
|
||||
#endif
|
||||
} else {
|
||||
RTW_INFO("%s-%d TCP CSUM offload Error!!\n", __FUNCTION__, __LINE__);
|
||||
WARN_ON(1); /* we need a WARN() */
|
||||
}
|
||||
} else { /* IP fragmentation case */
|
||||
RTW_INFO("%s-%d nr_frags != 0, using skb_checksum_help(skb);!!\n", __FUNCTION__, __LINE__);
|
||||
skb_checksum_help(skb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int rtw_os_xmit_resource_alloc(_adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz, u8 flag)
|
||||
{
|
||||
if (alloc_sz > 0) {
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
pxmitbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)alloc_sz, &pxmitbuf->dma_transfer_addr);
|
||||
pxmitbuf->pbuf = pxmitbuf->pallocated_buf;
|
||||
if (pxmitbuf->pallocated_buf == NULL)
|
||||
return _FAIL;
|
||||
#else /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
|
||||
|
||||
pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz);
|
||||
if (pxmitbuf->pallocated_buf == NULL)
|
||||
return _FAIL;
|
||||
|
||||
pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
|
||||
|
||||
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
#ifdef CONFIG_USB_HCI
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (pxmitbuf->pxmit_urb[i] == NULL) {
|
||||
RTW_INFO("pxmitbuf->pxmit_urb[i]==NULL");
|
||||
return _FAIL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
void rtw_os_xmit_resource_free(_adapter *padapter, struct xmit_buf *pxmitbuf, u32 free_sz, u8 flag)
|
||||
{
|
||||
if (flag) {
|
||||
#ifdef CONFIG_USB_HCI
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (pxmitbuf->pxmit_urb[i]) {
|
||||
/* usb_kill_urb(pxmitbuf->pxmit_urb[i]); */
|
||||
usb_free_urb(pxmitbuf->pxmit_urb[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (free_sz > 0) {
|
||||
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
rtw_usb_buffer_free(pusbd, (size_t)free_sz, pxmitbuf->pallocated_buf, pxmitbuf->dma_transfer_addr);
|
||||
pxmitbuf->pallocated_buf = NULL;
|
||||
pxmitbuf->dma_transfer_addr = 0;
|
||||
#else /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
|
||||
if (pxmitbuf->pallocated_buf)
|
||||
rtw_mfree(pxmitbuf->pallocated_buf, free_sz);
|
||||
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
|
||||
}
|
||||
}
|
||||
|
||||
void dump_os_queue(void *sel, _adapter *padapter)
|
||||
{
|
||||
struct net_device *ndev = padapter->pnetdev;
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
RTW_PRINT_SEL(sel, "os_queue[%d]:%s\n"
|
||||
, i, __netif_subqueue_stopped(ndev, i) ? "stopped" : "waked");
|
||||
}
|
||||
#else
|
||||
RTW_PRINT_SEL(sel, "os_queue:%s\n"
|
||||
, netif_queue_stopped(ndev) ? "stopped" : "waked");
|
||||
#endif
|
||||
}
|
||||
|
||||
#define WMM_XMIT_THRESHOLD (NR_XMITFRAME*2/5)
|
||||
|
||||
static inline bool rtw_os_need_wake_queue(_adapter *padapter, u16 qidx)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
if (padapter->registrypriv.wifi_spec) {
|
||||
if (pxmitpriv->hwxmits[qidx].accnt < WMM_XMIT_THRESHOLD)
|
||||
return _TRUE;
|
||||
} else {
|
||||
#ifdef CONFIG_MCC_MODE
|
||||
if (MCC_EN(padapter)) {
|
||||
if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)
|
||||
&& MCC_STOP(padapter))
|
||||
return _FALSE;
|
||||
}
|
||||
#endif /* CONFIG_MCC_MODE */
|
||||
return _TRUE;
|
||||
}
|
||||
return _FALSE;
|
||||
#else
|
||||
#ifdef CONFIG_MCC_MODE
|
||||
if (MCC_EN(padapter)) {
|
||||
if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)
|
||||
&& MCC_STOP(padapter))
|
||||
return _FALSE;
|
||||
}
|
||||
#endif /* CONFIG_MCC_MODE */
|
||||
return _TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool rtw_os_need_stop_queue(_adapter *padapter, u16 qidx)
|
||||
{
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
if (padapter->registrypriv.wifi_spec) {
|
||||
/* No free space for Tx, tx_worker is too slow */
|
||||
if (pxmitpriv->hwxmits[qidx].accnt > WMM_XMIT_THRESHOLD)
|
||||
return _TRUE;
|
||||
} else {
|
||||
if (pxmitpriv->free_xmitframe_cnt <= 4)
|
||||
return _TRUE;
|
||||
}
|
||||
#else
|
||||
if (pxmitpriv->free_xmitframe_cnt <= 4)
|
||||
return _TRUE;
|
||||
#endif
|
||||
return _FALSE;
|
||||
}
|
||||
|
||||
void rtw_os_pkt_complete(_adapter *padapter, _pkt *pkt)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
u16 qidx;
|
||||
|
||||
qidx = skb_get_queue_mapping(pkt);
|
||||
if (rtw_os_need_wake_queue(padapter, qidx)) {
|
||||
if (DBG_DUMP_OS_QUEUE_CTL)
|
||||
RTW_INFO(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx);
|
||||
netif_wake_subqueue(padapter->pnetdev, qidx);
|
||||
}
|
||||
#else
|
||||
if (rtw_os_need_wake_queue(padapter, 0)) {
|
||||
if (DBG_DUMP_OS_QUEUE_CTL)
|
||||
RTW_INFO(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(padapter));
|
||||
netif_wake_queue(padapter->pnetdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
rtw_skb_free(pkt);
|
||||
}
|
||||
|
||||
void rtw_os_xmit_complete(_adapter *padapter, struct xmit_frame *pxframe)
|
||||
{
|
||||
if (pxframe->pkt)
|
||||
rtw_os_pkt_complete(padapter, pxframe->pkt);
|
||||
|
||||
pxframe->pkt = NULL;
|
||||
}
|
||||
|
||||
void rtw_os_xmit_schedule(_adapter *padapter)
|
||||
{
|
||||
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
|
||||
_adapter *pri_adapter = GET_PRIMARY_ADAPTER(padapter);
|
||||
|
||||
if (!padapter)
|
||||
return;
|
||||
|
||||
if (_rtw_queue_empty(&padapter->xmitpriv.pending_xmitbuf_queue) == _FALSE)
|
||||
_rtw_up_sema(&pri_adapter->xmitpriv.xmit_sema);
|
||||
|
||||
|
||||
#else
|
||||
_irqL irqL;
|
||||
struct xmit_priv *pxmitpriv;
|
||||
|
||||
if (!padapter)
|
||||
return;
|
||||
|
||||
pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
_enter_critical_bh(&pxmitpriv->lock, &irqL);
|
||||
|
||||
if (rtw_txframes_pending(padapter))
|
||||
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
|
||||
|
||||
_exit_critical_bh(&pxmitpriv->lock, &irqL);
|
||||
|
||||
#if defined(CONFIG_PCI_HCI) && defined(CONFIG_XMIT_THREAD_MODE)
|
||||
if (_rtw_queue_empty(&padapter->xmitpriv.pending_xmitbuf_queue) == _FALSE)
|
||||
_rtw_up_sema(&padapter->xmitpriv.xmit_sema);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool rtw_check_xmit_resource(_adapter *padapter, _pkt *pkt)
|
||||
{
|
||||
bool busy = _FALSE;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
u16 qidx;
|
||||
|
||||
qidx = skb_get_queue_mapping(pkt);
|
||||
if (rtw_os_need_stop_queue(padapter, qidx)) {
|
||||
if (DBG_DUMP_OS_QUEUE_CTL)
|
||||
RTW_INFO(FUNC_ADPT_FMT": netif_stop_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), qidx);
|
||||
netif_stop_subqueue(padapter->pnetdev, qidx);
|
||||
busy = _TRUE;
|
||||
}
|
||||
#else
|
||||
if (rtw_os_need_stop_queue(padapter, 0)) {
|
||||
if (DBG_DUMP_OS_QUEUE_CTL)
|
||||
RTW_INFO(FUNC_ADPT_FMT": netif_stop_queue\n", FUNC_ADPT_ARG(padapter));
|
||||
rtw_netif_stop_queue(padapter->pnetdev);
|
||||
busy = _TRUE;
|
||||
}
|
||||
#endif
|
||||
return busy;
|
||||
}
|
||||
|
||||
void rtw_os_wake_queue_at_free_stainfo(_adapter *padapter, int *qcnt_freed)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (qcnt_freed[i] == 0)
|
||||
continue;
|
||||
|
||||
if (rtw_os_need_wake_queue(padapter, i)) {
|
||||
if (DBG_DUMP_OS_QUEUE_CTL)
|
||||
RTW_INFO(FUNC_ADPT_FMT": netif_wake_subqueue[%d]\n", FUNC_ADPT_ARG(padapter), i);
|
||||
netif_wake_subqueue(padapter->pnetdev, i);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (qcnt_freed[0] || qcnt_freed[1] || qcnt_freed[2] || qcnt_freed[3]) {
|
||||
if (rtw_os_need_wake_queue(padapter, 0)) {
|
||||
if (DBG_DUMP_OS_QUEUE_CTL)
|
||||
RTW_INFO(FUNC_ADPT_FMT": netif_wake_queue\n", FUNC_ADPT_ARG(padapter));
|
||||
netif_wake_queue(padapter->pnetdev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TX_MCAST2UNI
|
||||
int rtw_mlcst2unicst(_adapter *padapter, struct sk_buff *skb)
|
||||
{
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
_irqL irqL;
|
||||
_list *phead, *plist;
|
||||
struct sk_buff *newskb;
|
||||
struct sta_info *psta = NULL;
|
||||
u8 chk_alive_num = 0;
|
||||
char chk_alive_list[NUM_STA];
|
||||
u8 bc_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
u8 null_addr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
int i;
|
||||
s32 res;
|
||||
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_m2u);
|
||||
|
||||
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
|
||||
phead = &pstapriv->asoc_list;
|
||||
plist = get_next(phead);
|
||||
|
||||
/* free sta asoc_queue */
|
||||
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
|
||||
int stainfo_offset;
|
||||
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
|
||||
plist = get_next(plist);
|
||||
|
||||
stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
|
||||
if (stainfo_offset_valid(stainfo_offset))
|
||||
chk_alive_list[chk_alive_num++] = stainfo_offset;
|
||||
}
|
||||
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
|
||||
|
||||
for (i = 0; i < chk_alive_num; i++) {
|
||||
psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
|
||||
if (!(psta->state & _FW_LINKED)) {
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_fw_linked);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* avoid come from STA1 and send back STA1 */
|
||||
if (_rtw_memcmp(psta->hwaddr, &skb->data[6], 6) == _TRUE
|
||||
|| _rtw_memcmp(psta->hwaddr, null_addr, 6) == _TRUE
|
||||
|| _rtw_memcmp(psta->hwaddr, bc_addr, 6) == _TRUE
|
||||
) {
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_m2u_ignore_self);
|
||||
continue;
|
||||
}
|
||||
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry);
|
||||
|
||||
newskb = rtw_skb_copy(skb);
|
||||
|
||||
if (newskb) {
|
||||
_rtw_memcpy(newskb->data, psta->hwaddr, 6);
|
||||
res = rtw_xmit(padapter, &newskb);
|
||||
if (res < 0) {
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_xmit);
|
||||
RTW_INFO("%s()-%d: rtw_xmit() return error! res=%d\n", __FUNCTION__, __LINE__, res);
|
||||
pxmitpriv->tx_drop++;
|
||||
rtw_skb_free(newskb);
|
||||
}
|
||||
} else {
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_m2u_entry_err_skb);
|
||||
RTW_INFO("%s-%d: rtw_skb_copy() failed!\n", __FUNCTION__, __LINE__);
|
||||
pxmitpriv->tx_drop++;
|
||||
/* rtw_skb_free(skb); */
|
||||
return _FALSE; /* Caller shall tx this multicast frame via normal way. */
|
||||
}
|
||||
}
|
||||
|
||||
rtw_skb_free(skb);
|
||||
return _TRUE;
|
||||
}
|
||||
#endif /* CONFIG_TX_MCAST2UNI */
|
||||
|
||||
|
||||
int _rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
#ifdef CONFIG_TX_MCAST2UNI
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
extern int rtw_mc2u_disable;
|
||||
#endif /* CONFIG_TX_MCAST2UNI */
|
||||
s32 res = 0;
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
u16 queue;
|
||||
#endif
|
||||
|
||||
|
||||
if (padapter->registrypriv.mp_mode) {
|
||||
RTW_INFO("MP_TX_DROP_OS_FRAME\n");
|
||||
goto drop_packet;
|
||||
}
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx);
|
||||
|
||||
if (rtw_if_up(padapter) == _FALSE) {
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_err_up);
|
||||
#ifdef DBG_TX_DROP_FRAME
|
||||
RTW_INFO("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__);
|
||||
#endif
|
||||
goto drop_packet;
|
||||
}
|
||||
|
||||
rtw_check_xmit_resource(padapter, pkt);
|
||||
|
||||
#ifdef CONFIG_TX_MCAST2UNI
|
||||
if (!rtw_mc2u_disable
|
||||
&& check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE
|
||||
&& (IP_MCAST_MAC(pkt->data)
|
||||
|| ICMPV6_MCAST_MAC(pkt->data)
|
||||
#ifdef CONFIG_TX_BCAST2UNI
|
||||
|| is_broadcast_mac_addr(pkt->data)
|
||||
#endif
|
||||
)
|
||||
&& (padapter->registrypriv.wifi_spec == 0)
|
||||
) {
|
||||
if (pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME / 4)) {
|
||||
res = rtw_mlcst2unicst(padapter, pkt);
|
||||
if (res == _TRUE)
|
||||
goto exit;
|
||||
} else {
|
||||
/* RTW_INFO("Stop M2U(%d, %d)! ", pxmitpriv->free_xmitframe_cnt, pxmitpriv->free_xmitbuf_cnt); */
|
||||
/* RTW_INFO("!m2u ); */
|
||||
DBG_COUNTER(padapter->tx_logs.os_tx_m2u_stop);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_TX_MCAST2UNI */
|
||||
|
||||
res = rtw_xmit(padapter, &pkt);
|
||||
if (res < 0) {
|
||||
#ifdef DBG_TX_DROP_FRAME
|
||||
RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__);
|
||||
#endif
|
||||
goto drop_packet;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
||||
drop_packet:
|
||||
pxmitpriv->tx_drop++;
|
||||
rtw_os_pkt_complete(padapter, pkt);
|
||||
|
||||
exit:
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw_xmit_entry(_pkt *pkt, _nic_hdl pnetdev)
|
||||
{
|
||||
_adapter *padapter = (_adapter *)rtw_netdev_priv(pnetdev);
|
||||
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
|
||||
int ret = 0;
|
||||
|
||||
if (pkt) {
|
||||
if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
|
||||
rtw_monitor_xmit_entry((struct sk_buff *)pkt, pnetdev);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, pkt->truesize);
|
||||
ret = _rtw_xmit_entry(pkt, pnetdev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,513 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#define _MLME_OSDEP_C_
|
||||
|
||||
#include <drv_conf.h>
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
#include <mlme_osdep.h>
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
void rtw_join_timeout_handler (void *FunctionContext)
|
||||
#else
|
||||
void rtw_join_timeout_handler(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct adapter *adapter = (struct adapter *)FunctionContext;
|
||||
#else
|
||||
struct adapter *adapter = from_timer(adapter, t, mlmepriv.assoc_timer);
|
||||
#endif
|
||||
_rtw_join_timeout_handler(adapter);
|
||||
}
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
void _rtw_scan_timeout_handler (void *FunctionContext)
|
||||
#else
|
||||
void _rtw_scan_timeout_handler(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct adapter *adapter = (struct adapter *)FunctionContext;
|
||||
#else
|
||||
struct adapter *adapter = from_timer(adapter, t, mlmepriv.scan_to_timer);
|
||||
#endif
|
||||
rtw_scan_timeout_handler(adapter);
|
||||
}
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
static void _dynamic_check_timer_handlder (void *FunctionContext)
|
||||
#else
|
||||
static void _dynamic_check_timer_handlder(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct adapter *adapter = (struct adapter *)FunctionContext;
|
||||
#else
|
||||
struct adapter *adapter = from_timer(adapter, t, mlmepriv.dynamic_chk_timer);
|
||||
#endif
|
||||
rtw_dynamic_check_timer_handlder(adapter);
|
||||
|
||||
_set_timer(&adapter->mlmepriv.dynamic_chk_timer, 2000);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
static void _rtw_set_scan_deny_timer_hdl(void *FunctionContext)
|
||||
#else
|
||||
static void _rtw_set_scan_deny_timer_hdl(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct adapter *adapter = (struct adapter *)FunctionContext;
|
||||
#else
|
||||
struct adapter *adapter = from_timer(adapter, t, mlmepriv.set_scan_deny_timer);
|
||||
#endif
|
||||
rtw_set_scan_deny_timer_hdl(adapter);
|
||||
}
|
||||
|
||||
void rtw_init_mlme_timer(struct adapter *padapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
_init_timer(&pmlmepriv->assoc_timer, padapter->pnetdev, rtw_join_timeout_handler, padapter);
|
||||
_init_timer(&pmlmepriv->scan_to_timer, padapter->pnetdev, _rtw_scan_timeout_handler, padapter);
|
||||
|
||||
_init_timer(&pmlmepriv->dynamic_chk_timer, padapter->pnetdev, _dynamic_check_timer_handlder, padapter);
|
||||
|
||||
_init_timer(&pmlmepriv->set_scan_deny_timer, padapter->pnetdev, _rtw_set_scan_deny_timer_hdl, padapter);
|
||||
#else
|
||||
timer_setup(&pmlmepriv->assoc_timer, rtw_join_timeout_handler, 0);
|
||||
timer_setup(&pmlmepriv->scan_to_timer, _rtw_scan_timeout_handler, 0);
|
||||
timer_setup(&pmlmepriv->dynamic_chk_timer, _dynamic_check_timer_handlder, 0);
|
||||
timer_setup(&pmlmepriv->set_scan_deny_timer, _rtw_set_scan_deny_timer_hdl, 0);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
|
||||
if (padapter->HalFunc.hal_init_checkbthang_workqueue)
|
||||
padapter->HalFunc.hal_init_checkbthang_workqueue(padapter);
|
||||
#endif
|
||||
}
|
||||
|
||||
void rtw_os_indicate_connect(struct adapter *adapter)
|
||||
{
|
||||
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
|
||||
;
|
||||
|
||||
if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) ||
|
||||
(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)))
|
||||
rtw_cfg80211_ibss_indicate_connect(adapter);
|
||||
else
|
||||
rtw_cfg80211_indicate_connect(adapter);
|
||||
|
||||
rtw_indicate_wx_assoc_event(adapter);
|
||||
netif_carrier_on(adapter->pnetdev);
|
||||
|
||||
if (adapter->pid[2] !=0)
|
||||
rtw_signal_process(adapter->pid[2], SIGALRM);
|
||||
}
|
||||
|
||||
void rtw_os_indicate_scan_done( struct adapter *padapter, bool aborted)
|
||||
{
|
||||
rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), aborted);
|
||||
indicate_wx_scan_complete_event(padapter);
|
||||
}
|
||||
|
||||
static RT_PMKID_LIST backupPMKIDList[ NUM_PMKID_CACHE ];
|
||||
void rtw_reset_securitypriv( struct adapter *adapter )
|
||||
{
|
||||
u8 backupPMKIDIndex = 0;
|
||||
u8 backupTKIPCountermeasure = 0x00;
|
||||
u32 backupTKIPcountermeasure_time = 0;
|
||||
/* add for CONFIG_IEEE80211W, none 11w also can use */
|
||||
unsigned long irqL;
|
||||
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
|
||||
|
||||
spin_lock_bh(&adapter->security_key_mutex);
|
||||
|
||||
if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)/* 802.1x */
|
||||
{
|
||||
/* Added by Albert 2009/02/18 */
|
||||
/* We have to backup the PMK information for WiFi PMK Caching test item. */
|
||||
/* */
|
||||
/* Backup the btkip_countermeasure information. */
|
||||
/* When the countermeasure is trigger, the driver have to disconnect with AP for 60 seconds. */
|
||||
|
||||
memset( &backupPMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
|
||||
|
||||
memcpy( &backupPMKIDList[ 0 ], &adapter->securitypriv.PMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
|
||||
backupPMKIDIndex = adapter->securitypriv.PMKIDIndex;
|
||||
backupTKIPCountermeasure = adapter->securitypriv.btkip_countermeasure;
|
||||
backupTKIPcountermeasure_time = adapter->securitypriv.btkip_countermeasure_time;
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
/* reset RX BIP packet number */
|
||||
pmlmeext->mgnt_80211w_IPN_rx = 0;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
memset((unsigned char *)&adapter->securitypriv, 0, sizeof (struct security_priv));
|
||||
|
||||
/* Added by Albert 2009/02/18 */
|
||||
/* Restore the PMK information to securitypriv structure for the following connection. */
|
||||
memcpy( &adapter->securitypriv.PMKIDList[ 0 ], &backupPMKIDList[ 0 ], sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
|
||||
adapter->securitypriv.PMKIDIndex = backupPMKIDIndex;
|
||||
adapter->securitypriv.btkip_countermeasure = backupTKIPCountermeasure;
|
||||
adapter->securitypriv.btkip_countermeasure_time = backupTKIPcountermeasure_time;
|
||||
|
||||
adapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
|
||||
adapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
|
||||
|
||||
}
|
||||
else /* reset values in securitypriv */
|
||||
{
|
||||
/* if (adapter->mlmepriv.fw_state & WIFI_STATION_STATE) */
|
||||
/* */
|
||||
struct security_priv *psec_priv=&adapter->securitypriv;
|
||||
|
||||
psec_priv->dot11AuthAlgrthm =dot11AuthAlgrthm_Open; /* open system */
|
||||
psec_priv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
|
||||
psec_priv->dot11PrivacyKeyIndex = 0;
|
||||
|
||||
psec_priv->dot118021XGrpPrivacy = _NO_PRIVACY_;
|
||||
psec_priv->dot118021XGrpKeyid = 1;
|
||||
|
||||
psec_priv->ndisauthtype = Ndis802_11AuthModeOpen;
|
||||
psec_priv->ndisencryptstatus = Ndis802_11WEPDisabled;
|
||||
/* */
|
||||
}
|
||||
/* add for CONFIG_IEEE80211W, none 11w also can use */
|
||||
spin_unlock_bh(&adapter->security_key_mutex);
|
||||
}
|
||||
|
||||
void rtw_os_indicate_disconnect( struct adapter *adapter )
|
||||
{
|
||||
netif_carrier_off(adapter->pnetdev); /* Do it first for tx broadcast pkt after disconnection issue! */
|
||||
|
||||
rtw_cfg80211_indicate_disconnect(adapter);
|
||||
|
||||
rtw_indicate_wx_disassoc_event(adapter);
|
||||
|
||||
/* modify for CONFIG_IEEE80211W, none 11w also can use the same command */
|
||||
rtw_reset_securitypriv_cmd(adapter);
|
||||
}
|
||||
|
||||
void rtw_report_sec_ie(struct adapter *adapter,u8 authmode,u8 *sec_ie)
|
||||
{
|
||||
uint len;
|
||||
u8 *buff,*p,i;
|
||||
union iwreq_data wrqu;
|
||||
|
||||
RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("+rtw_report_sec_ie, authmode=%d\n", authmode));
|
||||
|
||||
buff = NULL;
|
||||
if (authmode==_WPA_IE_ID_) {
|
||||
RT_TRACE(_module_mlme_osdep_c_,_drv_info_,("rtw_report_sec_ie, authmode=%d\n", authmode));
|
||||
|
||||
buff = rtw_malloc(IW_CUSTOM_MAX);
|
||||
|
||||
memset(buff,0,IW_CUSTOM_MAX);
|
||||
|
||||
p=buff;
|
||||
|
||||
p+=sprintf(p,"ASSOCINFO(ReqIEs=");
|
||||
|
||||
len = sec_ie[1]+2;
|
||||
len = (len < IW_CUSTOM_MAX) ? len:IW_CUSTOM_MAX;
|
||||
|
||||
for (i=0;i<len;i++) {
|
||||
p+=sprintf(p,"%02x",sec_ie[i]);
|
||||
}
|
||||
|
||||
p+=sprintf(p,")");
|
||||
|
||||
memset(&wrqu,0,sizeof(wrqu));
|
||||
|
||||
wrqu.data.length=p-buff;
|
||||
|
||||
wrqu.data.length = (wrqu.data.length<IW_CUSTOM_MAX) ? wrqu.data.length:IW_CUSTOM_MAX;
|
||||
|
||||
if (buff)
|
||||
rtw_mfree(buff, IW_CUSTOM_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
static void _survey_timer_hdl (void *FunctionContext)
|
||||
#else
|
||||
static void _survey_timer_hdl(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct adapter *padapter = (struct adapter *)FunctionContext;
|
||||
#else
|
||||
struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.survey_timer);
|
||||
#endif
|
||||
|
||||
survey_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
static void _link_timer_hdl (void *FunctionContext)
|
||||
#else
|
||||
static void _link_timer_hdl(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct adapter *padapter = (struct adapter *)FunctionContext;
|
||||
#else
|
||||
struct adapter *padapter = from_timer(padapter, t, mlmeextpriv.link_timer);
|
||||
#endif
|
||||
link_timer_hdl(padapter);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
static void _addba_timer_hdl(void *FunctionContext)
|
||||
#else
|
||||
static void _addba_timer_hdl(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct sta_info *psta = (struct sta_info *)FunctionContext;
|
||||
#else
|
||||
struct sta_info *psta = from_timer(psta, t, addba_retry_timer);
|
||||
#endif
|
||||
addba_timer_hdl(psta);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
void _sa_query_timer_hdl (void *FunctionContext)
|
||||
{
|
||||
struct adapter *padapter = (struct adapter *)FunctionContext;
|
||||
sa_query_timer_hdl(padapter);
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
|
||||
void init_addba_retry_timer(struct adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
_init_timer(&psta->addba_retry_timer, padapter->pnetdev, _addba_timer_hdl, psta);
|
||||
#else
|
||||
timer_setup(&psta->addba_retry_timer, _addba_timer_hdl, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_mlme_ext_timer(struct adapter *padapter)
|
||||
{
|
||||
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
_init_timer(&pmlmeext->survey_timer, padapter->pnetdev, _survey_timer_hdl, padapter);
|
||||
_init_timer(&pmlmeext->link_timer, padapter->pnetdev, _link_timer_hdl, padapter);
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
_init_timer(&pmlmeext->sa_query_timer, padapter->pnetdev, _sa_query_timer_hdl, padapter);
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#else
|
||||
timer_setup(&pmlmeext->survey_timer, _survey_timer_hdl, 0);
|
||||
timer_setup(&pmlmeext->link_timer, _link_timer_hdl, 0);
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
timer_setup(&pmlmeext->sa_query_timer, _sa_query_timer_hdl, 0);
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AP_MODE
|
||||
|
||||
void rtw_indicate_sta_assoc_event(struct adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
union iwreq_data wrqu;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
|
||||
if (psta== NULL)
|
||||
return;
|
||||
|
||||
if (psta->aid > NUM_STA)
|
||||
return;
|
||||
|
||||
if (pstapriv->sta_aid[psta->aid - 1] != psta)
|
||||
return;
|
||||
|
||||
|
||||
wrqu.addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
|
||||
|
||||
DBG_88E("+rtw_indicate_sta_assoc_event\n");
|
||||
}
|
||||
|
||||
void rtw_indicate_sta_disassoc_event(struct adapter *padapter, struct sta_info *psta)
|
||||
{
|
||||
union iwreq_data wrqu;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
|
||||
if (psta== NULL)
|
||||
return;
|
||||
|
||||
if (psta->aid > NUM_STA)
|
||||
return;
|
||||
|
||||
if (pstapriv->sta_aid[psta->aid - 1] != psta)
|
||||
return;
|
||||
|
||||
|
||||
wrqu.addr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
memcpy(wrqu.addr.sa_data, psta->hwaddr, ETH_ALEN);
|
||||
|
||||
DBG_88E("+rtw_indicate_sta_disassoc_event\n");
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOSTAPD_MLME
|
||||
|
||||
static int mgnt_xmit_entry(struct sk_buff *skb, struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
struct adapter *padapter = (struct adapter *)phostapdpriv->padapter;
|
||||
|
||||
/* DBG_88E("%s\n", __FUNCTION__); */
|
||||
|
||||
return rtw_hal_hostap_mgnt_xmit_entry(padapter, skb);
|
||||
}
|
||||
|
||||
static int mgnt_netdev_open(struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
|
||||
DBG_88E("mgnt_netdev_open: MAC Address:" MAC_FMT "\n", MAC_ARG(pnetdev->dev_addr));
|
||||
|
||||
|
||||
init_usb_anchor(&phostapdpriv->anchored);
|
||||
|
||||
if (!rtw_netif_queue_stopped(pnetdev))
|
||||
rtw_netif_start_queue(pnetdev);
|
||||
else
|
||||
rtw_netif_wake_queue(pnetdev);
|
||||
|
||||
netif_carrier_on(pnetdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int mgnt_netdev_close(struct net_device *pnetdev)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
|
||||
DBG_88E("%s\n", __FUNCTION__);
|
||||
|
||||
usb_kill_anchored_urbs(&phostapdpriv->anchored);
|
||||
|
||||
netif_carrier_off(pnetdev);
|
||||
|
||||
if (!rtw_netif_queue_stopped(pnetdev))
|
||||
rtw_netif_stop_queue(pnetdev);
|
||||
|
||||
/* rtw_write16(phostapdpriv->padapter, 0x0116, 0x3f3f); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
|
||||
static const struct net_device_ops rtl871x_mgnt_netdev_ops = {
|
||||
.ndo_open = mgnt_netdev_open,
|
||||
.ndo_stop = mgnt_netdev_close,
|
||||
.ndo_start_xmit = mgnt_xmit_entry,
|
||||
/* ndo_set_mac_address = r871x_net_set_mac_address, */
|
||||
/* ndo_get_stats = r871x_net_get_stats, */
|
||||
/* ndo_do_ioctl = r871x_mp_ioctl, */
|
||||
};
|
||||
#endif
|
||||
|
||||
int hostapd_mode_init(struct adapter *padapter)
|
||||
{
|
||||
unsigned char mac[ETH_ALEN];
|
||||
struct hostapd_priv *phostapdpriv;
|
||||
struct net_device *pnetdev;
|
||||
|
||||
pnetdev = rtw_alloc_etherdev(sizeof(struct hostapd_priv));
|
||||
if (!pnetdev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* SET_MODULE_OWNER(pnetdev); */
|
||||
ether_setup(pnetdev);
|
||||
|
||||
/* pnetdev->type = ARPHRD_IEEE80211; */
|
||||
|
||||
phostapdpriv = rtw_netdev_priv(pnetdev);
|
||||
phostapdpriv->pmgnt_netdev = pnetdev;
|
||||
phostapdpriv->padapter= padapter;
|
||||
padapter->phostapdpriv = phostapdpriv;
|
||||
|
||||
/* pnetdev->init = NULL; */
|
||||
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
|
||||
|
||||
DBG_88E("register rtl871x_mgnt_netdev_ops to netdev_ops\n");
|
||||
|
||||
pnetdev->netdev_ops = &rtl871x_mgnt_netdev_ops;
|
||||
|
||||
#else
|
||||
|
||||
pnetdev->open = mgnt_netdev_open;
|
||||
|
||||
pnetdev->stop = mgnt_netdev_close;
|
||||
|
||||
pnetdev->hard_start_xmit = mgnt_xmit_entry;
|
||||
#endif
|
||||
|
||||
pnetdev->watchdog_timeo = HZ; /* 1 second timeout */
|
||||
|
||||
if (dev_alloc_name(pnetdev,"mgnt.wlan%d") < 0)
|
||||
DBG_88E("hostapd_mode_init(): dev_alloc_name, fail!\n");
|
||||
|
||||
mac[0]=0x00;
|
||||
mac[1]=0xe0;
|
||||
mac[2]=0x4c;
|
||||
mac[3]=0x87;
|
||||
mac[4]=0x11;
|
||||
mac[5]=0x12;
|
||||
|
||||
memcpy(pnetdev->dev_addr, mac, ETH_ALEN);
|
||||
|
||||
|
||||
netif_carrier_off(pnetdev);
|
||||
|
||||
|
||||
/* Tell the network stack we exist */
|
||||
if (register_netdev(pnetdev) != 0) {
|
||||
DBG_88E("hostapd_mode_init(): register_netdev fail!\n");
|
||||
if (pnetdev)
|
||||
rtw_free_netdev(pnetdev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hostapd_mode_unload(struct adapter *padapter)
|
||||
{
|
||||
struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
|
||||
struct net_device *pnetdev = phostapdpriv->pmgnt_netdev;
|
||||
|
||||
unregister_netdev(pnetdev);
|
||||
rtw_free_netdev(pnetdev);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
1746
os_dep/os_intfs.c
1746
os_dep/os_intfs.c
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,424 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _RECV_OSDEP_C_
|
||||
|
||||
#include <drv_conf.h>
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
|
||||
#include <wifi.h>
|
||||
#include <recv_osdep.h>
|
||||
|
||||
#include <osdep_intf.h>
|
||||
#include <ethernet.h>
|
||||
#include <usb_ops.h>
|
||||
|
||||
/* init os related resource in struct recv_priv */
|
||||
int rtw_os_recv_resource_init(struct recv_priv *precvpriv, struct adapter *padapter)
|
||||
{
|
||||
int res=_SUCCESS;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* alloc os related resource in union recv_frame */
|
||||
int rtw_os_recv_resource_alloc(struct adapter *padapter, union recv_frame *precvframe)
|
||||
{
|
||||
int res=_SUCCESS;
|
||||
|
||||
precvframe->u.hdr.pkt_newalloc = precvframe->u.hdr.pkt = NULL;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
/* free os related resource in union recv_frame */
|
||||
void rtw_os_recv_resource_free(struct recv_priv *precvpriv)
|
||||
{
|
||||
sint i;
|
||||
union recv_frame *precvframe;
|
||||
precvframe = (union recv_frame*) precvpriv->precv_frame_buf;
|
||||
|
||||
for (i=0; i < NR_RECVFRAME; i++)
|
||||
{
|
||||
if (precvframe->u.hdr.pkt)
|
||||
{
|
||||
rtw_skb_free(precvframe->u.hdr.pkt);/* free skb by driver */
|
||||
precvframe->u.hdr.pkt = NULL;
|
||||
}
|
||||
precvframe++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* alloc os related resource in struct recv_buf */
|
||||
int rtw_os_recvbuf_resource_alloc(struct adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
int res=_SUCCESS;
|
||||
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
precvbuf->irp_pending = false;
|
||||
precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (precvbuf->purb == NULL) {
|
||||
res = _FAIL;
|
||||
}
|
||||
|
||||
precvbuf->pskb = NULL;
|
||||
|
||||
precvbuf->reuse = false;
|
||||
|
||||
precvbuf->pallocated_buf = precvbuf->pbuf = NULL;
|
||||
|
||||
precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL;
|
||||
|
||||
precvbuf->transfer_len = 0;
|
||||
|
||||
precvbuf->len = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* free os related resource in struct recv_buf */
|
||||
int rtw_os_recvbuf_resource_free(struct adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
int ret = _SUCCESS;
|
||||
|
||||
if (precvbuf->purb)
|
||||
usb_free_urb(precvbuf->purb);
|
||||
if (precvbuf->pskb)
|
||||
rtw_skb_free(precvbuf->pskb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rtw_handle_tkip_mic_err(struct adapter *padapter,u8 bgroup)
|
||||
{
|
||||
enum nl80211_key_type key_type;
|
||||
union iwreq_data wrqu;
|
||||
struct iw_michaelmicfailure ev;
|
||||
struct mlme_priv* pmlmepriv = &padapter->mlmepriv;
|
||||
struct security_priv *psecuritypriv = &padapter->securitypriv;
|
||||
u32 cur_time = 0;
|
||||
|
||||
if ( psecuritypriv->last_mic_err_time == 0 ) {
|
||||
psecuritypriv->last_mic_err_time = jiffies;
|
||||
} else {
|
||||
cur_time = jiffies;
|
||||
|
||||
if ( cur_time - psecuritypriv->last_mic_err_time < 60*HZ ) {
|
||||
psecuritypriv->btkip_countermeasure = true;
|
||||
psecuritypriv->last_mic_err_time = 0;
|
||||
psecuritypriv->btkip_countermeasure_time = cur_time;
|
||||
} else {
|
||||
psecuritypriv->last_mic_err_time = jiffies;
|
||||
}
|
||||
}
|
||||
|
||||
if ( bgroup )
|
||||
key_type |= NL80211_KEYTYPE_GROUP;
|
||||
else
|
||||
key_type |= NL80211_KEYTYPE_PAIRWISE;
|
||||
|
||||
cfg80211_michael_mic_failure(padapter->pnetdev, (u8 *)&pmlmepriv->assoc_bssid[ 0 ], key_type, -1,
|
||||
NULL, GFP_ATOMIC);
|
||||
|
||||
memset( &ev, 0x00, sizeof( ev ) );
|
||||
if ( bgroup )
|
||||
ev.flags |= IW_MICFAILURE_GROUP;
|
||||
else
|
||||
ev.flags |= IW_MICFAILURE_PAIRWISE;
|
||||
|
||||
ev.src_addr.sa_family = ARPHRD_ETHER;
|
||||
memcpy( ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
|
||||
|
||||
memset( &wrqu, 0x00, sizeof( wrqu ) );
|
||||
wrqu.data.length = sizeof( ev );
|
||||
}
|
||||
|
||||
void rtw_hostapd_mlme_rx(struct adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
#ifdef CONFIG_HOSTAPD_MLME
|
||||
struct sk_buff *skb;
|
||||
struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
|
||||
struct net_device *pmgnt_netdev = phostapdpriv->pmgnt_netdev;
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("+rtw_hostapd_mlme_rx\n"));
|
||||
|
||||
skb = precv_frame->u.hdr.pkt;
|
||||
|
||||
if (skb == NULL)
|
||||
return;
|
||||
|
||||
skb->data = precv_frame->u.hdr.rx_data;
|
||||
skb->tail = precv_frame->u.hdr.rx_tail;
|
||||
skb->len = precv_frame->u.hdr.len;
|
||||
|
||||
/* pskb_copy = rtw_skb_copy(skb); */
|
||||
/* if (skb == NULL) goto _exit; */
|
||||
|
||||
skb->dev = pmgnt_netdev;
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
memset(skb->cb, 0, sizeof(skb->cb));
|
||||
|
||||
rtw_netif_rx(pmgnt_netdev, skb);
|
||||
|
||||
precv_frame->u.hdr.pkt = NULL; /* set pointer to NULL before rtw_free_recvframe() if call rtw_netif_rx() */
|
||||
#endif
|
||||
}
|
||||
|
||||
int rtw_recv_indicatepkt(struct adapter *padapter, union recv_frame *precv_frame)
|
||||
{
|
||||
struct recv_priv *precvpriv;
|
||||
struct __queue *pfree_recv_queue;
|
||||
struct sk_buff *skb;
|
||||
struct mlme_priv*pmlmepriv = &padapter->mlmepriv;
|
||||
#ifdef CONFIG_BR_EXT
|
||||
void *br_port = NULL;
|
||||
#endif
|
||||
|
||||
precvpriv = &padapter->recvpriv;
|
||||
pfree_recv_queue = &precvpriv->free_recv_queue;
|
||||
|
||||
#ifdef CONFIG_DRVEXT_MODULE
|
||||
if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS)
|
||||
{
|
||||
goto _recv_indicatepkt_drop;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!precv_frame)
|
||||
goto _recv_indicatepkt_drop;
|
||||
skb = precv_frame->u.hdr.pkt;
|
||||
if (skb == NULL)
|
||||
{
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb== NULL something wrong!!!!\n"));
|
||||
goto _recv_indicatepkt_drop;
|
||||
}
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n"));
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data));
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d\n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len));
|
||||
|
||||
skb->data = precv_frame->u.hdr.rx_data;
|
||||
|
||||
skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
|
||||
|
||||
skb->len = precv_frame->u.hdr.len;
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb->tail, skb->end, skb->len));
|
||||
|
||||
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
|
||||
{
|
||||
struct sk_buff *pskb2= NULL;
|
||||
struct sta_info *psta = NULL;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
|
||||
int bmcast = IS_MCAST(pattrib->dst);
|
||||
|
||||
/* DBG_88E("bmcast=%d\n", bmcast); */
|
||||
|
||||
if (_rtw_memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)==false)
|
||||
{
|
||||
/* DBG_88E("not ap psta=%p, addr=%pM\n", psta, pattrib->dst); */
|
||||
|
||||
if (bmcast)
|
||||
{
|
||||
psta = rtw_get_bcmc_stainfo(padapter);
|
||||
pskb2 = rtw_skb_clone(skb);
|
||||
} else {
|
||||
psta = rtw_get_stainfo(pstapriv, pattrib->dst);
|
||||
}
|
||||
|
||||
if (psta)
|
||||
{
|
||||
struct net_device *pnetdev= (struct net_device*)padapter->pnetdev;
|
||||
|
||||
/* DBG_88E("directly forwarding to the rtw_xmit_entry\n"); */
|
||||
|
||||
/* skb->ip_summed = CHECKSUM_NONE; */
|
||||
skb->dev = pnetdev;
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
|
||||
skb_set_queue_mapping(skb, rtw_recv_select_queue(skb));
|
||||
#else
|
||||
skb_set_queue_mapping(skb, rtw_recv_select_queue(skb,
|
||||
NULL, NULL));
|
||||
#endif
|
||||
#endif /* LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35) */
|
||||
|
||||
_rtw_xmit_entry(skb, pnetdev);
|
||||
|
||||
if (bmcast)
|
||||
skb = pskb2;
|
||||
else
|
||||
goto _recv_indicatepkt_end;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else/* to APself */
|
||||
{
|
||||
/* DBG_88E("to APSelf\n"); */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_BR_EXT
|
||||
|
||||
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
|
||||
br_port = padapter->pnetdev->br_port;
|
||||
#else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
|
||||
rcu_read_lock();
|
||||
br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
|
||||
rcu_read_unlock();
|
||||
#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
|
||||
|
||||
if ( br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == true) )
|
||||
{
|
||||
int nat25_handle_frame(struct adapter *priv, struct sk_buff *skb);
|
||||
if (nat25_handle_frame(padapter, skb) == -1) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BR_EXT */
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
skb->dev = padapter->pnetdev;
|
||||
skb->protocol = eth_type_trans(skb, padapter->pnetdev);
|
||||
|
||||
#ifdef DBG_TRX_STA_PKTS
|
||||
{
|
||||
|
||||
struct sta_info *psta = NULL;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
|
||||
int bmcast = IS_MCAST(pattrib->dst);
|
||||
|
||||
if (bmcast)
|
||||
{
|
||||
psta = rtw_get_bcmc_stainfo(padapter);
|
||||
|
||||
} else {
|
||||
psta = rtw_get_stainfo(pstapriv, pattrib->src);
|
||||
}
|
||||
if (psta)
|
||||
{
|
||||
switch (pattrib->priority)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
psta->rx_bk_cnt++;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
psta->rx_vi_cnt++;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
psta->rx_vo_cnt++;
|
||||
break;
|
||||
case 0:
|
||||
case 3:
|
||||
default:
|
||||
psta->rx_be_cnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rtw_netif_rx(padapter->pnetdev, skb);
|
||||
|
||||
_recv_indicatepkt_end:
|
||||
|
||||
precv_frame->u.hdr.pkt = NULL; /* pointers to NULL before rtw_free_recvframe() */
|
||||
|
||||
rtw_free_recvframe(precv_frame, pfree_recv_queue);
|
||||
|
||||
RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_netif_rx!!!!\n"));
|
||||
|
||||
;
|
||||
|
||||
return _SUCCESS;
|
||||
|
||||
_recv_indicatepkt_drop:
|
||||
|
||||
/* enqueue back to free_recv_queue */
|
||||
if (precv_frame)
|
||||
rtw_free_recvframe(precv_frame, pfree_recv_queue);
|
||||
|
||||
return _FAIL;
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
void rtw_os_read_port(struct adapter *padapter, struct recv_buf *precvbuf)
|
||||
{
|
||||
struct recv_priv *precvpriv = &padapter->recvpriv;
|
||||
|
||||
precvbuf->ref_cnt--;
|
||||
|
||||
/* free skb in recv_buf */
|
||||
rtw_skb_free(precvbuf->pskb);
|
||||
|
||||
precvbuf->pskb = NULL;
|
||||
precvbuf->reuse = false;
|
||||
|
||||
if (precvbuf->irp_pending == false)
|
||||
{
|
||||
rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
|
||||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
static void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext)
|
||||
#else
|
||||
static void _rtw_reordering_ctrl_timeout_handler(struct timer_list *t)
|
||||
#endif
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)FunctionContext;
|
||||
#else
|
||||
struct recv_reorder_ctrl *preorder_ctrl = from_timer(preorder_ctrl, t, reordering_ctrl_timer);
|
||||
#endif
|
||||
rtw_reordering_ctrl_timeout_handler(preorder_ctrl);
|
||||
}
|
||||
|
||||
void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
struct adapter *padapter = preorder_ctrl->padapter;
|
||||
|
||||
_init_timer(&preorder_ctrl->reordering_ctrl_timer, padapter->pnetdev, _rtw_reordering_ctrl_timeout_handler, preorder_ctrl);
|
||||
#else
|
||||
|
||||
timer_setup(&preorder_ctrl->reordering_ctrl_timer, _rtw_reordering_ctrl_timeout_handler, 0);
|
||||
#endif
|
||||
|
||||
}
|
|
@ -1,761 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include <rtw_android.h>
|
||||
#include <osdep_service.h>
|
||||
#include <rtw_debug.h>
|
||||
#include <ioctl_cfg80211.h>
|
||||
#include <rtw_ioctl_set.h>
|
||||
|
||||
#include <drv_types.h>
|
||||
|
||||
#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)
|
||||
#include <linux/platform_device.h>
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
#include <linux/wlan_plat.h>
|
||||
#else
|
||||
#include <linux/wifi_tiwlan.h>
|
||||
#endif
|
||||
#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */
|
||||
|
||||
static const char *android_wifi_cmd_str[ANDROID_WIFI_CMD_MAX] = {
|
||||
"START",
|
||||
"STOP",
|
||||
"SCAN-ACTIVE",
|
||||
"SCAN-PASSIVE",
|
||||
"RSSI",
|
||||
"LINKSPEED",
|
||||
"RXFILTER-START",
|
||||
"RXFILTER-STOP",
|
||||
"RXFILTER-ADD",
|
||||
"RXFILTER-REMOVE",
|
||||
"BTCOEXSCAN-START",
|
||||
"BTCOEXSCAN-STOP",
|
||||
"BTCOEXMODE",
|
||||
"SETSUSPENDOPT",
|
||||
"P2P_DEV_ADDR",
|
||||
"SETFWPATH",
|
||||
"SETBAND",
|
||||
"GETBAND",
|
||||
"COUNTRY",
|
||||
"P2P_SET_NOA",
|
||||
"P2P_GET_NOA",
|
||||
"P2P_SET_PS",
|
||||
"SET_AP_WPS_P2P_IE",
|
||||
#ifdef PNO_SUPPORT
|
||||
"PNOSSIDCLR",
|
||||
"PNOSETUP ",
|
||||
"PNOFORCE",
|
||||
"PNODEBUG",
|
||||
#endif
|
||||
|
||||
"MACADDR",
|
||||
|
||||
"BLOCK",
|
||||
"WFD-ENABLE",
|
||||
"WFD-DISABLE",
|
||||
"WFD-SET-TCPPORT",
|
||||
"WFD-SET-MAXTPUT",
|
||||
"WFD-SET-DEVTYPE",
|
||||
};
|
||||
|
||||
#ifdef PNO_SUPPORT
|
||||
#define PNO_TLV_PREFIX 'S'
|
||||
#define PNO_TLV_VERSION '1'
|
||||
#define PNO_TLV_SUBVERSION '2'
|
||||
#define PNO_TLV_RESERVED '0'
|
||||
#define PNO_TLV_TYPE_SSID_IE 'S'
|
||||
#define PNO_TLV_TYPE_TIME 'T'
|
||||
#define PNO_TLV_FREQ_REPEAT 'R'
|
||||
#define PNO_TLV_FREQ_EXPO_MAX 'M'
|
||||
|
||||
typedef struct cmd_tlv {
|
||||
char prefix;
|
||||
char version;
|
||||
char subver;
|
||||
char reserved;
|
||||
} cmd_tlv_t;
|
||||
#endif /* PNO_SUPPORT */
|
||||
|
||||
typedef struct android_wifi_priv_cmd {
|
||||
char *buf;
|
||||
int used_len;
|
||||
int total_len;
|
||||
} android_wifi_priv_cmd;
|
||||
|
||||
/**
|
||||
* Local (static) functions and variables
|
||||
*/
|
||||
|
||||
/* Initialize g_wifi_on to 1 so dhd_bus_start will be called for the first
|
||||
* time (only) in dhd_open, subsequential wifi on will be handled by
|
||||
* wl_android_wifi_on
|
||||
*/
|
||||
static int g_wifi_on = true;
|
||||
|
||||
static unsigned int oob_irq;
|
||||
|
||||
#ifdef PNO_SUPPORT
|
||||
static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len)
|
||||
{
|
||||
wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
|
||||
int res = -1;
|
||||
int nssid = 0;
|
||||
cmd_tlv_t *cmd_tlv_temp;
|
||||
char *str_ptr;
|
||||
int tlv_size_left;
|
||||
int pno_time = 0;
|
||||
int pno_repeat = 0;
|
||||
int pno_freq_expo_max = 0;
|
||||
|
||||
#ifdef PNO_SET_DEBUG
|
||||
int i;
|
||||
char pno_in_example[] = {
|
||||
'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
|
||||
'S', '1', '2', '0',
|
||||
'S',
|
||||
0x05,
|
||||
'd', 'l', 'i', 'n', 'k',
|
||||
'S',
|
||||
0x04,
|
||||
'G', 'O', 'O', 'G',
|
||||
'T',
|
||||
'0', 'B',
|
||||
'R',
|
||||
'2',
|
||||
'M',
|
||||
'2',
|
||||
0x00
|
||||
};
|
||||
#endif /* PNO_SET_DEBUG */
|
||||
|
||||
DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));
|
||||
|
||||
if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
|
||||
DBG_88E("%s argument=%d less min size\n", __FUNCTION__, total_len);
|
||||
goto exit_proc;
|
||||
}
|
||||
|
||||
#ifdef PNO_SET_DEBUG
|
||||
memcpy(command, pno_in_example, sizeof(pno_in_example));
|
||||
for (i = 0; i < sizeof(pno_in_example); i++)
|
||||
printf("%02X ", command[i]);
|
||||
printf("\n");
|
||||
total_len = sizeof(pno_in_example);
|
||||
#endif
|
||||
|
||||
str_ptr = command + strlen(CMD_PNOSETUP_SET);
|
||||
tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET);
|
||||
|
||||
cmd_tlv_temp = (cmd_tlv_t *)str_ptr;
|
||||
memset(ssids_local, 0, sizeof(ssids_local));
|
||||
|
||||
if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) &&
|
||||
(cmd_tlv_temp->version == PNO_TLV_VERSION) &&
|
||||
(cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) {
|
||||
|
||||
str_ptr += sizeof(cmd_tlv_t);
|
||||
tlv_size_left -= sizeof(cmd_tlv_t);
|
||||
|
||||
if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local,
|
||||
MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) {
|
||||
DBG_88E("SSID is not presented or corrupted ret=%d\n", nssid);
|
||||
goto exit_proc;
|
||||
} else {
|
||||
if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {
|
||||
DBG_88E("%s scan duration corrupted field size %d\n",
|
||||
__FUNCTION__, tlv_size_left);
|
||||
goto exit_proc;
|
||||
}
|
||||
str_ptr++;
|
||||
pno_time = simple_strtoul(str_ptr, &str_ptr, 16);
|
||||
DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time));
|
||||
|
||||
if (str_ptr[0] != 0) {
|
||||
if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {
|
||||
DBG_88E("%s pno repeat : corrupted field\n",
|
||||
__FUNCTION__);
|
||||
goto exit_proc;
|
||||
}
|
||||
str_ptr++;
|
||||
pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);
|
||||
DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat));
|
||||
if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {
|
||||
DBG_88E("%s FREQ_EXPO_MAX corrupted field size\n",
|
||||
__FUNCTION__);
|
||||
goto exit_proc;
|
||||
}
|
||||
str_ptr++;
|
||||
pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);
|
||||
DHD_INFO(("%s: pno_freq_expo_max=%d\n",
|
||||
__FUNCTION__, pno_freq_expo_max));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DBG_88E("%s get wrong TLV command\n", __FUNCTION__);
|
||||
goto exit_proc;
|
||||
}
|
||||
|
||||
res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max);
|
||||
|
||||
exit_proc:
|
||||
return res;
|
||||
}
|
||||
#endif /* PNO_SUPPORT */
|
||||
|
||||
int rtw_android_cmdstr_to_num(char *cmdstr)
|
||||
{
|
||||
int cmd_num;
|
||||
for (cmd_num=0 ; cmd_num<ANDROID_WIFI_CMD_MAX; cmd_num++)
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
|
||||
if (!strncasecmp(cmdstr, android_wifi_cmd_str[cmd_num],
|
||||
strlen(android_wifi_cmd_str[cmd_num])))
|
||||
#else
|
||||
if (0 == strnicmp(cmdstr, android_wifi_cmd_str[cmd_num],
|
||||
strlen(android_wifi_cmd_str[cmd_num])))
|
||||
#endif
|
||||
break;
|
||||
|
||||
return cmd_num;
|
||||
}
|
||||
|
||||
static int rtw_android_get_rssi(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net);
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct wlan_network *pcur_network = &pmlmepriv->cur_network;
|
||||
int bytes_written = 0;
|
||||
|
||||
if (check_fwstate(pmlmepriv, _FW_LINKED) == true) {
|
||||
bytes_written += snprintf(&command[bytes_written], total_len, "%s rssi %d",
|
||||
pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
|
||||
}
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_get_link_speed(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net);
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
struct wlan_network *pcur_network = &pmlmepriv->cur_network;
|
||||
int bytes_written = 0;
|
||||
u16 link_speed = 0;
|
||||
|
||||
link_speed = rtw_get_cur_max_rate(padapter)/10;
|
||||
bytes_written = snprintf(command, total_len, "LinkSpeed %d", link_speed);
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_get_macaddr(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
struct adapter *adapter = (struct adapter *)rtw_netdev_priv(net);
|
||||
int bytes_written = 0;
|
||||
|
||||
bytes_written = snprintf(command, total_len, "Macaddr = "MAC_FMT, MAC_ARG(net->dev_addr));
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_set_country(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
struct adapter *adapter = (struct adapter *)rtw_netdev_priv(net);
|
||||
char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1;
|
||||
int ret = _FAIL;
|
||||
|
||||
ret = rtw_set_country(adapter, country_code);
|
||||
|
||||
return (ret==_SUCCESS)?0:-1;
|
||||
}
|
||||
|
||||
static int rtw_android_get_p2p_dev_addr(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
int bytes_written = 0;
|
||||
|
||||
/* We use the same address as our HW MAC address */
|
||||
memcpy(command, net->dev_addr, ETH_ALEN);
|
||||
|
||||
bytes_written = ETH_ALEN;
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
static int rtw_android_set_block(struct net_device *net, char *command, int total_len)
|
||||
{
|
||||
struct adapter *adapter = (struct adapter *)rtw_netdev_priv(net);
|
||||
char *block_value = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_BLOCK]) + 1;
|
||||
|
||||
wdev_to_priv(adapter->rtw_wdev)->block = (*block_value=='0')?false:true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_int_from_command(char *pcmd)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for ( i = 0; i < strlen( pcmd ); i++ )
|
||||
{
|
||||
if ( pcmd[ i ] == '=' )
|
||||
{
|
||||
/* Skip the '=' and space characters. */
|
||||
i += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ( rtw_atoi( pcmd + i ) );
|
||||
}
|
||||
|
||||
int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
int ret = 0;
|
||||
char *command = NULL;
|
||||
int cmd_num;
|
||||
int bytes_written = 0;
|
||||
android_wifi_priv_cmd priv_cmd;
|
||||
struct adapter* padapter = ( struct adapter * ) rtw_netdev_priv(net);
|
||||
#ifdef CONFIG_P2P
|
||||
struct wifi_display_info *pwfd_info;
|
||||
#endif
|
||||
|
||||
rtw_lock_suspend();
|
||||
|
||||
if (!ifr->ifr_data) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) {
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* DBG_88E("%s priv_cmd.buf=%p priv_cmd.total_len=%d priv_cmd.used_len=%d\n",__func__,priv_cmd.buf,priv_cmd.total_len,priv_cmd.used_len); */
|
||||
command = rtw_zmalloc(priv_cmd.total_len);
|
||||
if (!command)
|
||||
{
|
||||
DBG_88E("%s: failed to allocate memory\n", __FUNCTION__);
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!access_ok(VERIFY_READ, (const void __user *)priv_cmd.buf, priv_cmd.total_len)) {
|
||||
DBG_88E("%s: failed to access memory\n", __FUNCTION__);
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
if (copy_from_user(command, (const void __user *)priv_cmd.buf, priv_cmd.total_len)) {
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
DBG_88E("%s: Android private cmd \"%s\" on %s\n"
|
||||
, __FUNCTION__, command, ifr->ifr_name);
|
||||
|
||||
cmd_num = rtw_android_cmdstr_to_num(command);
|
||||
|
||||
switch (cmd_num) {
|
||||
case ANDROID_WIFI_CMD_START:
|
||||
/* bytes_written = wl_android_wifi_on(net); */
|
||||
goto response;
|
||||
case ANDROID_WIFI_CMD_SETFWPATH:
|
||||
goto response;
|
||||
}
|
||||
|
||||
if (!g_wifi_on) {
|
||||
DBG_88E("%s: Ignore private cmd \"%s\" - iface %s is down\n"
|
||||
,__FUNCTION__, command, ifr->ifr_name);
|
||||
ret = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
switch (cmd_num) {
|
||||
|
||||
case ANDROID_WIFI_CMD_STOP:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_SCAN_ACTIVE:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_SCAN_PASSIVE:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RSSI:
|
||||
bytes_written = rtw_android_get_rssi(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_LINKSPEED:
|
||||
bytes_written = rtw_android_get_link_speed(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_MACADDR:
|
||||
bytes_written = rtw_android_get_macaddr(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_BLOCK:
|
||||
bytes_written = rtw_android_set_block(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RXFILTER_START:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RXFILTER_STOP:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RXFILTER_ADD:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_RXFILTER_REMOVE:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_BTCOEXSCAN_START:
|
||||
/* TBD: BTCOEXSCAN-START */
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP:
|
||||
/* TBD: BTCOEXSCAN-STOP */
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_BTCOEXMODE:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_SETSUSPENDOPT:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_SETBAND:
|
||||
{
|
||||
uint band = *(command + strlen("SETBAND") + 1) - '0';
|
||||
struct adapter* padapter = ( struct adapter * ) rtw_netdev_priv(net);
|
||||
|
||||
if (padapter->chip_type == RTL8192D)
|
||||
padapter->setband = band;
|
||||
|
||||
break;
|
||||
}
|
||||
case ANDROID_WIFI_CMD_GETBAND:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_COUNTRY:
|
||||
bytes_written = rtw_android_set_country(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
#ifdef PNO_SUPPORT
|
||||
case ANDROID_WIFI_CMD_PNOSSIDCLR_SET:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_PNOSETUP_SET:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_PNOENABLE_SET:
|
||||
break;
|
||||
#endif
|
||||
case ANDROID_WIFI_CMD_P2P_DEV_ADDR:
|
||||
bytes_written = rtw_android_get_p2p_dev_addr(net, command, priv_cmd.total_len);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_P2P_SET_NOA:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_P2P_GET_NOA:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_P2P_SET_PS:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE:
|
||||
{
|
||||
int skip = strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_SET_AP_WPS_P2P_IE]) + 3;
|
||||
bytes_written = rtw_cfg80211_set_mgnt_wpsp2pie(net, command + skip, priv_cmd.total_len - skip, *(command + skip - 2) - '0');
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_P2P
|
||||
case ANDROID_WIFI_CMD_WFD_ENABLE:
|
||||
/* Commented by Albert 2012/07/24 */
|
||||
/* We can enable the WFD function by using the following command: */
|
||||
/* wpa_cli driver wfd-enable */
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if ( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
|
||||
pwfd_info->wfd_enable = true;
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_DISABLE:
|
||||
/* Commented by Albert 2012/07/24 */
|
||||
/* We can disable the WFD function by using the following command: */
|
||||
/* wpa_cli driver wfd-disable */
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if ( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
|
||||
pwfd_info->wfd_enable = false;
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_SET_TCPPORT:
|
||||
/* Commented by Albert 2012/07/24 */
|
||||
/* We can set the tcp port number by using the following command: */
|
||||
/* wpa_cli driver wfd-set-tcpport = 554 */
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if ( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
|
||||
pwfd_info->rtsp_ctrlport = (u16)get_int_from_command(priv_cmd.buf);
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_SET_MAX_TPUT:
|
||||
break;
|
||||
case ANDROID_WIFI_CMD_WFD_SET_DEVTYPE:
|
||||
{
|
||||
/* Commented by Albert 2012/08/28 */
|
||||
/* Specify the WFD device type ( WFD source/primary sink ) */
|
||||
|
||||
struct wifi_display_info *pwfd_info;
|
||||
struct adapter* padapter = ( struct adapter * ) rtw_netdev_priv(net);
|
||||
|
||||
pwfd_info = &padapter->wfd_info;
|
||||
if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
|
||||
pwfd_info->wfd_device_type = (u8)get_int_from_command(priv_cmd.buf);
|
||||
|
||||
pwfd_info->wfd_device_type &= WFD_DEVINFO_DUAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
DBG_88E("Unknown PRIVATE command %s - ignored\n", command);
|
||||
snprintf(command, 3, "OK");
|
||||
bytes_written = strlen("OK");
|
||||
}
|
||||
|
||||
response:
|
||||
if (bytes_written >= 0) {
|
||||
if ((bytes_written == 0) && (priv_cmd.total_len > 0))
|
||||
command[0] = '\0';
|
||||
if (bytes_written >= priv_cmd.total_len) {
|
||||
DBG_88E("%s: bytes_written = %d\n", __FUNCTION__, bytes_written);
|
||||
bytes_written = priv_cmd.total_len;
|
||||
} else {
|
||||
bytes_written++;
|
||||
}
|
||||
priv_cmd.used_len = bytes_written;
|
||||
if (copy_to_user((void __user *)priv_cmd.buf, command, bytes_written)) {
|
||||
DBG_88E("%s: failed to copy data to user buffer\n", __FUNCTION__);
|
||||
ret = -EFAULT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = bytes_written;
|
||||
}
|
||||
|
||||
exit:
|
||||
rtw_unlock_suspend();
|
||||
if (command) {
|
||||
rtw_mfree(command, priv_cmd.total_len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Functions for Android WiFi card detection
|
||||
*/
|
||||
#if defined(RTW_ENABLE_WIFI_CONTROL_FUNC)
|
||||
|
||||
static int g_wifidev_registered = 0;
|
||||
static struct semaphore wifi_control_sem;
|
||||
static struct wifi_platform_data *wifi_control_data = NULL;
|
||||
static struct resource *wifi_irqres = NULL;
|
||||
|
||||
static int wifi_add_dev(void);
|
||||
static void wifi_del_dev(void);
|
||||
|
||||
int rtw_android_wifictrl_func_add(void)
|
||||
{
|
||||
int ret = 0;
|
||||
sema_init(&wifi_control_sem, 0);
|
||||
|
||||
ret = wifi_add_dev();
|
||||
if (ret) {
|
||||
DBG_88E("%s: platform_driver_register failed\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
g_wifidev_registered = 1;
|
||||
|
||||
/* Waiting callback after platform_driver_register is done or exit with error */
|
||||
if (down_timeout(&wifi_control_sem, msecs_to_jiffies(1000)) != 0) {
|
||||
ret = -EINVAL;
|
||||
DBG_88E("%s: platform_driver_register timeout\n", __FUNCTION__);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rtw_android_wifictrl_func_del(void)
|
||||
{
|
||||
if (g_wifidev_registered)
|
||||
{
|
||||
wifi_del_dev();
|
||||
g_wifidev_registered = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *wl_android_prealloc(int section, unsigned long size)
|
||||
{
|
||||
void *alloc_ptr = NULL;
|
||||
if (wifi_control_data && wifi_control_data->mem_prealloc) {
|
||||
alloc_ptr = wifi_control_data->mem_prealloc(section, size);
|
||||
if (alloc_ptr) {
|
||||
DBG_88E("success alloc section %d\n", section);
|
||||
if (size != 0L)
|
||||
memset(alloc_ptr, 0, size);
|
||||
return alloc_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
DBG_88E("can't alloc section %d\n", section);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int wifi_get_irq_number(unsigned long *irq_flags_ptr)
|
||||
{
|
||||
if (wifi_irqres) {
|
||||
*irq_flags_ptr = wifi_irqres->flags & IRQF_TRIGGER_MASK;
|
||||
return (int)wifi_irqres->start;
|
||||
}
|
||||
#ifdef CUSTOM_OOB_GPIO_NUM
|
||||
return CUSTOM_OOB_GPIO_NUM;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int wifi_set_power(int on, unsigned long msec)
|
||||
{
|
||||
DBG_88E("%s = %d\n", __FUNCTION__, on);
|
||||
if (wifi_control_data && wifi_control_data->set_power) {
|
||||
wifi_control_data->set_power(on);
|
||||
}
|
||||
if (msec)
|
||||
msleep(msec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
|
||||
int wifi_get_mac_addr(unsigned char *buf)
|
||||
{
|
||||
DBG_88E("%s\n", __FUNCTION__);
|
||||
if (!buf)
|
||||
return -EINVAL;
|
||||
if (wifi_control_data && wifi_control_data->get_mac_addr) {
|
||||
return wifi_control_data->get_mac_addr(buf);
|
||||
}
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) */
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) || defined(COMPAT_KERNEL_RELEASE)
|
||||
void *wifi_get_country_code(char *ccode)
|
||||
{
|
||||
DBG_88E("%s\n", __FUNCTION__);
|
||||
if (!ccode)
|
||||
return NULL;
|
||||
if (wifi_control_data && wifi_control_data->get_country_code) {
|
||||
return wifi_control_data->get_country_code(ccode);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */
|
||||
|
||||
static int wifi_set_carddetect(int on)
|
||||
{
|
||||
DBG_88E("%s = %d\n", __FUNCTION__, on);
|
||||
if (wifi_control_data && wifi_control_data->set_carddetect) {
|
||||
wifi_control_data->set_carddetect(on);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wifi_platform_data *wifi_ctrl =
|
||||
(struct wifi_platform_data *)(pdev->dev.platform_data);
|
||||
int wifi_wake_gpio = 0;
|
||||
|
||||
DBG_88E("## %s\n", __FUNCTION__);
|
||||
wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
|
||||
|
||||
if (wifi_irqres == NULL)
|
||||
wifi_irqres = platform_get_resource_byname(pdev,
|
||||
IORESOURCE_IRQ, "bcm4329_wlan_irq");
|
||||
else
|
||||
wifi_wake_gpio = wifi_irqres->start;
|
||||
|
||||
wifi_control_data = wifi_ctrl;
|
||||
|
||||
wifi_set_power(1, 0); /* Power On */
|
||||
wifi_set_carddetect(1); /* CardDetect (0->1) */
|
||||
|
||||
up(&wifi_control_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct wifi_platform_data *wifi_ctrl =
|
||||
(struct wifi_platform_data *)(pdev->dev.platform_data);
|
||||
|
||||
DBG_88E("## %s\n", __FUNCTION__);
|
||||
wifi_control_data = wifi_ctrl;
|
||||
|
||||
wifi_set_power(0, 0); /* Power Off */
|
||||
wifi_set_carddetect(0); /* CardDetect (1->0) */
|
||||
|
||||
up(&wifi_control_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
DBG_88E("##> %s\n", __FUNCTION__);
|
||||
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
|
||||
bcmsdh_oob_intr_set(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wifi_resume(struct platform_device *pdev)
|
||||
{
|
||||
DBG_88E("##> %s\n", __FUNCTION__);
|
||||
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY)
|
||||
if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
|
||||
bcmsdh_oob_intr_set(1);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* temporarily use these two */
|
||||
static struct platform_driver wifi_device = {
|
||||
.probe = wifi_probe,
|
||||
.remove = wifi_remove,
|
||||
.suspend = wifi_suspend,
|
||||
.resume = wifi_resume,
|
||||
.driver = {
|
||||
.name = "bcmdhd_wlan",
|
||||
}
|
||||
};
|
||||
|
||||
static struct platform_driver wifi_device_legacy = {
|
||||
.probe = wifi_probe,
|
||||
.remove = wifi_remove,
|
||||
.suspend = wifi_suspend,
|
||||
.resume = wifi_resume,
|
||||
.driver = {
|
||||
.name = "bcm4329_wlan",
|
||||
}
|
||||
};
|
||||
|
||||
static int wifi_add_dev(void)
|
||||
{
|
||||
DBG_88E("## Calling platform_driver_register\n");
|
||||
platform_driver_register(&wifi_device);
|
||||
platform_driver_register(&wifi_device_legacy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wifi_del_dev(void)
|
||||
{
|
||||
DBG_88E("## Unregister platform_driver_register\n");
|
||||
platform_driver_unregister(&wifi_device);
|
||||
platform_driver_unregister(&wifi_device_legacy);
|
||||
}
|
||||
#endif /* defined(RTW_ENABLE_WIFI_CONTROL_FUNC) */
|
1335
os_dep/usb_intf.c
1335
os_dep/usb_intf.c
File diff suppressed because it is too large
Load diff
|
@ -1,600 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*******************************************************************************/
|
||||
#define _USB_OPS_LINUX_C_
|
||||
|
||||
#include <drv_types.h>
|
||||
#include <usb_ops_linux.h>
|
||||
#include <rtw_sreset.h>
|
||||
|
||||
#ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
|
||||
static void _usbctrl_vendorreq_async_callback(struct urb *urb, struct pt_regs *regs)
|
||||
{
|
||||
if (urb) {
|
||||
if (urb->context) {
|
||||
rtw_mfree(urb->context);
|
||||
}
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
}
|
||||
|
||||
static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
|
||||
u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
|
||||
{
|
||||
int rc;
|
||||
unsigned int pipe;
|
||||
u8 reqtype;
|
||||
struct usb_ctrlrequest *dr;
|
||||
struct urb *urb;
|
||||
struct rtl819x_async_write_data {
|
||||
u8 data[VENDOR_CMD_MAX_DATA_LEN];
|
||||
struct usb_ctrlrequest dr;
|
||||
} *buf;
|
||||
|
||||
|
||||
if (requesttype == VENDOR_READ) {
|
||||
pipe = usb_rcvctrlpipe(udev, 0);/* read_in */
|
||||
reqtype = REALTEK_USB_VENQT_READ;
|
||||
}
|
||||
else {
|
||||
pipe = usb_sndctrlpipe(udev, 0);/* write_out */
|
||||
reqtype = REALTEK_USB_VENQT_WRITE;
|
||||
}
|
||||
|
||||
buf = (struct rtl819x_async_write_data *)rtw_zmalloc(sizeof(*buf));
|
||||
if (!buf) {
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!urb) {
|
||||
rtw_mfree((u8*)buf, sizeof(*buf));
|
||||
rc = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dr = &buf->dr;
|
||||
|
||||
dr->bRequestType = reqtype;
|
||||
dr->bRequest = request;
|
||||
dr->wValue = cpu_to_le16(value);
|
||||
dr->wIndex = cpu_to_le16(index);
|
||||
dr->wLength = cpu_to_le16(len);
|
||||
|
||||
memcpy(buf, pdata, len);
|
||||
|
||||
usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr, buf, len,
|
||||
_usbctrl_vendorreq_async_callback, buf);
|
||||
|
||||
rc = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (rc < 0) {
|
||||
rtw_mfree((u8*)buf, sizeof(*buf));
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int usb_write_async(struct usb_device *udev, u32 addr, void *pdata, u16 len)
|
||||
{
|
||||
u8 request;
|
||||
u8 requesttype;
|
||||
u16 wvalue;
|
||||
u16 index;
|
||||
|
||||
int ret;
|
||||
|
||||
requesttype = VENDOR_WRITE;/* write_out */
|
||||
request = REALTEK_USB_VENQT_CMD_REQ;
|
||||
index = REALTEK_USB_VENQT_CMD_IDX;/* n/a */
|
||||
|
||||
wvalue = (u16)(addr&0x0000ffff);
|
||||
|
||||
ret = _usbctrl_vendorreq_async_write(udev, request, wvalue, index, pdata, len, requesttype);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
|
||||
{
|
||||
u8 data;
|
||||
int ret;
|
||||
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
|
||||
struct usb_device *udev=pdvobjpriv->pusbdev;
|
||||
|
||||
;
|
||||
data = val;
|
||||
ret = usb_write_async(udev, addr, &data, 1);
|
||||
;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
|
||||
{
|
||||
u16 data;
|
||||
int ret;
|
||||
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
|
||||
struct usb_device *udev=pdvobjpriv->pusbdev;
|
||||
|
||||
;
|
||||
data = val;
|
||||
ret = usb_write_async(udev, addr, &data, 2);
|
||||
;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
|
||||
{
|
||||
u32 data;
|
||||
int ret;
|
||||
struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
|
||||
struct usb_device *udev=pdvobjpriv->pusbdev;
|
||||
|
||||
;
|
||||
data = val;
|
||||
ret = usb_write_async(udev, addr, &data, 4);
|
||||
;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */
|
||||
|
||||
unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
|
||||
{
|
||||
unsigned int pipe=0, ep_num=0;
|
||||
struct usb_device *pusbd = pdvobj->pusbdev;
|
||||
|
||||
if (addr == RECV_BULK_IN_ADDR) {
|
||||
pipe=usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]);
|
||||
|
||||
} else if (addr == RECV_INT_IN_ADDR) {
|
||||
pipe=usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[1]);
|
||||
|
||||
} else if (addr < HW_QUEUE_ENTRY) {
|
||||
ep_num = pdvobj->Queue2Pipe[addr];
|
||||
pipe = usb_sndbulkpipe(pusbd, ep_num);
|
||||
}
|
||||
|
||||
return pipe;
|
||||
}
|
||||
|
||||
struct zero_bulkout_context{
|
||||
void *pbuf;
|
||||
void *purb;
|
||||
void *pirp;
|
||||
void *padapter;
|
||||
};
|
||||
|
||||
static void usb_bulkout_zero_complete(struct urb *purb, struct pt_regs *regs)
|
||||
{
|
||||
struct zero_bulkout_context *pcontext = (struct zero_bulkout_context *)purb->context;
|
||||
|
||||
/* DBG_8192C("+usb_bulkout_zero_complete\n"); */
|
||||
|
||||
if (pcontext)
|
||||
{
|
||||
if (pcontext->pbuf)
|
||||
{
|
||||
rtw_mfree(pcontext->pbuf, sizeof(int));
|
||||
}
|
||||
|
||||
if (pcontext->purb && (pcontext->purb==purb))
|
||||
{
|
||||
usb_free_urb(pcontext->purb);
|
||||
}
|
||||
|
||||
|
||||
rtw_mfree((u8*)pcontext, sizeof(struct zero_bulkout_context));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr)
|
||||
{
|
||||
int pipe, status, len;
|
||||
u32 ret;
|
||||
unsigned char *pbuf;
|
||||
struct zero_bulkout_context *pcontext;
|
||||
struct urb * purb = NULL;
|
||||
struct adapter *padapter = (struct adapter *)pintfhdl->padapter;
|
||||
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobj->pusbdev;
|
||||
|
||||
/* DBG_88E("%s\n", __func__); */
|
||||
|
||||
|
||||
if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx))
|
||||
{
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
|
||||
pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context));
|
||||
|
||||
pbuf = (unsigned char *)rtw_zmalloc(sizeof(int));
|
||||
purb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
|
||||
len = 0;
|
||||
pcontext->pbuf = pbuf;
|
||||
pcontext->purb = purb;
|
||||
pcontext->pirp = NULL;
|
||||
pcontext->padapter = padapter;
|
||||
|
||||
|
||||
/* translate DMA FIFO addr to pipehandle */
|
||||
/* pipe = ffaddr2pipehdl(pdvobj, addr); */
|
||||
|
||||
usb_fill_bulk_urb(purb, pusbd, pipe,
|
||||
pbuf,
|
||||
len,
|
||||
usb_bulkout_zero_complete,
|
||||
pcontext);/* context is pcontext */
|
||||
|
||||
status = usb_submit_urb(purb, GFP_ATOMIC);
|
||||
|
||||
if (!status)
|
||||
{
|
||||
ret= _SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret= _FAIL;
|
||||
}
|
||||
|
||||
|
||||
return _SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void usb_read_port_cancel(struct intf_hdl *pintfhdl)
|
||||
{
|
||||
int i;
|
||||
struct recv_buf *precvbuf;
|
||||
struct adapter *padapter = pintfhdl->padapter;
|
||||
precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
|
||||
|
||||
DBG_88E("%s\n", __func__);
|
||||
|
||||
padapter->bReadPortCancel = true;
|
||||
|
||||
for (i=0; i < NR_RECVBUFF ; i++) {
|
||||
|
||||
precvbuf->reuse = true;
|
||||
if (precvbuf->purb) {
|
||||
/* DBG_8192C("usb_read_port_cancel : usb_kill_urb\n"); */
|
||||
usb_kill_urb(precvbuf->purb);
|
||||
}
|
||||
precvbuf++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_INTERRUPT_IN_PIPE
|
||||
usb_kill_urb(padapter->recvpriv.int_in_urb);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long irqL;
|
||||
int i;
|
||||
struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
|
||||
/* struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; */
|
||||
/* struct adapter *padapter = pxmitframe->padapter; */
|
||||
struct adapter *padapter = pxmitbuf->padapter;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
/* struct pkt_attrib *pattrib = &pxmitframe->attrib; */
|
||||
|
||||
;
|
||||
|
||||
switch (pxmitbuf->flags)
|
||||
{
|
||||
case VO_QUEUE_INX:
|
||||
pxmitpriv->voq_cnt--;
|
||||
break;
|
||||
case VI_QUEUE_INX:
|
||||
pxmitpriv->viq_cnt--;
|
||||
break;
|
||||
case BE_QUEUE_INX:
|
||||
pxmitpriv->beq_cnt--;
|
||||
break;
|
||||
case BK_QUEUE_INX:
|
||||
pxmitpriv->bkq_cnt--;
|
||||
break;
|
||||
case HIGH_QUEUE_INX:
|
||||
#ifdef CONFIG_AP_MODE
|
||||
rtw_chk_hi_queue_cmd(padapter);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||padapter->bWritePortCancel)
|
||||
{
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
|
||||
DBG_8192C("%s(): TX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bWritePortCancel(%d) pxmitbuf->ext_tag(%x)\n",
|
||||
__FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved,padapter->bReadPortCancel,pxmitbuf->ext_tag);
|
||||
|
||||
goto check_completion;
|
||||
}
|
||||
|
||||
|
||||
if (purb->status== 0) {
|
||||
|
||||
} else {
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete : purb->status(%d) != 0\n", purb->status));
|
||||
DBG_88E("###=> urb_write_port_complete status(%d)\n",purb->status);
|
||||
if ((purb->status==-EPIPE)||(purb->status==-EPROTO))
|
||||
{
|
||||
/* usb_clear_halt(pusbdev, purb->pipe); */
|
||||
/* msleep(10); */
|
||||
sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL);
|
||||
} else if (purb->status == -EINPROGRESS) {
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: EINPROGESS\n"));
|
||||
goto check_completion;
|
||||
|
||||
} else if (purb->status == -ENOENT) {
|
||||
DBG_88E("%s: -ENOENT\n", __func__);
|
||||
goto check_completion;
|
||||
|
||||
} else if (purb->status == -ECONNRESET) {
|
||||
DBG_88E("%s: -ECONNRESET\n", __func__);
|
||||
goto check_completion;
|
||||
|
||||
} else if (purb->status == -ESHUTDOWN) {
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete: ESHUTDOWN\n"));
|
||||
padapter->bDriverStopped=true;
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bDriverStopped=true\n"));
|
||||
|
||||
goto check_completion;
|
||||
}
|
||||
else
|
||||
{
|
||||
padapter->bSurpriseRemoved=true;
|
||||
DBG_8192C("bSurpriseRemoved=true\n");
|
||||
/* rtl8192cu_trigger_gpio_0(padapter); */
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port_complete:bSurpriseRemoved=true\n"));
|
||||
|
||||
goto check_completion;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
|
||||
pHalData->srestpriv.last_tx_complete_time = jiffies;
|
||||
}
|
||||
check_completion:
|
||||
_enter_critical(&pxmitpriv->lock_sctx, &irqL);
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx,
|
||||
purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
|
||||
_exit_critical(&pxmitpriv->lock_sctx, &irqL);
|
||||
|
||||
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
|
||||
|
||||
/* if (rtw_txframes_pending(padapter)) */
|
||||
{
|
||||
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
|
||||
{
|
||||
unsigned long irqL;
|
||||
unsigned int pipe;
|
||||
int status;
|
||||
u32 ret = _FAIL, bwritezero = false;
|
||||
struct urb *purb = NULL;
|
||||
struct adapter *padapter = (struct adapter *)pintfhdl->padapter;
|
||||
struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem;
|
||||
struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
|
||||
struct usb_device *pusbd = pdvobj->pusbdev;
|
||||
struct pkt_attrib *pattrib = &pxmitframe->attrib;
|
||||
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("+usb_write_port\n"));
|
||||
|
||||
if ((padapter->bDriverStopped) || (padapter->bSurpriseRemoved) ||(dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx)) {
|
||||
#ifdef DBG_TX
|
||||
DBG_88E(" DBG_TX %s:%d bDriverStopped%d, bSurpriseRemoved:%d, pnp_bstop_trx:%d\n",__FUNCTION__, __LINE__
|
||||
,padapter->bDriverStopped, padapter->bSurpriseRemoved, dvobj_to_pwrctl(pdvobj)->pnp_bstop_trx );
|
||||
#endif
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||pwrctl->pnp_bstop_trx)!!!\n"));
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
_enter_critical(&pxmitpriv->lock, &irqL);
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case VO_QUEUE_INX:
|
||||
pxmitpriv->voq_cnt++;
|
||||
pxmitbuf->flags = VO_QUEUE_INX;
|
||||
break;
|
||||
case VI_QUEUE_INX:
|
||||
pxmitpriv->viq_cnt++;
|
||||
pxmitbuf->flags = VI_QUEUE_INX;
|
||||
break;
|
||||
case BE_QUEUE_INX:
|
||||
pxmitpriv->beq_cnt++;
|
||||
pxmitbuf->flags = BE_QUEUE_INX;
|
||||
break;
|
||||
case BK_QUEUE_INX:
|
||||
pxmitpriv->bkq_cnt++;
|
||||
pxmitbuf->flags = BK_QUEUE_INX;
|
||||
break;
|
||||
case HIGH_QUEUE_INX:
|
||||
pxmitbuf->flags = HIGH_QUEUE_INX;
|
||||
break;
|
||||
default:
|
||||
pxmitbuf->flags = MGT_QUEUE_INX;
|
||||
break;
|
||||
}
|
||||
|
||||
_exit_critical(&pxmitpriv->lock, &irqL);
|
||||
|
||||
#ifdef DBG_TRX_STA_PKTS
|
||||
{
|
||||
struct sta_info *psta = NULL;
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
int bmcast = IS_MCAST(pattrib->dst);
|
||||
u8 agg_num = 1;
|
||||
|
||||
if (pxmitframe->agg_num>1)
|
||||
agg_num = pxmitframe->agg_num;
|
||||
|
||||
if (bmcast)
|
||||
psta = rtw_get_bcmc_stainfo(padapter);
|
||||
|
||||
else
|
||||
psta = rtw_get_stainfo(pstapriv, pattrib->dst);
|
||||
if (psta) {
|
||||
switch (pattrib->priority) {
|
||||
case 1:
|
||||
case 2:
|
||||
psta->tx_bk_cnt += agg_num;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
psta->tx_vi_cnt += agg_num;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
psta->tx_vo_cnt += agg_num;
|
||||
break;
|
||||
case 0:
|
||||
case 3:
|
||||
default:
|
||||
psta->tx_be_cnt += agg_num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
purb = pxmitbuf->pxmit_urb[0];
|
||||
|
||||
/* translate DMA FIFO addr to pipehandle */
|
||||
pipe = ffaddr2pipehdl(pdvobj, addr);
|
||||
|
||||
#ifdef CONFIG_REDUCE_USB_TX_INT
|
||||
if ( (pxmitpriv->free_xmitbuf_cnt%NR_XMITBUFF == 0)
|
||||
|| (pxmitbuf->ext_tag == true) )
|
||||
{
|
||||
purb->transfer_flags &= (~URB_NO_INTERRUPT);
|
||||
} else {
|
||||
purb->transfer_flags |= URB_NO_INTERRUPT;
|
||||
/* DBG_8192C("URB_NO_INTERRUPT "); */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
usb_fill_bulk_urb(purb, pusbd, pipe,
|
||||
pxmitframe->buf_addr, /* pxmitbuf->pbuf */
|
||||
cnt,
|
||||
usb_write_port_complete,
|
||||
pxmitbuf);/* context is pxmitbuf */
|
||||
status = usb_submit_urb(purb, GFP_ATOMIC);
|
||||
if (!status) {
|
||||
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
|
||||
pHalData->srestpriv.last_tx_time = jiffies;
|
||||
} else {
|
||||
rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
|
||||
DBG_88E("usb_write_port, status=%d\n", status);
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_write_port(): usb_submit_urb, status=%x\n", status));
|
||||
|
||||
switch (status) {
|
||||
case -ENODEV:
|
||||
padapter->bDriverStopped=true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret= _SUCCESS;
|
||||
|
||||
/* Commented by Albert 2009/10/13 */
|
||||
/* We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */
|
||||
/*
|
||||
if (bwritezero == true)
|
||||
{
|
||||
usb_bulkout_zero(pintfhdl, addr);
|
||||
}
|
||||
*/
|
||||
|
||||
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("-usb_write_port\n"));
|
||||
|
||||
exit:
|
||||
if (ret != _SUCCESS)
|
||||
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
|
||||
;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void usb_write_port_cancel(struct intf_hdl *pintfhdl)
|
||||
{
|
||||
int i, j;
|
||||
struct adapter *padapter = pintfhdl->padapter;
|
||||
struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf;
|
||||
|
||||
DBG_88E("%s\n", __func__);
|
||||
|
||||
padapter->bWritePortCancel = true;
|
||||
|
||||
for (i=0; i<NR_XMITBUFF; i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
if (pxmitbuf->pxmit_urb[j]) {
|
||||
usb_kill_urb(pxmitbuf->pxmit_urb[j]);
|
||||
}
|
||||
}
|
||||
pxmitbuf++;
|
||||
}
|
||||
|
||||
pxmitbuf = (struct xmit_buf*)padapter->xmitpriv.pxmit_extbuf;
|
||||
for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
|
||||
for (j=0; j<8; j++) {
|
||||
if (pxmitbuf->pxmit_urb[j]) {
|
||||
usb_kill_urb(pxmitbuf->pxmit_urb[j]);
|
||||
}
|
||||
}
|
||||
pxmitbuf++;
|
||||
}
|
||||
}
|
|
@ -1,339 +0,0 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
#define _XMIT_OSDEP_C_
|
||||
|
||||
#include <drv_conf.h>
|
||||
#include <osdep_service.h>
|
||||
#include <drv_types.h>
|
||||
|
||||
#include <if_ether.h>
|
||||
#include <ip.h>
|
||||
#include <wifi.h>
|
||||
#include <mlme_osdep.h>
|
||||
#include <xmit_osdep.h>
|
||||
#include <osdep_intf.h>
|
||||
#include <circ_buf.h>
|
||||
|
||||
uint rtw_remainder_len(struct pkt_file *pfile)
|
||||
{
|
||||
return (pfile->buf_len - ((SIZE_PTR)(pfile->cur_addr) - (SIZE_PTR)(pfile->buf_start)));
|
||||
}
|
||||
|
||||
void _rtw_open_pktfile (struct sk_buff *pktptr, struct pkt_file *pfile)
|
||||
{
|
||||
;
|
||||
|
||||
pfile->pkt = pktptr;
|
||||
pfile->cur_addr = pfile->buf_start = pktptr->data;
|
||||
pfile->pkt_len = pfile->buf_len = pktptr->len;
|
||||
|
||||
pfile->cur_buffer = pfile->buf_start ;
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
uint _rtw_pktfile_read (struct pkt_file *pfile, u8 *rmem, uint rlen)
|
||||
{
|
||||
uint len = 0;
|
||||
|
||||
len = rtw_remainder_len(pfile);
|
||||
len = (rlen > len)? len: rlen;
|
||||
|
||||
if (rmem)
|
||||
skb_copy_bits(pfile->pkt, pfile->buf_len-pfile->pkt_len, rmem, len);
|
||||
|
||||
pfile->cur_addr += len;
|
||||
pfile->pkt_len -= len;
|
||||
return len;
|
||||
}
|
||||
|
||||
sint rtw_endofpktfile(struct pkt_file *pfile)
|
||||
{
|
||||
if (pfile->pkt_len == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf,u32 alloc_sz)
|
||||
{
|
||||
int i;
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz);
|
||||
if (pxmitbuf->pallocated_buf == NULL)
|
||||
{
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
pxmitbuf->pbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitbuf->pallocated_buf), XMITBUF_ALIGN_SZ);
|
||||
pxmitbuf->dma_transfer_addr = 0;
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (pxmitbuf->pxmit_urb[i] == NULL) {
|
||||
DBG_88E("pxmitbuf->pxmit_urb[i]== NULL");
|
||||
return _FAIL;
|
||||
}
|
||||
|
||||
}
|
||||
return _SUCCESS;
|
||||
}
|
||||
|
||||
void rtw_os_xmit_resource_free(struct adapter *padapter, struct xmit_buf *pxmitbuf,u32 free_sz)
|
||||
{
|
||||
int i;
|
||||
struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
|
||||
struct usb_device *pusbd = pdvobjpriv->pusbdev;
|
||||
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
if (pxmitbuf->pxmit_urb[i])
|
||||
{
|
||||
/* usb_kill_urb(pxmitbuf->pxmit_urb[i]); */
|
||||
usb_free_urb(pxmitbuf->pxmit_urb[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pxmitbuf->pallocated_buf)
|
||||
rtw_mfree(pxmitbuf->pallocated_buf, free_sz);
|
||||
}
|
||||
|
||||
#define WMM_XMIT_THRESHOLD (NR_XMITFRAME*2/5)
|
||||
|
||||
void rtw_os_pkt_complete(struct adapter *padapter, struct sk_buff *pkt)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
|
||||
u16 queue;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
queue = skb_get_queue_mapping(pkt);
|
||||
if (padapter->registrypriv.wifi_spec) {
|
||||
if (__netif_subqueue_stopped(padapter->pnetdev, queue) &&
|
||||
(pxmitpriv->hwxmits[queue].accnt < WMM_XMIT_THRESHOLD))
|
||||
{
|
||||
netif_wake_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
} else {
|
||||
if (__netif_subqueue_stopped(padapter->pnetdev, queue))
|
||||
netif_wake_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
#else
|
||||
if (netif_queue_stopped(padapter->pnetdev))
|
||||
netif_wake_queue(padapter->pnetdev);
|
||||
#endif
|
||||
|
||||
rtw_skb_free(pkt);
|
||||
}
|
||||
|
||||
void rtw_os_xmit_complete(struct adapter *padapter, struct xmit_frame *pxframe)
|
||||
{
|
||||
if (pxframe->pkt)
|
||||
rtw_os_pkt_complete(padapter, pxframe->pkt);
|
||||
|
||||
pxframe->pkt = NULL;
|
||||
}
|
||||
|
||||
void rtw_os_xmit_schedule(struct adapter *padapter)
|
||||
{
|
||||
struct adapter *pri_adapter = padapter;
|
||||
|
||||
unsigned long irqL;
|
||||
struct xmit_priv *pxmitpriv;
|
||||
|
||||
if (!padapter)
|
||||
return;
|
||||
|
||||
pxmitpriv = &padapter->xmitpriv;
|
||||
|
||||
spin_lock_bh(&pxmitpriv->lock);
|
||||
|
||||
if (rtw_txframes_pending(padapter))
|
||||
tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
|
||||
|
||||
spin_unlock_bh(&pxmitpriv->lock);
|
||||
}
|
||||
|
||||
static void rtw_check_xmit_resource(struct adapter *padapter, struct sk_buff *pkt)
|
||||
{
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
|
||||
u16 queue;
|
||||
|
||||
queue = skb_get_queue_mapping(pkt);
|
||||
if (padapter->registrypriv.wifi_spec) {
|
||||
/* No free space for Tx, tx_worker is too slow */
|
||||
if (pxmitpriv->hwxmits[queue].accnt > WMM_XMIT_THRESHOLD) {
|
||||
/* DBG_88E("%s(): stop netif_subqueue[%d]\n", __FUNCTION__, queue); */
|
||||
netif_stop_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
} else {
|
||||
if (pxmitpriv->free_xmitframe_cnt<=4) {
|
||||
if (!netif_tx_queue_stopped(netdev_get_tx_queue(padapter->pnetdev, queue)))
|
||||
netif_stop_subqueue(padapter->pnetdev, queue);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (pxmitpriv->free_xmitframe_cnt<=4)
|
||||
{
|
||||
if (!rtw_netif_queue_stopped(padapter->pnetdev))
|
||||
rtw_netif_stop_queue(padapter->pnetdev);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb)
|
||||
{
|
||||
struct sta_priv *pstapriv = &padapter->stapriv;
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
unsigned long irqL;
|
||||
struct list_head *phead, *plist;
|
||||
struct sk_buff *newskb;
|
||||
struct sta_info *psta = NULL;
|
||||
u8 chk_alive_num = 0;
|
||||
char chk_alive_list[NUM_STA];
|
||||
u8 bc_addr[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
u8 null_addr[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
int i;
|
||||
s32 res;
|
||||
|
||||
spin_lock_bh(&pstapriv->asoc_list_lock);
|
||||
phead = &pstapriv->asoc_list;
|
||||
plist = get_next(phead);
|
||||
|
||||
/* free sta asoc_queue */
|
||||
while ((rtw_end_of_queue_search(phead, plist)) == false) {
|
||||
int stainfo_offset;
|
||||
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
|
||||
plist = get_next(plist);
|
||||
|
||||
stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
|
||||
if (stainfo_offset_valid(stainfo_offset)) {
|
||||
chk_alive_list[chk_alive_num++] = stainfo_offset;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&pstapriv->asoc_list_lock);
|
||||
|
||||
for (i = 0; i < chk_alive_num; i++) {
|
||||
psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
|
||||
if (!(psta->state &_FW_LINKED))
|
||||
continue;
|
||||
|
||||
/* avoid come from STA1 and send back STA1 */
|
||||
if (_rtw_memcmp(psta->hwaddr, &skb->data[6], 6) == true
|
||||
|| _rtw_memcmp(psta->hwaddr, null_addr, 6) == true
|
||||
|| _rtw_memcmp(psta->hwaddr, bc_addr, 6) == true
|
||||
)
|
||||
continue;
|
||||
|
||||
newskb = rtw_skb_copy(skb);
|
||||
|
||||
if (newskb) {
|
||||
memcpy(newskb->data, psta->hwaddr, 6);
|
||||
res = rtw_xmit(padapter, &newskb);
|
||||
if (res < 0) {
|
||||
DBG_88E("%s()-%d: rtw_xmit() return error!\n", __FUNCTION__, __LINE__);
|
||||
pxmitpriv->tx_drop++;
|
||||
rtw_skb_free(newskb);
|
||||
} else
|
||||
pxmitpriv->tx_pkts++;
|
||||
} else {
|
||||
DBG_88E("%s-%d: rtw_skb_copy() failed!\n", __FUNCTION__, __LINE__);
|
||||
pxmitpriv->tx_drop++;
|
||||
/* rtw_skb_free(skb); */
|
||||
return false; /* Caller shall tx this multicast frame via normal way. */
|
||||
}
|
||||
}
|
||||
|
||||
rtw_skb_free(skb);
|
||||
return true;
|
||||
}
|
||||
|
||||
int _rtw_xmit_entry(struct sk_buff *pkt, struct net_device * pnetdev)
|
||||
{
|
||||
struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev);
|
||||
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
|
||||
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
|
||||
s32 res = 0;
|
||||
#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
|
||||
u16 queue;
|
||||
#endif
|
||||
|
||||
;
|
||||
|
||||
RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("+xmit_enry\n"));
|
||||
|
||||
if (rtw_if_up(padapter) == false) {
|
||||
RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("rtw_xmit_entry: rtw_if_up fail\n"));
|
||||
#ifdef DBG_TX_DROP_FRAME
|
||||
DBG_88E("DBG_TX_DROP_FRAME %s if_up fail\n", __FUNCTION__);
|
||||
#endif
|
||||
goto drop_packet;
|
||||
}
|
||||
|
||||
rtw_check_xmit_resource(padapter, pkt);
|
||||
|
||||
if ( !rtw_mc2u_disable
|
||||
&& check_fwstate(pmlmepriv, WIFI_AP_STATE) == true
|
||||
&& ( IP_MCAST_MAC(pkt->data)
|
||||
|| ICMPV6_MCAST_MAC(pkt->data) )
|
||||
&& (padapter->registrypriv.wifi_spec == 0)
|
||||
)
|
||||
{
|
||||
if ( pxmitpriv->free_xmitframe_cnt > (NR_XMITFRAME/4) ) {
|
||||
res = rtw_mlcst2unicst(padapter, pkt);
|
||||
if (res == true) {
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = rtw_xmit(padapter, &pkt);
|
||||
if (res < 0) {
|
||||
#ifdef DBG_TX_DROP_FRAME
|
||||
DBG_88E("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__);
|
||||
#endif
|
||||
goto drop_packet;
|
||||
}
|
||||
|
||||
pxmitpriv->tx_pkts++;
|
||||
RT_TRACE(_module_xmit_osdep_c_, _drv_info_, ("rtw_xmit_entry: tx_pkts=%d\n", (u32)pxmitpriv->tx_pkts));
|
||||
goto exit;
|
||||
|
||||
drop_packet:
|
||||
pxmitpriv->tx_drop++;
|
||||
rtw_skb_free(pkt);
|
||||
RT_TRACE(_module_xmit_osdep_c_, _drv_notice_, ("rtw_xmit_entry: drop, tx_drop=%d\n", (u32)pxmitpriv->tx_drop));
|
||||
|
||||
exit:
|
||||
|
||||
;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtw_xmit_entry(struct sk_buff *pkt, struct net_device * pnetdev)
|
||||
{
|
||||
if (pkt)
|
||||
rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, pkt->truesize);
|
||||
return _rtw_xmit_entry(pkt, pnetdev);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue