summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRavi Joshi <ravij@qca.qualcomm.com>2016-07-07 14:00:38 -0700
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-07-18 11:52:52 +0530
commit70b8870064ea75060ddf8289c72a7aacfc5a7144 (patch)
tree3a3a0e001c869c58aa507a70a19ed176cc920bda
parent4571c68bfcf136fdaf53350e42b055f0805c4f43 (diff)
qcacld-2.0: Add support for multicast traffic over NDI
Add support for passing multicast traffic over nan data interface. CRs-Fixed: 962367 Change-Id: Iaf012c08e6b5a7a6327b84b12c06ab27963a704c
-rw-r--r--CORE/HDD/src/wlan_hdd_tx_rx.c120
-rw-r--r--CORE/HDD/src/wlan_hdd_wext.c72
2 files changed, 103 insertions, 89 deletions
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index cfe12b02face..79eddf3fee46 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -399,6 +399,56 @@ void wlan_hdd_classify_pkt(struct sk_buff *skb)
ADF_NBUF_SET_WAPI(skb);
}
+/**
+ * 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,
+ v_MACADDR_t *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 (vos_is_macaddr_broadcast(dst_addr) ||
+ vos_is_macaddr_group(dst_addr)) {
+ hddLog(LOG1,
+ "Received MC/BC packet for transmission");
+ mcbc_addr = true;
+ } else {
+ } hddLog(LOGE,
+ "UC frame with invalid destination address");
+ }
+
+ if (adapter->device_mode == WLAN_HDD_IBSS) {
+ /*
+ * This check is necessary to make sure station id is not
+ * overwritten for UC traffic in IBSS mode
+ */
+ if (mcbc_addr)
+ *station_id = IBSS_BROADCAST_STAID;
+ } else if (adapter->device_mode == WLAN_HDD_NDI) {
+ /*
+ * 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];
+ }
+}
+
/**============================================================================
@brief hdd_hard_start_xmit() - Function registered with the Linux OS for
transmitting packets. This version of the function directly passes the packet
@@ -422,6 +472,7 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct sk_buff *skb_next, *list_head = NULL, *list_tail = NULL;
void *vdev_handle = NULL, *vdev_temp;
bool is_update_ac_stats = FALSE;
+ v_MACADDR_t *pDestMacAddress = NULL;
#ifdef QCA_PKT_PROTO_TRACE
hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter);
v_U8_t proto_type = 0;
@@ -448,54 +499,13 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
while (skb) {
skb_next = skb->next;
- /* memset skb control block */
- vos_mem_zero(skb->cb, sizeof(skb->cb));
- wlan_hdd_classify_pkt(skb);
- if (WLAN_HDD_IBSS == pAdapter->device_mode)
- {
- v_MACADDR_t *pDestMacAddress = (v_MACADDR_t*)skb->data;
-
- if ( VOS_STATUS_SUCCESS !=
- hdd_get_peer_sta_id(&pAdapter->sessionCtx.station,
- pDestMacAddress, &STAId))
- {
- STAId = HDD_WLAN_INVALID_STA_ID;
- }
+ pDestMacAddress = (v_MACADDR_t*)skb->data;
+ STAId = HDD_WLAN_INVALID_STA_ID;
- if ((STAId == HDD_WLAN_INVALID_STA_ID) &&
- (vos_is_macaddr_broadcast( pDestMacAddress ) ||
- vos_is_macaddr_group(pDestMacAddress)))
- {
- STAId = IBSS_BROADCAST_STAID;
- VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO_LOW,
- "%s: BC/MC packet", __func__);
- }
- else if (STAId == HDD_WLAN_INVALID_STA_ID)
- {
- VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
- "%s: Received Unicast frame with invalid staID", __func__);
- goto drop_pkt;
- }
- } else if (WLAN_HDD_NDI == pAdapter->device_mode) {
- v_MACADDR_t *pDestMacAddress = (v_MACADDR_t *)skb->data;
- if (hdd_get_peer_sta_id(&pAdapter->sessionCtx.station,
- pDestMacAddress, &STAId)
- != VOS_STATUS_SUCCESS) {
- VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_WARN,
- FL("Can't find peer: %pM, dropping packet"),
- pDestMacAddress);
- goto drop_pkt;
- }
- } else {
- if (WLAN_HDD_OCB != pAdapter->device_mode
- && eConnectionState_Associated !=
- pHddStaCtx->conn_info.connState) {
- VOS_TRACE(VOS_MODULE_ID_HDD_DATA, VOS_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_transmit_sta_id(pAdapter, pDestMacAddress, &STAId);
+ if (STAId == HDD_WLAN_INVALID_STA_ID) {
+ hddLog(LOGE, "Invalid station id, transmit operation suspended");
+ goto drop_pkt;
}
vdev_temp = tlshim_peer_validity(
@@ -527,22 +537,25 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
#endif /* QCA_LL_TX_FLOW_CT */
- //Get TL AC corresponding to Qdisc queue index/AC.
+ /* Get TL AC corresponding to Qdisc queue index/AC */
ac = hdd_QdiscAcToTlAC[skb->queue_mapping];
- //user priority from IP header, which is already extracted and set from
- //select_queue call back function
+ /*
+ * user priority from IP header, which is already extracted and set from
+ * select_queue call back function
+ */
up = skb->priority;
++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac];
#ifdef HDD_WMM_DEBUG
VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_FATAL,
"%s: Classified as ac %d up %d", __func__, ac, up);
-#endif // HDD_WMM_DEBUG
+#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
*/
@@ -571,7 +584,8 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (!granted) {
bool isDefaultAc = VOS_FALSE;
- /* ADDTS request for this AC is sent, for now
+ /*
+ * ADDTS request for this AC is sent, for now
* send this packet through next available lower
* Access category until ADDTS negotiation completes.
*/
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 33d4dfdead53..6c38ef5ffa28 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -10236,55 +10236,59 @@ int wlan_hdd_setIPv6Filter(hdd_context_t *pHddCtx, tANI_U8 filterType,
return 0;
}
+/**
+ * wlan_hdd_set_mc_addr_list() - Set multicast address list
+ * @pAdapter: Adapter context
+ * @set: flag to notify set/clear action on the multicast addr
+ *
+ * Returns: None
+ */
void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set)
{
v_U8_t i;
tpSirRcvFltMcAddrList pMulticastAddrs = NULL;
- tHalHandle hHal = NULL;
+ tHalHandle hHal;
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)
- {
- hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD CTX is NULL"));
+ ENTER();
+
+ if (wlan_hdd_validate_context(pHddCtx))
return;
- }
hHal = pHddCtx->hHal;
- if (NULL == hHal)
- {
+ if (NULL == hHal) {
hddLog(VOS_TRACE_LEVEL_ERROR, FL("HAL Handle is NULL"));
return;
}
- /* Check if INI is enabled or not, other wise just return
- */
- if (pHddCtx->cfg_ini->fEnableMCAddrList)
- {
+ if (!sta_ctx) {
+ hddLog(LOGE, "sta_ctx is NULL");
+ return;
+ }
+
+ if (pHddCtx->cfg_ini->fEnableMCAddrList) {
pMulticastAddrs = vos_mem_malloc(sizeof(tSirRcvFltMcAddrList));
- if (NULL == pMulticastAddrs)
- {
+ if (NULL == pMulticastAddrs) {
hddLog(VOS_TRACE_LEVEL_ERROR, FL("Could not allocate Memory"));
return;
}
vos_mem_zero(pMulticastAddrs, sizeof(tSirRcvFltMcAddrList));
pMulticastAddrs->action = set;
- if (set)
- {
- /* Following pre-conditions should be satisfied before we
- * configure the MC address list.
- */
- if (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
- (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT))
- && pAdapter->mc_addr_list.mc_cnt
- && (eConnectionState_Associated ==
- (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
- {
+ if (set) {
+ if (pAdapter->mc_addr_list.mc_cnt &&
+ (((pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
+ pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) &&
+ hdd_connIsConnected(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],
&pAdapter->mc_addr_list.addr[i * ETH_ALEN],
ETH_ALEN);
@@ -10297,19 +10301,15 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set)
/* Set multicast filter */
sme_8023MulticastList(hHal, pAdapter->sessionId,
pMulticastAddrs);
- }
- else {
+ } else {
hddLog(VOS_TRACE_LEVEL_INFO,
FL("MC address list not sent to FW, cnt: %d"),
pAdapter->mc_addr_list.mc_cnt);
}
- }
- else
- {
+ } else {
/* Need to clear only if it was previously configured
*/
- if (pAdapter->mc_addr_list.isFilterApplied)
- {
+ if (pAdapter->mc_addr_list.isFilterApplied) {
pMulticastAddrs->ulMulticastAddrCnt =
pAdapter->mc_addr_list.mc_cnt;
i = 0;
@@ -10336,12 +10336,12 @@ void wlan_hdd_set_mc_addr_list(hdd_adapter_t *pAdapter, v_U8_t set)
pAdapter->mc_addr_list.isFilterApplied = set ? TRUE : FALSE;
vos_mem_free(pMulticastAddrs);
- }
- else
- {
+ } else {
hddLog(VOS_TRACE_LEVEL_INFO,
FL("gMCAddrListEnable is not enabled in INI"));
}
+
+ EXIT();
return;
}