qcacld-3.0: Enable/Disable MC filter when connected

Multicast address filtering only makes sense if the interface is
connected and capable of receiving traffic. Avoid enabling/disabling
the multicast address filter list on an interface that is disconnected.

Change-Id: Id8aff136e920bb726b8c7dd539d477ff44f080d4
CRs-Fixed: 2282003
Este commit está contenido en:
Dustin Brown
2018-07-19 14:06:34 -07:00
cometido por nshrivas
padre 68b8b4e394
commit 0127a73a2d
Se han modificado 5 ficheros con 88 adiciones y 70 borrados

Ver fichero

@@ -64,14 +64,12 @@ static QDF_STATUS pmo_core_cache_arp_in_vdev_priv(
/* cache arp request */
qdf_spin_lock_bh(&vdev_ctx->pmo_vdev_lock);
qdf_mem_copy(&vdev_ctx->vdev_arp_req, request,
sizeof(vdev_ctx->vdev_arp_req));
sizeof(vdev_ctx->vdev_arp_req));
qdf_spin_unlock_bh(&vdev_ctx->pmo_vdev_lock);
pmo_debug("arp offload ipv4 addr: %d.%d.%d.%d enable: %d",
request->host_ipv4_addr[0],
request->host_ipv4_addr[1],
request->host_ipv4_addr[2],
request->host_ipv4_addr[3],
request->enable);
pmo_debug("cached arp offload; addr:" QDF_IPV4_ADDR_STR ", enable:%d",
QDF_IPV4_ADDR_ARRAY(request->host_ipv4_addr),
request->enable);
free_req:
qdf_mem_free(request);

Ver fichero

@@ -339,9 +339,6 @@ static QDF_STATUS pmo_core_mc_addr_flitering_sanity(
return QDF_STATUS_E_INVAL;
}
if (!pmo_core_is_vdev_connected(vdev))
return QDF_STATUS_E_INVAL;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS pmo_core_cache_mc_addr_list(
@@ -380,6 +377,7 @@ QDF_STATUS pmo_core_cache_mc_addr_list(
mc_list_config->vdev_id, mc_list_config->psoc);
status = pmo_core_cache_mc_addr_list_in_vdev_priv(mc_list_config, vdev);
dec_ref:
pmo_vdev_put_ref(vdev);
out:
@@ -516,6 +514,11 @@ QDF_STATUS pmo_core_enable_mc_addr_filtering_in_fwr(
if (status != QDF_STATUS_SUCCESS)
goto put_vdev;
if (!pmo_core_is_vdev_connected(vdev)) {
status = QDF_STATUS_E_INVAL;
goto put_vdev;
}
pmo_debug("enable mclist trigger: %d", trigger);
status = pmo_core_handle_enable_mc_list_trigger(vdev, trigger);
@@ -613,6 +616,11 @@ QDF_STATUS pmo_core_disable_mc_addr_filtering_in_fwr(
if (status != QDF_STATUS_SUCCESS)
goto put_ref;
if (!pmo_core_is_vdev_connected(vdev)) {
status = QDF_STATUS_E_INVAL;
goto put_ref;
}
pmo_debug("disable mclist trigger: %d", trigger);
status = pmo_core_handle_disable_mc_list_trigger(vdev, trigger);

Ver fichero

@@ -233,6 +233,14 @@ bool hdd_is_fils_connection(struct hdd_adapter *adapter);
*/
bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx);
/**
* hdd_adapter_is_connected_sta() - check if @adapter is a connected station
* @adapter: the adapter to check
*
* Return: true if @adapter is a connected station
*/
bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter);
/**
* hdd_conn_get_connected_band() - get current connection radio band
* @sta_ctx: pointer to global HDD Station context

Ver fichero

@@ -268,56 +268,47 @@ void hdd_conn_set_connection_state(struct hdd_adapter *adapter,
*/
static inline bool
hdd_conn_get_connection_state(struct hdd_station_ctx *sta_ctx,
eConnectionState *pConnState)
eConnectionState *out_state)
{
bool connected = false;
eConnectionState connState;
eConnectionState state = sta_ctx->conn_info.connState;
/* get the connection state. */
connState = sta_ctx->conn_info.connState;
if (out_state)
*out_state = state;
if (eConnectionState_Associated == connState ||
eConnectionState_IbssConnected == connState ||
eConnectionState_IbssDisconnected == connState) {
connected = true;
switch (state) {
case eConnectionState_Associated:
case eConnectionState_IbssConnected:
case eConnectionState_IbssDisconnected:
case eConnectionState_NdiConnected:
return true;
default:
return false;
}
if (pConnState)
*pConnState = connState;
return connected;
}
/**
* hdd_is_connecting() - Function to check connection progress
* @hdd_sta_ctx: pointer to global HDD Station context
*
* Return: true if connecting, false otherwise
*/
bool hdd_is_connecting(struct hdd_station_ctx *hdd_sta_ctx)
{
return hdd_sta_ctx->conn_info.connState ==
eConnectionState_Connecting;
}
/**
* hdd_conn_is_connected() - Function to check connection status
* @sta_ctx: pointer to global HDD Station context
*
* Return: false if any errors encountered, true otherwise
*/
bool hdd_conn_is_connected(struct hdd_station_ctx *sta_ctx)
{
return hdd_conn_get_connection_state(sta_ctx, NULL);
}
/**
* hdd_conn_get_connected_band() - get current connection radio band
* @sta_ctx: pointer to global HDD Station context
*
* Return: BAND_2G or BAND_5G based on current AP connection
* BAND_ALL if not connected
*/
bool hdd_adapter_is_connected_sta(struct hdd_adapter *adapter)
{
switch (adapter->device_mode) {
case QDF_STA_MODE:
case QDF_P2P_CLIENT_MODE:
case QDF_NDI_MODE:
return hdd_conn_is_connected(&adapter->session.station);
default:
return false;
}
}
enum band_info hdd_conn_get_connected_band(struct hdd_station_ctx *sta_ctx)
{
uint8_t staChannel = 0;

Ver fichero

@@ -878,13 +878,13 @@ void hdd_enable_arp_offload(struct hdd_adapter *adapter,
status = pmo_ucfg_cache_arp_offload_req(arp_req);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("failed to cache arp offload request");
hdd_err("failed to cache arp offload req; status:%d", status);
goto free_req;
}
status = pmo_ucfg_enable_arp_offload_in_fwr(adapter->hdd_vdev, trigger);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("failed to configure arp offload in firmware");
hdd_err("failed arp offload config in fw; status:%d", status);
goto free_req;
}
@@ -921,40 +921,48 @@ out:
}
void hdd_enable_mc_addr_filtering(struct hdd_adapter *adapter,
enum pmo_offload_trigger trigger)
enum pmo_offload_trigger trigger)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
QDF_STATUS status;
struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
hdd_enter();
if (wlan_hdd_validate_context(hdd_ctx))
goto out;
status = pmo_ucfg_enable_mc_addr_filtering_in_fwr(psoc,
adapter->session_id, trigger);
if (!hdd_adapter_is_connected_sta(adapter))
goto out;
status = pmo_ucfg_enable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc,
adapter->session_id,
trigger);
if (QDF_IS_STATUS_ERROR(status))
hdd_info("failed to enable mc list status %d", status);
hdd_err("failed to enable mc list; status:%d", status);
out:
hdd_exit();
}
void hdd_disable_mc_addr_filtering(struct hdd_adapter *adapter,
enum pmo_offload_trigger trigger)
enum pmo_offload_trigger trigger)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
QDF_STATUS status;
hdd_enter();
if (wlan_hdd_validate_context(hdd_ctx))
goto out;
status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc,
adapter->session_id, trigger);
if (status != QDF_STATUS_SUCCESS)
hdd_info("failed to disable mc list status %d", status);
if (!hdd_adapter_is_connected_sta(adapter))
goto out;
status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc,
adapter->session_id,
trigger);
if (QDF_IS_STATUS_ERROR(status))
hdd_err("failed to disable mc list; status:%d", status);
out:
hdd_exit();
@@ -972,23 +980,28 @@ int hdd_cache_mc_addr_list(struct pmo_mc_addr_list_params *mc_list_config)
}
void hdd_disable_and_flush_mc_addr_list(struct hdd_adapter *adapter,
enum pmo_offload_trigger trigger)
enum pmo_offload_trigger trigger)
{
struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct wlan_objmgr_psoc *psoc = hdd_ctx->hdd_psoc;
QDF_STATUS status = QDF_STATUS_SUCCESS;
QDF_STATUS status;
hdd_enter();
/* disable mc list first */
status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(psoc,
adapter->session_id, trigger);
if (status != QDF_STATUS_SUCCESS)
hdd_info("fail to disable mc list");
/* flush mc list */
status = pmo_ucfg_flush_mc_addr_list(psoc, adapter->session_id);
if (status != QDF_STATUS_SUCCESS)
hdd_info("fail to flush mc list status %d", status);
if (!hdd_adapter_is_connected_sta(adapter))
goto flush_mc_list;
/* disable mc list first because the mc list is cached in PMO */
status = pmo_ucfg_disable_mc_addr_filtering_in_fwr(hdd_ctx->hdd_psoc,
adapter->session_id,
trigger);
if (QDF_IS_STATUS_ERROR(status))
hdd_err("failed to disable mc list; status:%d", status);
flush_mc_list:
status = pmo_ucfg_flush_mc_addr_list(hdd_ctx->hdd_psoc,
adapter->session_id);
if (QDF_IS_STATUS_ERROR(status))
hdd_err("failed to flush mc list; status:%d", status);
hdd_exit();