qcacld-3.0: Add support for multicast traffic over NDI

Add support for passing multicast traffic over nan data interface.

Integration from qcacld-2.0 to qcacld-3.0.

CRs-Fixed: 1046519
Change-Id: Iaf012c08e6b5a7a6327b84b12c06ab27963a704c
This commit is contained in:
Ravi Joshi
2016-07-19 15:45:09 -07:00
committed by Vishwajith Upendra
parent 4f447cb765
commit 24477b7c2b
2 changed files with 90 additions and 71 deletions

View File

@@ -924,11 +924,12 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set)
tpSirRcvFltMcAddrList pMulticastAddrs = NULL;
tHalHandle hHal = NULL;
hdd_context_t *pHddCtx = (hdd_context_t *) pAdapter->pHddCtx;
hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
if (NULL == pHddCtx) {
hdd_err("HDD CTX is NULL");
ENTER();
if (wlan_hdd_validate_context(pHddCtx))
return;
}
hHal = pHddCtx->hHal;
@@ -937,8 +938,12 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set)
return;
}
/* Check if INI is enabled or not, other wise just return
*/
if (!sta_ctx) {
hdd_err("sta_ctx is NULL");
return;
}
/* Check if INI is enabled or not, other wise just return */
if (!pHddCtx->config->fEnableMCAddrList) {
hdd_notice("gMCAddrListEnable is not enabled in INI");
return;
@@ -952,23 +957,24 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set)
pMulticastAddrs->action = set;
if (set) {
/* Following pre-conditions should be satisfied before we
/*
* Following pre-conditions should be satisfied before we
* configure the MC address list.
*/
if (((pAdapter->device_mode == QDF_STA_MODE)
|| (pAdapter->device_mode == QDF_P2P_CLIENT_MODE))
&& pAdapter->mc_addr_list.mc_cnt
&& (eConnectionState_Associated ==
(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->
conn_info.connState)) {
if (pAdapter->mc_addr_list.mc_cnt &&
(((pAdapter->device_mode == QDF_STA_MODE ||
pAdapter->device_mode == QDF_P2P_CLIENT_MODE) &&
hdd_conn_is_connected(sta_ctx)) ||
(WLAN_HDD_IS_NDI(pAdapter) &&
WLAN_HDD_IS_NDI_CONNECTED(pAdapter)))) {
pMulticastAddrs->ulMulticastAddrCnt =
pAdapter->mc_addr_list.mc_cnt;
for (i = 0; i < pAdapter->mc_addr_list.mc_cnt;
i++) {
for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) {
memcpy(pMulticastAddrs->multicastAddr[i].bytes,
pAdapter->mc_addr_list.addr[i],
sizeof(pAdapter->mc_addr_list.
addr[i]));
sizeof(pAdapter->mc_addr_list.addr[i]));
hdd_info("%s multicast filter: addr ="
MAC_ADDRESS_STR,
set ? "setting" : "clearing",
@@ -984,12 +990,10 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set)
if (pAdapter->mc_addr_list.isFilterApplied) {
pMulticastAddrs->ulMulticastAddrCnt =
pAdapter->mc_addr_list.mc_cnt;
for (i = 0; i < pAdapter->mc_addr_list.mc_cnt;
i++) {
for (i = 0; i < pAdapter->mc_addr_list.mc_cnt; i++) {
memcpy(pMulticastAddrs->multicastAddr[i].bytes,
pAdapter->mc_addr_list.addr[i],
sizeof(pAdapter->mc_addr_list.
addr[i]));
sizeof(pAdapter->mc_addr_list.addr[i]));
}
sme_8023_multicast_list(hHal, pAdapter->sessionId,
pMulticastAddrs);
@@ -1003,6 +1007,8 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, uint8_t set)
pAdapter->mc_addr_list.isFilterApplied = set ? true : false;
qdf_mem_free(pMulticastAddrs);
EXIT();
return;
}
#endif

View File

@@ -297,6 +297,55 @@ static bool wlan_hdd_is_eapol_or_wai(struct sk_buff *skb)
return false;
}
/**
* hdd_get_transmit_sta_id() - function to retrieve station id to be used for
* sending traffic towards a particular destination address. The destination
* address can be unicast, multicast or broadcast
*
* @adapter: Handle to adapter context
* @dst_addr: Destination address
* @station_id: station id
*
* Returns: None
*/
static void hdd_get_transmit_sta_id(hdd_adapter_t *adapter,
struct qdf_mac_addr *dst_addr, uint8_t *station_id)
{
bool mcbc_addr = false;
hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
hdd_get_peer_sta_id(sta_ctx, dst_addr, station_id);
if (*station_id == HDD_WLAN_INVALID_STA_ID) {
if (qdf_is_macaddr_broadcast(dst_addr) ||
qdf_is_macaddr_group(dst_addr)) {
hdd_info("Received MC/BC packet for transmission");
mcbc_addr = true;
} else {
hdd_err("UC frame with invalid destination address");
}
}
if (adapter->device_mode == QDF_IBSS_MODE) {
/*
* This check is necessary to make sure station id is not
* overwritten for UC traffic in IBSS mode
*/
if (mcbc_addr)
*station_id = sta_ctx->broadcast_ibss_staid;
} else if (adapter->device_mode == QDF_NDI_MODE) {
/*
* This check is necessary to make sure station id is not
* overwritten for UC traffic in NAN data mode
*/
if (mcbc_addr)
*station_id = NDP_BROADCAST_STAID;
} else {
/* For the rest, traffic is directed to AP/P2P GO */
if (eConnectionState_Associated == sta_ctx->conn_info.connState)
*station_id = sta_ctx->conn_info.staId[0];
}
}
/**
* hdd_hard_start_xmit() - Transmit a frame
* @skb: pointer to OS packet (sk_buff)
@@ -317,6 +366,7 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
bool granted;
uint8_t STAId = WLAN_MAX_STA_COUNT;
hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
struct qdf_mac_addr *pDestMacAddress = NULL;
#ifdef QCA_PKT_PROTO_TRACE
uint8_t proto_type = 0;
#endif /* QCA_PKT_PROTO_TRACE */
@@ -336,54 +386,14 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop_pkt;
}
if (QDF_IBSS_MODE == pAdapter->device_mode) {
struct qdf_mac_addr *pDestMacAddress =
(struct qdf_mac_addr *) skb->data;
if (QDF_STATUS_SUCCESS !=
hdd_get_peer_sta_id(&pAdapter->sessionCtx.station,
pDestMacAddress, &STAId))
pDestMacAddress = (struct qdf_mac_addr *)skb->data;
STAId = HDD_WLAN_INVALID_STA_ID;
if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
(qdf_is_macaddr_broadcast(pDestMacAddress) ||
qdf_is_macaddr_group(pDestMacAddress))) {
STAId = pHddStaCtx->broadcast_ibss_staid;
QDF_TRACE(QDF_MODULE_ID_HDD_DATA,
QDF_TRACE_LEVEL_INFO_LOW, "%s: BC/MC packet",
__func__);
} else if (STAId == HDD_WLAN_INVALID_STA_ID) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_WARN,
"%s: Received Unicast frame with invalid staID",
__func__);
hdd_get_transmit_sta_id(pAdapter, pDestMacAddress, &STAId);
if (STAId == HDD_WLAN_INVALID_STA_ID) {
hddLog(LOGE, "Invalid station id, transmit operation suspended");
goto drop_pkt;
}
} else if (QDF_NDI_MODE == pAdapter->device_mode) {
struct qdf_mac_addr *dest_mac_addr =
(struct qdf_mac_addr *)skb->data;
if (hdd_get_peer_sta_id(&pAdapter->sessionCtx.station,
dest_mac_addr, &STAId) !=
QDF_STATUS_SUCCESS) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_WARN,
FL("Can't find peer: %pM, dropping packet"),
dest_mac_addr);
++pAdapter->stats.tx_dropped;
++pAdapter->hdd_stats.hddTxRxStats.txXmitDropped;
kfree_skb(skb);
return NETDEV_TX_OK;
}
} else {
if (QDF_OCB_MODE != pAdapter->device_mode &&
eConnectionState_Associated !=
pHddStaCtx->conn_info.connState) {
QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_INFO,
FL("Tx frame in not associated state in %d context"),
pAdapter->device_mode);
goto drop_pkt;
}
STAId = pHddStaCtx->conn_info.staId[0];
}
hdd_get_tx_resource(pAdapter, STAId,
WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
@@ -398,7 +408,8 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
goto drop_pkt_accounting;
}
/* user priority from IP header, which is already extracted and set from
/*
* user priority from IP header, which is already extracted and set from
* select_queue call back function
*/
up = skb->priority;
@@ -410,7 +421,8 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
#endif /* HDD_WMM_DEBUG */
if (HDD_PSB_CHANGED == pAdapter->psbChanged) {
/* Function which will determine acquire admittance for a
/*
* Function which will determine acquire admittance for a
* WMM AC is required or not based on psb configuration done
* in the framework
*/
@@ -435,7 +447,8 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!granted) {
bool isDefaultAc = false;
/* ADDTS request for this AC is sent, for now
/*
* ADDTS request for this AC is sent, for now
* send this packet through next avaiable lower
* Access category until ADDTS negotiation completes.
*/