mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 06:03:36 -04:00
qcacld-3.0: Add monitor mode support
Add monitor mode support. Configure target to deliver 802.11 packets in raw mode. Below is the procedure to start the monitor mode. insmod /system/lib/modules/wlan.ko con_mode=4 ifconfig wlan0 up "iwpriv wlan0 setMonChan 36 2" or "iw dev mon0 set channel 36 HT40+" tcpdump -i wlan0 -w <tcpdump.pcap> In this mode concurrency is not supported and module doesnot support Tx. Change-Id: I211ece0a66e2d43bc111e523714942e1557e36f4 CRs-Fixed: 963060
This commit is contained in:
parent
2476ef58f4
commit
59f861d11d
11 changed files with 538 additions and 25 deletions
|
|
@ -631,6 +631,20 @@ typedef struct hdd_cfg80211_state_s {
|
|||
eP2PActionFrameState actionFrmState;
|
||||
} hdd_cfg80211_state_t;
|
||||
|
||||
/**
|
||||
* struct hdd_mon_set_ch_info - Holds monitor mode channel switch params
|
||||
* @channel: Channel number.
|
||||
* @cb_mode: Channel bonding
|
||||
* @channel_width: Channel width 0/1/2 for 20/40/80MHz respectively.
|
||||
* @phy_mode: PHY mode
|
||||
*/
|
||||
struct hdd_mon_set_ch_info {
|
||||
uint8_t channel;
|
||||
uint8_t cb_mode;
|
||||
uint32_t channel_width;
|
||||
eCsrPhyMode phy_mode;
|
||||
};
|
||||
|
||||
struct hdd_station_ctx {
|
||||
/** Handle to the Wireless Extension State */
|
||||
hdd_wext_state_t WextState;
|
||||
|
|
@ -665,6 +679,8 @@ struct hdd_station_ctx {
|
|||
int staDebugState;
|
||||
|
||||
uint8_t broadcast_ibss_staid;
|
||||
|
||||
struct hdd_mon_set_ch_info ch_info;
|
||||
};
|
||||
|
||||
#define BSS_STOP 0
|
||||
|
|
|
|||
|
|
@ -128,11 +128,9 @@ static inline void wlan_hdd_log_eapol(struct sk_buff *skb,
|
|||
}
|
||||
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
|
||||
|
||||
|
||||
const char *hdd_reason_type_to_string(enum netif_reason_type reason);
|
||||
const char *hdd_action_type_to_string(enum netif_action_type action);
|
||||
void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
|
||||
enum netif_action_type action, enum netif_reason_type reason);
|
||||
|
||||
|
||||
int hdd_set_mon_rx_cb(struct net_device *dev);
|
||||
#endif /* end #if !defined(WLAN_HDD_TX_RX_H) */
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include <csr_api.h>
|
||||
#include <wlan_hdd_misc.h>
|
||||
#include <wlan_hdd_napi.h>
|
||||
#include <cds_concurrency.h>
|
||||
|
||||
static void
|
||||
cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId)
|
||||
|
|
@ -5474,6 +5475,66 @@ config_exit:
|
|||
return qdf_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_disable_runtime_pm() - Override to disable runtime_pm.
|
||||
* @cfg_ini: Handle to struct hdd_config
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#ifdef FEATURE_RUNTIME_PM
|
||||
static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
|
||||
{
|
||||
cfg_ini->runtime_pm = 0;
|
||||
}
|
||||
#else
|
||||
static void hdd_disable_runtime_pm(struct hdd_config *cfg_ini)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_disable_auto_shutdown() - Override to disable auto_shutdown.
|
||||
* @cfg_ini: Handle to struct hdd_config
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
|
||||
static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
|
||||
{
|
||||
cfg_ini->WlanAutoShutdown = 0;
|
||||
}
|
||||
#else
|
||||
static void hdd_disable_auto_shutdown(struct hdd_config *cfg_ini)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_override_all_ps() - overrides to disables all the powersave features.
|
||||
* @hdd_ctx: Pointer to HDD context.
|
||||
* Overrides below powersave ini configurations.
|
||||
* gEnableImps=0
|
||||
* gEnableBmps=0
|
||||
* gRuntimePM=0
|
||||
* gWlanAutoShutdown = 0
|
||||
* gEnableSuspend=0
|
||||
* gEnablePowerSaveOffload=0
|
||||
* gEnableWoW=0
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void hdd_override_all_ps(hdd_context_t *hdd_ctx)
|
||||
{
|
||||
struct hdd_config *cfg_ini = hdd_ctx->config;
|
||||
|
||||
cfg_ini->fIsImpsEnabled = 0;
|
||||
cfg_ini->is_ps_enabled = 0;
|
||||
hdd_disable_runtime_pm(cfg_ini);
|
||||
hdd_disable_auto_shutdown(cfg_ini);
|
||||
cfg_ini->enablePowersaveOffload = 0;
|
||||
cfg_ini->wowEnable = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_parse_config_ini() - parse the ini configuration file
|
||||
* @pHddCtx: the pointer to hdd context
|
||||
|
|
@ -5577,6 +5638,8 @@ QDF_STATUS hdd_parse_config_ini(hdd_context_t *pHddCtx)
|
|||
hdd_napi_event(NAPI_EVT_INI_FILE,
|
||||
(void *)pHddCtx->config->napi_enable);
|
||||
#endif /* FEATURE_NAPI */
|
||||
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
|
||||
hdd_override_all_ps(pHddCtx);
|
||||
|
||||
config_exit:
|
||||
release_firmware(fw);
|
||||
|
|
|
|||
|
|
@ -505,6 +505,24 @@ wlan_hdd_p2p_p2p_iface_limit[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_limit
|
||||
wlan_hdd_mon_iface_limit[] = {
|
||||
{
|
||||
.max = 3, /* Monitor interface */
|
||||
.types = BIT(NL80211_IFTYPE_MONITOR),
|
||||
},
|
||||
};
|
||||
|
||||
static struct ieee80211_iface_combination
|
||||
wlan_hdd_mon_iface[] = {
|
||||
{
|
||||
.limits = wlan_hdd_mon_iface_limit,
|
||||
.max_interfaces = 3,
|
||||
.num_different_channels = 2,
|
||||
.n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit),
|
||||
},
|
||||
};
|
||||
|
||||
static struct ieee80211_iface_combination
|
||||
wlan_hdd_iface_combination[] = {
|
||||
/* STA */
|
||||
|
|
@ -5908,26 +5926,35 @@ int wlan_hdd_cfg80211_init(struct device *dev,
|
|||
|
||||
wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
|
||||
|
||||
/* Supports STATION & AD-HOC modes right now */
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_ADHOC)
|
||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||
| BIT(NL80211_IFTYPE_P2P_GO)
|
||||
| BIT(NL80211_IFTYPE_AP);
|
||||
if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE) {
|
||||
/* Supports STATION & AD-HOC modes right now */
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_ADHOC)
|
||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||
| BIT(NL80211_IFTYPE_P2P_GO)
|
||||
| BIT(NL80211_IFTYPE_AP);
|
||||
|
||||
if (pCfg->advertiseConcurrentOperation) {
|
||||
if (pCfg->enableMCC) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(wlan_hdd_iface_combination);
|
||||
i++) {
|
||||
if (!pCfg->allowMCCGODiffBI)
|
||||
wlan_hdd_iface_combination[i].
|
||||
beacon_int_infra_match = true;
|
||||
if (pCfg->advertiseConcurrentOperation) {
|
||||
if (pCfg->enableMCC) {
|
||||
int i;
|
||||
|
||||
for (i = 0;
|
||||
i < ARRAY_SIZE(wlan_hdd_iface_combination);
|
||||
i++) {
|
||||
if (!pCfg->allowMCCGODiffBI)
|
||||
wlan_hdd_iface_combination[i].
|
||||
beacon_int_infra_match = true;
|
||||
}
|
||||
}
|
||||
wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(wlan_hdd_iface_combination);
|
||||
wiphy->iface_combinations = wlan_hdd_iface_combination;
|
||||
}
|
||||
} else {
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_MONITOR);
|
||||
wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(wlan_hdd_iface_combination);
|
||||
wiphy->iface_combinations = wlan_hdd_iface_combination;
|
||||
ARRAY_SIZE(wlan_hdd_mon_iface);
|
||||
wiphy->iface_combinations = wlan_hdd_mon_iface;
|
||||
}
|
||||
|
||||
/* Before registering we need to update the ht capabilitied based
|
||||
|
|
@ -8242,6 +8269,10 @@ void hdd_select_cbmode(hdd_adapter_t *pAdapter, uint8_t operationChannel)
|
|||
uint8_t iniDot11Mode = (WLAN_HDD_GET_CTX(pAdapter))->config->dot11Mode;
|
||||
eHddDot11Mode hddDot11Mode = iniDot11Mode;
|
||||
struct ch_params_s ch_params;
|
||||
hdd_station_ctx_t *station_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
|
||||
uint32_t cb_mode;
|
||||
struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info;
|
||||
|
||||
ch_params.ch_width =
|
||||
(WLAN_HDD_GET_CTX(pAdapter))->config->vhtChannelWidth;
|
||||
|
||||
|
|
@ -8264,10 +8295,20 @@ void hdd_select_cbmode(hdd_adapter_t *pAdapter, uint8_t operationChannel)
|
|||
break;
|
||||
}
|
||||
/* This call decides required channel bonding mode */
|
||||
sme_set_ch_params((WLAN_HDD_GET_CTX(pAdapter)->hHal),
|
||||
cb_mode = sme_set_ch_params((WLAN_HDD_GET_CTX(pAdapter)->hHal),
|
||||
hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
|
||||
operationChannel, 0,
|
||||
&ch_params);
|
||||
|
||||
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) {
|
||||
ch_info->channel_width = ch_params.ch_width;
|
||||
ch_info->phy_mode = hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode);
|
||||
ch_info->channel = operationChannel;
|
||||
ch_info->cb_mode = cb_mode;
|
||||
hdd_info("ch_info width %d, phymode %d channel %d",
|
||||
ch_info->channel_width, ch_info->phy_mode,
|
||||
ch_info->channel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -11841,6 +11882,93 @@ enum cds_con_mode wlan_hdd_convert_nl_iftype_to_hdd_type(
|
|||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
|
||||
* @wiphy: Handle to struct wiphy to get handle to module context.
|
||||
* @chandef: Contains information about the capture channel to be set.
|
||||
*
|
||||
* This interface is called if and only if monitor mode interface alone is
|
||||
* active.
|
||||
*
|
||||
* Return: 0 success or error code on failure.
|
||||
*/
|
||||
static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
|
||||
hdd_adapter_t *adapter;
|
||||
hdd_station_ctx_t *sta_ctx;
|
||||
struct hdd_mon_set_ch_info *ch_info;
|
||||
QDF_STATUS status;
|
||||
tHalHandle hal_hdl;
|
||||
struct qdf_mac_addr bssid;
|
||||
tCsrRoamProfile roam_profile;
|
||||
struct ch_params_s ch_params;
|
||||
int ret;
|
||||
uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq);
|
||||
|
||||
ENTER();
|
||||
|
||||
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hal_hdl = hdd_ctx->hHal;
|
||||
|
||||
adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
|
||||
if (!adapter)
|
||||
return -EIO;
|
||||
|
||||
hdd_info("%s: set monitor mode Channel %d and freq %d",
|
||||
adapter->dev->name, chan_num, chandef->chan->center_freq);
|
||||
|
||||
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
ch_info = &sta_ctx->ch_info;
|
||||
hdd_select_cbmode(adapter, chan_num);
|
||||
roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
|
||||
roam_profile.ChannelInfo.numOfChannels = 1;
|
||||
roam_profile.phyMode = ch_info->phy_mode;
|
||||
roam_profile.ch_params.ch_width = chandef->width;
|
||||
|
||||
qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
ch_params.ch_width = chandef->width;
|
||||
sme_set_ch_params(hal_hdl, ch_info->phy_mode, chan_num, 0,
|
||||
&ch_params);
|
||||
status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params,
|
||||
&roam_profile);
|
||||
if (status) {
|
||||
hdd_err("Status: %d Failed to set sme_RoamChannel for monitor mode",
|
||||
status);
|
||||
ret = qdf_status_to_os_return(status);
|
||||
return ret;
|
||||
}
|
||||
EXIT();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
|
||||
* @wiphy: Handle to struct wiphy to get handle to module context.
|
||||
* @chandef: Contains information about the capture channel to be set.
|
||||
*
|
||||
* This interface is called if and only if monitor mode interface alone is
|
||||
* active.
|
||||
*
|
||||
* Return: 0 success or error code on failure.
|
||||
*/
|
||||
static int wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __wlan_hdd_cfg80211_set_mon_ch(wiphy, chandef);
|
||||
cds_ssr_unprotect(__func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct cfg80211_ops - cfg80211_ops
|
||||
*
|
||||
|
|
@ -11956,4 +12084,5 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = {
|
|||
#ifdef CHANNEL_SWITCH_SUPPORTED
|
||||
.channel_switch = wlan_hdd_cfg80211_channel_switch,
|
||||
#endif
|
||||
.set_monitor_channel = wlan_hdd_cfg80211_set_mon_ch,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1435,6 +1435,42 @@ bool hdd_is_valid_mac_address(const uint8_t *pMacAddr)
|
|||
return xdigit == 12 && (separator == 5 || separator == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* __hdd__mon_open() - HDD Open function
|
||||
* @dev: Pointer to net_device structure
|
||||
*
|
||||
* This is called in response to ifconfig up
|
||||
*
|
||||
* Return: 0 for success; non-zero for failure
|
||||
*/
|
||||
static int __hdd_mon_open(struct net_device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ENTER_DEV(dev);
|
||||
ret = hdd_set_mon_rx_cb(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
|
||||
* @dev: Pointer to net_device structure
|
||||
*
|
||||
* This is called in response to ifconfig up
|
||||
*
|
||||
* Return: 0 for success; non-zero for failure
|
||||
*/
|
||||
int hdd_mon_open(struct net_device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cds_ssr_protect(__func__);
|
||||
ret = __hdd_mon_open(dev);
|
||||
cds_ssr_unprotect(__func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* __hdd_open() - HDD Open function
|
||||
* @dev: Pointer to net_device structure
|
||||
|
|
@ -1892,9 +1928,44 @@ static struct net_device_ops wlan_drv_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
|
||||
static struct net_device_ops wlan_mon_drv_ops = {
|
||||
.ndo_open = hdd_mon_open,
|
||||
.ndo_stop = hdd_stop,
|
||||
.ndo_get_stats = hdd_get_stats,
|
||||
};
|
||||
|
||||
/**
|
||||
* hdd_set_station_ops() - update net_device ops for monitor mode
|
||||
* @pWlanDev: Handle to struct net_device to be updated.
|
||||
* Return: None
|
||||
*/
|
||||
void hdd_set_station_ops(struct net_device *pWlanDev)
|
||||
{
|
||||
pWlanDev->netdev_ops = &wlan_drv_ops;
|
||||
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
|
||||
pWlanDev->netdev_ops = &wlan_mon_drv_ops;
|
||||
else
|
||||
pWlanDev->netdev_ops = &wlan_drv_ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
|
||||
* @dev: Handle to struct net_device to be updated.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void hdd_mon_mode_ether_setup(struct net_device *dev)
|
||||
{
|
||||
dev->header_ops = NULL;
|
||||
dev->type = ARPHRD_IEEE80211_RADIOTAP;
|
||||
dev->hard_header_len = ETH_HLEN;
|
||||
dev->mtu = ETH_DATA_LEN;
|
||||
dev->addr_len = ETH_ALEN;
|
||||
dev->tx_queue_len = 1000; /* Ethernet wants good queues */
|
||||
dev->flags = IFF_BROADCAST|IFF_MULTICAST;
|
||||
dev->priv_flags |= IFF_TX_SKB_SHARING;
|
||||
|
||||
memset(dev->broadcast, 0xFF, ETH_ALEN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1922,7 +1993,9 @@ static hdd_adapter_t *hdd_alloc_station_adapter(hdd_context_t *hdd_ctx,
|
|||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
|
||||
name_assign_type,
|
||||
#endif
|
||||
ether_setup, NUM_TX_QUEUES);
|
||||
(QDF_GLOBAL_MONITOR_MODE == cds_get_conparam() ?
|
||||
hdd_mon_mode_ether_setup : ether_setup),
|
||||
NUM_TX_QUEUES);
|
||||
|
||||
if (pWlanDev != NULL) {
|
||||
|
||||
|
|
@ -2434,6 +2507,7 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
|
|||
case QDF_P2P_CLIENT_MODE:
|
||||
case QDF_P2P_DEVICE_MODE:
|
||||
case QDF_OCB_MODE:
|
||||
case QDF_MONITOR_MODE:
|
||||
{
|
||||
adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
|
||||
name_assign_type,
|
||||
|
|
@ -2450,6 +2524,8 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, uint8_t session_type,
|
|||
adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
|
||||
else if (QDF_P2P_DEVICE_MODE == session_type)
|
||||
adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
|
||||
else if (QDF_MONITOR_MODE == session_type)
|
||||
adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
|
||||
else
|
||||
adapter->wdev.iftype = NL80211_IFTYPE_STATION;
|
||||
|
||||
|
|
@ -5635,6 +5711,21 @@ static inline int hdd_open_p2p_interface(struct hdd_context_t *hdd_ctx,
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hdd_open_monitor_interface() - Open monitor mode interface
|
||||
* @hdd_ctx: HDD context
|
||||
* @rtnl_held: True if RTNL lock is held
|
||||
*
|
||||
* Return: Primary adapter on success and PTR_ERR on failure
|
||||
*/
|
||||
static hdd_adapter_t *hdd_open_monitor_interface(hdd_context_t *hdd_ctx,
|
||||
bool rtnl_held)
|
||||
{
|
||||
return hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
|
||||
wlan_hdd_get_intf_addr(hdd_ctx),
|
||||
NET_NAME_UNKNOWN, rtnl_held);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_open_interfaces - Open all required interfaces
|
||||
* hdd_ctx: HDD context
|
||||
|
|
@ -6059,7 +6150,10 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
|
|||
|
||||
rtnl_held = hdd_hold_rtnl_lock();
|
||||
|
||||
adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
|
||||
if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam())
|
||||
adapter = hdd_open_monitor_interface(hdd_ctx, rtnl_held);
|
||||
else
|
||||
adapter = hdd_open_interfaces(hdd_ctx, rtnl_held);
|
||||
|
||||
if (IS_ERR(adapter)) {
|
||||
ret = PTR_ERR(adapter);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "wlan_hdd_lro.h"
|
||||
|
||||
#include "cdp_txrx_peer_ops.h"
|
||||
#include "ol_txrx.h"
|
||||
|
||||
#ifdef FEATURE_WLAN_DIAG_SUPPORT
|
||||
#define HDD_EAPOL_ETHER_TYPE (0x888E)
|
||||
|
|
@ -669,6 +670,84 @@ QDF_STATUS hdd_deinit_tx_rx(hdd_adapter_t *pAdapter)
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_mon_rx_packet_cbk() - Receive callback registered with OL layer.
|
||||
* @context: [in] pointer to qdf context
|
||||
* @rxBuf: [in] pointer to rx qdf_nbuf
|
||||
*
|
||||
* TL will call this to notify the HDD when one or more packets were
|
||||
* received for a registered STA.
|
||||
*
|
||||
* Return: QDF_STATUS_E_FAILURE if any errors encountered, QDF_STATUS_SUCCESS
|
||||
* otherwise
|
||||
*/
|
||||
static QDF_STATUS hdd_mon_rx_packet_cbk(void *context, qdf_nbuf_t rxbuf)
|
||||
{
|
||||
hdd_adapter_t *adapter;
|
||||
int rxstat;
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb_next;
|
||||
unsigned int cpu_index;
|
||||
|
||||
/* Sanity check on inputs */
|
||||
if ((NULL == context) || (NULL == rxbuf)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: Null params being passed", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
adapter = (hdd_adapter_t *)context;
|
||||
if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
|
||||
"invalid adapter %p", adapter);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
cpu_index = wlan_hdd_get_cpu();
|
||||
|
||||
/* walk the chain until all are processed */
|
||||
skb = (struct sk_buff *) rxbuf;
|
||||
while (NULL != skb) {
|
||||
skb_next = skb->next;
|
||||
skb->dev = adapter->dev;
|
||||
|
||||
++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
|
||||
++adapter->stats.rx_packets;
|
||||
adapter->stats.rx_bytes += skb->len;
|
||||
|
||||
/* Remove SKB from internal tracking table before submitting
|
||||
* it to stack
|
||||
*/
|
||||
qdf_net_buf_debug_release_skb(skb);
|
||||
|
||||
/*
|
||||
* If this is not a last packet on the chain
|
||||
* Just put packet into backlog queue, not scheduling RX sirq
|
||||
*/
|
||||
if (skb->next) {
|
||||
rxstat = netif_rx(skb);
|
||||
} else {
|
||||
/*
|
||||
* This is the last packet on the chain
|
||||
* Scheduling rx sirq
|
||||
*/
|
||||
rxstat = netif_rx_ni(skb);
|
||||
}
|
||||
|
||||
if (NET_RX_SUCCESS == rxstat)
|
||||
++adapter->
|
||||
hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
|
||||
else
|
||||
++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
|
||||
|
||||
skb = skb_next;
|
||||
}
|
||||
|
||||
adapter->dev->last_rx = jiffies;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_rx_packet_cbk() - Receive packet handler
|
||||
* @context: pointer to HDD context
|
||||
|
|
@ -1108,3 +1187,45 @@ void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
|
|||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_set_mon_rx_cb() - Set Monitor mode Rx callback
|
||||
* @dev: Pointer to net_device structure
|
||||
*
|
||||
* Return: 0 for success; non-zero for failure
|
||||
*/
|
||||
int hdd_set_mon_rx_cb(struct net_device *dev)
|
||||
{
|
||||
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
|
||||
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
int ret;
|
||||
QDF_STATUS qdf_status;
|
||||
struct ol_txrx_desc_type sta_desc = {0};
|
||||
struct ol_txrx_ops txrx_ops;
|
||||
|
||||
ret = wlan_hdd_validate_context(hdd_ctx);
|
||||
if (0 != ret)
|
||||
return ret;
|
||||
|
||||
qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
|
||||
txrx_ops.rx.rx = hdd_mon_rx_packet_cbk;
|
||||
ol_txrx_vdev_register(
|
||||
ol_txrx_get_vdev_from_vdev_id(adapter->sessionId),
|
||||
adapter, &txrx_ops);
|
||||
/* peer is created wma_vdev_attach->wma_create_peer */
|
||||
qdf_status = ol_txrx_register_peer(&sta_desc);
|
||||
if (QDF_STATUS_SUCCESS != qdf_status) {
|
||||
hdd_err("WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08X]",
|
||||
qdf_status, qdf_status);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
qdf_status = sme_create_mon_session(hdd_ctx->hHal,
|
||||
adapter->macAddressCurrent.bytes);
|
||||
if (QDF_STATUS_SUCCESS != qdf_status) {
|
||||
hdd_err("sme_create_mon_session() failed to register. Status= %d [0x%08X]",
|
||||
qdf_status, qdf_status);
|
||||
}
|
||||
exit:
|
||||
ret = qdf_status_to_os_return(qdf_status);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -367,6 +367,7 @@ static const hdd_freq_chan_map_t freq_chan_map[] = {
|
|||
|
||||
#define WE_SET_DUAL_MAC_SCAN_CONFIG 21
|
||||
#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
|
||||
#define WE_SET_MON_MODE_CHAN 23
|
||||
|
||||
#ifdef FEATURE_WLAN_TDLS
|
||||
#undef MAX_VAR_ARGS
|
||||
|
|
@ -9728,6 +9729,53 @@ static int iw_set_band_config(struct net_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_hdd_set_mon_chan() - Set capture channel on the monitor mode interface.
|
||||
* @adapter: Handle to adapter
|
||||
* @chan: Monitor mode channel
|
||||
* @bandwidth: Capture channel bandwidth
|
||||
*
|
||||
* Return: 0 on success else error code.
|
||||
*/
|
||||
static int wlan_hdd_set_mon_chan(hdd_adapter_t *adapter, uint32_t chan,
|
||||
uint32_t bandwidth)
|
||||
{
|
||||
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
|
||||
hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
|
||||
struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
|
||||
QDF_STATUS status;
|
||||
tHalHandle hal_hdl = hdd_ctx->hHal;
|
||||
struct qdf_mac_addr bssid;
|
||||
tCsrRoamProfile roam_profile;
|
||||
struct ch_params_s ch_params;
|
||||
|
||||
if (QDF_GLOBAL_MONITOR_MODE != hdd_get_conparam()) {
|
||||
hdd_err("Not supported, device is not in monitor mode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hdd_info("Set monitor mode Channel %d", chan);
|
||||
hdd_select_cbmode(adapter, chan);
|
||||
roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
|
||||
roam_profile.ChannelInfo.numOfChannels = 1;
|
||||
roam_profile.phyMode = ch_info->phy_mode;
|
||||
roam_profile.ch_params.ch_width = bandwidth;
|
||||
|
||||
qdf_mem_copy(bssid.bytes, adapter->macAddressCurrent.bytes,
|
||||
QDF_MAC_ADDR_SIZE);
|
||||
|
||||
ch_params.ch_width = bandwidth;
|
||||
sme_set_ch_params(hal_hdl, ch_info->phy_mode, chan, 0, &ch_params);
|
||||
status = sme_roam_channel_change_req(hal_hdl, bssid, &ch_params,
|
||||
&roam_profile);
|
||||
if (status) {
|
||||
hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
|
||||
status);
|
||||
}
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
}
|
||||
|
||||
static int __iw_set_two_ints_getnone(struct net_device *dev,
|
||||
struct iw_request_info *info,
|
||||
union iwreq_data *wrqu, char *extra)
|
||||
|
|
@ -9793,6 +9841,9 @@ static int __iw_set_two_ints_getnone(struct net_device *dev,
|
|||
if (value[1] == DUMP_DP_TRACE)
|
||||
qdf_dp_trace_dump_all(value[2]);
|
||||
break;
|
||||
case WE_SET_MON_MODE_CHAN:
|
||||
ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]);
|
||||
break;
|
||||
default:
|
||||
hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
|
||||
break;
|
||||
|
|
@ -11014,6 +11065,10 @@ static const struct iw_priv_args we_private_args[] = {
|
|||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
|
||||
0, "dump_dp_trace"}
|
||||
,
|
||||
{WE_SET_MON_MODE_CHAN,
|
||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
|
||||
0, "setMonChan"}
|
||||
,
|
||||
};
|
||||
|
||||
const struct iw_handler_def we_handler_def = {
|
||||
|
|
|
|||
|
|
@ -494,6 +494,7 @@ typedef enum eSirBssType {
|
|||
eSIR_INFRA_AP_MODE, /* Added for softAP support */
|
||||
eSIR_IBSS_MODE,
|
||||
eSIR_AUTO_MODE,
|
||||
eSIR_MONITOR_MODE,
|
||||
eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE
|
||||
} tSirBssType;
|
||||
|
||||
|
|
@ -2429,6 +2430,18 @@ typedef struct sSirUpdateParams {
|
|||
uint8_t ssidHidden; /* Hide SSID */
|
||||
} tSirUpdateParams, *tpSirUpdateParams;
|
||||
|
||||
/**
|
||||
* struct sir_create_session - Used for creating session in monitor mode
|
||||
* @type: SME host message type.
|
||||
* @msg_len: Length of the message.
|
||||
* @bss_id: bss_id for creating the session.
|
||||
*/
|
||||
struct sir_create_session {
|
||||
uint16_t type;
|
||||
uint16_t msg_len;
|
||||
struct qdf_mac_addr bss_id;
|
||||
};
|
||||
|
||||
/* Beacon Interval */
|
||||
typedef struct sSirChangeBIParams {
|
||||
uint16_t messageType;
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ enum eWniMsgTypes {
|
|||
eWNI_SME_SET_ANTENNA_MODE_REQ,
|
||||
eWNI_SME_SET_ANTENNA_MODE_RESP,
|
||||
eWNI_SME_TSF_EVENT,
|
||||
eWNI_SME_MON_INIT_SESSION,
|
||||
eWNI_SME_MSG_TYPES_END
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1125,4 +1125,5 @@ QDF_STATUS sme_get_bpf_offload_capabilities(tHalHandle hal);
|
|||
QDF_STATUS sme_set_bpf_instructions(tHalHandle hal,
|
||||
struct sir_bpf_set_offload *);
|
||||
|
||||
QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, uint8_t *bssid);
|
||||
#endif /* #if !defined( __SME_API_H ) */
|
||||
|
|
|
|||
|
|
@ -15630,7 +15630,6 @@ QDF_STATUS sme_remove_beacon_filter(tHalHandle hal, uint32_t session_id)
|
|||
return qdf_status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sme_get_bpf_offload_capabilities() - Get length for BPF offload
|
||||
* @hal: Global HAL handle
|
||||
|
|
@ -15754,3 +15753,26 @@ QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal,
|
|||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* sme_create_mon_session() - post message to create PE session for monitormode
|
||||
* operation
|
||||
* @hal_handle: Handle to the HAL
|
||||
* @bssid: pointer to bssid
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, non-zero error code on failure.
|
||||
*/
|
||||
QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, tSirMacAddr bss_id)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||
struct sir_create_session *msg;
|
||||
|
||||
msg = qdf_mem_malloc(sizeof(*msg));
|
||||
if (NULL != msg) {
|
||||
msg->type = eWNI_SME_MON_INIT_SESSION;
|
||||
msg->msg_len = sizeof(*msg);
|
||||
qdf_mem_copy(msg->bss_id.bytes, bss_id, QDF_MAC_ADDR_SIZE);
|
||||
status = cds_send_mb_message_to_mac(msg);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue