Merge commit '34a8aa2497' into HEAD

Change-Id: I8f98d7fdbcf039d3e0406a3d6fa784edba96cb3c
This commit is contained in:
sumap 2023-11-16 14:58:38 +05:30
commit d8bf480b51
22 changed files with 516 additions and 83 deletions

1
Kbuild
View file

@ -2620,6 +2620,7 @@ cppflags-$(CONFIG_FEATURE_WLAN_SCAN_PNO) += -DFEATURE_WLAN_SCAN_PNO
cppflags-$(CONFIG_WLAN_FEATURE_PACKET_FILTERING) += -DWLAN_FEATURE_PACKET_FILTERING
cppflags-$(CONFIG_DHCP_SERVER_OFFLOAD) += -DDHCP_SERVER_OFFLOAD
cppflags-$(CONFIG_WLAN_NS_OFFLOAD) += -DWLAN_NS_OFFLOAD
cppflags-$(CONFIG_WLAN_DYNAMIC_ARP_NS_OFFLOAD) += -DFEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
cppflags-$(CONFIG_FEATURE_WLAN_RA_FILTERING) += -DFEATURE_WLAN_RA_FILTERING
cppflags-$(CONFIG_FEATURE_WLAN_LPHB) += -DFEATURE_WLAN_LPHB
cppflags-$(CONFIG_QCA_SUPPORT_TX_THROTTLE) += -DQCA_SUPPORT_TX_THROTTLE

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -238,6 +239,20 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
*/
bool pkt_capture_is_tx_mgmt_enable(struct wlan_objmgr_pdev *pdev);
/**
* pkt_capture_is_frame_filter_set - Check if filter type set by user and packet
* type matches
* @buf: netbuf
* @frame_filter: filter set by user via vendor command
* @direction: Tx or Rx
*
* Return: bool
*/
bool
pkt_capture_is_frame_filter_set(qdf_nbuf_t buf,
struct pkt_capture_frame_filter *frame_filter,
bool direction);
#ifdef WLAN_FEATURE_PKT_CAPTURE_V2
/**
* pkt_capture_get_pktcap_mode_v2 - Get packet capture mode

View file

@ -1634,9 +1634,51 @@ void pkt_capture_offload_deliver_indication_handler(
struct pkt_capture_tx_hdr_elem_t *ptr_pktcapture_hdr;
struct pkt_capture_tx_hdr_elem_t pktcapture_hdr = {0};
uint32_t txcap_hdr_size = sizeof(struct pkt_capture_tx_hdr_elem_t);
struct wlan_objmgr_vdev *vdev;
struct pkt_capture_vdev_priv *vdev_priv;
struct pkt_capture_frame_filter *frame_filter;
QDF_STATUS ret = QDF_STATUS_SUCCESS;
offload_deliver_msg = (struct htt_tx_offload_deliver_ind_hdr_t *)msg;
vdev = pkt_capture_get_vdev();
ret = pkt_capture_vdev_get_ref(vdev);
if (QDF_IS_STATUS_ERROR(ret))
return;
vdev_priv = pkt_capture_vdev_get_priv(vdev);
if (!vdev_priv) {
pkt_capture_err("vdev priv is NULL");
pkt_capture_vdev_put_ref(vdev);
return;
}
frame_filter = &vdev_priv->frame_filter;
nbuf_len = offload_deliver_msg->tx_mpdu_bytes;
netbuf = qdf_nbuf_alloc(NULL,
roundup(nbuf_len + RESERVE_BYTES, 4),
RESERVE_BYTES, 4, false);
if (!netbuf) {
pkt_capture_vdev_put_ref(vdev);
return;
}
qdf_nbuf_put_tail(netbuf, nbuf_len);
qdf_mem_copy(qdf_nbuf_data(netbuf),
buf + sizeof(struct htt_tx_offload_deliver_ind_hdr_t),
nbuf_len);
if (!(frame_filter->data_tx_frame_filter &
PKT_CAPTURE_DATA_FRAME_TYPE_ALL) &&
!pkt_capture_is_frame_filter_set(
netbuf, frame_filter, IEEE80211_FC1_DIR_TODS)) {
qdf_nbuf_free(netbuf);
pkt_capture_vdev_put_ref(vdev);
return;
}
pktcapture_hdr.timestamp = offload_deliver_msg->phy_timestamp_l32;
pktcapture_hdr.preamble = offload_deliver_msg->preamble;
pktcapture_hdr.mcs = offload_deliver_msg->mcs;
@ -1656,25 +1698,11 @@ void pkt_capture_offload_deliver_indication_handler(
status = offload_deliver_msg->status;
pkt_format = offload_deliver_msg->format;
nbuf_len = offload_deliver_msg->tx_mpdu_bytes;
netbuf = qdf_nbuf_alloc(NULL,
roundup(nbuf_len + RESERVE_BYTES, 4),
RESERVE_BYTES, 4, false);
if (!netbuf)
return;
qdf_nbuf_put_tail(netbuf, nbuf_len);
qdf_mem_copy(qdf_nbuf_data(netbuf),
buf + sizeof(struct htt_tx_offload_deliver_ind_hdr_t),
nbuf_len);
qdf_nbuf_push_head(netbuf, txcap_hdr_size);
ptr_pktcapture_hdr =
(struct pkt_capture_tx_hdr_elem_t *)qdf_nbuf_data(netbuf);
qdf_mem_copy(ptr_pktcapture_hdr, &pktcapture_hdr, txcap_hdr_size);
pkt_capture_datapkt_process(
@ -1682,5 +1710,7 @@ void pkt_capture_offload_deliver_indication_handler(
netbuf, TXRX_PROCESS_TYPE_DATA_TX,
tid, status, pkt_format, bssid, soc,
offload_deliver_msg->tx_retry_cnt);
pkt_capture_vdev_put_ref(vdev);
}
#endif

View file

@ -407,7 +407,7 @@ pkt_capture_process_tx_data(void *soc, void *log_data, u_int16_t vdev_id,
* Return: true, if filter bit is set
* false, if filter bit is not set
*/
static bool
bool
pkt_capture_is_frame_filter_set(qdf_nbuf_t buf,
struct pkt_capture_frame_filter *frame_filter,
bool direction)
@ -595,8 +595,6 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data,
struct htt_tx_offload_deliver_ind_hdr_t *offload_deliver_msg;
bool is_pkt_during_roam = false;
uint32_t freq = 0;
qdf_nbuf_t buf = log_data +
sizeof(struct htt_tx_offload_deliver_ind_hdr_t);
if (!frame_filter->data_tx_frame_filter) {
pkt_capture_vdev_put_ref(vdev);
@ -616,17 +614,9 @@ void pkt_capture_callback(void *soc, enum WDI_EVENT event, void *log_data,
vdev_id = offload_deliver_msg->vdev_id;
}
if (frame_filter->data_tx_frame_filter &
PKT_CAPTURE_DATA_FRAME_TYPE_ALL) {
pkt_capture_offload_deliver_indication_handler(
pkt_capture_offload_deliver_indication_handler(
log_data,
vdev_id, bssid, soc);
} else if (pkt_capture_is_frame_filter_set(
buf, frame_filter, IEEE80211_FC1_DIR_TODS)) {
pkt_capture_offload_deliver_indication_handler(
log_data,
vdev_id, bssid, soc);
}
break;
}
@ -1257,7 +1247,7 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
ol_txrx_soc_handle soc;
QDF_STATUS status;
enum pkt_capture_config config = 0;
bool check_enable_beacon = 0, send_bcn = 0;
bool send_bcn = 0;
struct vdev_mlme_obj *vdev_mlme;
uint32_t bcn_interval, nth_beacon_value;
@ -1342,16 +1332,13 @@ QDF_STATUS pkt_capture_set_filter(struct pkt_capture_frame_filter frame_filter,
PKT_CAPTURE_MGMT_CONNECT_NO_BEACON) {
mode |= PACKET_CAPTURE_MODE_MGMT_ONLY;
config |= PACKET_CAPTURE_CONFIG_NO_BEACON_ENABLE;
} else {
check_enable_beacon = 1;
}
}
if (check_enable_beacon) {
if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
PKT_CAPTURE_MGMT_CONNECT_BEACON)
PKT_CAPTURE_MGMT_CONNECT_BEACON) {
if (!send_bcn)
config |= PACKET_CAPTURE_CONFIG_BEACON_ENABLE;
}
if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
PKT_CAPTURE_MGMT_CONNECT_SCAN_BEACON)

View file

@ -592,10 +592,6 @@ pkt_capture_is_beacon_forward_enable(struct wlan_objmgr_vdev *vdev,
return false;
}
if (vdev_priv->frame_filter.mgmt_rx_frame_filter &
PKT_CAPTURE_MGMT_CONNECT_NO_BEACON)
return false;
mac_hdr = (tpSirMacMgmtHdr)(qdf_nbuf_data(wbuf));
wlan_vdev_get_bss_peer_mac(vdev, &connected_bssid);

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -110,6 +111,9 @@ struct wlan_pmo_ctx {
* @dyn_listen_interval: dynamically user configured listen interval
* @restore_dtim_setting: DTIM settings restore flag
* @pmo_vdev_lock: spin lock for pmo vdev priv ctx
* @dyn_arp_ns_offload_disable: true when arp/ns offload is disable
* @dyn_arp_ns_offload_rt_lock: wake lock which prevent runtime pm happen if
* arp/ns offload is disable
*/
struct pmo_vdev_priv_obj {
struct pmo_psoc_priv_obj *pmo_psoc_ctx;
@ -132,6 +136,10 @@ struct pmo_vdev_priv_obj {
uint32_t dyn_listen_interval;
bool restore_dtim_setting;
qdf_spinlock_t pmo_vdev_lock;
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
bool dyn_arp_ns_offload_disable;
qdf_runtime_lock_t dyn_arp_ns_offload_rt_lock;
#endif
};
#endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */

View file

@ -180,6 +180,112 @@ bool pmo_core_vdev_get_restore_dtim(struct wlan_objmgr_vdev *vdev)
return value;
}
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
/**
* pmo_core_dynamic_arp_ns_offload_enable() - Enable vdev arp/ns offload
* @vdev: objmgr vdev handle
*
* Return: QDF_STATUS_E_ALREADY if arp/ns offload already enable
*/
static inline QDF_STATUS
pmo_core_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev)
{
bool value;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct pmo_vdev_priv_obj *vdev_ctx;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
value = vdev_ctx->dyn_arp_ns_offload_disable;
if (!value)
status = QDF_STATUS_E_ALREADY;
else
vdev_ctx->dyn_arp_ns_offload_disable = false;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
return status;
}
/**
* pmo_core_dynamic_arp_ns_offload_disable() - Disable vdev arp/ns offload
* @vdev: objmgr vdev handle
*
* Return: QDF_STATUS_E_ALREADY if arp/ns offload already disable
*/
static inline QDF_STATUS
pmo_core_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
{
bool value;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct pmo_vdev_priv_obj *vdev_ctx;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
value = vdev_ctx->dyn_arp_ns_offload_disable;
if (value)
status = QDF_STATUS_E_ALREADY;
else
vdev_ctx->dyn_arp_ns_offload_disable = true;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
return status;
}
/**
* pmo_core_get_dynamic_arp_ns_offload_disable() - Get arp/ns offload state
* @vdev: objmgr vdev handle
*
* Return: true if vdev arp/ns offload is disable
*/
static inline bool
pmo_core_get_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
{
bool value;
struct pmo_vdev_priv_obj *vdev_ctx;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
value = vdev_ctx->dyn_arp_ns_offload_disable;
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
return value;
}
/**
* pmo_core_dynamic_arp_ns_offload_runtime_prevent() - Prevent runtime suspend
* @vdev: objmgr vdev handle
*
* API to prevent runtime suspend happen when arp/ns offload is disable
*
* Return: None
*/
static inline void
pmo_core_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev)
{
struct pmo_vdev_priv_obj *vdev_ctx;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_runtime_pm_prevent_suspend(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
}
/**
* pmo_core_dynamic_arp_ns_offload_runtime_allow() - Allow runtime suspend
* @vdev: objmgr vdev handle
*
* API to allow runtime suspend happen when arp/ns offload is enable
*
* Return: None
*/
static inline void
pmo_core_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev)
{
struct pmo_vdev_priv_obj *vdev_ctx;
vdev_ctx = pmo_vdev_get_priv(vdev);
qdf_runtime_pm_allow_suspend(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
}
#endif
/**
* pmo_core_update_power_save_mode() - update power save mode
* @vdev: objmgr vdev handle

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -129,6 +129,7 @@ pmo_core_do_enable_arp_offload(struct wlan_objmgr_vdev *vdev,
status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
break;
case pmo_apps_suspend:
case pmo_arp_ns_offload_dynamic_update:
/* enable arp when active offload is false (apps suspend) */
status = pmo_tgt_enable_arp_offload_req(vdev, vdev_id);
break;
@ -162,6 +163,7 @@ static QDF_STATUS pmo_core_do_disable_arp_offload(struct wlan_objmgr_vdev *vdev,
switch (trigger) {
case pmo_apps_resume:
case pmo_arp_ns_offload_dynamic_update:
/* disable arp on apps resume when active offload is disable */
status = pmo_tgt_disable_arp_offload_req(vdev, vdev_id);
break;

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -166,6 +166,7 @@ static QDF_STATUS pmo_core_do_enable_ns_offload(struct wlan_objmgr_vdev *vdev,
status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
break;
case pmo_apps_suspend:
case pmo_arp_ns_offload_dynamic_update:
/* enable arp when active offload is false (apps suspend) */
status = pmo_tgt_enable_ns_offload_req(vdev, vdev_id);
break;
@ -201,6 +202,7 @@ static QDF_STATUS pmo_core_do_disable_ns_offload(struct wlan_objmgr_vdev *vdev,
status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
break;
case pmo_apps_resume:
case pmo_arp_ns_offload_dynamic_update:
status = pmo_tgt_disable_ns_offload_req(vdev, vdev_id);
break;
default:

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -205,6 +206,7 @@ typedef QDF_STATUS(*pmo_psoc_resume_handler)
* @pmo_ns_offload_dynamic_update: enable/disable ns offload on the fly
* @pmo_peer_disconnect: trigger is peer disconnect
* @pmo_mcbc_setting_dynamic_update: mcbc value update on the fly
* @pmo_arp_ns_offload_dynamic_update: enable/disable arp/ns offload on the fly
*
* @pmo_offload_trigger_max: Max trigger value
*/
@ -219,6 +221,7 @@ enum pmo_offload_trigger {
pmo_ns_offload_dynamic_update,
pmo_peer_disconnect,
pmo_mcbc_setting_dynamic_update,
pmo_arp_ns_offload_dynamic_update,
pmo_offload_trigger_max,
};

View file

@ -545,6 +545,79 @@ ucfg_pmo_enhanced_mc_filter_disable(struct wlan_objmgr_vdev *vdev)
return pmo_core_enhanced_mc_filter_disable(vdev);
}
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
/**
* ucfg_pmo_dynamic_arp_ns_offload_enable() - enable arp/ns offload
* @vdev: vdev objmgr handle
*
* Return: QDF_STATUS
*/
QDF_STATUS
ucfg_pmo_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_pmo_dynamic_arp_ns_offload_disable() - disable arp/ns offload
* @vdev: vdev objmgr handle
*
* Return: QDF_STATUS
*/
QDF_STATUS
ucfg_pmo_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_pmo_get_arp_ns_offload_dynamic_disable() - get arp/ns offload state
* @vdev: vdev objmgr handle
*
* Return: QDF_STATUS
*/
bool
ucfg_pmo_get_arp_ns_offload_dynamic_disable(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent() - prevent runtime suspend
* @vdev: vdev objmgr handle
*
* Return: none
*/
void
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev);
/**
* ucfg_pmo_dynamic_arp_ns_offload_runtime_allow() - allow runtime suspend
* @vdev: vdev objmgr handle
*
* Return: none
*/
void
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev);
#else
static inline QDF_STATUS
ucfg_pmo_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS
ucfg_pmo_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
}
static inline bool
ucfg_pmo_get_arp_ns_offload_dynamic_disable(struct wlan_objmgr_vdev *vdev)
{
return false;
}
static inline void
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev)
{
}
static inline void
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev) {}
#endif
/**
* ucfg_pmo_enable_mc_addr_filtering_in_fwr(): Enable cached mc add list in fwr
* @psoc: objmgr psoc handle

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -227,6 +228,26 @@ out:
return status;
}
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
static inline void
pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj *vdev_ctx)
{
qdf_runtime_lock_init(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
}
static inline void
pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj *vdev_ctx)
{
qdf_runtime_lock_deinit(&vdev_ctx->dyn_arp_ns_offload_rt_lock);
}
#else
static inline void
pmo_vdev_dynamic_arp_ns_offload_init(struct pmo_vdev_priv_obj *vdev_ctx) {}
static inline void
pmo_vdev_dynamic_arp_ns_offload_deinit(struct pmo_vdev_priv_obj *vdev_ctx) {}
#endif
QDF_STATUS pmo_vdev_object_created_notification(
struct wlan_objmgr_vdev *vdev, void *arg)
{
@ -261,6 +282,7 @@ QDF_STATUS pmo_vdev_object_created_notification(
psoc_ctx->psoc_cfg.ptrn_match_enable_all_vdev;
vdev_ctx->pmo_psoc_ctx = psoc_ctx;
qdf_atomic_init(&vdev_ctx->gtk_err_enable);
pmo_vdev_dynamic_arp_ns_offload_init(vdev_ctx);
out:
pmo_exit();
@ -306,6 +328,7 @@ QDF_STATUS pmo_vdev_object_destroyed_notification(
pmo_err("Failed to detach vdev_ctx with vdev");
qdf_spinlock_destroy(&vdev_ctx->pmo_vdev_lock);
pmo_vdev_dynamic_arp_ns_offload_deinit(vdev_ctx);
qdf_mem_free(vdev_ctx);
return status;

View file

@ -195,6 +195,38 @@ ucfg_pmo_disable_ns_offload_in_fwr(struct wlan_objmgr_vdev *vdev,
}
#endif /* WLAN_NS_OFFLOAD */
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
QDF_STATUS
ucfg_pmo_dynamic_arp_ns_offload_enable(struct wlan_objmgr_vdev *vdev)
{
return pmo_core_dynamic_arp_ns_offload_enable(vdev);
}
QDF_STATUS
ucfg_pmo_dynamic_arp_ns_offload_disable(struct wlan_objmgr_vdev *vdev)
{
return pmo_core_dynamic_arp_ns_offload_disable(vdev);
}
bool
ucfg_pmo_get_arp_ns_offload_dynamic_disable(struct wlan_objmgr_vdev *vdev)
{
return pmo_core_get_dynamic_arp_ns_offload_disable(vdev);
}
void
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(struct wlan_objmgr_vdev *vdev)
{
return pmo_core_dynamic_arp_ns_offload_runtime_prevent(vdev);
}
void
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(struct wlan_objmgr_vdev *vdev)
{
return pmo_core_dynamic_arp_ns_offload_runtime_allow(vdev);
}
#endif
QDF_STATUS
ucfg_pmo_get_ns_offload_params(struct wlan_objmgr_vdev *vdev,
struct pmo_ns_offload_params *params)

View file

@ -7242,6 +7242,7 @@ const struct nla_policy wlan_hdd_wifi_config_policy[
[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_NSS] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_NSS] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD] = {.type = NLA_U8 },
[QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE] = {
.type = NLA_U8 },
};
@ -9024,6 +9025,103 @@ static int hdd_set_nss(struct hdd_adapter *adapter,
return ret;
}
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
#define DYNAMIC_ARP_NS_ENABLE 1
#define DYNAMIC_ARP_NS_DISABLE 0
/**
* hdd_set_arp_ns_offload() - enable/disable arp/ns offload feature
* @adapter: hdd adapter
* @attr: pointer to nla attr
*
* Return: 0 on success, negative errno on failure
*/
static int hdd_set_arp_ns_offload(struct hdd_adapter *adapter,
const struct nlattr *attr)
{
uint8_t offload_state;
int errno;
QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct wlan_objmgr_vdev *vdev;
errno = wlan_hdd_validate_context(hdd_ctx);
if (errno)
return errno;
if (!ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc) ||
!ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) {
hdd_err_rl("ARP/NS Offload is disabled by ini");
return -EINVAL;
}
if (!ucfg_pmo_is_active_mode_offloaded(hdd_ctx->psoc)) {
hdd_err_rl("active mode offload is disabled by ini");
return -EINVAL;
}
if (adapter->device_mode != QDF_STA_MODE &&
adapter->device_mode != QDF_P2P_CLIENT_MODE) {
hdd_err_rl("only support on sta/p2p-cli mode");
return -EINVAL;
}
vdev = hdd_objmgr_get_vdev(adapter);
if (!vdev) {
hdd_err("vdev is NULL");
return -EINVAL;
}
offload_state = nla_get_u8(attr);
if (offload_state == DYNAMIC_ARP_NS_ENABLE)
qdf_status = ucfg_pmo_dynamic_arp_ns_offload_enable(vdev);
else if (offload_state == DYNAMIC_ARP_NS_DISABLE)
qdf_status = ucfg_pmo_dynamic_arp_ns_offload_disable(vdev);
if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
if (offload_state == DYNAMIC_ARP_NS_ENABLE)
ucfg_pmo_dynamic_arp_ns_offload_runtime_allow(vdev);
else
ucfg_pmo_dynamic_arp_ns_offload_runtime_prevent(vdev);
}
hdd_objmgr_put_vdev(vdev);
if (QDF_IS_STATUS_ERROR(qdf_status)) {
if (qdf_status == QDF_STATUS_E_ALREADY) {
hdd_info_rl("already set arp/ns offload %d",
offload_state);
return 0;
}
return qdf_status_to_os_return(qdf_status);
}
if (!hdd_is_vdev_in_conn_state(adapter)) {
hdd_info("set not in connect state, updated state %d",
offload_state);
return 0;
}
if (offload_state == DYNAMIC_ARP_NS_ENABLE) {
hdd_enable_arp_offload(adapter,
pmo_arp_ns_offload_dynamic_update);
hdd_enable_ns_offload(adapter,
pmo_arp_ns_offload_dynamic_update);
} else if (offload_state == DYNAMIC_ARP_NS_DISABLE) {
hdd_disable_arp_offload(adapter,
pmo_arp_ns_offload_dynamic_update);
hdd_disable_ns_offload(adapter,
pmo_arp_ns_offload_dynamic_update);
}
return 0;
}
#undef DYNAMIC_ARP_NS_ENABLE
#undef DYNAMIC_ARP_NS_DISABLE
#endif
/**
* hdd_set_wfc_state() - Set wfc state
* @adapter: hdd adapter
@ -9168,6 +9266,10 @@ static const struct independent_setters independent_setters[] = {
hdd_config_udp_qos_upgrade_threshold},
{QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
hdd_set_ft_over_ds},
#ifdef FEATURE_WLAN_DYNAMIC_ARP_NS_OFFLOAD
{QCA_WLAN_VENDOR_ATTR_CONFIG_ARP_NS_OFFLOAD,
hdd_set_arp_ns_offload},
#endif
{QCA_WLAN_VENDOR_ATTR_CONFIG_WFC_STATE,
hdd_set_wfc_state},
};

View file

@ -6656,6 +6656,36 @@ static void disconnect_sta_and_stop_sap(struct hdd_context *hdd_ctx,
}
}
/**
* hdd_check_chan_and_fill_freq() - to validate chan and convert into freq
* @pdev: The physical dev to cache the channels for
* @in_chan: input as channel number or freq
* @freq: frequency for input in_chan (output parameter)
*
* This function checks input "in_chan" is channel number, if yes then fills
* appropriate frequency into "freq" out param. If the "in_param" is greater
* than MAX_5GHZ_CHANNEL then gets the valid frequencies for legacy channels
* else get the valid channel for 6Ghz frequency.
*
* Return: true if "in_chan" is valid channel/frequency; false otherwise
*/
static bool hdd_check_chan_and_fill_freq(struct wlan_objmgr_pdev *pdev,
uint32_t *in_chan, qdf_freq_t *freq)
{
if (IS_CHANNEL_VALID(*in_chan)) {
*freq = wlan_reg_legacy_chan_to_freq(pdev, *in_chan);
} else if (WLAN_REG_IS_24GHZ_CH_FREQ(*in_chan) ||
WLAN_REG_IS_5GHZ_CH_FREQ(*in_chan) ||
WLAN_REG_IS_6GHZ_CHAN_FREQ(*in_chan)) {
*freq = *in_chan;
*in_chan = wlan_reg_freq_to_chan(pdev, *in_chan);
} else {
return false;
}
return true;
}
/**
* hdd_parse_disable_chan_cmd() - Parse the channel list received
* in command.
@ -6665,11 +6695,13 @@ static void disconnect_sta_and_stop_sap(struct hdd_context *hdd_ctx,
* This function parses the channel list received in the command.
* command should be a string having format
* SET_DISABLE_CHANNEL_LIST <num of channels>
* <channels separated by spaces>.
* If the command comes multiple times than this function will compare
* the channels received in the command with the channles cached in the
* first command, if the channel list matches with the cached channles,
* it returns success otherwise returns failure.
* <channels separated by spaces>/<frequency separated by spaces>.
* If this command has frequency as input, this function first converts into
* equivalent channel.
* If the command comes multiple times then the channels received in the
* command or channels converted from frequency will be compared with the
* channels cached in the first command, if the channel list matches with
* the cached channels, it returns success otherwise returns failure.
*
* Return: 0 on success, Error code on failure
*/
@ -6681,6 +6713,7 @@ static int hdd_parse_disable_chan_cmd(struct hdd_adapter *adapter, uint8_t *ptr)
int j, i, temp_int, ret = 0, num_channels;
qdf_freq_t *chan_freq_list = NULL;
bool is_command_repeated = false;
qdf_freq_t freq = 0;
if (!hdd_ctx) {
hdd_err("HDD Context is NULL");
@ -6780,15 +6813,16 @@ static int hdd_parse_disable_chan_cmd(struct hdd_adapter *adapter, uint8_t *ptr)
goto parse_failed;
}
if (!IS_CHANNEL_VALID(temp_int)) {
if (!hdd_check_chan_and_fill_freq(hdd_ctx->pdev, &temp_int,
&freq)) {
hdd_err("Invalid channel number received");
ret = -EINVAL;
goto parse_failed;
}
hdd_debug("channel[%d] = %d", j, temp_int);
chan_freq_list[j] = wlan_reg_legacy_chan_to_freq(hdd_ctx->pdev,
temp_int);
hdd_debug("channel[%d] = %d Frequency[%d] = %d", j, temp_int,
j, freq);
chan_freq_list[j] = freq;
}
/*extra arguments check*/

View file

@ -564,7 +564,7 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
}
return os_if_nan_process_ndp_cmd(hdd_ctx->psoc, data, data_len,
hdd_is_ndp_allowed(hdd_ctx));
hdd_is_ndp_allowed(hdd_ctx), wdev);
}
/**

View file

@ -572,11 +572,23 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter,
ns_req->trigger = trigger;
ns_req->count = 0;
vdev = hdd_objmgr_get_vdev(adapter);
if (!vdev) {
hdd_err("vdev is NULL");
goto free_req;
}
/* check if offload cache and send is required or not */
status = ucfg_pmo_ns_offload_check(psoc, trigger, adapter->vdev_id);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_debug("NS offload is not required");
goto free_req;
goto put_vdev;
}
if (ucfg_pmo_get_arp_ns_offload_dynamic_disable(vdev)) {
hdd_debug("Dynamic arp ns offload disabled");
ucfg_pmo_flush_ns_offload_req(vdev);
goto skip_cache_ns;
}
/* Unicast Addresses */
@ -586,7 +598,7 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter,
if (errno) {
hdd_disable_ns_offload(adapter, trigger);
hdd_debug("Max supported addresses: disabling NS offload");
goto free_req;
goto put_vdev;
}
/* Anycast Addresses */
@ -596,21 +608,17 @@ void hdd_enable_ns_offload(struct hdd_adapter *adapter,
if (errno) {
hdd_disable_ns_offload(adapter, trigger);
hdd_debug("Max supported addresses: disabling NS offload");
goto free_req;
goto put_vdev;
}
/* cache ns request */
status = ucfg_pmo_cache_ns_offload_req(ns_req);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_debug("Failed to cache ns request; status:%d", status);
goto free_req;
goto put_vdev;
}
vdev = hdd_objmgr_get_vdev(adapter);
if (!vdev) {
hdd_err("vdev is NULL");
goto free_req;
}
skip_cache_ns:
/* enable ns request */
status = ucfg_pmo_enable_ns_offload_in_fwr(vdev, trigger);
if (QDF_IS_STATUS_ERROR(status)) {
@ -1284,6 +1292,12 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter,
goto put_vdev;
}
if (ucfg_pmo_get_arp_ns_offload_dynamic_disable(vdev)) {
hdd_debug("Dynamic arp ns offload disabled");
ucfg_pmo_flush_arp_offload_req(vdev);
goto skip_cache_arp;
}
ifa = hdd_get_ipv4_local_interface(adapter);
if (!ifa || !ifa->ifa_local) {
hdd_info("IP Address is not assigned");
@ -1299,6 +1313,7 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter,
goto put_vdev;
}
skip_cache_arp:
status = ucfg_pmo_enable_arp_offload_in_fwr(vdev, trigger);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("failed arp offload config in fw; status:%d", status);

View file

@ -32,9 +32,9 @@
#define QWLAN_VERSION_MAJOR 2
#define QWLAN_VERSION_MINOR 0
#define QWLAN_VERSION_PATCH 8
#define QWLAN_VERSION_EXTRA "R"
#define QWLAN_VERSION_BUILD 33
#define QWLAN_VERSION_EXTRA "B"
#define QWLAN_VERSION_BUILD 34
#define QWLAN_VERSIONSTR "2.0.8.33R"
#define QWLAN_VERSIONSTR "2.0.8.34B"
#endif /* QWLAN_VERSION_H */

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -3230,7 +3230,8 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx,
sap_debug("Restore chan freq: %d, width: %d",
restart_freq, restart_ch_width);
*csa_reason = CSA_REASON_BAND_RESTRICTED;
} else if (wlan_reg_is_disable_for_freq(mac->pdev,
} else if (wlan_reg_is_disable_in_secondary_list_for_freq(
mac->pdev,
sap_ctx->chan_freq)) {
sap_debug("channel is disabled");
*csa_reason = CSA_REASON_CHAN_DISABLED;

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -54,12 +55,14 @@ struct ndi_find_vdev_filter {
* @data_len: length of data
* @is_ndp_allowed: Indicates whether to allow NDP creation.
* NDI creation is always allowed.
* @wdev: Wireless device structure pointer
*
* Return: status of operation
*/
int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
const void *data, int data_len,
bool is_ndp_allowed);
bool is_ndp_allowed,
struct wireless_dev *wdev);
/**
* os_if_nan_register_hdd_callbacks: os_if api to register hdd callbacks

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -759,7 +759,6 @@ static int os_if_nan_process_ndp_initiator_req(struct wlan_objmgr_psoc *psoc,
* Return: 0 on success or error code on failure
*/
static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
char *iface_name,
struct nlattr **tb)
{
int ret = 0;
@ -767,6 +766,8 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
enum nan_datapath_state state;
struct wlan_objmgr_vdev *nan_vdev = NULL;
struct nan_datapath_responder_req req = {0};
char *iface_name;
int errno;
if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) {
osif_err("ndp_rsp is unavailable");
@ -775,6 +776,13 @@ static int __os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]);
if (req.ndp_rsp == NAN_DATAPATH_RESPONSE_ACCEPT) {
errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR,
&iface_name);
if (errno) {
osif_err("NAN data iface not provided");
return errno;
}
/* Check for an existing NAN interface */
nan_vdev = os_if_get_ndi_vdev_by_ifname(psoc, iface_name);
if (!nan_vdev) {
@ -902,26 +910,17 @@ responder_req_failed:
}
static int os_if_nan_process_ndp_responder_req(struct wlan_objmgr_psoc *psoc,
struct nlattr **tb)
struct nlattr **tb,
struct wireless_dev *wdev)
{
struct net_device *net_dev;
struct osif_vdev_sync *vdev_sync;
char *ifname;
int errno;
errno = osif_nla_str(tb, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, &ifname);
errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
if (errno)
return errno;
errno = osif_net_dev_from_ifname(psoc, ifname, &net_dev);
if (errno)
return errno;
errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
if (errno)
return errno;
errno = __os_if_nan_process_ndp_responder_req(psoc, ifname, tb);
errno = __os_if_nan_process_ndp_responder_req(psoc, tb);
osif_vdev_sync_op_stop(vdev_sync);
@ -1021,7 +1020,8 @@ static int os_if_nan_process_ndp_end_req(struct wlan_objmgr_psoc *psoc,
int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
const void *data, int data_len,
bool is_ndp_allowed)
bool is_ndp_allowed,
struct wireless_dev *wdev)
{
uint32_t ndp_cmd_type;
uint16_t transaction_id;
@ -1084,7 +1084,7 @@ int os_if_nan_process_ndp_cmd(struct wlan_objmgr_psoc *psoc,
osif_err("Unsupported concurrency for NAN datapath");
return -EOPNOTSUPP;
}
return os_if_nan_process_ndp_responder_req(psoc, tb);
return os_if_nan_process_ndp_responder_req(psoc, tb, wdev);
case QCA_WLAN_VENDOR_ATTR_NDP_END_REQUEST:
if (!is_ndp_allowed) {
osif_err("Unsupported concurrency for NAN datapath");

View file

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@ -150,7 +150,7 @@ QDF_STATUS os_if_monitor_mode_configure(struct hdd_adapter *adapter,
BIT(SET_MONITOR_MODE_CONNECTED_BEACON_INTERVAL);
}
osif_debug("Monitor mode config %s data tx %d data rx %d mgmt tx %d mgmt rx %d ctrl tx %d ctrl rx %d bi %d\n",
osif_debug("Monitor mode config data tx %d data rx %d mgmt tx %d mgmt rx %d ctrl tx %d ctrl rx %d bi %d\n",
frame_filter.data_tx_frame_filter,
frame_filter.data_rx_frame_filter,
frame_filter.mgmt_tx_frame_filter,