summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.c50
-rw-r--r--CORE/CLD_TXRX/TLSHIM/tl_shim.h5
-rw-r--r--CORE/HDD/inc/wlan_hdd_ipa.h12
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h3
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c10
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c8
-rw-r--r--CORE/HDD/src/wlan_hdd_ipa.c1215
-rw-r--r--CORE/VOSS/src/vos_trace.c7
8 files changed, 685 insertions, 625 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index ef00f2d6fe26..b3df3a7f9f5c 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -1575,3 +1575,53 @@ VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id)
*vdev_id = peer->vdev->vdev_id;
return VOS_STATUS_SUCCESS;
}
+
+/*
+ * Function to get vdev(tl_context) given the MAC address.
+ */
+void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr)
+{
+ struct ol_txrx_peer_t *peer = NULL;
+ ol_txrx_pdev_handle pdev = NULL;
+ uint8_t peer_id;
+
+ if (vos_context == NULL || mac_addr == NULL) {
+ TLSHIM_LOGE("Invalid argument %p, %p", vos_context, mac_addr);
+ return NULL;
+ }
+
+ pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context);
+ peer = ol_txrx_find_peer_by_addr(pdev, mac_addr, &peer_id);
+
+ if (!peer) {
+ TLSHIM_LOGE("PEER [%pM] not found", mac_addr);
+ return NULL;
+ }
+
+ return peer->vdev;
+}
+
+/*
+ * Function to get vdev(tl_context) given the TL station ID.
+ */
+void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id)
+{
+ struct ol_txrx_peer_t *peer = NULL;
+ ol_txrx_pdev_handle pdev = NULL;
+
+ if (sta_id >= WLAN_MAX_STA_COUNT) {
+ TLSHIM_LOGE("Invalid sta id passed");
+ return NULL;
+ }
+
+ pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos_context);
+
+ peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
+
+ if (!peer) {
+ TLSHIM_LOGE("PEER [%d] not found", sta_id);
+ return NULL;
+ }
+
+ return peer->vdev;
+}
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
index a5d8fa836a3c..31084662b82b 100644
--- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h
+++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h
@@ -28,6 +28,9 @@
#ifndef TXRX_TL_SHIM_H
#define TXRX_TL_SHIM_H
+#include <ol_txrx_osif_api.h>
+#include <adf_os_lock.h>
+
#ifdef FEATURE_WLAN_CCX
typedef struct deferred_iapp_work {
pVosContextType pVosGCtx;
@@ -86,5 +89,7 @@ VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id);
* BETTER_AP_FOUND event is received from roam engine.
*/
int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id);
+void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr);
+void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id);
#endif
diff --git a/CORE/HDD/inc/wlan_hdd_ipa.h b/CORE/HDD/inc/wlan_hdd_ipa.h
index d0c532f945e0..aaac547e70ce 100644
--- a/CORE/HDD/inc/wlan_hdd_ipa.h
+++ b/CORE/HDD/inc/wlan_hdd_ipa.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -44,12 +44,12 @@
#ifdef IPA_OFFLOAD
#include <mach/ipa.h>
-VOS_STATUS hdd_ipa_init(hdd_context_t *pHddCtx);
-VOS_STATUS hdd_ipa_cleanup(hdd_context_t *pHddCtx);
-int hdd_ipa_wlan_evt(void *pAdapter, uint8_t sta_id,
- enum ipa_wlan_event type, uint8_t *mac_addr);
+VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx);
+VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx);
+int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
+ enum ipa_wlan_event type, uint8_t *mac_addr);
VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rxBuf,
- v_U8_t staId);
+ v_U8_t sta_id);
bool hdd_ipa_is_enabled(hdd_context_t *pHddCtx);
#endif
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 7213c73da511..0f741496f550 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1026,6 +1026,9 @@ struct hdd_adapter_s
#ifdef QCA_WIFI_2_0
v_BOOL_t internalCancelRemainOnChReq;
#endif
+#ifdef IPA_OFFLOAD
+ void *ipa_context;
+#endif
};
#define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station)
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index f07a5df4674c..30dc08dd1d77 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -813,8 +813,8 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *
#ifdef IPA_OFFLOAD
if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
- WLAN_STA_DISCONNECT, pAdapter->dev->dev_addr);
+ hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
+ WLAN_STA_DISCONNECT, pHddStaCtx->conn_info.bssId);
#endif
if(pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting)
@@ -1299,9 +1299,9 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs
pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
#ifdef IPA_OFFLOAD
- if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT,
- pAdapter->dev->dev_addr);
+ if (hdd_ipa_is_enabled(pHddCtx))
+ hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId, WLAN_STA_CONNECT,
+ pRoamInfo->bssid);
#endif
#ifdef FEATURE_WLAN_TDLS
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index 5dafbabe316f..3518e8f62882 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -511,8 +511,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
}
#ifdef IPA_OFFLOAD
if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pHostapdAdapter, WLAN_RX_SAP_SELF_STA_ID,
- WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr);
+ hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId,
+ WLAN_AP_CONNECT, pHostapdAdapter->dev->dev_addr);
#endif
if (0 != (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->nAPAutoShutOff)
@@ -596,8 +596,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
pHddApCtx->operatingChannel = 0; //Invalidate the channel info.
#ifdef IPA_OFFLOAD
if (hdd_ipa_is_enabled(pHddCtx))
- hdd_ipa_wlan_evt(pHostapdAdapter, WLAN_RX_SAP_SELF_STA_ID,
- WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr);
+ hdd_ipa_wlan_evt(pHostapdAdapter, pHddApCtx->uBCStaId,
+ WLAN_AP_DISCONNECT, pHostapdAdapter->dev->dev_addr);
#endif
goto stopbss;
case eSAP_STA_SET_KEY_EVENT:
diff --git a/CORE/HDD/src/wlan_hdd_ipa.c b/CORE/HDD/src/wlan_hdd_ipa.c
index 5965f7892afc..88da1e7337b0 100644
--- a/CORE/HDD/src/wlan_hdd_ipa.c
+++ b/CORE/HDD/src/wlan_hdd_ipa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -24,7 +24,6 @@
* under proprietary terms before Copyright ownership was assigned
* to the Linux Foundation.
*/
-
/*========================================================================
\file wlan_hdd_ipa.c
@@ -50,18 +49,14 @@ Include Files
#include <wlan_hdd_softap_tx_rx.h>
#include "vos_sched.h"
-#include "wlan_qct_tl.h"
-#include "ol_txrx_peer_find.h"
#include "tl_shim.h"
+#include "wlan_qct_tl.h"
#define HDD_IPA_DESC_BUFFER_RATIO 4
#define HDD_IPA_IPV4_NAME_EXT "_ipv4"
#define HDD_IPA_IPV6_NAME_EXT "_ipv6"
#define HDD_IPA_RX_INACTIVITY_MSEC_DELAY 2000
-#define HDD_IPA_WLAN_HDR_ONLY_LEN 4
-#define HDD_IPA_WLAN_HDR_STA_ID_OFFSET 3
-#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0
struct llc_snap_hdr {
uint8_t dsap;
@@ -70,49 +65,60 @@ struct llc_snap_hdr {
__be16 eth_type;
} __packed;
-struct ipa_tx_hdr {
+struct hdd_ipa_tx_hdr {
struct ethhdr eth;
struct llc_snap_hdr llc_snap;
} __packed;
/* For Tx pipes, use 802.3 Header format */
-struct ipa_tx_hdr ipa_set_tx_hdr = {
+static struct hdd_ipa_tx_hdr ipa_tx_hdr = {
{
- {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */
- {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */
- 0x00 /* length can be zero */
+ {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF},
+ {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF},
+ 0x00 /* length can be zero */
},
{
- /* LLC SNAP header 8 bytes */
- 0xaa, 0xaa,
- {0x03, 0x00, 0x00, 0x00},
- 0x0008 /* type value(2 bytes) ,filled by wlan */
- /* 0x0800 - IPV4, 0x86dd - IPV6 */
+ /* LLC SNAP header 8 bytes */
+ 0xaa, 0xaa,
+ {0x03, 0x00, 0x00, 0x00},
+ 0x0008 /* type value(2 bytes) ,filled by wlan */
+ /* 0x0800 - IPV4, 0x86dd - IPV6 */
}
};
-struct ipa_rx_hdr {
- uint8_t hdr[HDD_IPA_WLAN_HDR_ONLY_LEN];
+/*
+ +----------+----------+--------------+--------+
+ | Reserved | QCMAP ID | interface id | STA ID |
+ +----------+----------+--------------+--------+
+ */
+struct hdd_ipa_cld_hdr {
+ uint8_t reserved[2];
+ uint8_t iface_id;
+ uint8_t sta_id;
+} __packed;
+
+struct hdd_ipa_rx_hdr {
+ struct hdd_ipa_cld_hdr cld_hdr;
struct ethhdr eth;
} __packed;
-/* For Rx pipe, use Ethernet-II Header format */
-struct ipa_rx_hdr ipa_set_rx_hdr = {
- {0x00, 0x00, 0x00, 0x00}, /* 4 bytes header */
- {
- {0x00, 0x03, 0x7f, 0xaa, 0xbb, 0xcc}, /* Des_MAC filled by IPA */
- {0x00, 0x03, 0x7f, 0xdd, 0xee, 0xff}, /* Src. MAC filled by IPA */
- 0x0008 /* type value(2 bytes) ,filled by wlan */
- /* 0x0800 - IPV4, 0x86dd - IPV6 */
- }
-};
+#define HDD_IPA_WLAN_CLD_HDR_LEN sizeof(struct hdd_ipa_cld_hdr)
+#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_tx_hdr)
+#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(struct hdd_ipa_rx_hdr)
+#define HDD_IPA_WLAN_HDR_DES_MAC_OFFSET 0
+
+#define HDD_IPA_GET_IFACE_ID(_data) \
+ (((struct hdd_ipa_cld_hdr *) (_data))->iface_id)
-#define HDD_IPA_WLAN_TX_HDR_LEN sizeof(ipa_set_tx_hdr)
-#define HDD_IPA_WLAN_RX_HDR_LEN sizeof(ipa_set_rx_hdr)
-#define HDD_IPA_WLAN_HDR_PARTIAL 1
#define HDD_IPA_LOG(LVL, fmt, args...) VOS_TRACE(VOS_MODULE_ID_HDD, LVL, \
- "%s:%d "fmt"\n", __func__, __LINE__, ## args)
+ "%s:%d: "fmt, __func__, __LINE__, ## args)
+
+#define HDD_IPA_DBG_DUMP(_lvl, _prefix, _buf, _len) \
+ do {\
+ VOS_TRACE(VOS_MODULE_ID_HDD, _lvl, "%s:", _prefix); \
+ VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, _lvl, _buf, _len); \
+ } while(0)
enum hdd_ipa_rm_state {
HDD_IPA_RM_RELEASED,
@@ -121,101 +127,106 @@ enum hdd_ipa_rm_state {
HDD_IPA_RM_RELEASE_PENDING,
};
-enum hdd_ipa_pipe_index {
- HDD_IPA_TX_WLAN0_PIPE,
- HDD_IPA_TX_WLAN1_PIPE,
- HDD_IPA_TX_WLAN2_PIPE,
- HDD_IPA_RX_PIPE,
- HDD_IPA_MAX_PIPE
+#define HDD_IPA_MAX_IFACE 3
+#define HDD_IPA_MAX_SYSBAM_PIPE 4
+#define HDD_IPA_RX_PIPE HDD_IPA_MAX_IFACE
+
+static struct hdd_ipa_adapter_2_client {
+ enum ipa_client_type cons_client;
+ enum ipa_client_type prod_client;
+} hdd_ipa_adapter_2_client[HDD_IPA_MAX_IFACE] = {
+ {IPA_CLIENT_WLAN1_CONS, IPA_CLIENT_WLAN1_PROD},
+ {IPA_CLIENT_WLAN2_CONS, IPA_CLIENT_WLAN1_PROD},
+ {IPA_CLIENT_WLAN3_CONS, IPA_CLIENT_WLAN1_PROD},
};
-enum hdd_ipa_ip_ver {
- HDD_IPA_IPV4 = 1,
- HDD_IPA_IPV6 = 2
+struct hdd_ipa_sys_pipe {
+ uint32_t conn_hdl;
+ uint8_t conn_hdl_valid;
+ struct ipa_sys_connect_params ipa_sys_params;
};
-#define HDD_IPA_WLAN_MAX_STA_ID 255
+struct hdd_ipa_priv;
-uint8_t wlan_sta_id_2_hdd_pipe_id[HDD_IPA_WLAN_MAX_STA_ID] = {0xFF};
+struct hdd_ipa_iface_context {
+ struct hdd_ipa_priv *hdd_ipa;
+ hdd_adapter_t *adapter;
+ void *tl_context;
-uint8_t hdd_pipe_id_2_ipa_client_id[HDD_IPA_MAX_PIPE] = {
- IPA_CLIENT_WLAN1_CONS,
- IPA_CLIENT_WLAN2_CONS,
- IPA_CLIENT_WLAN3_CONS,
- IPA_CLIENT_WLAN1_PROD
-};
+ enum ipa_client_type cons_client;
+ enum ipa_client_type prod_client;
-uint8_t ipa_client_id_2_hdd_pipe_id[IPA_CLIENT_MAX] = {
- [IPA_CLIENT_WLAN1_CONS] = HDD_IPA_TX_WLAN0_PIPE,
- [IPA_CLIENT_WLAN2_CONS] = HDD_IPA_TX_WLAN1_PIPE,
- [IPA_CLIENT_WLAN3_CONS] = HDD_IPA_TX_WLAN2_PIPE,
- [IPA_CLIENT_WLAN1_PROD] = HDD_IPA_RX_PIPE
+ uint8_t iface_id; /* This iface ID */
+ uint8_t sta_id; /* This iface station ID */
};
-struct hdd_ipa_sys_pipe {
- uint32_t conn_hdl;
- uint8_t conn_hdl_valid;
- struct ipa_sys_connect_params ipa_sys_params;
+
+struct hdd_ipa_stats {
+ uint32_t event[IPA_WLAN_EVENT_MAX];
+ uint32_t send_msg;
+ uint32_t free_msg;
+
+ uint64_t prefilter;
+ uint64_t rm_grant;
+ uint64_t rm_release;
+#ifdef HDD_IPA_EXTRA_DP_COUNTERS
+ uint64_t rx_ipa_rm_qued;
+#endif
+ uint64_t rx_ipa_sent_desc_cnt;
+ uint64_t rx_ipa_write_done;
+ uint64_t rx_ipa_excep;
+
+ uint64_t rx_ipa_hw_maxed_out;
+
+ uint64_t freeq_empty;
+ uint64_t freeq_cnt;
+
+#ifdef HDD_IPA_EXTRA_DP_COUNTERS
+ uint64_t rxt_drop;
+ uint64_t rxt_recv;
+ uint64_t rx_ipa_hw_max_qued;
+ uint64_t rxt_d_drop;
+ uint64_t rxt_dh_drop;
+ uint64_t rxt_0;
+ uint64_t rxt_1;
+ uint64_t rxt_2;
+ uint64_t rxt_3;
+ uint64_t rxt_4;
+ uint64_t rxt_5;
+ uint64_t rxt_6;
+ uint64_t freeq_use;
+ uint64_t freeq_reclaim;
+ uint64_t rx_ipa_dh_sent;
+ uint64_t rx_ipa_dh_reclaim;
+ uint64_t rx_ipa_dh_not_used;
+#endif
+ uint64_t ipa_lb_cnt;
+ uint64_t tx_ipa_recv;
+ uint64_t tx_comp_cnt;
+ uint64_t tx_dp_err_cnt;
};
struct hdd_ipa_priv {
- struct hdd_ipa_sys_pipe sys_pipe[HDD_IPA_MAX_PIPE];
+ struct hdd_ipa_sys_pipe sys_pipe[HDD_IPA_MAX_SYSBAM_PIPE];
+ struct hdd_ipa_iface_context iface_context[HDD_IPA_MAX_IFACE];
atomic_t rm_state;
#ifndef HDD_IPA_USE_IPA_RM_TIMER
struct timer_list rm_timer;
uint8_t rm_timer_on;
#endif
+ enum ipa_client_type prod_client;
+
uint32_t pending_desc_cnt;
uint32_t hw_desc_cnt;
spinlock_t q_lock;
struct list_head free_desc_head;
struct list_head pend_desc_head;
- struct ol_txrx_vdev_t *pipe_to_vdev[HDD_IPA_MAX_PIPE];
-
hdd_context_t *hdd_ctx;
struct dentry *debugfs_dir;
- struct {
- uint64_t prefilter;
- uint64_t rm_grant;
- uint64_t rm_release;
-#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- uint64_t rx_ipa_rm_qued;
-#endif
- uint64_t rx_ipa_sent_desc_cnt;
- uint64_t rx_ipa_write_done;
- uint64_t rx_ipa_excep;
-
- uint64_t rx_ipa_hw_maxed_out;
-
- uint64_t freeq_empty;
- uint64_t freeq_cnt;
+ struct hdd_ipa_stats stats;
-#ifdef HDD_IPA_EXTRA_DP_COUNTERS
- uint64_t rxt_drop;
- uint64_t rxt_recv;
- uint64_t rx_ipa_hw_max_qued;
- uint64_t rxt_d_drop;
- uint64_t rxt_dh_drop;
- uint64_t rxt_0;
- uint64_t rxt_1;
- uint64_t rxt_2;
- uint64_t rxt_3;
- uint64_t rxt_4;
- uint64_t rxt_5;
- uint64_t rxt_6;
- uint64_t freeq_use;
- uint64_t freeq_reclaim;
- uint64_t rx_ipa_dh_sent;
- uint64_t rx_ipa_dh_reclaim;
- uint64_t rx_ipa_dh_not_used;
-#endif
- uint64_t ipa_lb_cnt;
- uint64_t tx_ipa_recv;
- uint64_t tx_comp_cnt;
- uint64_t tx_dp_err_cnt;
- } stats;
};
enum hdd_ipa_evt {
@@ -239,12 +250,22 @@ bool hdd_ipa_is_enabled(hdd_context_t *hdd_ctx)
return hdd_ctx->cfg_ini->IpaEnable;
}
-static inline void *hdd_ipa_kzalloc(uint32_t size)
+static inline bool hdd_ipa_is_pre_filter_enabled(struct hdd_ipa_priv *hdd_ipa)
+{
+ hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
+ return hdd_ctx->cfg_ini->IpaPreFilterEnable;
+}
+
+static inline bool hdd_ipa_is_ipv6_enabled(struct hdd_ipa_priv *hdd_ipa)
{
- void *data = NULL;
+ hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
+ return hdd_ctx->cfg_ini->IpaIPv6Enable;
+}
- data = adf_os_mem_alloc(NULL, size);
- return data;
+static inline bool hdd_ipa_is_rm_enabled(struct hdd_ipa_priv *hdd_ipa)
+{
+ hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
+ return hdd_ctx->cfg_ini->IpaRMEnable;
}
static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void)
@@ -254,7 +275,8 @@ static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void)
spin_lock_bh(&ghdd_ipa->q_lock);
if (!list_empty(&ghdd_ipa->free_desc_head)) {
- desc = list_first_entry(&ghdd_ipa->free_desc_head, struct ipa_tx_data_desc, link);
+ desc = list_first_entry(&ghdd_ipa->free_desc_head,
+ struct ipa_tx_data_desc, link);
list_del(&desc->link);
hdd_ipa->stats.freeq_cnt--;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
@@ -267,22 +289,33 @@ static inline struct ipa_tx_data_desc *hdd_ipa_get_desc_from_freeq(void)
return desc;
}
-static inline bool hdd_ipa_can_pre_filter(struct hdd_ipa_priv *hdd_ipa)
+static bool hdd_ipa_can_send_to_ipa(struct hdd_ipa_priv *hdd_ipa, void *data)
{
- hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
- return hdd_ctx->cfg_ini->IpaPreFilterEnable;
-}
+ struct ethhdr *eth = (struct ethhdr *)data;
+ struct llc_snap_hdr *ls_hdr;
+ uint16_t eth_type;
-static inline bool hdd_ipa_is_ipv6_enabled(struct hdd_ipa_priv *hdd_ipa)
-{
- hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
- return hdd_ctx->cfg_ini->IpaIPv6Enable;
-}
+ if (!hdd_ipa_is_pre_filter_enabled(hdd_ipa))
+ return true;
-static inline bool hdd_ipa_is_rm_enabled(struct hdd_ipa_priv *hdd_ipa)
-{
- hdd_context_t *hdd_ctx = hdd_ipa->hdd_ctx;
- return hdd_ctx->cfg_ini->IpaRMEnable;
+ eth_type = be16_to_cpu(eth->h_proto);
+ if (eth_type < 0x600) {
+ /* Non Ethernet II framing format */
+ ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data +
+ sizeof(struct ethhdr));
+
+ if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) ||
+ ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB)))
+ eth_type = be16_to_cpu(ls_hdr->eth_type);
+ }
+
+ if (eth_type == ETH_P_IP)
+ return true;
+
+ if (hdd_ipa_is_ipv6_enabled(hdd_ipa) && eth_type == ETH_P_IPV6)
+ return true;
+
+ return false;
}
static int hdd_ipa_rm_request(struct hdd_ipa_priv *hdd_ipa)
@@ -362,7 +395,7 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_rm_create_resource(&create_params);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "create resource fail");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Create RM resource failed");
goto setup_rm_fail;
}
@@ -370,11 +403,13 @@ static int hdd_ipa_setup_rm(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_WLAN_PROD,
HDD_IPA_RX_INACTIVITY_MSEC_DELAY);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "timer fail");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Timer init failed");
goto setup_rm_fail;
}
#endif
+ atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_RELEASED);
+
setup_rm_fail:
return ret;
}
@@ -391,10 +426,10 @@ static void hdd_ipa_destory_rm_resource(struct hdd_ipa_priv *hdd_ipa)
#endif
ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WLAN_PROD);
if (ret)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "fail");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "RM resource delete failed");
}
-void hdd_ipa_rm_timer_handler(unsigned long ptr)
+static void hdd_ipa_rm_timer_handler(unsigned long ptr)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
atomic_set(&hdd_ipa->rm_state,
@@ -402,27 +437,26 @@ void hdd_ipa_rm_timer_handler(unsigned long ptr)
hdd_ipa_rm_release(hdd_ipa);
}
-void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adap_dev)
+static void hdd_ipa_send_skb_to_network(adf_nbuf_t skb, hdd_adapter_t *adapter)
{
- if (!adap_dev || (adap_dev &&
- adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: adap=0x%x",
- adap_dev);
+ if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid adapter: 0x%p",
+ adapter);
- adf_nbuf_free(skb);
- return;
- }
- skb->dev = adap_dev->dev;
- skb->protocol = eth_type_trans(skb, skb->dev);
- skb->ip_summed = CHECKSUM_NONE;
- ++adap_dev->hdd_stats.hddTxRxStats.rxPackets;
- ++adap_dev->stats.rx_packets;
- adap_dev->stats.rx_bytes += skb->len;
- if (netif_rx_ni(skb) == NET_RX_SUCCESS)
- ++adap_dev->hdd_stats.hddTxRxStats.rxDelivered;
- else
- ++adap_dev->hdd_stats.hddTxRxStats.rxRefused;
- adap_dev->dev->last_rx = jiffies;
+ adf_nbuf_free(skb);
+ return;
+ }
+ skb->dev = adapter->dev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ skb->ip_summed = CHECKSUM_NONE;
+ ++adapter->hdd_stats.hddTxRxStats.rxPackets;
+ ++adapter->stats.rx_packets;
+ adapter->stats.rx_bytes += skb->len;
+ if (netif_rx_ni(skb) == NET_RX_SUCCESS)
+ ++adapter->hdd_stats.hddTxRxStats.rxDelivered;
+ else
+ ++adapter->hdd_stats.hddTxRxStats.rxRefused;
+ adapter->dev->last_rx = jiffies;
}
static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
@@ -478,21 +512,25 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
hdd_ipa->stats.rx_ipa_dh_sent++; /* for desc head */
#endif
spin_unlock_bh(&hdd_ipa->q_lock);
- if (ipa_tx_dp_mul(hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE],
+ if (ipa_tx_dp_mul(hdd_ipa->prod_client,
send_desc_head) != 0) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_tx_dp_mul failed!!! (cur_send_cnt=%d)", cur_send_cnt);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "ipa_tx_dp_mul failed!!!"
+ " (cur_send_cnt=%d)",
+ cur_send_cnt);
hdd_ipa->stats.tx_dp_err_cnt++;
spin_lock_bh(&hdd_ipa->q_lock);
list_for_each_entry_safe(desc, tmp,
- &send_desc_head->link, link) {
+ &send_desc_head->link, link) {
list_del(&desc->link);
buf = desc->priv;
adf_nbuf_free(buf);
desc->priv = NULL;
desc->pyld_buffer = NULL;
desc->pyld_len = 0;
- list_add_tail(&desc->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&desc->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.freeq_reclaim++;
@@ -501,7 +539,8 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
}
/* return anchor node */
- list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&send_desc_head->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_dh_reclaim++;
@@ -517,7 +556,8 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
hdd_ipa->stats.rx_ipa_hw_maxed_out++;
list_splice_tail_init(&send_desc_head->link,
&hdd_ipa->pend_desc_head);
- list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&send_desc_head->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_dh_not_used++;
@@ -528,52 +568,25 @@ static void hdd_ipa_send_pkt_to_ipa(struct ipa_tx_data_desc *send_desc_head,
}
-static int hdd_ipa_is_ip_pkt(void *data, uint8_t ip_ver)
-{
- struct ethhdr *eth = (struct ethhdr *)data;
- struct llc_snap_hdr *ls_hdr;
- uint16_t eth_type;
- int ret = 0;
-
- eth_type = be16_to_cpu(eth->h_proto);
- if (eth_type < 0x600) {
- /* Non Ethernet II framing format */
- ls_hdr = (struct llc_snap_hdr *)((uint8_t *)data +
- sizeof(struct ethhdr));
-
- if (((ls_hdr->dsap == 0xAA) && (ls_hdr->ssap == 0xAA)) ||
- ((ls_hdr->dsap == 0xAB) && (ls_hdr->ssap == 0xAB)))
- eth_type = be16_to_cpu(ls_hdr->eth_type);
- }
-
- if (((eth_type == ETH_P_IP) && (ip_ver == HDD_IPA_IPV4)) ||
- ((eth_type == ETH_P_IPV6) && (ip_ver == HDD_IPA_IPV6)))
- ret = 1;
-
- if (ret != 1)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "NOT IP Packet!!! (eth_type=0x%x, ip_ver=%d)", eth_type, ip_ver);
-
- return ret;
-}
-
-
static void hdd_ipa_process_evt(int evt, void *priv)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
struct hdd_ipa_rxt *rxt;
struct ipa_tx_data_desc *send_desc_head = NULL, *send_desc,
*done_desc_head, *done_desc, *tmp;
- hdd_adapter_t *adap_dev = NULL;
+ hdd_adapter_t *adapter = NULL;
+ struct hdd_ipa_iface_context *iface_context = NULL;
adf_nbuf_t buf, next_buf;
uint8_t cur_cnt = 0;
+ struct hdd_ipa_cld_hdr *cld_hdr;
switch (evt) {
case HDD_IPA_RXT_EVT:
rxt = priv;
- adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[rxt->sta_id];
- if (!adap_dev ||
- (adap_dev && adap_dev->magic != WLAN_HDD_ADAPTER_MAGIC)) {
+ adapter = hdd_ipa->hdd_ctx->sta_to_adapter[rxt->sta_id];
+ if (!adapter ||
+ (adapter && adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid sta_id");
buf = rxt->rx_buf_list;
while (buf) {
@@ -586,10 +599,14 @@ static void hdd_ipa_process_evt(int evt, void *priv)
}
return;
}
+
+ iface_context =
+ (struct hdd_ipa_iface_context *) adapter->ipa_context;
/* send_desc_head is a anchor node */
send_desc_head = hdd_ipa_get_desc_from_freeq();
if (!send_desc_head) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "send_desc_head=Null. FreeQ Empty");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "send_desc_head=Null. FreeQ Empty");
buf = rxt->rx_buf_list;
while (buf) {
next_buf = adf_nbuf_queue_next(buf);
@@ -612,34 +629,28 @@ static void hdd_ipa_process_evt(int evt, void *priv)
INIT_LIST_HEAD(&send_desc_head->link);
buf = rxt->rx_buf_list;
while (buf) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "RX data:\n \
- %02x %02x %02x %02x %02x %02x %02x %02x\n \
- %02x %02x %02x %02x %02x %02x %02x %02x\n \
- %02x %02x %02x %02x %02x %02x %02x %02x\n",
- buf->data[0], buf->data[1], buf->data[2], buf->data[3],
- buf->data[4], buf->data[5], buf->data[6], buf->data[7],
- buf->data[8], buf->data[9], buf->data[10], buf->data[11],
- buf->data[12], buf->data[13], buf->data[14], buf->data[15],
- buf->data[16], buf->data[17], buf->data[18], buf->data[19],
- buf->data[20], buf->data[21], buf->data[22], buf->data[23]);
+ HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "RX data",
+ buf->data, 24);
next_buf = adf_nbuf_queue_next(buf);
- /* we want to send Rx packets to IPA only when it is IPV4 or IPV6i(if IPV6
- is enabled). All other packets will be sent to network stack directly. */
- if (hdd_ipa_can_pre_filter(hdd_ipa) &&
- (!hdd_ipa_is_ip_pkt(buf->data, HDD_IPA_IPV4) &&
- (!hdd_ipa_is_ipv6_enabled(hdd_ipa) ||
- !hdd_ipa_is_ip_pkt(buf->data, HDD_IPA_IPV6)))) {
+ /*
+ * we want to send Rx packets to IPA only when it is
+ * IPV4 or IPV6i(if IPV6 is enabled). All other packets
+ * will be sent to network stack directly.
+ */
+ if (!hdd_ipa_can_send_to_ipa(hdd_ipa, buf->data)) {
hdd_ipa->stats.prefilter++;
- hdd_ipa_send_skb_to_network(buf, adap_dev);
+ hdd_ipa_send_skb_to_network(buf, adapter);
buf = next_buf;
continue;
}
- skb_push(buf, HDD_IPA_WLAN_HDR_ONLY_LEN);
- /* vos_mem_zero(((struct ipa_rx_hdr *)(buf->data))->hdr, HDD_IPA_WLAN_HDR_ONLY_LEN); */
- ((struct ipa_rx_hdr *)(buf->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET] = rxt->sta_id;
+ cld_hdr = (struct hdd_ipa_cld_hdr *) skb_push(buf,
+ HDD_IPA_WLAN_CLD_HDR_LEN);
+ cld_hdr->sta_id = rxt->sta_id;
+ cld_hdr->iface_id = iface_context->iface_id;
+
send_desc = hdd_ipa_get_desc_from_freeq();
if (send_desc) {
send_desc->priv = buf;
@@ -680,7 +691,8 @@ static void hdd_ipa_process_evt(int evt, void *priv)
if(cur_cnt == 0){
spin_lock_bh(&hdd_ipa->q_lock);
- list_add_tail(&send_desc_head->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&send_desc_head->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.rx_ipa_dh_not_used++;
@@ -699,7 +711,8 @@ static void hdd_ipa_process_evt(int evt, void *priv)
HDD_IPA_RM_GRANT_PENDING);
hdd_ipa_rm_request(hdd_ipa);
}
- /* hdd_ipa_rm_request can immediately grant so check again. */
+ /* hdd_ipa_rm_request can immediately grant so check
+ again. */
if (atomic_read(&hdd_ipa->rm_state)
== HDD_IPA_RM_GRANT_PENDING) {
spin_lock_bh(&hdd_ipa->q_lock);
@@ -740,7 +753,8 @@ rxt_end:
done_desc->priv = NULL;
done_desc->pyld_buffer = NULL;
done_desc->pyld_len = 0;
- list_add_tail(&done_desc->link, &hdd_ipa->free_desc_head);
+ list_add_tail(&done_desc->link,
+ &hdd_ipa->free_desc_head);
hdd_ipa->stats.freeq_cnt++;
#ifdef HDD_IPA_EXTRA_DP_COUNTERS
hdd_ipa->stats.freeq_reclaim++;
@@ -781,12 +795,6 @@ rxt_end:
}
}
-static void hdd_ipa_w2i_write_done_handler(
- struct ipa_tx_data_desc *done_desc_head)
-{
- hdd_ipa_process_evt(HDD_IPA_WRITE_DONE_EVT, done_desc_head);
-}
-
VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list,
v_U8_t sta_id)
{
@@ -804,50 +812,43 @@ VOS_STATUS hdd_ipa_process_rxt(v_VOID_t *vosContext, adf_nbuf_t rx_buf_list,
return VOS_STATUS_SUCCESS;
}
-
-
-void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
+static void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt,
+ unsigned long data)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- uint8_t client;
+ struct hdd_ipa_priv *hdd_ipa = NULL;
+ hdd_adapter_t *adapter = NULL;
struct ipa_tx_data_desc *done_desc_head;
adf_nbuf_t skb;
- uint8_t sta_id;
- hdd_adapter_t *adap_dev=NULL;
+ uint8_t iface_id;
- client = *((uint8_t *)priv);
- if (client != hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "w2i cb wrong pipe: %d %x %x",
- client, priv,
- &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE]);
- return;
- }
+ hdd_ipa = (struct hdd_ipa_priv *)priv;
switch (evt) {
case IPA_RECEIVE:
skb = (adf_nbuf_t) data;
- sta_id = ((struct ipa_rx_hdr *)(skb->data))->hdr[HDD_IPA_WLAN_HDR_STA_ID_OFFSET];
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
- skb_pull(skb, HDD_IPA_WLAN_HDR_ONLY_LEN);
-
- if (sta_id < ARRAY_SIZE(hdd_ipa->hdd_ctx->sta_to_adapter)) {
- adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id];
- } else {
+ iface_id = HDD_IPA_GET_IFACE_ID(skb->data);
+ if (iface_id >= HDD_IPA_MAX_IFACE) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
- "w2i cb: wrong sta_id: %d", sta_id);
+ "IPA_RECEIVE: Invalid iface_id: %u\n",
+ iface_id);
+ adf_nbuf_free(skb);
+ return;
}
+ adapter = hdd_ipa->iface_context[iface_id].adapter;
+
+ HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "w2i -- skb", skb->data,
+ 8);
+
+ skb_pull(skb, HDD_IPA_WLAN_CLD_HDR_LEN);
+
hdd_ipa->stats.rx_ipa_excep++;
- hdd_ipa_send_skb_to_network(skb, adap_dev);
+ hdd_ipa_send_skb_to_network(skb, adapter);
break;
case IPA_WRITE_DONE:
done_desc_head = (struct ipa_tx_data_desc *)data;
- hdd_ipa_w2i_write_done_handler(done_desc_head);
+ hdd_ipa_process_evt(HDD_IPA_WRITE_DONE_EVT, done_desc_head);
break;
default:
HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
@@ -856,93 +857,33 @@ void hdd_ipa_w2i_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
}
}
-void hdd_ipa_nbuf_cb(adf_nbuf_t skb)
+static void hdd_ipa_nbuf_cb(adf_nbuf_t skb)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
/* TX COMP counter at frame free location. */
hdd_ipa->stats.tx_comp_cnt++;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb));
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "%lx", NBUF_OWNER_PRIV_DATA(skb));
ipa_free_skb((struct ipa_rx_data *) NBUF_OWNER_PRIV_DATA(skb));
}
-#ifdef WLAN_TX_MUL
-void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
+static void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt,
+ unsigned long data)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- struct ipa_rx_data_mul *ipa_tx_desc;
- adf_nbuf_t skb;
- uint8_t client, pipe_id;
-
- if (evt == IPA_RECEIVE) {
- client = *((uint8_t *)priv);
- struct list_head *head = (struct list_head *)data;
-
- pipe_id = ipa_client_id_2_hdd_pipe_id[client];
-
- if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (vdev=NULL)");
- /* TODO: need to free ipa_desc and skb here */
- return;
- }
-
- list_for_each_entry(ipa_tx_desc, head, link) {
- if (ipa_tx_desc->dd == NULL)
- break;
-
- /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer.*/
- hdd_ipa->stats.tx_ipa_recv++;
-
- skb = ipa_tx_desc->dd->skb;
-
- /* skb->dev = ipa_client_id_2_hdd_pipe_id[client]; */
- adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
- NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
- NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
- NBUF_MAPPED_PADDR_LO(skb) = ipa_tx_desc->dd->dma_addr;
-
- NBUF_OWNER_PRIV_DATA(skb) = (unsigned long)ipa_tx_desc->dd;
-
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
-
- skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id],
- ipa_tx_desc->dd->skb);
- if (skb) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail");
- ipa_free_skb(ipa_tx_desc->dd);
- continue;
- }
- }
- ipa_free_desc(data);
-
- } else {
- /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */
- skb = (adf_nbuf_t) data;
- dev_kfree_skb_any(skb);
- }
-}
-
-#else
-
-void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
-{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+ struct hdd_ipa_priv *hdd_ipa = NULL;
struct ipa_rx_data *ipa_tx_desc;
+ struct hdd_ipa_iface_context *iface_context;
adf_nbuf_t skb;
- uint8_t client, pipe_id;
if (evt == IPA_RECEIVE) {
- /* TX frame Counter at HDD CB function called by IPA loopback, to push lower layer */
- hdd_ipa->stats.tx_ipa_recv++;
- client = *((uint8_t *)priv);
+ iface_context = (struct hdd_ipa_iface_context *) priv;
ipa_tx_desc = (struct ipa_rx_data *)data;
skb = ipa_tx_desc->skb;
+ hdd_ipa = iface_context->hdd_ipa;
+
adf_os_mem_set(skb->cb, 0, sizeof(skb->cb));
NBUF_OWNER_ID(skb) = IPA_NBUF_OWNER_ID;
NBUF_CALLBACK_FN(skb) = hdd_ipa_nbuf_cb;
@@ -950,36 +891,22 @@ void hdd_ipa_i2w_cb(void *priv, enum ipa_dp_evt_type evt, unsigned long data)
NBUF_OWNER_PRIV_DATA(skb) = data;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "0x%p", NBUF_OWNER_PRIV_DATA(skb));
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "skb:0x%p: %02x %02x %02x %02x %02x %02x %02x %02x", skb,
- skb->data[0], skb->data[1], skb->data[2], skb->data[3],
- skb->data[4], skb->data[5], skb->data[6], skb->data[7]);
-
- pipe_id = ipa_client_id_2_hdd_pipe_id[client];
+ HDD_IPA_DBG_DUMP(VOS_TRACE_LEVEL_DEBUG, "i2w", skb->data, 8);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, "client=%d, pipe_to_vdev[%d]=0x%x", client, pipe_id, hdd_ipa->pipe_to_vdev[pipe_id]);
-
- if (hdd_ipa->pipe_to_vdev[pipe_id] == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail (pipe_to_vdev[%d]=NULL)", pipe_id);
- ipa_free_skb(ipa_tx_desc);
- return;
- }
+ hdd_ipa->stats.tx_ipa_recv++;
- skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext, hdd_ipa->pipe_to_vdev[pipe_id],
- ipa_tx_desc->skb);
+ skb = WLANTL_SendIPA_DataFrame(hdd_ipa->hdd_ctx->pvosContext,
+ iface_context->tl_context, ipa_tx_desc->skb);
if (skb) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "TLSHIM tx fail");
ipa_free_skb(ipa_tx_desc);
return;
}
} else {
- /* HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "i2w cb wrong evt: %d", evt);
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Testing hack code data path"); */
skb = (adf_nbuf_t) data;
dev_kfree_skb_any(skb);
}
}
-#endif
static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
{
@@ -987,12 +914,12 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
struct ipa_sys_connect_params *ipa;
/*setup TX pipes */
- for (i = 0; i < HDD_IPA_RX_PIPE; i++) {
+ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
ipa = &hdd_ipa->sys_pipe[i].ipa_sys_params;
- ipa->client = hdd_pipe_id_2_ipa_client_id[i];
+ ipa->client = hdd_ipa_adapter_2_client[i].cons_client;
ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize;
- ipa->priv = &hdd_pipe_id_2_ipa_client_id[i];
+ ipa->priv = &hdd_ipa->iface_context[i];
ipa->notify = hdd_ipa_i2w_cb;
ipa->ipa_ep_cfg.hdr.hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
@@ -1000,17 +927,35 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl));
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Fail: %d", ret);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for pipe %d"
+ " ret: %d", i, ret);
goto setup_sys_pipe_fail;
}
hdd_ipa->sys_pipe[i].conn_hdl_valid = 1;
}
+ /*
+ * Hard code it here, this can be extended if in case PROD pipe is also
+ * per interface. Right now there is no advantage of doing this.
+ */
+ hdd_ipa->prod_client = IPA_CLIENT_WLAN1_PROD;
+
ipa = &hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].ipa_sys_params;
- ipa->client = hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE];
- ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize + sizeof(struct sps_iovec); /* To make sure total # of desc is 1 less than the desc FIFO size */
- ipa->priv = &hdd_pipe_id_2_ipa_client_id[HDD_IPA_RX_PIPE];
+ ipa->client = hdd_ipa->prod_client;
+
+ /* The maximum number of descriptors that can be provided to a BAM at
+ * once is one less than the total number of descriptors that the buffer
+ * can contain.
+ * If max_num_of_descriptors = (BAM_PIPE_DESCRIPTOR_FIFO_SIZE / sizeof
+ * (SPS_DESCRIPTOR)), then (max_num_of_descriptors - 1) descriptors can
+ * be provided at once.
+ * Because of above requirement, one extra descriptor will be added to
+ * make sure hardware always has one descriptor.
+ */
+ ipa->desc_fifo_sz = hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize
+ + sizeof(struct sps_iovec);
+ ipa->priv = hdd_ipa;
ipa->notify = hdd_ipa_w2i_cb;
ipa->ipa_ep_cfg.nat.nat_en = IPA_BYPASS_NAT;
@@ -1020,59 +965,73 @@ static int hdd_ipa_setup_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
ret = ipa_setup_sys_pipe(ipa, &(hdd_ipa->sys_pipe[i].conn_hdl));
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Fail: %d", ret);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed for RX pipe: %d",
+ ret);
goto setup_sys_pipe_fail;
}
hdd_ipa->sys_pipe[HDD_IPA_RX_PIPE].conn_hdl_valid = 1;
+ return ret;
+
setup_sys_pipe_fail:
+
+ while (--i >= 0) {
+ ipa_teardown_sys_pipe(hdd_ipa->sys_pipe[i].conn_hdl);
+ vos_mem_zero(&hdd_ipa->sys_pipe[i],
+ sizeof(struct hdd_ipa_sys_pipe ));
+ }
+
return ret;
}
/* Disconnect all the Sys pipes */
-void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
+static void hdd_ipa_teardown_sys_pipe(struct hdd_ipa_priv *hdd_ipa)
{
int ret = 0, i;
- for (i = 0; i < HDD_IPA_MAX_PIPE; i++) {
+ for (i = 0; i < HDD_IPA_MAX_SYSBAM_PIPE; i++) {
if (hdd_ipa->sys_pipe[i].conn_hdl_valid) {
ret = ipa_teardown_sys_pipe(
hdd_ipa->sys_pipe[i].conn_hdl);
if (ret)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "fail: %d",
- ret);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Failed: %d",
+ ret);
hdd_ipa->sys_pipe[i].conn_hdl_valid = 0;
}
}
}
-int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, const char *ifname)
+static int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa,
+ struct hdd_ipa_iface_context *iface_context)
{
struct ipa_tx_intf tx_intf;
struct ipa_rx_intf rx_intf;
struct ipa_ioc_tx_intf_prop *tx_prop = NULL;
struct ipa_ioc_rx_intf_prop *rx_prop = NULL;
+ char *ifname = iface_context->adapter->dev->name;
char ipv4_hdr_name[IPA_RESOURCE_NAME_MAX];
char ipv6_hdr_name[IPA_RESOURCE_NAME_MAX];
- int ip_max = HDD_IPA_IPV4;
+ int num_prop = 1;
int ret = 0;
if (hdd_ipa_is_ipv6_enabled(hdd_ipa))
- ip_max = HDD_IPA_IPV6;
+ num_prop++;
/* Allocate TX properties for TOS categories, 1 each for IPv4 & IPv6 */
- tx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_tx_intf_prop) * ip_max);
+ tx_prop = vos_mem_malloc(sizeof(struct ipa_ioc_tx_intf_prop) *
+ num_prop);
if (!tx_prop) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "tx_prop allocation failed");
goto register_interface_fail;
}
/* Allocate RX properties, 1 each for IPv4 & IPv6 */
- rx_prop = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_rx_intf_prop) * ip_max);
+ rx_prop = vos_mem_malloc(sizeof(struct ipa_ioc_rx_intf_prop) *
+ num_prop);
if (!rx_prop) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "rx_prop allocation failed");
goto register_interface_fail;
}
vos_mem_zero(&tx_intf, sizeof(tx_intf));
@@ -1084,23 +1043,42 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con
ifname, HDD_IPA_IPV6_NAME_EXT);
rx_prop[IPA_IP_v4].ip = IPA_IP_v4;
- rx_prop[IPA_IP_v4].src_pipe = IPA_CLIENT_WLAN1_PROD;
+ rx_prop[IPA_IP_v4].src_pipe = iface_context->prod_client;
+
+ rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA;
+
+ /*
+ * Interface ID is 3rd byte in the CLD header. Add the meta data and
+ * mask to identify the interface in IPA hardware
+ */
+ rx_prop[IPA_IP_v4].attrib.meta_data =
+ htonl(iface_context->iface_id << 16);
+ rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000);
+
rx_intf.num_props++;
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
rx_prop[IPA_IP_v6].ip = IPA_IP_v6;
- rx_prop[IPA_IP_v6].src_pipe = IPA_CLIENT_WLAN1_PROD;
+ rx_prop[IPA_IP_v6].src_pipe = iface_context->prod_client;
+
+ rx_prop[IPA_IP_v4].attrib.attrib_mask = IPA_FLT_META_DATA;
+ rx_prop[IPA_IP_v4].attrib.meta_data =
+ htonl(iface_context->iface_id << 16);
+ rx_prop[IPA_IP_v4].attrib.meta_data_mask = htonl(0x00FF0000);
+
rx_intf.num_props++;
}
tx_prop[IPA_IP_v4].ip = IPA_IP_v4;
- tx_prop[IPA_IP_v4].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]];
- strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name, IPA_RESOURCE_NAME_MAX);
+ tx_prop[IPA_IP_v4].dst_pipe = iface_context->cons_client;
+ strlcpy(tx_prop[IPA_IP_v4].hdr_name, ipv4_hdr_name,
+ IPA_RESOURCE_NAME_MAX);
tx_intf.num_props++;
+
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
tx_prop[IPA_IP_v6].ip = IPA_IP_v6;
- tx_prop[IPA_IP_v6].dst_pipe = hdd_pipe_id_2_ipa_client_id[wlan_sta_id_2_hdd_pipe_id[sta_id]];
+ tx_prop[IPA_IP_v6].dst_pipe = iface_context->cons_client;
strlcpy(tx_prop[IPA_IP_v6].hdr_name, ipv6_hdr_name,
- IPA_RESOURCE_NAME_MAX);
+ IPA_RESOURCE_NAME_MAX);
tx_intf.num_props++;
}
@@ -1111,201 +1089,248 @@ int hdd_ipa_register_interface(struct hdd_ipa_priv *hdd_ipa, uint8_t sta_id, con
ret = ipa_register_intf(ifname, &tx_intf, &rx_intf);
register_interface_fail:
- adf_os_mem_free(tx_prop);
- adf_os_mem_free(rx_prop);
+ vos_mem_free(tx_prop);
+ vos_mem_free(rx_prop);
return ret;
}
-static int hdd_ipa_add_header_info(enum ipa_wlan_event type, uint8_t sta_id, uint8_t *mac_addr)
+static void hdd_remove_ipa_header(char *name)
{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- char *ifname;
- struct ipa_ioc_add_hdr *ipahdr = NULL;
- int i, ret = -EINVAL;
- hdd_adapter_t *adap_dev;
- struct ol_txrx_pdev_t *pdev;
- struct ol_txrx_vdev_t *vdev;
-
- adap_dev = hdd_ipa->hdd_ctx->sta_to_adapter[sta_id];
- if (!adap_dev) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "adap_dev NULL");
- goto add_header_info_ctx_fail;
+ struct ipa_ioc_get_hdr hdrlookup;
+ int ret = 0, len;
+ struct ipa_ioc_del_hdr *ipa_hdr;
+
+ vos_mem_zero(&hdrlookup, sizeof(hdrlookup));
+ strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name));
+ ret = ipa_get_hdr(&hdrlookup);
+ if (ret) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Hdr deleted already %s, %d",
+ name, ret);
+ return;
}
- ifname = adap_dev->dev->name;
- for (i = 0; i < HDD_IPA_MAX_PIPE; i++)
- hdd_ipa->pipe_to_vdev[i] = NULL;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "hdl: 0x%x", hdrlookup.hdl);
+ len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del)*1;
+ ipa_hdr = (struct ipa_ioc_del_hdr *) vos_mem_malloc(len);
+ if (ipa_hdr == NULL) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "ipa_hdr allocation failed");
+ return;
+ }
+ ipa_hdr->num_hdls = 1;
+ ipa_hdr->commit = 0;
+ ipa_hdr->hdl[0].hdl = hdrlookup.hdl;
+ ipa_hdr->hdl[0].status = -1;
+ ret = ipa_del_hdr(ipa_hdr);
+ if (ret != 0)
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Delete header failed: %d",
+ ret);
- if (wlan_sta_id_2_hdd_pipe_id[sta_id] == 0xFF) {
- switch (type) {
- case WLAN_AP_CONNECT:
- wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN0_PIPE; /* TODO: need to expand to AP+AP */
- break;
- case WLAN_STA_CONNECT:
- /* Register pipe_to_vdev for STA mode */
- pdev = ((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev)->pvosContext))->pdev_txrx_ctx;
- /* find the "vdev" this STA interface belongs to */
- TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) {
- if (adf_os_mem_cmp(mac_addr, vdev->mac_addr.raw, IEEE80211_ADDR_LEN) == 0) {
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = vdev;
- break;
- }
- }
+ vos_mem_free(ipa_hdr);
+}
- wlan_sta_id_2_hdd_pipe_id[sta_id] = HDD_IPA_TX_WLAN2_PIPE; /* STA Mode */
- break;
- default:
- break;
- }
- }
- HDD_IPA_LOG(VOS_TRACE_LEVEL_DEBUG, " wlan_sta_id_2_hdd_pipe_id[%d]: %d",
- sta_id, wlan_sta_id_2_hdd_pipe_id[sta_id]);
+static int hdd_ipa_add_header_info(struct hdd_ipa_priv *hdd_ipa,
+ struct hdd_ipa_iface_context *iface_context, uint8_t *mac_addr)
+{
+ hdd_adapter_t *adapter = iface_context->adapter;
+ char *ifname;
+ struct ipa_ioc_add_hdr *ipa_hdr = NULL;
+ int ret = -EINVAL;
+ struct hdd_ipa_tx_hdr *tx_hdr = NULL;
+ ifname = adapter->dev->name;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifindex: %d Add Partial hdr: %s, %p\n",
- sta_id, ifname, mac_addr);
- if (ifname == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ifname NULL");
- goto add_header_info_ctx_fail;
- }
+
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Add Partial hdr: %s, %pM",
+ ifname, mac_addr);
/* dynamically allocate the memory to add the hdrs */
- ipahdr = hdd_ipa_kzalloc(sizeof(struct ipa_ioc_add_hdr) +
- sizeof(struct ipa_hdr_add));
- if (!ipahdr) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s: ENOMEM", ifname);
- return -ENOMEM;
+ ipa_hdr = vos_mem_malloc(sizeof(struct ipa_ioc_add_hdr)
+ + sizeof(struct ipa_hdr_add));
+ if (!ipa_hdr) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: ipa_hdr allocation failed", ifname);
+ ret = -ENOMEM;
+ goto end;
}
- ipahdr->commit = 0;
- ipahdr->num_hdrs = 1;
+ ipa_hdr->commit = 0;
+ ipa_hdr->num_hdrs = 1;
+
+ tx_hdr = (struct hdd_ipa_tx_hdr *)ipa_hdr->hdr[0].hdr;
+
/* Set the Source MAC */
- memcpy(ipahdr->hdr[0].hdr, (uint8_t *)&ipa_set_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
- memcpy((uint8_t *)(((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->eth.h_source), mac_addr,
- ETH_ALEN);
+ memcpy(tx_hdr, &ipa_tx_hdr, HDD_IPA_WLAN_TX_HDR_LEN);
+ memcpy(tx_hdr->eth.h_source, mac_addr, ETH_ALEN);
- snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
- ifname, HDD_IPA_IPV4_NAME_EXT);
- ipahdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
- ipahdr->hdr[0].is_partial = HDD_IPA_WLAN_HDR_PARTIAL;
- ipahdr->hdr[0].hdr_hdl = 0;
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV4_NAME_EXT);
+ ipa_hdr->hdr[0].hdr_len = HDD_IPA_WLAN_TX_HDR_LEN;
+ ipa_hdr->hdr[0].is_partial = 1;
+ ipa_hdr->hdr[0].hdr_hdl = 0;
/* Set the type to IPV4 in the header*/
- ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IP);
+ tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IP);
- ret = ipa_add_hdr(ipahdr);
+ ret = ipa_add_hdr(ipa_hdr);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 fail: %d", ifname
- , ret);
- goto add_header_info_fail;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "%s IPv4 add hdr failed: %d",
+ ifname, ret);
+ goto end;
}
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv4 hdr_hdl: %x",
- ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv4 hdr_hdl: 0x%x",
+ ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl);
+
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
- snprintf(ipahdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
- ifname, HDD_IPA_IPV6_NAME_EXT);
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV6_NAME_EXT);
+
/* Set the type to IPV6 in the header*/
- ((struct ipa_tx_hdr *)(ipahdr->hdr[0].hdr))->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6);
+ tx_hdr->llc_snap.eth_type = cpu_to_be16(ETH_P_IPV6);
+
+ ret = ipa_add_hdr(ipa_hdr);
- ret = ipa_add_hdr(ipahdr);
if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
- "%s: IPv6 hdr fail: %d", ifname, ret);
- goto add_header_info_fail;
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "%s: IPv6 add hdr failed: %d",
+ ifname, ret);
+ goto clean_ipv4_hdr;
}
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv6 hdr_hdl: %x",
- ipahdr->hdr[0].name, ipahdr->hdr[0].hdr_hdl);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: IPv6 hdr_hdl: 0x%x",
+ ipa_hdr->hdr[0].name, ipa_hdr->hdr[0].hdr_hdl);
}
- /* Configure the TX and RX pipes filter rules */
- ret = hdd_ipa_register_interface(hdd_ipa, sta_id, ifname);
-add_header_info_fail:
- adf_os_mem_free(ipahdr);
-add_header_info_ctx_fail:
- return ret;
-}
-
-void hdd_remove_ipa_header(char *name)
-{
- struct ipa_ioc_get_hdr hdrlookup;
- int ret = 0, len;
- struct ipa_ioc_del_hdr *ipahdr;
-
- vos_mem_zero(&hdrlookup, sizeof(hdrlookup));
- strlcpy(hdrlookup.name, name, sizeof(hdrlookup.name));
- ret = ipa_get_hdr(&hdrlookup);
- if (ret) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Hdr deleted already %s, %d",
- name, ret);
- return;
- }
+ vos_mem_free(ipa_hdr);
+ return ret;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "hdl: %x", hdrlookup.hdl);
- len = sizeof(struct ipa_ioc_del_hdr) + sizeof(struct ipa_hdr_del)*1;
- ipahdr = (struct ipa_ioc_del_hdr *) hdd_ipa_kzalloc(len);
- if (ipahdr == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM");
- return;
- }
- ipahdr->num_hdls = 1;
- ipahdr->commit = 0;
- ipahdr->hdl[0].hdl = hdrlookup.hdl;
- ipahdr->hdl[0].status = -1;
- ret = ipa_del_hdr(ipahdr);
- if (ret != 0)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "Fail: %d", ret);
+clean_ipv4_hdr:
+ snprintf(ipa_hdr->hdr[0].name, IPA_RESOURCE_NAME_MAX, "%s%s",
+ ifname, HDD_IPA_IPV4_NAME_EXT);
+ hdd_remove_ipa_header(ipa_hdr->hdr[0].name);
+end:
+ if(ipa_hdr)
+ vos_mem_free(ipa_hdr);
- adf_os_mem_free(ipahdr);
+ return ret;
}
-void hdd_ipa_clean_hdr(hdd_adapter_t *adap_dev, uint8_t sta_id)
+static void hdd_ipa_clean_hdr(hdd_adapter_t *adapter)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
int ret;
char name_ipa[IPA_RESOURCE_NAME_MAX];
- wlan_sta_id_2_hdd_pipe_id[sta_id] = 0xFF;
-
/* Remove the headers */
snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
- adap_dev->dev->name, HDD_IPA_IPV4_NAME_EXT);
+ adapter->dev->name, HDD_IPA_IPV4_NAME_EXT);
hdd_remove_ipa_header(name_ipa);
if (hdd_ipa_is_ipv6_enabled(hdd_ipa)) {
snprintf(name_ipa, IPA_RESOURCE_NAME_MAX, "%s%s",
- adap_dev->dev->name, HDD_IPA_IPV6_NAME_EXT);
+ adapter->dev->name, HDD_IPA_IPV6_NAME_EXT);
hdd_remove_ipa_header(name_ipa);
}
/* unregister the interface with IPA */
- ret = ipa_deregister_intf(adap_dev->dev->name);
+ ret = ipa_deregister_intf(adapter->dev->name);
if (ret)
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
- "%s: ipa_deregister_intf fail: %d", adap_dev->dev->name, ret);
+ "%s: ipa_deregister_intf fail: %d",
+ adapter->dev->name, ret);
+}
+
+static void hdd_ipa_cleanup_iface(struct hdd_ipa_priv *hdd_ipa,
+ struct hdd_ipa_iface_context *iface_context)
+{
+ hdd_ipa_clean_hdr(iface_context->adapter);
+
+ iface_context->adapter->ipa_context = NULL;
+ iface_context->adapter = NULL;
+ iface_context->tl_context = NULL;
+}
+
+
+static int hdd_ipa_setup_iface(struct hdd_ipa_priv *hdd_ipa,
+ hdd_adapter_t *adapter, uint8_t sta_id)
+{
+ struct hdd_ipa_iface_context *iface_context = NULL;
+ void *tl_context = NULL;
+ int i, ret = 0;
+
+ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
+ if (hdd_ipa->iface_context[i].adapter == NULL) {
+ iface_context = &hdd_ipa->iface_context[i];
+ break;
+ }
+ }
+
+ if (iface_context == NULL) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "All the IPA interfaces are in use");
+ ret = -ENOMEM;
+ goto end;
+ }
+
+
+ adapter->ipa_context = iface_context;
+ iface_context->adapter = adapter;
+ iface_context->sta_id = sta_id;
+ tl_context = tl_shim_get_vdev_by_sta_id(hdd_ipa->hdd_ctx->pvosContext,
+ sta_id);
+
+ if (tl_context == NULL) {
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "Not able to get TL context sta_id: %d",
+ sta_id);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ iface_context->tl_context = tl_context;
+
+ ret = hdd_ipa_add_header_info(hdd_ipa, iface_context,
+ adapter->dev->dev_addr);
+
+ if (ret)
+ goto end;
+
+ /* Configure the TX and RX pipes filter rules */
+ ret = hdd_ipa_register_interface(hdd_ipa, iface_context);
+ if (ret)
+ goto cleanup_header;
+
+ return ret;
+
+cleanup_header:
+
+ hdd_ipa_clean_hdr(adapter);
+end:
+ if (iface_context)
+ hdd_ipa_cleanup_iface(hdd_ipa, iface_context);
+ return ret;
}
static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
{
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "msg type:%d, len:%d\n", type, len);
- adf_os_mem_free(buff);
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "msg type:%d, len:%d", type, len);
+ ghdd_ipa->stats.free_msg++;
+ vos_mem_free(buff);
}
-int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
+int hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
enum ipa_wlan_event type, uint8_t *mac_addr)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- hdd_adapter_t *adap_dev = Adapter;
struct ipa_msg_meta meta;
struct ipa_wlan_msg *msg;
struct ipa_wlan_msg_ex *msg_ex = NULL;
int ret;
- const char *hdd_ipa_event_name[IPA_EVENT_MAX] = {
+ const char *hdd_ipa_event_name[IPA_WLAN_EVENT_MAX] = {
__stringify(WLAN_CLIENT_CONNECT),
__stringify(WLAN_CLIENT_DISCONNECT),
__stringify(WLAN_CLIENT_POWER_SAVE_MODE),
@@ -1318,69 +1343,67 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
__stringify(WLAN_STA_DISCONNECT),
__stringify(WLAN_CLIENT_CONNECT_EX),
};
- struct ol_txrx_peer_t *peer;
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: %s evt, MAC: %pM sta_id: %d",
- adap_dev->dev->name, hdd_ipa_event_name[type],
- mac_addr, sta_id);
- if (type >= IPA_EVENT_MAX)
+ adapter->dev->name, hdd_ipa_event_name[type], mac_addr,
+ sta_id);
+
+ if (type >= IPA_WLAN_EVENT_MAX)
return -EINVAL;
if (WARN_ON(is_zero_ether_addr(mac_addr)))
return -EINVAL;
+ hdd_ipa->stats.event[type]++;
+
switch (type) {
case WLAN_STA_CONNECT:
case WLAN_AP_CONNECT:
- hdd_ipa_add_header_info(type, sta_id, mac_addr);
+ ret = hdd_ipa_setup_iface(hdd_ipa, adapter, sta_id);
+ if (ret)
+ goto end;
break;
case WLAN_STA_DISCONNECT:
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN2_PIPE] = NULL;
case WLAN_AP_DISCONNECT:
- hdd_ipa_clean_hdr(adap_dev, sta_id);
+ hdd_ipa_cleanup_iface(hdd_ipa,
+ adapter->ipa_context);
break;
case WLAN_CLIENT_CONNECT_EX:
- /* Register pipe map to txrx_vdev into hdd_ipa */
- peer = ol_txrx_peer_find_by_local_id(((pVosContextType)(WLAN_HDD_GET_CTX(adap_dev))->pvosContext)->pdev_txrx_ctx, sta_id);
- if (!peer) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "Invalid peer");
- return -EINVAL;
- }
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d", adap_dev->dev->ifindex, sta_id);
- if (hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] == NULL) {
- hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = peer->vdev; /* TODO: need to expand to AP+AP */
- }
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%d %d",
+ adapter->dev->ifindex, sta_id);
meta.msg_type = type;
meta.msg_len = (sizeof(struct ipa_wlan_msg_ex) +
sizeof(struct ipa_wlan_hdr_attrib_val));
- msg_ex = hdd_ipa_kzalloc (meta.msg_len);
+ msg_ex = vos_mem_malloc (meta.msg_len);
+
if (msg_ex == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "msg_ex allocation failed");
return -ENOMEM;
}
- strlcpy(msg_ex->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX);
+ strlcpy(msg_ex->name, adapter->dev->name,
+ IPA_RESOURCE_NAME_MAX);
msg_ex->num_of_attribs = 1;
msg_ex->attribs[0].attrib_type = WLAN_HDR_ATTRIB_MAC_ADDR;
msg_ex->attribs[0].offset = HDD_IPA_WLAN_HDR_DES_MAC_OFFSET;
memcpy(msg_ex->attribs[0].u.mac_addr, mac_addr,
- IPA_MAC_ADDR_SIZE);
+ IPA_MAC_ADDR_SIZE);
ret = ipa_send_msg(&meta, msg_ex, hdd_ipa_msg_free_fn);
if (ret) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d : %d",
msg_ex->name, meta.msg_type, ret);
- adf_os_mem_free(msg_ex);
+ vos_mem_free(msg_ex);
return ret;
}
+ hdd_ipa->stats.send_msg++;
+
return 0;
case WLAN_CLIENT_DISCONNECT:
- /* TODO: need to expand to AP+AP */
- /* This will remove the vdev for rest of the connected clients */
- //hdd_ipa->pipe_to_vdev[HDD_IPA_TX_WLAN0_PIPE] = NULL;
break;
default:
@@ -1388,30 +1411,59 @@ int hdd_ipa_wlan_evt(void *Adapter, uint8_t sta_id,
}
meta.msg_len = sizeof(struct ipa_wlan_msg);
- msg = hdd_ipa_kzalloc(meta.msg_len);
+ msg = vos_mem_malloc(meta.msg_len);
if (msg == NULL) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR, "msg allocation failed");
return -ENOMEM;
}
meta.msg_type = type;
- strlcpy(msg->name, adap_dev->dev->name, IPA_RESOURCE_NAME_MAX);
+ strlcpy(msg->name, adapter->dev->name, IPA_RESOURCE_NAME_MAX);
memcpy(msg->mac_addr, mac_addr, ETH_ALEN);
+
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d",
msg->name, meta.msg_type);
+
ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn);
if (ret) {
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "%s: Evt: %d fail:%d",
msg->name, meta.msg_type, ret);
- adf_os_mem_free(msg);
+ vos_mem_free(msg);
return ret;
}
+ hdd_ipa->stats.send_msg++;
+
+end:
return ret;
}
+static void hdd_ipa_rx_pipe_desc_free(void)
+{
+ struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
+ uint32_t i = 0, max_desc_cnt;
+ struct ipa_tx_data_desc *desc, *tmp;
+
+ max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO;
+
+ spin_lock_bh(&hdd_ipa->q_lock);
+ list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) {
+ list_del(&desc->link);
+ spin_unlock_bh(&hdd_ipa->q_lock);
+ vos_mem_free(desc);
+ spin_lock_bh(&hdd_ipa->q_lock);
+ i++;
+ }
+ spin_unlock_bh(&hdd_ipa->q_lock);
+
+ if (i != max_desc_cnt)
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "free desc leak");
+
+}
+
+
static int hdd_ipa_rx_pipe_desc_alloc(void)
{
struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
@@ -1424,46 +1476,34 @@ static int hdd_ipa_rx_pipe_desc_alloc(void)
max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO;
spin_lock_init(&hdd_ipa->q_lock);
- spin_lock_bh(&hdd_ipa->q_lock);
+
INIT_LIST_HEAD(&hdd_ipa->free_desc_head);
INIT_LIST_HEAD(&hdd_ipa->pend_desc_head);
hdd_ipa->stats.freeq_cnt = max_desc_cnt;
for (i = 0; i < max_desc_cnt; i++) {
- tmp_desc = hdd_ipa_kzalloc(sizeof(struct
+ tmp_desc = vos_mem_malloc(sizeof(struct
ipa_tx_data_desc));
if (!tmp_desc) {
- ret = -1;
- break;
+ ret = -ENOMEM;
+
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_ERROR,
+ "Descriptor allocation failed\n");
+ goto fail;
}
+ spin_lock_bh(&hdd_ipa->q_lock);
list_add_tail(&tmp_desc->link, &hdd_ipa->free_desc_head);
+ spin_unlock_bh(&hdd_ipa->q_lock);
}
- spin_unlock_bh(&hdd_ipa->q_lock);
+
+
HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO,
"Desc sz:%d h_desc_cnt:%d freeq_cnt:%llu",
hdd_ipa->hdd_ctx->cfg_ini->IpaDescSize, hdd_ipa->hw_desc_cnt,
hdd_ipa->stats.freeq_cnt);
return ret;
-}
-
-static void hdd_ipa_rx_pipe_desc_free(void)
-{
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
- uint32_t i = 0, max_desc_cnt;
- struct ipa_tx_data_desc *desc, *tmp;
-
- max_desc_cnt = hdd_ipa->hw_desc_cnt * HDD_IPA_DESC_BUFFER_RATIO;
-
- spin_lock_bh(&hdd_ipa->q_lock);
- list_for_each_entry_safe(desc, tmp, &hdd_ipa->free_desc_head, link) {
- list_del(&desc->link);
- adf_os_mem_free(desc);
- i++;
- }
- spin_unlock_bh(&hdd_ipa->q_lock);
-
- if (i != max_desc_cnt)
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "free mem leak");
-
+fail:
+ hdd_ipa_rx_pipe_desc_free();
+ return ret;
}
static ssize_t hdd_ipa_debugfs_read_ipa_stats(struct file *file,
@@ -1573,7 +1613,7 @@ static const struct file_operations fops_ipa_stats = {
};
-int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
+static int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
{
#ifdef WLAN_OPEN_SOURCE
hdd_ipa->debugfs_dir = debugfs_create_dir("cld",
@@ -1587,6 +1627,13 @@ int hdd_ipa_debugfs_init(struct hdd_ipa_priv *hdd_ipa)
return 0;
}
+static void hdd_ipa_debugfs_remove(struct hdd_ipa_priv *hdd_ipa)
+{
+#ifdef WLAN_OPEN_SOURCE
+ debugfs_remove_recursive(hdd_ipa->debugfs_dir);
+#endif
+}
+
/**
* hdd_ipa_init() - Allocate hdd_ipa resources, ipa pipe resource and register
* wlan interface with IPA module.
@@ -1599,21 +1646,31 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
{
struct hdd_ipa_priv *hdd_ipa = NULL;
int ret, i;
- if (!hdd_ipa_is_enabled(hdd_ctx))
- return 0;
+ struct hdd_ipa_iface_context *iface_context = NULL;
- for (i = 0; i < HDD_IPA_WLAN_MAX_STA_ID; i++)
- wlan_sta_id_2_hdd_pipe_id[i] = 0xFF;
+ if (!hdd_ipa_is_enabled(hdd_ctx))
+ return VOS_STATUS_SUCCESS;
- hdd_ipa = hdd_ipa_kzalloc(sizeof(struct hdd_ipa_priv));
+ hdd_ipa = vos_mem_malloc(sizeof(struct hdd_ipa_priv));
if (!hdd_ipa) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "ENOMEM");
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "hdd_ipa allocation failed");
goto fail_setup_rm;
}
hdd_ctx->hdd_ipa = hdd_ipa;
ghdd_ipa = hdd_ipa;
hdd_ipa->hdd_ctx = hdd_ctx;
+ /* Create the interface context */
+ for (i = 0; i < HDD_IPA_MAX_IFACE; i++) {
+ iface_context = &hdd_ipa->iface_context[i];
+ iface_context->hdd_ipa = hdd_ipa;
+ iface_context->cons_client =
+ hdd_ipa_adapter_2_client[i].cons_client;
+ iface_context->prod_client =
+ hdd_ipa_adapter_2_client[i].prod_client;
+ iface_context->iface_id = i;
+ }
+
ret = hdd_ipa_setup_rm(hdd_ipa);
if (ret)
goto fail_setup_rm;
@@ -1622,8 +1679,6 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
if (ret)
goto fail_create_sys_pipe;
- atomic_set(&hdd_ipa->rm_state, HDD_IPA_RM_RELEASED);
-
ret = hdd_ipa_rx_pipe_desc_alloc();
if (ret)
goto fail_alloc_rx_pipe_desc;
@@ -1632,17 +1687,21 @@ VOS_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx)
if (ret)
goto fail_alloc_rx_pipe_desc;
- HDD_IPA_LOG(VOS_TRACE_LEVEL_FATAL, "IPA Init Done");
#ifndef HDD_IPA_USE_IPA_RM_TIMER
setup_timer(&hdd_ipa->rm_timer, hdd_ipa_rm_timer_handler,
(unsigned long) &hdd_ipa);
#endif
+ HDD_IPA_LOG(VOS_TRACE_LEVEL_INFO, "IPA Init Done");
+
return VOS_STATUS_SUCCESS;
fail_alloc_rx_pipe_desc:
hdd_ipa_rx_pipe_desc_free();
fail_create_sys_pipe:
hdd_ipa_destory_rm_resource(hdd_ipa);
fail_setup_rm:
+ if (hdd_ipa)
+ vos_mem_free(hdd_ipa);
+
return VOS_STATUS_E_FAILURE;
}
@@ -1653,6 +1712,8 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx)
if (!hdd_ipa_is_enabled(hdd_ctx))
return VOS_STATUS_SUCCESS;
+ hdd_ipa_debugfs_remove(hdd_ipa);
+
#ifndef HDD_IPA_USE_IPA_RM_TIMER
del_timer(&hdd_ipa->rm_timer);
#endif
@@ -1664,73 +1725,9 @@ VOS_STATUS hdd_ipa_cleanup(hdd_context_t *hdd_ctx)
hdd_ipa_teardown_sys_pipe(hdd_ipa);
hdd_ipa_destory_rm_resource(hdd_ipa);
- adf_os_mem_free(hdd_ctx->hdd_ipa);
+ vos_mem_free(hdd_ipa);
+ hdd_ctx->hdd_ipa = NULL;
return VOS_STATUS_SUCCESS;
}
-
-#if 0
-/**
-* hdd_ipa_start_xmit() - This is a hack code for IPA loopback test
-*/
-int hdd_ipa_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- hdd_adapter_t *pAdapter = (hdd_adapter_t *)netdev_priv(dev);
- hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
- uint8_t sta_id;
- struct hdd_ipa_priv *hdd_ipa = ghdd_ipa;
-
- v_MACADDR_t *pDestMacAddress = (v_MACADDR_t *)skb->data;
-
- if (vos_is_macaddr_broadcast(pDestMacAddress) ||
- vos_is_macaddr_group(pDestMacAddress)) {
- /* The BC/MC station ID is assigned during BSS starting phase.
- SAP will return the station ID used for BC/MC traffic. */
- sta_id = pHddApCtx->uBCStaId;
- hdd_softap_hard_start_xmit(skb, dev);
- return NETDEV_TX_OK;
- } else {
- sta_id = *(uint8_t *)(((uint8_t *)(skb->data)) - 1);
- if (sta_id == HDD_WLAN_INVALID_STA_ID) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "Failed to find right station");
- goto drop_pkt;
- } else if (FALSE == pAdapter->aStaInfo[sta_id].isUsed) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "STA %d is unregistered", sta_id);
- goto drop_pkt;
- }
-
- if ((WLANTL_STA_CONNECTED !=
- pAdapter->aStaInfo[sta_id].tlSTAState) &&
- (WLANTL_STA_AUTHENTICATED !=
- pAdapter->aStaInfo[sta_id].tlSTAState)) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "Station not connected yet");
- goto drop_pkt;
- } else if (WLANTL_STA_CONNECTED ==
- pAdapter->aStaInfo[sta_id].tlSTAState) {
- if (ntohs(skb->protocol) !=
- HDD_ETHERTYPE_802_1_X) {
- HDD_IPA_LOG(VOS_TRACE_LEVEL_WARN,
- "NON-EAPOL packet in no-Auth state");
- goto drop_pkt;
- }
- }
- }
- if (hdd_ipa_is_ip_pkt(skb->data, HDD_IPA_IPV4)) {
- /* TX frame Counter at HDD entry from kernel network stack, before give frame to IPA Loopback */
- hdd_ipa->stats.ipa_lb_cnt++;
- ipa_tx_dp(IPA_CLIENT_WLAN1_CONS, skb, NULL);
- } else {
- hdd_softap_hard_start_xmit(skb, dev);
- }
-
- return NETDEV_TX_OK;
-drop_pkt:
- kfree_skb(skb);
- return NETDEV_TX_OK;
-}
-#endif
-
#endif
diff --git a/CORE/VOSS/src/vos_trace.c b/CORE/VOSS/src/vos_trace.c
index 5b5f33562506..ea81ece70c25 100644
--- a/CORE/VOSS/src/vos_trace.c
+++ b/CORE/VOSS/src/vos_trace.c
@@ -388,10 +388,15 @@ void vos_trace_hex_dump( VOS_MODULE_ID module, VOS_TRACE_LEVEL level,
{
char *buf = (char *)data;
int i;
+
+ if (!(gVosTraceInfo[module].moduleTraceLevel &
+ VOS_TRACE_LEVEL_TO_MODULE_BITMASK(level)))
+ return;
+
for (i=0; (i+7)<buf_len; i+=8)
{
vos_trace_msg( module, level,
- "%02x %02x %02x %02x %02x %02x %02x %02x \n",
+ "%02x %02x %02x %02x %02x %02x %02x %02x",
buf[i],
buf[i+1],
buf[i+2],