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:

committed by
Akash Patel

parent
2476ef58f4
commit
59f861d11d
@@ -631,6 +631,20 @@ typedef struct hdd_cfg80211_state_s {
|
|||||||
eP2PActionFrameState actionFrmState;
|
eP2PActionFrameState actionFrmState;
|
||||||
} hdd_cfg80211_state_t;
|
} 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 {
|
struct hdd_station_ctx {
|
||||||
/** Handle to the Wireless Extension State */
|
/** Handle to the Wireless Extension State */
|
||||||
hdd_wext_state_t WextState;
|
hdd_wext_state_t WextState;
|
||||||
@@ -665,6 +679,8 @@ struct hdd_station_ctx {
|
|||||||
int staDebugState;
|
int staDebugState;
|
||||||
|
|
||||||
uint8_t broadcast_ibss_staid;
|
uint8_t broadcast_ibss_staid;
|
||||||
|
|
||||||
|
struct hdd_mon_set_ch_info ch_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BSS_STOP 0
|
#define BSS_STOP 0
|
||||||
|
@@ -128,11 +128,9 @@ static inline void wlan_hdd_log_eapol(struct sk_buff *skb,
|
|||||||
}
|
}
|
||||||
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
|
#endif /* FEATURE_WLAN_DIAG_SUPPORT */
|
||||||
|
|
||||||
|
|
||||||
const char *hdd_reason_type_to_string(enum netif_reason_type reason);
|
const char *hdd_reason_type_to_string(enum netif_reason_type reason);
|
||||||
const char *hdd_action_type_to_string(enum netif_action_type action);
|
const char *hdd_action_type_to_string(enum netif_action_type action);
|
||||||
void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
|
void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
|
||||||
enum netif_action_type action, enum netif_reason_type reason);
|
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) */
|
#endif /* end #if !defined(WLAN_HDD_TX_RX_H) */
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
#include <csr_api.h>
|
#include <csr_api.h>
|
||||||
#include <wlan_hdd_misc.h>
|
#include <wlan_hdd_misc.h>
|
||||||
#include <wlan_hdd_napi.h>
|
#include <wlan_hdd_napi.h>
|
||||||
|
#include <cds_concurrency.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId)
|
cb_notify_set_roam_prefer5_g_hz(hdd_context_t *pHddCtx, unsigned long notifyId)
|
||||||
@@ -5474,6 +5475,66 @@ config_exit:
|
|||||||
return qdf_status;
|
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
|
* hdd_parse_config_ini() - parse the ini configuration file
|
||||||
* @pHddCtx: the pointer to hdd context
|
* @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,
|
hdd_napi_event(NAPI_EVT_INI_FILE,
|
||||||
(void *)pHddCtx->config->napi_enable);
|
(void *)pHddCtx->config->napi_enable);
|
||||||
#endif /* FEATURE_NAPI */
|
#endif /* FEATURE_NAPI */
|
||||||
|
if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
|
||||||
|
hdd_override_all_ps(pHddCtx);
|
||||||
|
|
||||||
config_exit:
|
config_exit:
|
||||||
release_firmware(fw);
|
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
|
static struct ieee80211_iface_combination
|
||||||
wlan_hdd_iface_combination[] = {
|
wlan_hdd_iface_combination[] = {
|
||||||
/* STA */
|
/* STA */
|
||||||
@@ -5908,26 +5926,35 @@ int wlan_hdd_cfg80211_init(struct device *dev,
|
|||||||
|
|
||||||
wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
|
wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
|
||||||
|
|
||||||
/* Supports STATION & AD-HOC modes right now */
|
if (cds_get_conparam() != QDF_GLOBAL_MONITOR_MODE) {
|
||||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
|
/* Supports STATION & AD-HOC modes right now */
|
||||||
| BIT(NL80211_IFTYPE_ADHOC)
|
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
|
||||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
| BIT(NL80211_IFTYPE_ADHOC)
|
||||||
| BIT(NL80211_IFTYPE_P2P_GO)
|
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||||
| BIT(NL80211_IFTYPE_AP);
|
| BIT(NL80211_IFTYPE_P2P_GO)
|
||||||
|
| BIT(NL80211_IFTYPE_AP);
|
||||||
|
|
||||||
if (pCfg->advertiseConcurrentOperation) {
|
if (pCfg->advertiseConcurrentOperation) {
|
||||||
if (pCfg->enableMCC) {
|
if (pCfg->enableMCC) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < ARRAY_SIZE(wlan_hdd_iface_combination);
|
|
||||||
i++) {
|
for (i = 0;
|
||||||
if (!pCfg->allowMCCGODiffBI)
|
i < ARRAY_SIZE(wlan_hdd_iface_combination);
|
||||||
wlan_hdd_iface_combination[i].
|
i++) {
|
||||||
beacon_int_infra_match = true;
|
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 =
|
wiphy->n_iface_combinations =
|
||||||
ARRAY_SIZE(wlan_hdd_iface_combination);
|
ARRAY_SIZE(wlan_hdd_mon_iface);
|
||||||
wiphy->iface_combinations = wlan_hdd_iface_combination;
|
wiphy->iface_combinations = wlan_hdd_mon_iface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Before registering we need to update the ht capabilitied based
|
/* 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;
|
uint8_t iniDot11Mode = (WLAN_HDD_GET_CTX(pAdapter))->config->dot11Mode;
|
||||||
eHddDot11Mode hddDot11Mode = iniDot11Mode;
|
eHddDot11Mode hddDot11Mode = iniDot11Mode;
|
||||||
struct ch_params_s ch_params;
|
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 =
|
ch_params.ch_width =
|
||||||
(WLAN_HDD_GET_CTX(pAdapter))->config->vhtChannelWidth;
|
(WLAN_HDD_GET_CTX(pAdapter))->config->vhtChannelWidth;
|
||||||
|
|
||||||
@@ -8264,10 +8295,20 @@ void hdd_select_cbmode(hdd_adapter_t *pAdapter, uint8_t operationChannel)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* This call decides required channel bonding mode */
|
/* 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),
|
hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
|
||||||
operationChannel, 0,
|
operationChannel, 0,
|
||||||
&ch_params);
|
&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;
|
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
|
* struct cfg80211_ops - cfg80211_ops
|
||||||
*
|
*
|
||||||
@@ -11956,4 +12084,5 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = {
|
|||||||
#ifdef CHANNEL_SWITCH_SUPPORTED
|
#ifdef CHANNEL_SWITCH_SUPPORTED
|
||||||
.channel_switch = wlan_hdd_cfg80211_channel_switch,
|
.channel_switch = wlan_hdd_cfg80211_channel_switch,
|
||||||
#endif
|
#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);
|
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
|
* __hdd_open() - HDD Open function
|
||||||
* @dev: Pointer to net_device structure
|
* @dev: Pointer to net_device structure
|
||||||
@@ -1892,9 +1928,44 @@ static struct net_device_ops wlan_drv_ops = {
|
|||||||
#endif
|
#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)
|
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)
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
|
||||||
name_assign_type,
|
name_assign_type,
|
||||||
#endif
|
#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) {
|
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_CLIENT_MODE:
|
||||||
case QDF_P2P_DEVICE_MODE:
|
case QDF_P2P_DEVICE_MODE:
|
||||||
case QDF_OCB_MODE:
|
case QDF_OCB_MODE:
|
||||||
|
case QDF_MONITOR_MODE:
|
||||||
{
|
{
|
||||||
adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
|
adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
|
||||||
name_assign_type,
|
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;
|
adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
|
||||||
else if (QDF_P2P_DEVICE_MODE == session_type)
|
else if (QDF_P2P_DEVICE_MODE == session_type)
|
||||||
adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
|
adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
|
||||||
|
else if (QDF_MONITOR_MODE == session_type)
|
||||||
|
adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
|
||||||
else
|
else
|
||||||
adapter->wdev.iftype = NL80211_IFTYPE_STATION;
|
adapter->wdev.iftype = NL80211_IFTYPE_STATION;
|
||||||
|
|
||||||
@@ -5635,6 +5711,21 @@ static inline int hdd_open_p2p_interface(struct hdd_context_t *hdd_ctx,
|
|||||||
}
|
}
|
||||||
#endif
|
#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_open_interfaces - Open all required interfaces
|
||||||
* hdd_ctx: HDD context
|
* hdd_ctx: HDD context
|
||||||
@@ -6059,7 +6150,10 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc)
|
|||||||
|
|
||||||
rtnl_held = hdd_hold_rtnl_lock();
|
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)) {
|
if (IS_ERR(adapter)) {
|
||||||
ret = PTR_ERR(adapter);
|
ret = PTR_ERR(adapter);
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
#include "wlan_hdd_lro.h"
|
#include "wlan_hdd_lro.h"
|
||||||
|
|
||||||
#include "cdp_txrx_peer_ops.h"
|
#include "cdp_txrx_peer_ops.h"
|
||||||
|
#include "ol_txrx.h"
|
||||||
|
|
||||||
#ifdef FEATURE_WLAN_DIAG_SUPPORT
|
#ifdef FEATURE_WLAN_DIAG_SUPPORT
|
||||||
#define HDD_EAPOL_ETHER_TYPE (0x888E)
|
#define HDD_EAPOL_ETHER_TYPE (0x888E)
|
||||||
@@ -669,6 +670,84 @@ QDF_STATUS hdd_deinit_tx_rx(hdd_adapter_t *pAdapter)
|
|||||||
return status;
|
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
|
* hdd_rx_packet_cbk() - Receive packet handler
|
||||||
* @context: pointer to HDD context
|
* @context: pointer to HDD context
|
||||||
@@ -1108,3 +1187,45 @@ void wlan_hdd_netif_queue_control(hdd_adapter_t *adapter,
|
|||||||
return;
|
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_SCAN_CONFIG 21
|
||||||
#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
|
#define WE_SET_DUAL_MAC_FW_MODE_CONFIG 22
|
||||||
|
#define WE_SET_MON_MODE_CHAN 23
|
||||||
|
|
||||||
#ifdef FEATURE_WLAN_TDLS
|
#ifdef FEATURE_WLAN_TDLS
|
||||||
#undef MAX_VAR_ARGS
|
#undef MAX_VAR_ARGS
|
||||||
@@ -9728,6 +9729,53 @@ static int iw_set_band_config(struct net_device *dev,
|
|||||||
return ret;
|
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,
|
static int __iw_set_two_ints_getnone(struct net_device *dev,
|
||||||
struct iw_request_info *info,
|
struct iw_request_info *info,
|
||||||
union iwreq_data *wrqu, char *extra)
|
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)
|
if (value[1] == DUMP_DP_TRACE)
|
||||||
qdf_dp_trace_dump_all(value[2]);
|
qdf_dp_trace_dump_all(value[2]);
|
||||||
break;
|
break;
|
||||||
|
case WE_SET_MON_MODE_CHAN:
|
||||||
|
ret = wlan_hdd_set_mon_chan(pAdapter, value[1], value[2]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
|
hddLog(LOGE, "%s: Invalid IOCTL command %d", __func__, sub_cmd);
|
||||||
break;
|
break;
|
||||||
@@ -11014,6 +11065,10 @@ static const struct iw_priv_args we_private_args[] = {
|
|||||||
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
|
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
|
||||||
0, "dump_dp_trace"}
|
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 = {
|
const struct iw_handler_def we_handler_def = {
|
||||||
|
@@ -494,6 +494,7 @@ typedef enum eSirBssType {
|
|||||||
eSIR_INFRA_AP_MODE, /* Added for softAP support */
|
eSIR_INFRA_AP_MODE, /* Added for softAP support */
|
||||||
eSIR_IBSS_MODE,
|
eSIR_IBSS_MODE,
|
||||||
eSIR_AUTO_MODE,
|
eSIR_AUTO_MODE,
|
||||||
|
eSIR_MONITOR_MODE,
|
||||||
eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE
|
eSIR_DONOT_USE_BSS_TYPE = SIR_MAX_ENUM_SIZE
|
||||||
} tSirBssType;
|
} tSirBssType;
|
||||||
|
|
||||||
@@ -2429,6 +2430,18 @@ typedef struct sSirUpdateParams {
|
|||||||
uint8_t ssidHidden; /* Hide SSID */
|
uint8_t ssidHidden; /* Hide SSID */
|
||||||
} tSirUpdateParams, *tpSirUpdateParams;
|
} 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 */
|
/* Beacon Interval */
|
||||||
typedef struct sSirChangeBIParams {
|
typedef struct sSirChangeBIParams {
|
||||||
uint16_t messageType;
|
uint16_t messageType;
|
||||||
|
@@ -249,6 +249,7 @@ enum eWniMsgTypes {
|
|||||||
eWNI_SME_SET_ANTENNA_MODE_REQ,
|
eWNI_SME_SET_ANTENNA_MODE_REQ,
|
||||||
eWNI_SME_SET_ANTENNA_MODE_RESP,
|
eWNI_SME_SET_ANTENNA_MODE_RESP,
|
||||||
eWNI_SME_TSF_EVENT,
|
eWNI_SME_TSF_EVENT,
|
||||||
|
eWNI_SME_MON_INIT_SESSION,
|
||||||
eWNI_SME_MSG_TYPES_END
|
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,
|
QDF_STATUS sme_set_bpf_instructions(tHalHandle hal,
|
||||||
struct sir_bpf_set_offload *);
|
struct sir_bpf_set_offload *);
|
||||||
|
|
||||||
|
QDF_STATUS sme_create_mon_session(tHalHandle hal_handle, uint8_t *bssid);
|
||||||
#endif /* #if !defined( __SME_API_H ) */
|
#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;
|
return qdf_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sme_get_bpf_offload_capabilities() - Get length for BPF offload
|
* sme_get_bpf_offload_capabilities() - Get length for BPF offload
|
||||||
* @hal: Global HAL handle
|
* @hal: Global HAL handle
|
||||||
@@ -15754,3 +15753,26 @@ QDF_STATUS sme_bpf_offload_register_callback(tHalHandle hal,
|
|||||||
}
|
}
|
||||||
return status;
|
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;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user