qcacmn: Add core\utils directory and files to qcacmn
As a part of UMAC convergence, move the core\utils logging to qcacmn. CRs-Fixed: 1109855 Change-Id: I499a392f74f3e52e99df4d03e4a27bce6cf5be7c
Šī revīzija ir iekļauta:

revīziju iesūtīja
qcabuildsw

vecāks
6195152790
revīzija
60644c29e6
199
utils/epping/inc/epping_internal.h
Parasts fails
199
utils/epping/inc/epping_internal.h
Parasts fails
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
#ifndef EPPING_INTERNAL_H
|
||||
#define EPPING_INTERNAL_H
|
||||
/**===========================================================================
|
||||
|
||||
\file epping_internal.h
|
||||
|
||||
\brief Linux epping internal head file
|
||||
|
||||
==========================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Include files
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/semaphore.h>
|
||||
#if defined(WLAN_OPEN_SOURCE) && defined(CONFIG_HAS_WAKELOCK)
|
||||
#include <linux/wakelock.h>
|
||||
#endif
|
||||
#include "htc_api.h"
|
||||
#include "htc_packet.h"
|
||||
#include "epping_test.h"
|
||||
#include <qdf_atomic.h>
|
||||
#include <sir_mac_prot_def.h>
|
||||
#include <sir_debug.h>
|
||||
|
||||
#define EPPING_LOG_MASK (1<<EPPING_CMD_CAPTURE_RECV_CNT)
|
||||
#define EPPING_STATS_LOG_COUNT 50000
|
||||
#define EPPING_KTID_KILL_WAIT_TIME_MS 50
|
||||
|
||||
#define EPPING_FRAG_PER_MSDU 1
|
||||
#ifndef EPPING_TXBUF
|
||||
#define EPPING_TXBUF (512/EPPING_FRAG_PER_MSDU)
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Preprocessor definitions and constants
|
||||
-------------------------------------------------------------------------*/
|
||||
#define EPPING_MAX_ADAPTERS 1
|
||||
|
||||
#define EPPING_LOG(level, args ...) QDF_TRACE(QDF_MODULE_ID_HDD, level, ## args)
|
||||
|
||||
struct epping_cookie {
|
||||
HTC_PACKET HtcPkt; /* HTC packet wrapper */
|
||||
struct epping_cookie *next;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
EPPING_CTX_STATE_INITIAL = 0,
|
||||
EPPING_CTX_STATE_HIF_INIT,
|
||||
EPPING_CTX_STATE_STARTUP,
|
||||
EPPING_CTX_STATE_STARTED,
|
||||
EPPING_CTX_STATE_STOP
|
||||
} epping_ctx_state_t;
|
||||
|
||||
#define EPPING_MAX_NUM_EPIDS 4
|
||||
#define MAX_COOKIE_SLOTS_NUM 4
|
||||
#define MAX_COOKIE_SLOT_SIZE 512
|
||||
#define MAX_TX_PKT_DUP_NUM 4
|
||||
|
||||
#ifdef HIF_PCI
|
||||
#define WLAN_EPPING_DELAY_TIMEOUT_US 10
|
||||
#define EPPING_MAX_CE_NUMS 8
|
||||
#define EPPING_MAX_WATER_MARK 8
|
||||
typedef struct {
|
||||
struct task_struct *pid;
|
||||
void *arg;
|
||||
bool done;
|
||||
qdf_nbuf_t skb;
|
||||
HTC_ENDPOINT_ID eid;
|
||||
struct semaphore sem;
|
||||
bool inited;
|
||||
qdf_atomic_t atm;
|
||||
} epping_poll_t;
|
||||
#endif
|
||||
|
||||
typedef struct epping_context {
|
||||
int32_t con_mode;
|
||||
char *pwlan_module_name;
|
||||
uint32_t target_type;
|
||||
void *p_cds_context; /* CDS context */
|
||||
struct device *parent_dev; /* Pointer to the parent device */
|
||||
epping_ctx_state_t e_ctx_state;
|
||||
bool wow_nack;
|
||||
void *epping_adapter;
|
||||
HTC_HANDLE HTCHandle;
|
||||
HTC_ENDPOINT_ID EppingEndpoint[EPPING_MAX_NUM_EPIDS];
|
||||
unsigned int kperf_num_rx_recv[EPPING_MAX_NUM_EPIDS];
|
||||
unsigned int kperf_num_tx_acks[EPPING_MAX_NUM_EPIDS];
|
||||
unsigned int total_rx_recv;
|
||||
unsigned int total_tx_acks;
|
||||
#ifdef HIF_PCI
|
||||
epping_poll_t epping_poll[EPPING_MAX_NUM_EPIDS];
|
||||
#endif
|
||||
struct epping_cookie *cookie_list;
|
||||
int cookie_count;
|
||||
struct epping_cookie *s_cookie_mem[MAX_COOKIE_SLOTS_NUM];
|
||||
qdf_spinlock_t cookie_lock;
|
||||
} epping_context_t;
|
||||
|
||||
typedef enum {
|
||||
EPPING_TX_TIMER_STOPPED,
|
||||
EPPING_TX_TIMER_RUNNING
|
||||
} epping_tx_timer_state_t;
|
||||
|
||||
typedef struct epping_adapter_s {
|
||||
epping_context_t *pEpping_ctx;
|
||||
enum tQDF_ADAPTER_MODE device_mode;
|
||||
/** Handle to the network device */
|
||||
struct net_device *dev;
|
||||
struct qdf_mac_addr macAddressCurrent;
|
||||
uint8_t sessionId;
|
||||
/* for mboxping */
|
||||
qdf_spinlock_t data_lock;
|
||||
qdf_nbuf_queue_t nodrop_queue;
|
||||
qdf_timer_t epping_timer;
|
||||
epping_tx_timer_state_t epping_timer_state;
|
||||
bool registered;
|
||||
bool started;
|
||||
struct net_device_stats stats;
|
||||
} epping_adapter_t;
|
||||
|
||||
/* epping_helper signatures */
|
||||
int epping_cookie_init(epping_context_t *pEpping_ctx);
|
||||
void epping_cookie_cleanup(epping_context_t *pEpping_ctx);
|
||||
void epping_free_cookie(epping_context_t *pEpping_ctx,
|
||||
struct epping_cookie *cookie);
|
||||
struct epping_cookie *epping_alloc_cookie(epping_context_t *pEpping_ctx);
|
||||
void epping_get_dummy_mac_addr(tSirMacAddr macAddr);
|
||||
void epping_hex_dump(void *data, int buf_len, const char *str);
|
||||
void *epping_get_qdf_ctx(void);
|
||||
void epping_log_packet(epping_adapter_t *pAdapter,
|
||||
EPPING_HEADER *eppingHdr, int ret, const char *str);
|
||||
void epping_log_stats(epping_adapter_t *pAdapter, const char *str);
|
||||
void epping_set_kperf_flag(epping_adapter_t *pAdapter,
|
||||
HTC_ENDPOINT_ID eid, A_UINT8 kperf_flag);
|
||||
|
||||
/* epping_tx signatures */
|
||||
void epping_tx_timer_expire(epping_adapter_t *pAdapter);
|
||||
void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue);
|
||||
int epping_tx_send(qdf_nbuf_t skb, epping_adapter_t *pAdapter);
|
||||
|
||||
#ifdef HIF_SDIO
|
||||
HTC_SEND_FULL_ACTION epping_tx_queue_full(void *Context, HTC_PACKET *pPacket);
|
||||
#endif
|
||||
void epping_tx_dup_pkt(epping_adapter_t *pAdapter,
|
||||
HTC_ENDPOINT_ID eid, qdf_nbuf_t skb);
|
||||
/* epping_rx signatures */
|
||||
void epping_rx(void *Context, HTC_PACKET *pPacket);
|
||||
|
||||
#ifdef HIF_SDIO
|
||||
void epping_refill(void *ctx, HTC_ENDPOINT_ID Endpoint);
|
||||
#endif
|
||||
|
||||
/* epping_txrx signatures */
|
||||
epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx,
|
||||
tSirMacAddr macAddr,
|
||||
enum tQDF_ADAPTER_MODE device_mode);
|
||||
void epping_destroy_adapter(epping_adapter_t *pAdapter);
|
||||
int epping_connect_service(epping_context_t *pEpping_ctx);
|
||||
#ifdef HIF_PCI
|
||||
void epping_register_tx_copier(HTC_ENDPOINT_ID eid,
|
||||
epping_context_t *pEpping_ctx);
|
||||
void epping_unregister_tx_copier(HTC_ENDPOINT_ID eid,
|
||||
epping_context_t *pEpping_ctx);
|
||||
void epping_tx_copier_schedule(epping_context_t *pEpping_ctx,
|
||||
HTC_ENDPOINT_ID eid, qdf_nbuf_t skb);
|
||||
#endif /* HIF_PCI */
|
||||
#endif /* end #ifndef EPPING_INTERNAL_H */
|
49
utils/epping/inc/epping_main.h
Parasts fails
49
utils/epping/inc/epping_main.h
Parasts fails
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
#ifndef EPPING_MAIN_H
|
||||
#define EPPING_MAIN_H
|
||||
/**===========================================================================
|
||||
|
||||
\file epping_main.h
|
||||
|
||||
\brief Linux epping head file
|
||||
|
||||
==========================================================================*/
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Include files
|
||||
-------------------------------------------------------------------------*/
|
||||
#include <qdf_lock.h>
|
||||
#include <qdf_types.h>
|
||||
|
||||
/* epping_main signatures */
|
||||
int epping_open(void);
|
||||
void epping_close(void);
|
||||
void epping_disable(void);
|
||||
int epping_enable(struct device *parent_dev);
|
||||
#endif /* end #ifndef EPPING_MAIN_H */
|
210
utils/epping/src/epping_helper.c
Parasts fails
210
utils/epping/src/epping_helper.c
Parasts fails
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
/*========================================================================
|
||||
|
||||
\file epping_main.c
|
||||
|
||||
\brief WLAN End Point Ping test tool implementation
|
||||
|
||||
========================================================================*/
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Include Files
|
||||
------------------------------------------------------------------------*/
|
||||
#include <cds_api.h>
|
||||
#include <cds_sched.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/delay.h>
|
||||
#include <wni_api.h>
|
||||
#include <wlan_ptt_sock_svc.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include "epping_main.h"
|
||||
#include "epping_internal.h"
|
||||
|
||||
int epping_cookie_init(epping_context_t *pEpping_ctx)
|
||||
{
|
||||
A_UINT32 i, j;
|
||||
|
||||
pEpping_ctx->cookie_list = NULL;
|
||||
pEpping_ctx->cookie_count = 0;
|
||||
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
|
||||
pEpping_ctx->s_cookie_mem[i] =
|
||||
qdf_mem_malloc(sizeof(struct epping_cookie) *
|
||||
MAX_COOKIE_SLOT_SIZE);
|
||||
if (pEpping_ctx->s_cookie_mem[i] == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: no mem for cookie (idx = %d)", __func__,
|
||||
i);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
qdf_spinlock_create(&pEpping_ctx->cookie_lock);
|
||||
|
||||
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
|
||||
struct epping_cookie *cookie_mem = pEpping_ctx->s_cookie_mem[i];
|
||||
for (j = 0; j < MAX_COOKIE_SLOT_SIZE; j++) {
|
||||
epping_free_cookie(pEpping_ctx, &cookie_mem[j]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
|
||||
if (pEpping_ctx->s_cookie_mem[i]) {
|
||||
qdf_mem_free(pEpping_ctx->s_cookie_mem[i]);
|
||||
pEpping_ctx->s_cookie_mem[i] = NULL;
|
||||
}
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* cleanup cookie queue */
|
||||
void epping_cookie_cleanup(epping_context_t *pEpping_ctx)
|
||||
{
|
||||
int i;
|
||||
qdf_spin_lock_bh(&pEpping_ctx->cookie_lock);
|
||||
pEpping_ctx->cookie_list = NULL;
|
||||
pEpping_ctx->cookie_count = 0;
|
||||
qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock);
|
||||
for (i = 0; i < MAX_COOKIE_SLOTS_NUM; i++) {
|
||||
if (pEpping_ctx->s_cookie_mem[i]) {
|
||||
qdf_mem_free(pEpping_ctx->s_cookie_mem[i]);
|
||||
pEpping_ctx->s_cookie_mem[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void epping_free_cookie(epping_context_t *pEpping_ctx,
|
||||
struct epping_cookie *cookie)
|
||||
{
|
||||
qdf_spin_lock_bh(&pEpping_ctx->cookie_lock);
|
||||
cookie->next = pEpping_ctx->cookie_list;
|
||||
pEpping_ctx->cookie_list = cookie;
|
||||
pEpping_ctx->cookie_count++;
|
||||
qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock);
|
||||
}
|
||||
|
||||
struct epping_cookie *epping_alloc_cookie(epping_context_t *pEpping_ctx)
|
||||
{
|
||||
struct epping_cookie *cookie;
|
||||
|
||||
qdf_spin_lock_bh(&pEpping_ctx->cookie_lock);
|
||||
cookie = pEpping_ctx->cookie_list;
|
||||
if (cookie != NULL) {
|
||||
pEpping_ctx->cookie_list = cookie->next;
|
||||
pEpping_ctx->cookie_count--;
|
||||
}
|
||||
qdf_spin_unlock_bh(&pEpping_ctx->cookie_lock);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
void epping_get_dummy_mac_addr(tSirMacAddr macAddr)
|
||||
{
|
||||
macAddr[0] = 69; /* E */
|
||||
macAddr[1] = 80; /* P */
|
||||
macAddr[2] = 80; /* P */
|
||||
macAddr[3] = 73; /* I */
|
||||
macAddr[4] = 78; /* N */
|
||||
macAddr[5] = 71; /* G */
|
||||
}
|
||||
|
||||
void epping_hex_dump(void *data, int buf_len, const char *str)
|
||||
{
|
||||
char *buf = (char *)data;
|
||||
int i;
|
||||
|
||||
printk("%s: E, %s\n", __func__, str);
|
||||
for (i = 0; (i + 7) < buf_len; i += 8) {
|
||||
printk("%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
buf[i],
|
||||
buf[i + 1],
|
||||
buf[i + 2],
|
||||
buf[i + 3],
|
||||
buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
|
||||
}
|
||||
|
||||
/* Dump the bytes in the last line */
|
||||
for (; i < buf_len; i++) {
|
||||
printk("%02x ", buf[i]);
|
||||
}
|
||||
printk("\n%s: X %s\n", __func__, str);
|
||||
}
|
||||
|
||||
void *epping_get_qdf_ctx(void)
|
||||
{
|
||||
qdf_device_t *qdf_ctx;
|
||||
|
||||
qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
return qdf_ctx;
|
||||
}
|
||||
|
||||
void epping_log_packet(epping_adapter_t *pAdapter,
|
||||
EPPING_HEADER *eppingHdr, int ret, const char *str)
|
||||
{
|
||||
if (eppingHdr->Cmd_h & EPPING_LOG_MASK) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: cmd = %d, seqNo = %u, flag = 0x%x, ret = %d, "
|
||||
"txCount = %lu, txDrop = %lu, txBytes = %lu,"
|
||||
"rxCount = %lu, rxDrop = %lu, rxBytes = %lu\n",
|
||||
str, eppingHdr->Cmd_h, eppingHdr->SeqNo,
|
||||
eppingHdr->CmdFlags_h, ret,
|
||||
pAdapter->stats.tx_packets,
|
||||
pAdapter->stats.tx_dropped,
|
||||
pAdapter->stats.tx_bytes,
|
||||
pAdapter->stats.rx_packets,
|
||||
pAdapter->stats.rx_dropped,
|
||||
pAdapter->stats.rx_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void epping_log_stats(epping_adapter_t *pAdapter, const char *str)
|
||||
{
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: txCount = %lu, txDrop = %lu, tx_bytes = %lu, "
|
||||
"rxCount = %lu, rxDrop = %lu, rx_bytes = %lu, tx_acks = %u\n",
|
||||
str,
|
||||
pAdapter->stats.tx_packets,
|
||||
pAdapter->stats.tx_dropped,
|
||||
pAdapter->stats.tx_bytes,
|
||||
pAdapter->stats.rx_packets,
|
||||
pAdapter->stats.rx_dropped,
|
||||
pAdapter->stats.rx_bytes,
|
||||
pAdapter->pEpping_ctx->total_tx_acks);
|
||||
}
|
||||
|
||||
void epping_set_kperf_flag(epping_adapter_t *pAdapter,
|
||||
HTC_ENDPOINT_ID eid, A_UINT8 kperf_flag)
|
||||
{
|
||||
pAdapter->pEpping_ctx->kperf_num_rx_recv[eid] = 0;
|
||||
pAdapter->pEpping_ctx->kperf_num_tx_acks[eid] = 0;
|
||||
}
|
354
utils/epping/src/epping_main.c
Parasts fails
354
utils/epping/src/epping_main.c
Parasts fails
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
/*========================================================================
|
||||
|
||||
\file epping_main.c
|
||||
|
||||
\brief WLAN End Point Ping test tool implementation
|
||||
|
||||
========================================================================*/
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Include Files
|
||||
------------------------------------------------------------------------*/
|
||||
#include <cds_api.h>
|
||||
#include <cds_sched.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <wni_api.h>
|
||||
#include <wlan_ptt_sock_svc.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/ctype.h>
|
||||
#include "bmi.h"
|
||||
#include "ol_fw.h"
|
||||
#include "ol_if_athvar.h"
|
||||
#include "hif.h"
|
||||
#include "epping_main.h"
|
||||
#include "epping_internal.h"
|
||||
#include "cds_concurrency.h"
|
||||
|
||||
#ifdef TIMER_MANAGER
|
||||
#define TIMER_MANAGER_STR " +TIMER_MANAGER"
|
||||
#else
|
||||
#define TIMER_MANAGER_STR ""
|
||||
#endif
|
||||
|
||||
#ifdef MEMORY_DEBUG
|
||||
#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
|
||||
#else
|
||||
#define MEMORY_DEBUG_STR ""
|
||||
#endif
|
||||
|
||||
#ifdef HIF_SDIO
|
||||
#define WLAN_WAIT_TIME_WLANSTART 10000
|
||||
#else
|
||||
#define WLAN_WAIT_TIME_WLANSTART 2000
|
||||
#endif
|
||||
|
||||
static struct epping_context *g_epping_ctx;
|
||||
|
||||
/**
|
||||
* epping_open(): End point ping driver open Function
|
||||
*
|
||||
* This function is called by HDD to open epping module
|
||||
*
|
||||
*
|
||||
* return - 0 for success, negative for failure
|
||||
*/
|
||||
int epping_open(void)
|
||||
{
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
|
||||
|
||||
g_epping_ctx = qdf_mem_malloc(sizeof(*g_epping_ctx));
|
||||
|
||||
if (g_epping_ctx == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: cannot alloc epping context", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
g_epping_ctx->con_mode = cds_get_conparam();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* epping_disable(): End point ping driver disable Function
|
||||
*
|
||||
* This is the driver disable function - called by HDD to
|
||||
* disable epping module
|
||||
*
|
||||
* return: none
|
||||
*/
|
||||
void epping_disable(void)
|
||||
{
|
||||
epping_context_t *pEpping_ctx;
|
||||
struct hif_opaque_softc *hif_ctx;
|
||||
HTC_HANDLE htc_handle;
|
||||
|
||||
pEpping_ctx = g_epping_ctx;
|
||||
if (pEpping_ctx == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: error: pEpping_ctx = NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pEpping_ctx->epping_adapter) {
|
||||
epping_destroy_adapter(pEpping_ctx->epping_adapter);
|
||||
pEpping_ctx->epping_adapter = NULL;
|
||||
}
|
||||
|
||||
hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
|
||||
if (hif_ctx == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: error: hif_ctx = NULL", __func__);
|
||||
return;
|
||||
}
|
||||
hif_disable_isr(hif_ctx);
|
||||
hif_reset_soc(hif_ctx);
|
||||
|
||||
htc_handle = cds_get_context(QDF_MODULE_ID_HTC);
|
||||
if (htc_handle == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: error: htc_handle = NULL", __func__);
|
||||
return;
|
||||
}
|
||||
htc_stop(htc_handle);
|
||||
epping_cookie_cleanup(pEpping_ctx);
|
||||
htc_destroy(htc_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* epping_close(): End point ping driver close Function
|
||||
*
|
||||
* This is the driver close function - called by HDD to close epping module
|
||||
*
|
||||
* return: none
|
||||
*/
|
||||
void epping_close(void)
|
||||
{
|
||||
epping_context_t *to_free;
|
||||
|
||||
|
||||
if (g_epping_ctx == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: error: g_epping_ctx = NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
to_free = g_epping_ctx;
|
||||
g_epping_ctx = NULL;
|
||||
qdf_mem_free(to_free);
|
||||
}
|
||||
|
||||
/**
|
||||
* epping_target_suspend_acknowledge() - process wow ack/nack from fw
|
||||
* @context: HTC_INIT_INFO->context
|
||||
* @wow_nack: true when wow is rejected
|
||||
*/
|
||||
static void epping_target_suspend_acknowledge(void *context, bool wow_nack)
|
||||
{
|
||||
if (NULL == g_epping_ctx) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: epping_ctx is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
/* EPPING_TODO: do we need wow_nack? */
|
||||
g_epping_ctx->wow_nack = wow_nack;
|
||||
}
|
||||
|
||||
/**
|
||||
* epping_update_ol_config - API to update ol configuration parameters
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void epping_update_ol_config(void)
|
||||
{
|
||||
struct ol_config_info cfg;
|
||||
struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
|
||||
|
||||
if (!ol_ctx)
|
||||
return;
|
||||
|
||||
cfg.enable_self_recovery = 0;
|
||||
cfg.enable_uart_print = 0;
|
||||
cfg.enable_fw_log = 0;
|
||||
cfg.enable_ramdump_collection = 0;
|
||||
cfg.enable_lpass_support = 0;
|
||||
|
||||
ol_init_ini_config(ol_ctx, &cfg);
|
||||
}
|
||||
/**
|
||||
* epping_enable(): End point ping driver enable Function
|
||||
*
|
||||
* This is the driver enable function - called by HDD to enable
|
||||
* epping module
|
||||
*
|
||||
* return - 0 : success, negative: error
|
||||
*/
|
||||
int epping_enable(struct device *parent_dev)
|
||||
{
|
||||
int ret = 0;
|
||||
epping_context_t *pEpping_ctx = NULL;
|
||||
cds_context_type *p_cds_context = NULL;
|
||||
qdf_device_t qdf_ctx;
|
||||
HTC_INIT_INFO htcInfo;
|
||||
struct hif_opaque_softc *scn;
|
||||
tSirMacAddr adapter_macAddr;
|
||||
struct hif_target_info *tgt_info;
|
||||
struct ol_context *ol_ctx;
|
||||
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Enter", __func__);
|
||||
|
||||
p_cds_context = cds_get_global_context();
|
||||
|
||||
if (p_cds_context == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: Failed cds_get_global_context", __func__);
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
pEpping_ctx = g_epping_ctx;
|
||||
if (pEpping_ctx == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: Failed to get pEpping_ctx", __func__);
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
pEpping_ctx->parent_dev = (void *)parent_dev;
|
||||
epping_get_dummy_mac_addr(adapter_macAddr);
|
||||
|
||||
/* Initialize the timer module */
|
||||
qdf_timer_module_init();
|
||||
|
||||
scn = cds_get_context(QDF_MODULE_ID_HIF);
|
||||
if (!scn) {
|
||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: scn is null!", __func__);
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
tgt_info = hif_get_target_info_handle(scn);
|
||||
|
||||
/* store target type and target version info in hdd ctx */
|
||||
pEpping_ctx->target_type = tgt_info->target_type;
|
||||
|
||||
ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
|
||||
if (!ol_ctx) {
|
||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: ol_ctx is NULL", __func__);
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
epping_update_ol_config();
|
||||
#ifndef FEATURE_BMI_2
|
||||
/* Initialize BMI and Download firmware */
|
||||
if (bmi_download_firmware(ol_ctx)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: BMI failed to download target", __func__);
|
||||
bmi_cleanup(ol_ctx);
|
||||
return A_ERROR;
|
||||
}
|
||||
#endif
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH,
|
||||
"%s: bmi_download_firmware done", __func__);
|
||||
|
||||
htcInfo.pContext = ol_ctx;
|
||||
htcInfo.TargetFailure = ol_target_failure;
|
||||
htcInfo.TargetSendSuspendComplete = epping_target_suspend_acknowledge;
|
||||
qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
|
||||
/* Create HTC */
|
||||
p_cds_context->htc_ctx = htc_create(scn, &htcInfo, qdf_ctx,
|
||||
cds_get_conparam());
|
||||
if (!p_cds_context->htc_ctx) {
|
||||
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: Failed to Create HTC", __func__);
|
||||
bmi_cleanup(ol_ctx);
|
||||
return A_ERROR;
|
||||
}
|
||||
pEpping_ctx->HTCHandle =
|
||||
cds_get_context(QDF_MODULE_ID_HTC);
|
||||
if (pEpping_ctx->HTCHandle == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: HTCHandle is NULL", __func__);
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
if (bmi_done(ol_ctx)) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: Failed to complete BMI phase", __func__);
|
||||
goto error_end;
|
||||
}
|
||||
|
||||
/* start HIF */
|
||||
if (htc_wait_target(pEpping_ctx->HTCHandle) != A_OK) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: htc_wait_target error", __func__);
|
||||
goto error_end;
|
||||
}
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC ready", __func__);
|
||||
|
||||
ret = epping_connect_service(pEpping_ctx);
|
||||
if (ret != 0) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: htc_wait_targetdone", __func__);
|
||||
goto error_end;
|
||||
}
|
||||
if (htc_start(pEpping_ctx->HTCHandle) != A_OK) {
|
||||
goto error_end;
|
||||
}
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: HTC started", __func__);
|
||||
|
||||
/* init the tx cookie resource */
|
||||
ret = epping_cookie_init(pEpping_ctx);
|
||||
if (ret == 0) {
|
||||
pEpping_ctx->epping_adapter = epping_add_adapter(pEpping_ctx,
|
||||
adapter_macAddr,
|
||||
QDF_STA_MODE);
|
||||
}
|
||||
if (ret < 0 || pEpping_ctx->epping_adapter == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: epping_add_adaptererror error", __func__);
|
||||
htc_stop(pEpping_ctx->HTCHandle);
|
||||
epping_cookie_cleanup(pEpping_ctx);
|
||||
goto error_end;
|
||||
}
|
||||
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO_HIGH, "%s: Exit", __func__);
|
||||
return ret;
|
||||
|
||||
error_end:
|
||||
htc_destroy(p_cds_context->htc_ctx);
|
||||
p_cds_context->htc_ctx = NULL;
|
||||
bmi_cleanup(ol_ctx);
|
||||
return A_ERROR;
|
||||
}
|
162
utils/epping/src/epping_rx.c
Parasts fails
162
utils/epping/src/epping_rx.c
Parasts fails
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
/*========================================================================
|
||||
|
||||
\file epping_rx.c
|
||||
|
||||
\brief WLAN End Point Ping test tool implementation
|
||||
|
||||
========================================================================*/
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Include Files
|
||||
------------------------------------------------------------------------*/
|
||||
#include <cds_api.h>
|
||||
#include <cds_sched.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <wni_api.h>
|
||||
#include <wlan_ptt_sock_svc.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/ctype.h>
|
||||
#include "epping_main.h"
|
||||
#include "epping_internal.h"
|
||||
#include "epping_test.h"
|
||||
#include <wlan_hdd_napi.h>
|
||||
|
||||
#define AR6000_MAX_RX_BUFFERS 16
|
||||
#define AR6000_BUFFER_SIZE 1664
|
||||
#define AR6000_MIN_HEAD_ROOM 64
|
||||
|
||||
static bool enb_rx_dump;
|
||||
|
||||
#ifdef HIF_SDIO
|
||||
void epping_refill(void *ctx, HTC_ENDPOINT_ID Endpoint)
|
||||
{
|
||||
epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
|
||||
void *osBuf;
|
||||
int RxBuffers;
|
||||
int buffersToRefill;
|
||||
HTC_PACKET *pPacket;
|
||||
HTC_PACKET_QUEUE queue;
|
||||
|
||||
buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
|
||||
htc_get_num_recv_buffers(pEpping_ctx->HTCHandle, Endpoint);
|
||||
|
||||
if (buffersToRefill <= 0) {
|
||||
/* fast return, nothing to fill */
|
||||
return;
|
||||
}
|
||||
|
||||
INIT_HTC_PACKET_QUEUE(&queue);
|
||||
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
|
||||
"%s: providing htc with %d buffers at eid=%d\n",
|
||||
__func__, buffersToRefill, Endpoint);
|
||||
|
||||
for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
|
||||
osBuf = qdf_nbuf_alloc(NULL, AR6000_BUFFER_SIZE,
|
||||
AR6000_MIN_HEAD_ROOM, 4, false);
|
||||
if (NULL == osBuf) {
|
||||
break;
|
||||
}
|
||||
/* the HTC packet wrapper is at the head of the reserved area
|
||||
* in the skb */
|
||||
pPacket = (HTC_PACKET *) (A_NETBUF_HEAD(osBuf));
|
||||
/* set re-fill info */
|
||||
SET_HTC_PACKET_INFO_RX_REFILL(pPacket, osBuf,
|
||||
qdf_nbuf_data(osBuf),
|
||||
AR6000_BUFFER_SIZE, Endpoint);
|
||||
SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, osBuf);
|
||||
/* add to queue */
|
||||
HTC_PACKET_ENQUEUE(&queue, pPacket);
|
||||
}
|
||||
|
||||
if (!HTC_QUEUE_EMPTY(&queue)) {
|
||||
/* add packets */
|
||||
htc_add_receive_pkt_multiple(pEpping_ctx->HTCHandle, &queue);
|
||||
}
|
||||
}
|
||||
#endif /* HIF_SDIO */
|
||||
|
||||
void epping_rx(void *ctx, HTC_PACKET *pPacket)
|
||||
{
|
||||
epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
|
||||
epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter;
|
||||
struct net_device *dev = pAdapter->dev;
|
||||
A_STATUS status = pPacket->Status;
|
||||
HTC_ENDPOINT_ID eid = pPacket->Endpoint;
|
||||
struct sk_buff *pktSkb = (struct sk_buff *)pPacket->pPktContext;
|
||||
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
|
||||
"%s: pAdapter = 0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d",
|
||||
__func__, pAdapter, eid, pktSkb, pPacket->pBuffer,
|
||||
pPacket->ActualLength, status);
|
||||
|
||||
if (status != A_OK) {
|
||||
if (status != A_ECANCELED) {
|
||||
printk("%s: RX ERR (%d)\n", __func__, status);
|
||||
}
|
||||
qdf_nbuf_free(pktSkb);
|
||||
return;
|
||||
}
|
||||
|
||||
/* deliver to up layer */
|
||||
if (pktSkb) {
|
||||
if (EPPING_ALIGNMENT_PAD > 0) {
|
||||
A_NETBUF_PULL(pktSkb, EPPING_ALIGNMENT_PAD);
|
||||
}
|
||||
if (enb_rx_dump)
|
||||
epping_hex_dump((void *)qdf_nbuf_data(pktSkb),
|
||||
pktSkb->len, __func__);
|
||||
pktSkb->dev = dev;
|
||||
if ((pktSkb->dev->flags & IFF_UP) == IFF_UP) {
|
||||
pktSkb->protocol = eth_type_trans(pktSkb, pktSkb->dev);
|
||||
++pAdapter->stats.rx_packets;
|
||||
pAdapter->stats.rx_bytes += pktSkb->len;
|
||||
qdf_net_buf_debug_release_skb(pktSkb);
|
||||
if (hdd_napi_enabled(HDD_NAPI_ANY))
|
||||
netif_receive_skb(pktSkb);
|
||||
else
|
||||
netif_rx_ni(pktSkb);
|
||||
if ((pAdapter->stats.rx_packets %
|
||||
EPPING_STATS_LOG_COUNT) == 0) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: total_rx_pkts = %lu",
|
||||
__func__,
|
||||
pAdapter->stats.rx_packets);
|
||||
}
|
||||
} else {
|
||||
++pAdapter->stats.rx_dropped;
|
||||
qdf_nbuf_free(pktSkb);
|
||||
}
|
||||
}
|
||||
}
|
405
utils/epping/src/epping_tx.c
Parasts fails
405
utils/epping/src/epping_tx.c
Parasts fails
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
/*========================================================================
|
||||
|
||||
\file epping_tx.c
|
||||
|
||||
\brief WLAN End Point Ping test tool implementation
|
||||
|
||||
========================================================================*/
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Include Files
|
||||
------------------------------------------------------------------------*/
|
||||
#include <cds_api.h>
|
||||
#include <cds_sched.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <wni_api.h>
|
||||
#include <wlan_ptt_sock_svc.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/ctype.h>
|
||||
#include "epping_main.h"
|
||||
#include "epping_internal.h"
|
||||
#include "epping_test.h"
|
||||
|
||||
#define TX_RETRY_TIMEOUT_IN_MS 1
|
||||
|
||||
static bool enb_tx_dump;
|
||||
|
||||
void epping_tx_dup_pkt(epping_adapter_t *pAdapter,
|
||||
HTC_ENDPOINT_ID eid, qdf_nbuf_t skb)
|
||||
{
|
||||
struct epping_cookie *cookie = NULL;
|
||||
int skb_len, ret;
|
||||
qdf_nbuf_t new_skb;
|
||||
|
||||
cookie = epping_alloc_cookie(pAdapter->pEpping_ctx);
|
||||
if (cookie == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: epping_alloc_cookie returns no resource\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
new_skb = qdf_nbuf_copy(skb);
|
||||
if (!new_skb) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: qdf_nbuf_copy returns no resource\n", __func__);
|
||||
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
|
||||
return;
|
||||
}
|
||||
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
|
||||
cookie, qdf_nbuf_data(skb),
|
||||
qdf_nbuf_len(new_skb), eid, 0);
|
||||
SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, new_skb);
|
||||
skb_len = (int)qdf_nbuf_len(new_skb);
|
||||
/* send the packet */
|
||||
ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
|
||||
if (ret != A_OK) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: htc_send_pkt failed, ret = %d\n", __func__, ret);
|
||||
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
|
||||
qdf_nbuf_free(new_skb);
|
||||
return;
|
||||
}
|
||||
pAdapter->stats.tx_bytes += skb_len;
|
||||
++pAdapter->stats.tx_packets;
|
||||
if (((pAdapter->stats.tx_packets +
|
||||
pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
|
||||
(pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) {
|
||||
epping_log_stats(pAdapter, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static int epping_tx_send_int(qdf_nbuf_t skb, epping_adapter_t *pAdapter)
|
||||
{
|
||||
EPPING_HEADER *eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
|
||||
HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
|
||||
struct epping_cookie *cookie = NULL;
|
||||
A_UINT8 ac = 0;
|
||||
A_STATUS ret = A_OK;
|
||||
int skb_len;
|
||||
EPPING_HEADER tmpHdr = *eppingHdr;
|
||||
|
||||
/* allocate resource for this packet */
|
||||
cookie = epping_alloc_cookie(pAdapter->pEpping_ctx);
|
||||
/* no resource */
|
||||
if (cookie == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: epping_alloc_cookie returns no resource\n",
|
||||
__func__);
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
if (enb_tx_dump)
|
||||
epping_hex_dump((void *)eppingHdr, skb->len, __func__);
|
||||
/*
|
||||
* a quirk of linux, the payload of the frame is 32-bit aligned and thus
|
||||
* the addition of the HTC header will mis-align the start of the HTC
|
||||
* frame, so we add some padding which will be stripped off in the target
|
||||
*/
|
||||
if (EPPING_ALIGNMENT_PAD > 0) {
|
||||
A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
|
||||
}
|
||||
/* prepare ep/HTC information */
|
||||
ac = eppingHdr->StreamNo_h;
|
||||
eid = pAdapter->pEpping_ctx->EppingEndpoint[ac];
|
||||
if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: invalid eid = %d, ac = %d\n", __func__, eid,
|
||||
ac);
|
||||
return A_ERROR;
|
||||
}
|
||||
if (tmpHdr.Cmd_h == EPPING_CMD_RESET_RECV_CNT ||
|
||||
tmpHdr.Cmd_h == EPPING_CMD_CONT_RX_START) {
|
||||
epping_set_kperf_flag(pAdapter, eid, tmpHdr.CmdBuffer_t[0]);
|
||||
}
|
||||
SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
|
||||
cookie, qdf_nbuf_data(skb), qdf_nbuf_len(skb),
|
||||
eid, 0);
|
||||
SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, skb);
|
||||
skb_len = skb->len;
|
||||
/* send the packet */
|
||||
ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
|
||||
epping_log_packet(pAdapter, &tmpHdr, ret, __func__);
|
||||
if (ret != A_OK) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: htc_send_pkt failed, status = %d\n", __func__,
|
||||
ret);
|
||||
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
|
||||
return A_ERROR;
|
||||
}
|
||||
pAdapter->stats.tx_bytes += skb_len;
|
||||
++pAdapter->stats.tx_packets;
|
||||
if (((pAdapter->stats.tx_packets +
|
||||
pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
|
||||
(pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) {
|
||||
epping_log_stats(pAdapter, __func__);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void epping_tx_timer_expire(epping_adapter_t *pAdapter)
|
||||
{
|
||||
qdf_nbuf_t nodrop_skb;
|
||||
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: queue len: %d\n", __func__,
|
||||
qdf_nbuf_queue_len(&pAdapter->nodrop_queue));
|
||||
|
||||
if (!qdf_nbuf_queue_len(&pAdapter->nodrop_queue)) {
|
||||
/* nodrop queue is empty so no need to arm timer */
|
||||
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to flush nodrop queue */
|
||||
while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) {
|
||||
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true);
|
||||
if (epping_tx_send_int(nodrop_skb, pAdapter)) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: nodrop: %p xmit fail in timer\n",
|
||||
__func__, nodrop_skb);
|
||||
/* fail to xmit so put the nodrop packet to the nodrop queue */
|
||||
qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue,
|
||||
nodrop_skb);
|
||||
break;
|
||||
} else {
|
||||
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false);
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
|
||||
"%s: nodrop: %p xmit ok in timer\n",
|
||||
__func__, nodrop_skb);
|
||||
}
|
||||
}
|
||||
|
||||
/* if nodrop queue is not empty, continue to arm timer */
|
||||
if (nodrop_skb) {
|
||||
qdf_spin_lock_bh(&pAdapter->data_lock);
|
||||
/* if nodrop queue is not empty, continue to arm timer */
|
||||
if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
|
||||
pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
|
||||
qdf_timer_mod(&pAdapter->epping_timer,
|
||||
TX_RETRY_TIMEOUT_IN_MS);
|
||||
}
|
||||
qdf_spin_unlock_bh(&pAdapter->data_lock);
|
||||
} else {
|
||||
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
|
||||
}
|
||||
}
|
||||
|
||||
int epping_tx_send(qdf_nbuf_t skb, epping_adapter_t *pAdapter)
|
||||
{
|
||||
qdf_nbuf_t nodrop_skb;
|
||||
EPPING_HEADER *eppingHdr;
|
||||
A_UINT8 ac = 0;
|
||||
|
||||
eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
|
||||
|
||||
if (!IS_EPPING_PACKET(eppingHdr)) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: Recived non endpoint ping packets\n", __func__);
|
||||
/* no packet to send, cleanup */
|
||||
qdf_nbuf_free(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* the stream ID is mapped to an access class */
|
||||
ac = eppingHdr->StreamNo_h;
|
||||
/* hard coded two ep ids */
|
||||
if (ac != 0 && ac != 1) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: ac %d is not mapped to mboxping service\n",
|
||||
__func__, ac);
|
||||
qdf_nbuf_free(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* some EPPING packets cannot be dropped no matter what access class
|
||||
* it was sent on. A special care has been taken:
|
||||
* 1. when there is no TX resource, queue the control packets to
|
||||
* a special queue
|
||||
* 2. when there is TX resource, send the queued control packets first
|
||||
* and then other packets
|
||||
* 3. a timer launches to check if there is queued control packets and
|
||||
* flush them
|
||||
*/
|
||||
|
||||
/* check the nodrop queue first */
|
||||
while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) {
|
||||
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true);
|
||||
if (epping_tx_send_int(nodrop_skb, pAdapter)) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: nodrop: %p xmit fail\n", __func__,
|
||||
nodrop_skb);
|
||||
/* fail to xmit so put the nodrop packet to the nodrop queue */
|
||||
qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue,
|
||||
nodrop_skb);
|
||||
/* no cookie so free the current skb */
|
||||
goto tx_fail;
|
||||
} else {
|
||||
htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false);
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
|
||||
"%s: nodrop: %p xmit ok\n", __func__,
|
||||
nodrop_skb);
|
||||
}
|
||||
}
|
||||
|
||||
/* send the original packet */
|
||||
if (epping_tx_send_int(skb, pAdapter))
|
||||
goto tx_fail;
|
||||
|
||||
return 0;
|
||||
|
||||
tx_fail:
|
||||
if (!IS_EPING_PACKET_NO_DROP(eppingHdr)) {
|
||||
/* allow to drop the skb so drop it */
|
||||
qdf_nbuf_free(skb);
|
||||
++pAdapter->stats.tx_dropped;
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: Tx skb %p dropped, stats.tx_dropped = %ld\n",
|
||||
__func__, skb, pAdapter->stats.tx_dropped);
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: nodrop: %p queued\n", __func__, skb);
|
||||
qdf_nbuf_queue_add(&pAdapter->nodrop_queue, skb);
|
||||
qdf_spin_lock_bh(&pAdapter->data_lock);
|
||||
if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
|
||||
pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
|
||||
qdf_timer_mod(&pAdapter->epping_timer,
|
||||
TX_RETRY_TIMEOUT_IN_MS);
|
||||
}
|
||||
qdf_spin_unlock_bh(&pAdapter->data_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HIF_SDIO
|
||||
HTC_SEND_FULL_ACTION epping_tx_queue_full(void *Context, HTC_PACKET *pPacket)
|
||||
{
|
||||
/*
|
||||
* Call netif_stop_queue frequently will impact the mboxping tx t-put.
|
||||
* Return HTC_SEND_FULL_KEEP directly in epping_tx_queue_full to avoid.
|
||||
*/
|
||||
return HTC_SEND_FULL_KEEP;
|
||||
}
|
||||
#endif /* HIF_SDIO */
|
||||
void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue)
|
||||
{
|
||||
epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
|
||||
epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter;
|
||||
struct net_device *dev = pAdapter->dev;
|
||||
A_STATUS status;
|
||||
HTC_ENDPOINT_ID eid;
|
||||
qdf_nbuf_t pktSkb;
|
||||
struct epping_cookie *cookie;
|
||||
A_BOOL flushing = false;
|
||||
qdf_nbuf_queue_t skb_queue;
|
||||
HTC_PACKET *htc_pkt;
|
||||
|
||||
qdf_nbuf_queue_init(&skb_queue);
|
||||
|
||||
qdf_spin_lock_bh(&pAdapter->data_lock);
|
||||
|
||||
while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
|
||||
htc_pkt = htc_packet_dequeue(pPacketQueue);
|
||||
if (htc_pkt == NULL)
|
||||
break;
|
||||
status = htc_pkt->Status;
|
||||
eid = htc_pkt->Endpoint;
|
||||
pktSkb = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
|
||||
cookie = htc_pkt->pPktContext;
|
||||
|
||||
if (!pktSkb) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: NULL skb from hc packet", __func__);
|
||||
QDF_BUG(0);
|
||||
} else {
|
||||
if (htc_pkt->pBuffer != qdf_nbuf_data(pktSkb)) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: htc_pkt buffer not equal to skb->data",
|
||||
__func__);
|
||||
QDF_BUG(0);
|
||||
}
|
||||
/* add this to the list, use faster non-lock API */
|
||||
qdf_nbuf_queue_add(&skb_queue, pktSkb);
|
||||
|
||||
if (A_SUCCESS(status)) {
|
||||
if (htc_pkt->ActualLength !=
|
||||
qdf_nbuf_len(pktSkb)) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: htc_pkt length not equal to skb->len",
|
||||
__func__);
|
||||
QDF_BUG(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO,
|
||||
"%s skb=%p data=%p len=0x%x eid=%d ",
|
||||
__func__, pktSkb, htc_pkt->pBuffer,
|
||||
htc_pkt->ActualLength, eid);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
if (status == A_ECANCELED) {
|
||||
/* a packet was flushed */
|
||||
flushing = true;
|
||||
}
|
||||
if (status != A_NO_RESOURCE) {
|
||||
printk("%s() -TX ERROR, status: 0x%x\n",
|
||||
__func__, status);
|
||||
}
|
||||
} else {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: OK\n", __func__);
|
||||
flushing = false;
|
||||
}
|
||||
|
||||
epping_free_cookie(pAdapter->pEpping_ctx, cookie);
|
||||
}
|
||||
|
||||
qdf_spin_unlock_bh(&pAdapter->data_lock);
|
||||
|
||||
/* free all skbs in our local list */
|
||||
while (qdf_nbuf_queue_len(&skb_queue)) {
|
||||
/* use non-lock version */
|
||||
pktSkb = qdf_nbuf_queue_remove(&skb_queue);
|
||||
if (pktSkb == NULL)
|
||||
break;
|
||||
qdf_nbuf_tx_free(pktSkb, QDF_NBUF_PKT_ERROR);
|
||||
pEpping_ctx->total_tx_acks++;
|
||||
}
|
||||
|
||||
if (!flushing) {
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
}
|
470
utils/epping/src/epping_txrx.c
Parasts fails
470
utils/epping/src/epping_txrx.c
Parasts fails
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
|
||||
*
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was originally distributed by Qualcomm Atheros, Inc.
|
||||
* under proprietary terms before Copyright ownership was assigned
|
||||
* to the Linux Foundation.
|
||||
*/
|
||||
|
||||
/*========================================================================
|
||||
|
||||
\file epping_txrx.c
|
||||
|
||||
\brief WLAN End Point Ping test tool implementation
|
||||
|
||||
========================================================================*/
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
Include Files
|
||||
------------------------------------------------------------------------*/
|
||||
#include <cds_api.h>
|
||||
#include <cds_sched.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <wni_api.h>
|
||||
#include <wlan_ptt_sock_svc.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <pld_common.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/ctype.h>
|
||||
#include "epping_main.h"
|
||||
#include "epping_internal.h"
|
||||
|
||||
static int epping_start_adapter(epping_adapter_t *pAdapter);
|
||||
static void epping_stop_adapter(epping_adapter_t *pAdapter);
|
||||
|
||||
static void epping_timer_expire(void *data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
epping_adapter_t *pAdapter;
|
||||
|
||||
if (dev == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: netdev = NULL", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
if (pAdapter == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: adapter = NULL", __func__);
|
||||
return;
|
||||
}
|
||||
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
|
||||
epping_tx_timer_expire(pAdapter);
|
||||
}
|
||||
|
||||
static int epping_ndev_open(struct net_device *dev)
|
||||
{
|
||||
epping_adapter_t *pAdapter;
|
||||
int ret = 0;
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
epping_start_adapter(pAdapter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int epping_ndev_stop(struct net_device *dev)
|
||||
{
|
||||
epping_adapter_t *pAdapter;
|
||||
int ret = 0;
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
if (NULL == pAdapter) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: EPPING adapter context is Null", __func__);
|
||||
ret = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
epping_stop_adapter(pAdapter);
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void epping_ndev_uninit(struct net_device *dev)
|
||||
{
|
||||
epping_adapter_t *pAdapter;
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
if (NULL == pAdapter) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: EPPING adapter context is Null", __func__);
|
||||
goto end;
|
||||
}
|
||||
epping_stop_adapter(pAdapter);
|
||||
end:
|
||||
return;
|
||||
}
|
||||
|
||||
static void epping_tx_queue_timeout(struct net_device *dev)
|
||||
{
|
||||
epping_adapter_t *pAdapter;
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
if (NULL == pAdapter) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: EPPING adapter context is Null", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: Transmission timeout occurred, pAdapter->started= %d",
|
||||
__func__, pAdapter->started);
|
||||
|
||||
/* Getting here implies we disabled the TX queues
|
||||
* for too long. Since this is epping
|
||||
* (not because of disassociation or low resource scenarios),
|
||||
* try to restart the queue
|
||||
*/
|
||||
if (pAdapter->started)
|
||||
netif_wake_queue(dev);
|
||||
end:
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
static int epping_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
epping_adapter_t *pAdapter;
|
||||
int ret = 0;
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
if (NULL == pAdapter) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: EPPING adapter context is Null", __func__);
|
||||
ret = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
ret = epping_tx_send(skb, pAdapter);
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct net_device_stats *epping_get_stats(struct net_device *dev)
|
||||
{
|
||||
epping_adapter_t *pAdapter = netdev_priv(dev);
|
||||
|
||||
if (NULL == pAdapter) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: pAdapter = NULL",
|
||||
__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &pAdapter->stats;
|
||||
}
|
||||
|
||||
static int epping_ndev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
epping_adapter_t *pAdapter;
|
||||
int ret = 0;
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
if (NULL == pAdapter) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: EPPING adapter context is Null", __func__);
|
||||
ret = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
if (dev != pAdapter->dev) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: HDD adapter/dev inconsistency", __func__);
|
||||
ret = -ENODEV;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((!ifr) || (!ifr->ifr_data)) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case (SIOCDEVPRIVATE + 1):
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: do not support ioctl %d (SIOCDEVPRIVATE + 1)",
|
||||
__func__, cmd);
|
||||
break;
|
||||
default:
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
|
||||
__func__, cmd);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int epping_set_mac_address(struct net_device *dev, void *addr)
|
||||
{
|
||||
epping_adapter_t *pAdapter = netdev_priv(dev);
|
||||
struct sockaddr *psta_mac_addr = addr;
|
||||
qdf_mem_copy(&pAdapter->macAddressCurrent,
|
||||
psta_mac_addr->sa_data, ETH_ALEN);
|
||||
qdf_mem_copy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void epping_stop_adapter(epping_adapter_t *pAdapter)
|
||||
{
|
||||
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
|
||||
if (!qdf_ctx) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: qdf_ctx is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pAdapter && pAdapter->started) {
|
||||
EPPING_LOG(LOG1, FL("Disabling queues"));
|
||||
netif_tx_disable(pAdapter->dev);
|
||||
netif_carrier_off(pAdapter->dev);
|
||||
pAdapter->started = false;
|
||||
pld_request_bus_bandwidth(qdf_ctx->dev,
|
||||
PLD_BUS_WIDTH_LOW);
|
||||
}
|
||||
}
|
||||
|
||||
static int epping_start_adapter(epping_adapter_t *pAdapter)
|
||||
{
|
||||
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
|
||||
|
||||
if (!qdf_ctx) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: qdf_ctx is NULL", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!pAdapter) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: pAdapter= NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!pAdapter->started) {
|
||||
pld_request_bus_bandwidth(qdf_ctx->dev,
|
||||
PLD_BUS_WIDTH_HIGH);
|
||||
netif_carrier_on(pAdapter->dev);
|
||||
EPPING_LOG(LOG1, FL("Enabling queues"));
|
||||
netif_tx_start_all_queues(pAdapter->dev);
|
||||
pAdapter->started = true;
|
||||
} else {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_WARN,
|
||||
"%s: pAdapter %p already started\n", __func__,
|
||||
pAdapter);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int epping_register_adapter(epping_adapter_t *pAdapter)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = register_netdev(pAdapter->dev);
|
||||
if (ret != 0) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: unable to register device\n",
|
||||
pAdapter->dev->name);
|
||||
} else {
|
||||
pAdapter->registered = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void epping_unregister_adapter(epping_adapter_t *pAdapter)
|
||||
{
|
||||
if (pAdapter) {
|
||||
epping_stop_adapter(pAdapter);
|
||||
if (pAdapter->registered) {
|
||||
unregister_netdev(pAdapter->dev);
|
||||
pAdapter->registered = false;
|
||||
}
|
||||
} else {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: pAdapter = NULL, unable to unregister device\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
||||
void epping_destroy_adapter(epping_adapter_t *pAdapter)
|
||||
{
|
||||
struct net_device *dev = NULL;
|
||||
epping_context_t *pEpping_ctx;
|
||||
|
||||
if (!pAdapter || !pAdapter->pEpping_ctx) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: pAdapter = NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dev = pAdapter->dev;
|
||||
pEpping_ctx = pAdapter->pEpping_ctx;
|
||||
epping_unregister_adapter(pAdapter);
|
||||
|
||||
qdf_spinlock_destroy(&pAdapter->data_lock);
|
||||
qdf_timer_free(&pAdapter->epping_timer);
|
||||
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
|
||||
|
||||
while (qdf_nbuf_queue_len(&pAdapter->nodrop_queue)) {
|
||||
qdf_nbuf_t tmp_nbuf = NULL;
|
||||
tmp_nbuf = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue);
|
||||
if (tmp_nbuf)
|
||||
qdf_nbuf_free(tmp_nbuf);
|
||||
}
|
||||
|
||||
free_netdev(dev);
|
||||
if (!pEpping_ctx)
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: pEpping_ctx = NULL\n", __func__);
|
||||
else
|
||||
pEpping_ctx->epping_adapter = NULL;
|
||||
}
|
||||
|
||||
static struct net_device_ops epping_drv_ops = {
|
||||
.ndo_open = epping_ndev_open,
|
||||
.ndo_stop = epping_ndev_stop,
|
||||
.ndo_uninit = epping_ndev_uninit,
|
||||
.ndo_start_xmit = epping_hard_start_xmit,
|
||||
.ndo_tx_timeout = epping_tx_queue_timeout,
|
||||
.ndo_get_stats = epping_get_stats,
|
||||
.ndo_do_ioctl = epping_ndev_ioctl,
|
||||
.ndo_set_mac_address = epping_set_mac_address,
|
||||
.ndo_select_queue = NULL,
|
||||
};
|
||||
|
||||
#define EPPING_TX_QUEUE_MAX_LEN 128 /* need to be power of 2 */
|
||||
|
||||
epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx,
|
||||
tSirMacAddr macAddr,
|
||||
enum tQDF_ADAPTER_MODE device_mode)
|
||||
{
|
||||
struct net_device *dev;
|
||||
epping_adapter_t *pAdapter;
|
||||
|
||||
dev = alloc_netdev(sizeof(epping_adapter_t), "wifi%d",
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
|
||||
NET_NAME_UNKNOWN,
|
||||
#endif
|
||||
ether_setup);
|
||||
if (dev == NULL) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"%s: Cannot allocate epping_adapter_t\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pAdapter = netdev_priv(dev);
|
||||
qdf_mem_zero(pAdapter, sizeof(*pAdapter));
|
||||
pAdapter->dev = dev;
|
||||
pAdapter->pEpping_ctx = pEpping_ctx;
|
||||
pAdapter->device_mode = device_mode; /* station, SAP, etc */
|
||||
qdf_mem_copy(dev->dev_addr, (void *)macAddr, sizeof(tSirMacAddr));
|
||||
qdf_mem_copy(pAdapter->macAddressCurrent.bytes,
|
||||
macAddr, sizeof(tSirMacAddr));
|
||||
qdf_spinlock_create(&pAdapter->data_lock);
|
||||
qdf_nbuf_queue_init(&pAdapter->nodrop_queue);
|
||||
pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
|
||||
qdf_timer_init(epping_get_qdf_ctx(), &pAdapter->epping_timer,
|
||||
epping_timer_expire, dev, QDF_TIMER_TYPE_SW);
|
||||
dev->type = ARPHRD_IEEE80211;
|
||||
dev->netdev_ops = &epping_drv_ops;
|
||||
dev->watchdog_timeo = 5 * HZ; /* XXX */
|
||||
dev->tx_queue_len = EPPING_TXBUF - 1; /* 1 for mgmt frame */
|
||||
if (epping_register_adapter(pAdapter) == 0) {
|
||||
EPPING_LOG(LOG1, FL("Disabling queues"));
|
||||
netif_tx_disable(dev);
|
||||
netif_carrier_off(dev);
|
||||
return pAdapter;
|
||||
} else {
|
||||
epping_destroy_adapter(pAdapter);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int epping_connect_service(epping_context_t *pEpping_ctx)
|
||||
{
|
||||
int status, i;
|
||||
HTC_SERVICE_CONNECT_REQ connect;
|
||||
HTC_SERVICE_CONNECT_RESP response;
|
||||
|
||||
qdf_mem_zero(&connect, sizeof(connect));
|
||||
qdf_mem_zero(&response, sizeof(response));
|
||||
|
||||
/* these fields are the same for all service endpoints */
|
||||
connect.EpCallbacks.pContext = pEpping_ctx;
|
||||
connect.EpCallbacks.EpTxCompleteMultiple = epping_tx_complete_multiple;
|
||||
connect.EpCallbacks.EpRecv = epping_rx;
|
||||
/* epping_tx_complete use Multiple version */
|
||||
connect.EpCallbacks.EpTxComplete = NULL;
|
||||
connect.MaxSendQueueDepth = 64;
|
||||
|
||||
#ifdef HIF_SDIO
|
||||
connect.EpCallbacks.EpRecvRefill = epping_refill;
|
||||
connect.EpCallbacks.EpSendFull =
|
||||
epping_tx_queue_full /* ar6000_tx_queue_full */;
|
||||
#elif defined(HIF_USB) || defined(HIF_PCI)
|
||||
connect.EpCallbacks.EpRecvRefill = NULL /* provided by HIF */;
|
||||
connect.EpCallbacks.EpSendFull = NULL /* provided by HIF */;
|
||||
/* disable flow control for hw flow control */
|
||||
connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
|
||||
#endif
|
||||
|
||||
/* connect to service */
|
||||
connect.service_id = WMI_DATA_BE_SVC;
|
||||
status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response);
|
||||
if (status != EOK) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"Failed to connect to Endpoint Ping BE service status:%d\n",
|
||||
status);
|
||||
return status;
|
||||
} else {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"eppingtest BE endpoint:%d\n", response.Endpoint);
|
||||
}
|
||||
pEpping_ctx->EppingEndpoint[0] = response.Endpoint;
|
||||
|
||||
#if defined(HIF_PCI) || defined(HIF_USB)
|
||||
connect.service_id = WMI_DATA_BK_SVC;
|
||||
status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response);
|
||||
if (status != EOK) {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"Failed to connect to Endpoint Ping BK service status:%d\n",
|
||||
status);
|
||||
return status;
|
||||
} else {
|
||||
EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
|
||||
"eppingtest BK endpoint:%d\n", response.Endpoint);
|
||||
}
|
||||
pEpping_ctx->EppingEndpoint[1] = response.Endpoint;
|
||||
/* Since we do not create other two SVC use BK endpoint
|
||||
* for rest ACs (2, 3) */
|
||||
for (i = 2; i < EPPING_MAX_NUM_EPIDS; i++) {
|
||||
pEpping_ctx->EppingEndpoint[i] = response.Endpoint;
|
||||
}
|
||||
#else
|
||||
/* we only use one endpoint for high latenance bus.
|
||||
* Map all AC's EPIDs to the same endpoint ID returned by HTC */
|
||||
for (i = 0; i < EPPING_MAX_NUM_EPIDS; i++) {
|
||||
pEpping_ctx->EppingEndpoint[i] = response.Endpoint;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
Atsaukties uz šo jaunā problēmā
Block a user