diff options
| author | Sravan Kumar Kairam <sgoud@qti.qualcomm.com> | 2016-01-13 13:12:21 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-02-01 15:01:56 +0530 |
| commit | 962cd9bcf597dff6a464e4ea5938d203b367f8f7 (patch) | |
| tree | 007af7ce326f42db08f139488cfe18c7124a095d | |
| parent | 067f55420d17b31419ef01af987447f9d9f9f9cd (diff) | |
qcacld-2.0: Send anycast addresses for NS offload
Current implementation has support for IPv6 addresses of type
unicast for NS offload to firmware.
As part of this change add anycast addresses for NS offload.
Change-Id: Ie3a94e34aa7ece18a69f543c65d73a7487fc28ee
CRs-Fixed: 954880
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_early_suspend.c | 169 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 1 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirMacProtDef.h | 2 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 4 |
4 files changed, 128 insertions, 48 deletions
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c index 0220e72436fd..427a533f9d87 100644 --- a/CORE/HDD/src/wlan_hdd_early_suspend.c +++ b/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -607,6 +607,93 @@ int wlan_hdd_ipv6_changed(struct notifier_block *nb, return ret; } +/** + * hdd_fill_ipv6_uc_addr() - fill IPv6 unicast addresses + * @idev: pointer to net device + * @ipv6addr: destination array to fill IPv6 addresses + * @ipv6addr_type: IPv6 Address type + * @count: number of IPv6 addresses + * + * This is the IPv6 utility function to populate unicast addresses. + * + * Return: 0 on success, error number otherwise. + */ +static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev, + uint8_t ipv6_uc_addr[][SIR_MAC_IPV6_ADDR_LEN], + uint8_t *ipv6addr_type, uint32_t *count) +{ + struct inet6_ifaddr *ifa; + struct list_head *p; + uint32_t scope; + + list_for_each(p, &idev->addr_list) { + if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) + return -EINVAL; + ifa = list_entry(p, struct inet6_ifaddr, if_list); + if (ifa->flags & IFA_F_DADFAILED) + continue; + scope = ipv6_addr_src_scope(&ifa->addr); + switch (scope) { + case IPV6_ADDR_SCOPE_GLOBAL: + case IPV6_ADDR_SCOPE_LINKLOCAL: + vos_mem_copy(ipv6_uc_addr[*count], &ifa->addr.s6_addr, + sizeof(ifa->addr.s6_addr)); + ipv6addr_type[*count] = SIR_IPV6_ADDR_UC_TYPE; + hddLog (LOG1, + FL("Index %d scope = %s Address: %pI6"), + *count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ? + "LINK LOCAL": "GLOBAL", ipv6_uc_addr[*count]); + *count += 1; + break; + default: + hddLog(LOGE, "The Scope %d is not supported", scope); + } + } + return 0; +} + +/** + * hdd_fill_ipv6_ac_addr() - fill IPv6 anycast addresses + * @idev: pointer to net device + * @ipv6addr: destination array to fill IPv6 addresses + * @ipv6addr_type: IPv6 Address type + * @count: number of IPv6 addresses + * + * This is the IPv6 utility function to populate anycast addresses. + * + * Return: 0 on success, error number otherwise. + */ +static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev, + uint8_t ipv6_ac_addr[][SIR_MAC_IPV6_ADDR_LEN], + uint8_t *ipv6addr_type, uint32_t *count) +{ + struct ifacaddr6 *ifaca; + uint32_t scope; + + for (ifaca = idev->ac_list; ifaca; ifaca = ifaca->aca_next) { + if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) + return -EINVAL; + /* For anycast addr no DAD */ + scope = ipv6_addr_src_scope(&ifaca->aca_addr); + switch (scope) { + case IPV6_ADDR_SCOPE_GLOBAL: + case IPV6_ADDR_SCOPE_LINKLOCAL: + vos_mem_copy(ipv6_ac_addr[*count], &ifaca->aca_addr, + sizeof(ifaca->aca_addr)); + ipv6addr_type[*count] = SIR_IPV6_ADDR_AC_TYPE; + hddLog (LOG1, + FL("Index %d scope = %s Address: %pI6"), + *count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ? + "LINK LOCAL": "GLOBAL", ipv6_ac_addr[*count]); + *count += 1; + break; + default: + hddLog(LOGE, "The Scope %d is not supported", scope); + } + } + return 0; +} + /**---------------------------------------------------------------------------- \brief hdd_conf_ns_offload() - Configure NS offload @@ -625,16 +712,15 @@ int wlan_hdd_ipv6_changed(struct notifier_block *nb, static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable) { struct inet6_dev *in6_dev; - struct inet6_ifaddr *ifp; - struct list_head *p; - tANI_U8 selfIPv6Addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA][SIR_MAC_IPV6_ADDR_LEN] = {{0,}}; - tANI_BOOLEAN selfIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0}; + uint8_t ipv6_addr[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] + [SIR_MAC_IPV6_ADDR_LEN] = {{0,}}; + uint8_t ipv6_addr_type[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA] = {0}; tSirHostOffloadReq offLoadRequest; hdd_context_t *pHddCtx; - int i =0; + int i = 0, ret; eHalStatus returnStatus; - uint32_t count = 0, scope; + uint32_t count = 0; ENTER(); hddLog(LOG1, FL(" fenable = %d"), fenable); @@ -655,31 +741,26 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable) if (fenable) { in6_dev = __in6_dev_get(pAdapter->dev); if (NULL != in6_dev) { - list_for_each(p, &in6_dev->addr_list) { - if (count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) { - hddLog(LOG1, FL("Reached max supported NS Offload addresses")); - break; - } - ifp = list_entry(p, struct inet6_ifaddr, if_list); - scope = ipv6_addr_src_scope(&ifp->addr); - switch (scope) { - case IPV6_ADDR_SCOPE_GLOBAL: - case IPV6_ADDR_SCOPE_LINKLOCAL: - vos_mem_copy(&selfIPv6Addr[count], &ifp->addr.s6_addr, - sizeof(ifp->addr.s6_addr)); - selfIPv6AddrValid[count] = SIR_IPV6_ADDR_VALID; - hddLog (LOG1, - FL("Index %d scope = %s Address : %pI6"), - count, (scope == IPV6_ADDR_SCOPE_LINKLOCAL) ? - "LINK LOCAL": "GLOBAL", selfIPv6Addr[count]); - count += 1; - break; - default: - hddLog(LOGE, "The Scope %d is not supported", - ipv6_addr_src_scope(&ifp->addr)); - } + /* Unicast Addresses */ + ret = hdd_fill_ipv6_uc_addr(in6_dev, ipv6_addr, + ipv6_addr_type, &count); + + if (0 > ret) { + hddLog(LOG1, + FL("Reached max supported addresses and not enabling NS offload")); + return; + } + /* Anycast Addresses */ + ret = hdd_fill_ipv6_ac_addr(in6_dev, ipv6_addr, + ipv6_addr_type, &count); + + if (0 > ret) { + hddLog(LOG1, + FL("Reached max supported addresses and not enabling NS offload")); + return; } + vos_mem_zero(&offLoadRequest, sizeof(offLoadRequest)); for (i = 0; i < count; i++) { /* Filling up the request structure @@ -697,33 +778,20 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable) offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][11] = 0x01; offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][12] = 0xFF; offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][13] = - selfIPv6Addr[i][13]; + ipv6_addr[i][13]; offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][14] = - selfIPv6Addr[i][14]; + ipv6_addr[i][14]; offLoadRequest.nsOffloadInfo.selfIPv6Addr[i][15] = - selfIPv6Addr[i][15]; + ipv6_addr[i][15]; offLoadRequest.nsOffloadInfo.slotIdx = i; vos_mem_copy(&offLoadRequest.nsOffloadInfo.targetIPv6Addr[i], - &selfIPv6Addr[i][0], SIR_MAC_IPV6_ADDR_LEN); + &ipv6_addr[i][0], SIR_MAC_IPV6_ADDR_LEN); offLoadRequest.nsOffloadInfo.targetIPv6AddrValid[i] = SIR_IPV6_ADDR_VALID; - - hddLog (LOG1, - FL("configuredMcastBcastFilter: %d"), - pHddCtx->configuredMcastBcastFilter); - - if ((VOS_TRUE == pHddCtx->sus_res_mcastbcast_filter_valid) - && ((HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST == - pHddCtx->sus_res_mcastbcast_filter) || - (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST == - pHddCtx->sus_res_mcastbcast_filter))) { - hddLog(LOG1, - FL("Set offLoadRequest with SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE")); - offLoadRequest.enableOrDisable = - SIR_OFFLOAD_NS_AND_MCAST_FILTER_ENABLE; - } + offLoadRequest.nsOffloadInfo.target_ipv6_addr_type[i] = + ipv6_addr_type[i]; vos_mem_copy(&offLoadRequest.params.hostIpv6Addr, &offLoadRequest.nsOffloadInfo.targetIPv6Addr[i], @@ -734,6 +802,11 @@ static void hdd_conf_ns_offload(hdd_adapter_t *pAdapter, int fenable) &offLoadRequest.nsOffloadInfo.selfIPv6Addr[i], &offLoadRequest.nsOffloadInfo.targetIPv6Addr[i], i); } + + hddLog (LOG1, + FL("configuredMcastBcastFilter: %d"), + pHddCtx->configuredMcastBcastFilter); + offLoadRequest.offloadType = SIR_IPV6_NS_OFFLOAD; offLoadRequest.enableOrDisable = SIR_OFFLOAD_ENABLE; vos_mem_copy(&offLoadRequest.nsOffloadInfo.selfMacAddr, diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 9feb0771d0fa..7247bed8c0fd 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -3400,6 +3400,7 @@ typedef struct sSirNsOffloadReq tANI_U8 selfMacAddr[6]; tANI_U8 srcIPv6AddrValid; tANI_U8 targetIPv6AddrValid[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]; + uint8_t target_ipv6_addr_type[SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA]; tANI_U8 slotIdx; } tSirNsOffloadReq, *tpSirNsOffloadReq; #endif //WLAN_NS_OFFLOAD diff --git a/CORE/MAC/inc/sirMacProtDef.h b/CORE/MAC/inc/sirMacProtDef.h index 9a01efdc2db3..8ec8d15878d5 100644 --- a/CORE/MAC/inc/sirMacProtDef.h +++ b/CORE/MAC/inc/sirMacProtDef.h @@ -503,6 +503,8 @@ #define SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA 16 #define SIR_MAC_IPV6_ADDR_LEN 16 #define SIR_IPV6_ADDR_VALID 1 +#define SIR_IPV6_ADDR_UC_TYPE 0 +#define SIR_IPV6_ADDR_AC_TYPE 1 #endif //WLAN_NS_OFFLOAD #define SIR_MAC_ARP_OFFLOAD_SIZE 1 diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 7dc49f75a7d3..a06a2c79deff 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -23239,6 +23239,8 @@ static VOS_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma, tpSirHostOffloadR &pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[i], sizeof(WMI_IPV6_ADDR)); A_MEMCPY(&ns_tuple->solicitation_ipaddr, &pHostOffloadParams->nsOffloadInfo.selfIPv6Addr[i], sizeof(WMI_IPV6_ADDR)); + if(pHostOffloadParams->nsOffloadInfo.target_ipv6_addr_type[i]) + ns_tuple->flags |= WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; WMA_LOGD("Index %d NS solicitedIp: %pI6, targetIp: %pI6", i, &pHostOffloadParams->nsOffloadInfo.selfIPv6Addr[i], &pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[i]); @@ -23302,6 +23304,8 @@ static VOS_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma, tpSirHostOffloadR A_MEMCPY(&ns_tuple->solicitation_ipaddr, &pHostOffloadParams->nsOffloadInfo.selfIPv6Addr[i], sizeof(WMI_IPV6_ADDR)); + if(pHostOffloadParams->nsOffloadInfo.target_ipv6_addr_type[i]) + ns_tuple->flags |= WMI_NSOFF_FLAGS_IS_IPV6_ANYCAST; WMA_LOGD("Index %d NS solicitedIp: %pI6, targetIp: %pI6", i, &pHostOffloadParams->nsOffloadInfo.selfIPv6Addr[i], &pHostOffloadParams->nsOffloadInfo.targetIPv6Addr[i]); |
