mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 04:12:04 -04:00
Add 'drivers/staging/qca-wifi-host-cmn/' from tag 'LA.UM.9.14.r1-18300-LAHAINA.0'
git-subtree-dir: drivers/staging/qca-wifi-host-cmn git-subtree-mainline:86b1e6e4ffgit-subtree-split:174fa50724Change-Id: I61e52ea156a16c34167f53404277bc5dc07f56a5
This commit is contained in:
commit
359ac2012b
946 changed files with 559389 additions and 0 deletions
1
drivers/staging/qca-wifi-host-cmn/README.txt
Normal file
1
drivers/staging/qca-wifi-host-cmn/README.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
This is CNSS WLAN Host Driver for products starting from iHelium
|
||||
2
drivers/staging/qca-wifi-host-cmn/VERSION.txt
Normal file
2
drivers/staging/qca-wifi-host-cmn/VERSION.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Current Component wlan-cmn.driver.lnx.1.0 version 5.1.1.17I
|
||||
Matches Component wlan-cld3.driver.lnx.1.1 version 5.1.0.22C
|
||||
60
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_converged.h
Normal file
60
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_converged.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: This file contains centralized definitions of converged configuration.
|
||||
*/
|
||||
|
||||
#ifndef __CFG_CONVERGED_H
|
||||
#define __CFG_CONVERGED_H
|
||||
|
||||
#include <wlan_scan_cfg.h>
|
||||
#include "cfg_mlme_score_params.h"
|
||||
#include "cfg_dp.h"
|
||||
#include "cfg_hif.h"
|
||||
#include <wlan_extscan_cfg.h>
|
||||
#ifdef WLAN_SUPPORT_GREEN_AP
|
||||
#include "cfg_green_ap_params.h"
|
||||
#else
|
||||
#define CFG_GREEN_AP_ALL
|
||||
#endif
|
||||
#include <cfg_spectral.h>
|
||||
#ifdef DCS_INTERFERENCE_DETECTION
|
||||
#include "wlan_dcs_cfg.h"
|
||||
#else
|
||||
#define CFG_DCS_ALL
|
||||
#endif
|
||||
#ifdef WLAN_CFR_ENABLE
|
||||
#include "cfr_cfg.h"
|
||||
#else
|
||||
#define CFG_CFR_ALL
|
||||
#endif
|
||||
|
||||
#define CFG_CONVERGED_ALL \
|
||||
CFG_SCAN_ALL \
|
||||
CFG_DP \
|
||||
CFG_EXTSCAN_ALL \
|
||||
CFG_GREEN_AP_ALL \
|
||||
CFG_SPECTRAL_ALL \
|
||||
CFG_HIF \
|
||||
CFG_DCS_ALL \
|
||||
CFG_CFR_ALL \
|
||||
CFG_MLME_SCORE_ALL
|
||||
|
||||
#endif /* __CFG_CONVERGED_H */
|
||||
|
||||
95
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_define.h
Normal file
95
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_define.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: APIs and macros for defining configuration.
|
||||
*/
|
||||
|
||||
#ifndef __CFG_DEFINE_H
|
||||
#define __CFG_DEFINE_H
|
||||
|
||||
enum cfg_fallback_behavior {
|
||||
CFG_VALUE_OR_CLAMP,
|
||||
CFG_VALUE_OR_DEFAULT,
|
||||
};
|
||||
|
||||
#define rm_parens(...) __VA_ARGS__
|
||||
#define __CFG(id, is_ini, mtype, args...) \
|
||||
__CFG_##is_ini##_##mtype(id, mtype, args)
|
||||
#define _CFG(id, args) __CFG(id, args)
|
||||
#define CFG(id) _CFG(__##id, rm_parens id)
|
||||
|
||||
#define __CFG_INI_INT(args...) __CFG_INI(args)
|
||||
#define __CFG_INI_UINT(args...) __CFG_INI(args)
|
||||
#define __CFG_INI_BOOL(args...) __CFG_INI(args)
|
||||
#define __CFG_INI_STRING(args...) __CFG_INI(args)
|
||||
#define __CFG_INI_MAC(args...) __CFG_INI(args)
|
||||
#define __CFG_INI_IPV4(args...) __CFG_INI(args)
|
||||
#define __CFG_INI_IPV6(args...) __CFG_INI(args)
|
||||
#define __CFG_INI(args...) (args)
|
||||
|
||||
#define __CFG_NON_INI_INT(args...) __CFG_NON_INI(args)
|
||||
#define __CFG_NON_INI_UINT(args...) __CFG_NON_INI(args)
|
||||
#define __CFG_NON_INI_BOOL(args...) __CFG_NON_INI(args)
|
||||
#define __CFG_NON_INI_STRING(args...) __CFG_NON_INI(args)
|
||||
#define __CFG_NON_INI_MAC(args...) __CFG_NON_INI(args)
|
||||
#define __CFG_NON_INI_IPV4(args...) __CFG_NON_INI(args)
|
||||
#define __CFG_NON_INI_IPV6(args...) __CFG_NON_INI(args)
|
||||
#define __CFG_NON_INI(args...)
|
||||
|
||||
/* configuration available in ini */
|
||||
#define CFG_INI_INT(name, min, max, def, fallback, desc) \
|
||||
(INI, INT, int32_t, name, min, max, fallback, desc, def)
|
||||
#define CFG_INI_UINT(name, min, max, def, fallback, desc) \
|
||||
(INI, UINT, uint32_t, name, min, max, fallback, desc, def)
|
||||
#define CFG_INI_BOOL(name, def, desc) \
|
||||
(INI, BOOL, bool, name, false, true, -1, desc, def)
|
||||
#define CFG_INI_STRING(name, min_len, max_len, def, desc) \
|
||||
(INI, STRING, char *, name, min_len, max_len, -1, desc, def)
|
||||
#define CFG_INI_MAC(name, def, desc) \
|
||||
(INI, MAC, struct qdf_mac_addr, name, -1, -1, -1, desc, def)
|
||||
#define CFG_INI_IPV4(name, def, desc) \
|
||||
(INI, IPV4, struct qdf_ipv4_addr, name, -1, -1, -1, desc, def)
|
||||
#define CFG_INI_IPV6(name, def, desc) \
|
||||
(INI, IPV6, struct qdf_ipv6_addr, name, -1, -1, -1, desc, def)
|
||||
|
||||
/* configuration *not* available in ini */
|
||||
#define CFG_INT(name, min, max, def, fallback, desc) \
|
||||
(NON_INI, INT, int32_t, name, min, max, fallback, desc, def)
|
||||
#define CFG_UINT(name, min, max, def, fallback, desc) \
|
||||
(NON_INI, UINT, uint32_t, name, min, max, fallback, desc, def)
|
||||
#define CFG_BOOL(name, def, desc) \
|
||||
(NON_INI, BOOL, bool, name, false, true, false, desc, def)
|
||||
#define CFG_STRING(name, min_len, max_len, def, desc) \
|
||||
(NON_INI, STRING, char *, name, min_len, max_len, -1, desc, def)
|
||||
#define CFG_MAC(name, def, desc) \
|
||||
(NON_INI, MAC, struct qdf_mac_addr, name, -1, -1, -1, desc, def)
|
||||
#define CFG_IPV4(name, def, desc) \
|
||||
(NON_INI, IPV4, struct qdf_ipv4_addr, name, -1, -1, -1, desc, def)
|
||||
#define CFG_IPV6(name, def, desc) \
|
||||
(NON_INI, IPV6, struct qdf_ipv6_addr, name, -1, -1, -1, desc, def)
|
||||
|
||||
/* utility macros/functions */
|
||||
#ifdef CONFIG_AP_PLATFORM
|
||||
#define PLATFORM_VALUE(non_ap_value, ap_value) ap_value
|
||||
#else
|
||||
#define PLATFORM_VALUE(non_ap_value, ap_value) non_ap_value
|
||||
#endif
|
||||
|
||||
#endif /* __CFG_DEFINE_H */
|
||||
|
||||
41
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_dispatcher.h
Normal file
41
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_dispatcher.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: Dispatcher related handler APIs for the configuration component
|
||||
*/
|
||||
#ifndef __CFG_DISPATCHER_H_
|
||||
#define __CFG_DISPATCHER_H_
|
||||
|
||||
#include <qdf_status.h>
|
||||
|
||||
/**
|
||||
* cfg_dispatcher_init() - Configuration component global init handler
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cfg_dispatcher_init(void);
|
||||
|
||||
/**
|
||||
* cfg_dispatcher_deinit() - Configuration component global deinit handler
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cfg_dispatcher_deinit(void);
|
||||
|
||||
#endif /* __CFG_DISPATCHER_H */
|
||||
286
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_ucfg_api.h
Normal file
286
drivers/staging/qca-wifi-host-cmn/cfg/inc/cfg_ucfg_api.h
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: UCFG APIs for the configuration component.
|
||||
*
|
||||
* Logically, configuration exists at the psoc level. This means, each psoc can
|
||||
* have its own custom configuration, and calls to lookup configuration take a
|
||||
* psoc parameter for reference. E.g.
|
||||
*
|
||||
* int32_t value = cfg_get(psoc, WLAN_SOME_INTEGER_CONFIG_ID);
|
||||
*
|
||||
* Configuration is cascading, and lookups happen in this order:
|
||||
*
|
||||
* 1) use psoc value, if configured
|
||||
* 2) use global value, if configured
|
||||
* 3) fallback to the default value for the configuration item
|
||||
*
|
||||
* This means a psoc configuration is a specialization of the global
|
||||
* configuration, and does not need to explicitly set the same values if they
|
||||
* would match the global config.
|
||||
*
|
||||
* In order to load and parse the global config, call cfg_parse(). In order to
|
||||
* load and parse psoc configs, call cfg_psoc_parse(). cfg_parse() MUST be
|
||||
* called before cfg_psoc_parse(), as global configuration will be consulted
|
||||
* during the psoc parsing process.
|
||||
*
|
||||
* There are two basic lifecycles supported:
|
||||
*
|
||||
* 1) The type and number of psocs is *not* known at load time
|
||||
*
|
||||
* // driver is loading
|
||||
* cfg_parse("/path/to/config");
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* // a psoc has just been created
|
||||
* cfg_psoc_parse(psoc, "/path/to/psoc/config");
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* // driver is unloading
|
||||
* cfg_release();
|
||||
*
|
||||
* 2) The type and number of psocs *is* known at load time
|
||||
*
|
||||
* // driver is loading
|
||||
* cfg_parse("/path/to/config");
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* // for each psoc
|
||||
* cfg_psoc_parse(psoc, "/path/to/psoc/config");
|
||||
*
|
||||
* // no further psocs will be created after this point
|
||||
* cfg_release();
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* // driver is unloaded later
|
||||
*
|
||||
* Each configuration store is reference counted to reduce memory footprint, and
|
||||
* the configuration component itself will hold one ref count on the global
|
||||
* config store. All psocs for which psoc-specific configurations have *not*
|
||||
* been provided will reference the global config store. Psocs for which psoc-
|
||||
* specific configurations *have* been provded will check for existings stores
|
||||
* with a matching path to use, before parsing the specified configuration file.
|
||||
*
|
||||
* If, at some point in time, it is known that no further psocs will ever be
|
||||
* created, a call to cfg_release() will release the global ref count held by
|
||||
* the configuration component. For systems which specify psoc-specific configs
|
||||
* for all psocs, this will release the unnecessary memory used by the global
|
||||
* config store. Otherwise, calling cfg_release() at unload time will ensure
|
||||
* the global config store is properly freed.
|
||||
*/
|
||||
|
||||
#ifndef __CFG_UCFG_H
|
||||
#define __CFG_UCFG_H
|
||||
|
||||
#include "cfg_all.h"
|
||||
#include "cfg_define.h"
|
||||
#include "i_cfg.h"
|
||||
#include "qdf_status.h"
|
||||
#include "qdf_str.h"
|
||||
#include "qdf_types.h"
|
||||
#include "wlan_objmgr_psoc_obj.h"
|
||||
|
||||
/**
|
||||
* cfg_parse() - parse an ini file, and populate the global config storei
|
||||
* @path: The full file path of the ini file to parse
|
||||
*
|
||||
* Note: A matching cfg_release() call is required to release allocated
|
||||
* resources.
|
||||
*
|
||||
* The *.ini file format is a simple format consiting of a list of key/value
|
||||
* pairs, separated by an '=' character. e.g.
|
||||
*
|
||||
* gConfigItem1=some string value
|
||||
* gConfigItem2=0xabc
|
||||
*
|
||||
* Comments are also supported, initiated with the '#' character:
|
||||
*
|
||||
* # This is a comment. It will be ignored by the *.ini parser
|
||||
* gConfigItem3=aa:bb:cc:dd:ee:ff # this is also a comment
|
||||
*
|
||||
* Several datatypes are natively supported:
|
||||
*
|
||||
* gInt=-123 # bin (0b), octal (0o), hex (0x), and decimal supported
|
||||
* gUint=123 # a non-negative integer value
|
||||
* gBool=y # (1, Y, y) -> true; (0, N, n) -> false
|
||||
* gString=any string # strings are useful for representing complex types
|
||||
* gMacAddr=aa:bb:cc:dd:ee:ff # colons are optional, upper and lower case
|
||||
* gIpv4Addr=127.0.0.1 # uses typical dot-decimal notation
|
||||
* gIpv6Addr=::1 # typical notation, supporting zero-compression
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cfg_parse(const char *path);
|
||||
|
||||
/**
|
||||
* cfg_release() - release the global configuration store
|
||||
*
|
||||
* This API releases the configuration component's reference to the global
|
||||
* config store.
|
||||
*
|
||||
* See also: this file's DOC section.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void cfg_release(void);
|
||||
|
||||
/**
|
||||
* cfg_psoc_parse() - specialize the config store for @psoc by parsing @path
|
||||
* @psoc: The psoc whose config store should be specialized
|
||||
* @path: The full file path of the ini file to parse
|
||||
*
|
||||
* See also: cfg_parse(), and this file's DOC section.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cfg_psoc_parse(struct wlan_objmgr_psoc *psoc, const char *path);
|
||||
|
||||
/**
|
||||
* cfg_parse_to_psoc_store() - Parse file @path and update psoc ini store
|
||||
* @psoc: The psoc whose config store should be updated
|
||||
* @path: The full file path of the ini file to parse
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cfg_parse_to_psoc_store(struct wlan_objmgr_psoc *psoc,
|
||||
const char *path);
|
||||
|
||||
/**
|
||||
* cfg_parse_to_global_store() Parse file @path and update global ini store
|
||||
* @path: The full file path of the ini file to parse
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS cfg_parse_to_global_store(const char *path);
|
||||
|
||||
/**
|
||||
* cfg_ucfg_store_print() prints the cfg ini/non ini logs
|
||||
* @psoc: psoc
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_cfg_store_print(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* ucfg_cfg_ini_config_print() prints the cfg ini/non ini to buffer
|
||||
* @psoc: psoc
|
||||
* @buf: cache to save ini config
|
||||
* @plen: the pointer to length
|
||||
* @buflen: total buf length
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_cfg_ini_config_print(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t *buf, ssize_t *plen,
|
||||
ssize_t buflen);
|
||||
|
||||
/**
|
||||
* cfg_get() - lookup the configured value for @id from @psoc
|
||||
* @psoc: The psoc from which to lookup the configured value
|
||||
* @id: The id of the configured value to lookup
|
||||
*
|
||||
* E.g.
|
||||
*
|
||||
* int32_t value = cfg_get(psoc, WLAN_SOME_INTEGER_CONFIG_ID);
|
||||
*
|
||||
* Return: The configured value
|
||||
*/
|
||||
#define cfg_get(psoc, id) __cfg_get(psoc, __##id)
|
||||
|
||||
/* Configuration Access APIs */
|
||||
#define __do_call(op, args...) op(args)
|
||||
#define do_call(op, args) __do_call(op, rm_parens args)
|
||||
|
||||
#define cfg_id(id) #id
|
||||
|
||||
#define __cfg_mtype(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
mtype
|
||||
#define cfg_mtype(id) do_call(__cfg_mtype, id)
|
||||
|
||||
#define __cfg_type(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
ctype
|
||||
#define cfg_type(id) do_call(__cfg_type, id)
|
||||
|
||||
#define __cfg_name(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
name
|
||||
#define cfg_name(id) do_call(__cfg_name, id)
|
||||
|
||||
#define __cfg_min(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
min
|
||||
#define cfg_min(id) do_call(__cfg_min, id)
|
||||
|
||||
#define __cfg_max(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
max
|
||||
#define cfg_max(id) do_call(__cfg_max, id)
|
||||
|
||||
#define __cfg_fb(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
fallback
|
||||
#define cfg_fallback(id) do_call(__cfg_fb, id)
|
||||
|
||||
#define __cfg_desc(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
desc
|
||||
#define cfg_description(id) do_call(__cfg_desc, id)
|
||||
|
||||
#define __cfg_def(ini, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
def
|
||||
#define cfg_default(id) do_call(__cfg_def, id)
|
||||
|
||||
#define __cfg_str(id...) #id
|
||||
#define cfg_str(id) #id __cfg_str(id)
|
||||
|
||||
/* validate APIs */
|
||||
static inline bool
|
||||
cfg_string_in_range(const char *value, qdf_size_t min_len, qdf_size_t max_len)
|
||||
{
|
||||
qdf_size_t len = qdf_str_len(value);
|
||||
|
||||
return len >= min_len && len <= max_len;
|
||||
}
|
||||
|
||||
#define __cfg_INT_in_range(value, min, max) (value >= min && value <= max)
|
||||
#define __cfg_UINT_in_range(value, min, max) (value >= min && value <= max)
|
||||
#define __cfg_STRING_in_range(value, min_len, max_len) \
|
||||
cfg_string_in_range(value, min_len, max_len)
|
||||
|
||||
#define __cfg_in_range(id, value, mtype) \
|
||||
__cfg_ ## mtype ## _in_range(value, cfg_min(id), cfg_max(id))
|
||||
|
||||
/* this may look redundant, but forces @mtype to be expanded */
|
||||
#define __cfg_in_range_type(id, value, mtype) \
|
||||
__cfg_in_range(id, value, mtype)
|
||||
|
||||
#define cfg_in_range(id, value) __cfg_in_range_type(id, value, cfg_mtype(id))
|
||||
|
||||
/* Value-or-Default APIs */
|
||||
#define __cfg_value_or_default(id, value, def) \
|
||||
(cfg_in_range(id, value) ? value : def)
|
||||
|
||||
#define cfg_value_or_default(id, value) \
|
||||
__cfg_value_or_default(id, value, cfg_default(id))
|
||||
|
||||
/* Value-or-Clamped APIs */
|
||||
#define __cfg_clamp(val, min, max) (val < min ? min : (val > max ? max : val))
|
||||
#define cfg_clamp(id, value) __cfg_clamp(value, cfg_min(id), cfg_max(id))
|
||||
|
||||
#endif /* __CFG_UCFG_H */
|
||||
|
||||
77
drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg.h
Normal file
77
drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg.h
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: Internal APIs for the configuration component.
|
||||
*/
|
||||
|
||||
#ifndef __I_CFG_H
|
||||
#define __I_CFG_H
|
||||
|
||||
#include "cfg_define.h"
|
||||
#include "qdf_trace.h"
|
||||
#include "qdf_types.h"
|
||||
#include "wlan_objmgr_psoc_obj.h"
|
||||
|
||||
#define cfg_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_enter() QDF_TRACE_ENTER(QDF_MODULE_ID_CONFIG, "enter")
|
||||
#define cfg_exit() QDF_TRACE_EXIT(QDF_MODULE_ID_CONFIG, "exit")
|
||||
|
||||
#define cfg_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_info_rl(params...) QDF_TRACE_INFO_RL(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_CONFIG, params)
|
||||
|
||||
#define cfg_nofl_err(params...) \
|
||||
QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_nofl_warn(params...) \
|
||||
QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_nofl_info(params...) \
|
||||
QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_CONFIG, params)
|
||||
#define cfg_nofl_debug(params...) \
|
||||
QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_CONFIG, params)
|
||||
|
||||
/* define global config values structure */
|
||||
|
||||
#undef __CFG_INI_STRING
|
||||
#define __CFG_INI_STRING(id, mtype, ctype, name, min, max, fallback, desc, \
|
||||
def...) \
|
||||
const char id##_internal[(max) + 1];
|
||||
#undef __CFG_INI
|
||||
#define __CFG_INI(id, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
const ctype id##_internal;
|
||||
|
||||
struct cfg_values {
|
||||
/* e.g. const int32_t __CFG_SCAN_DWELL_TIME_internal; */
|
||||
CFG_ALL
|
||||
};
|
||||
|
||||
#undef __CFG_INI_STRING
|
||||
#define __CFG_INI_STRING(args...) __CFG_INI(args)
|
||||
#undef __CFG_INI
|
||||
#define __CFG_INI(args...) (args)
|
||||
|
||||
struct cfg_values *cfg_psoc_get_values(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
#define __cfg_get(psoc, id) (cfg_psoc_get_values( \
|
||||
(struct wlan_objmgr_psoc *)psoc)->id##_internal)
|
||||
|
||||
#endif /* __I_CFG_H */
|
||||
|
||||
59
drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg_objmgr.h
Normal file
59
drivers/staging/qca-wifi-host-cmn/cfg/inc/i_cfg_objmgr.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: This file contains various object manager related wrappers and helpers
|
||||
*/
|
||||
|
||||
#ifndef __CFG_OBJMGR_H
|
||||
#define __CFG_OBJMGR_H
|
||||
|
||||
#include "wlan_cmn.h"
|
||||
#include "wlan_objmgr_global_obj.h"
|
||||
#include "wlan_objmgr_psoc_obj.h"
|
||||
|
||||
/* Private Data */
|
||||
|
||||
#define cfg_psoc_get_priv(psoc) \
|
||||
wlan_objmgr_psoc_get_comp_private_obj((psoc), WLAN_UMAC_COMP_CONFIG)
|
||||
#define cfg_psoc_set_priv(psoc, priv) \
|
||||
wlan_objmgr_psoc_component_obj_attach((psoc), WLAN_UMAC_COMP_CONFIG, \
|
||||
(priv), QDF_STATUS_SUCCESS)
|
||||
#define cfg_psoc_unset_priv(psoc, priv) \
|
||||
wlan_objmgr_psoc_component_obj_detach((psoc), WLAN_UMAC_COMP_CONFIG, \
|
||||
(priv))
|
||||
|
||||
/* event registration */
|
||||
|
||||
#define cfg_psoc_register_create(callback) \
|
||||
wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_CONFIG, \
|
||||
(callback), NULL)
|
||||
#define cfg_psoc_register_destroy(callback) \
|
||||
wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_CONFIG, \
|
||||
(callback), NULL)
|
||||
|
||||
/* event de-registration */
|
||||
|
||||
#define cfg_psoc_unregister_create(callback) \
|
||||
wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_CONFIG, \
|
||||
(callback), NULL)
|
||||
#define cfg_psoc_unregister_destroy(callback) \
|
||||
wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_CONFIG, \
|
||||
(callback), NULL)
|
||||
|
||||
#endif /* __CFG_OBJMGR_H */
|
||||
868
drivers/staging/qca-wifi-host-cmn/cfg/src/cfg.c
Normal file
868
drivers/staging/qca-wifi-host-cmn/cfg/src/cfg.c
Normal file
|
|
@ -0,0 +1,868 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "cfg_all.h"
|
||||
#include "cfg_define.h"
|
||||
#include "cfg_dispatcher.h"
|
||||
#include "cfg_ucfg_api.h"
|
||||
#include "i_cfg.h"
|
||||
#include "i_cfg_objmgr.h"
|
||||
#include "qdf_atomic.h"
|
||||
#include "qdf_list.h"
|
||||
#include "qdf_mem.h"
|
||||
#include "qdf_module.h"
|
||||
#include "qdf_parse.h"
|
||||
#include "qdf_status.h"
|
||||
#include "qdf_str.h"
|
||||
#include "qdf_trace.h"
|
||||
#include "qdf_types.h"
|
||||
#include "wlan_objmgr_psoc_obj.h"
|
||||
|
||||
/**
|
||||
* struct cfg_value_store - backing store for an ini file
|
||||
* @path: file path of the ini file
|
||||
* @node: internal list node for keeping track of all the allocated stores
|
||||
* @users: number of references on the store
|
||||
* @values: a values struct containing the parsed values from the ini file
|
||||
*/
|
||||
struct cfg_value_store {
|
||||
char *path;
|
||||
qdf_list_node_t node;
|
||||
qdf_atomic_t users;
|
||||
struct cfg_values values;
|
||||
};
|
||||
|
||||
/* define/populate dynamic metadata lookup table */
|
||||
|
||||
/**
|
||||
* struct cfg_meta - configuration item metadata for dynamic lookup during parse
|
||||
* @name: name of the config item used in the ini file (i.e. "gScanDwellTime")
|
||||
* @item_handler: parsing callback based on the type of the config item
|
||||
* @min: minimum value for use in bounds checking (min_len for strings)
|
||||
* @max: maximum value for use in bounds checking (max_len for strings)
|
||||
* @fallback: the fallback behavior to use when configured values are invalid
|
||||
*/
|
||||
struct cfg_meta {
|
||||
const char *name;
|
||||
const uint32_t field_offset;
|
||||
void (*const item_handler)(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *value);
|
||||
const int32_t min;
|
||||
const int32_t max;
|
||||
const enum cfg_fallback_behavior fallback;
|
||||
};
|
||||
|
||||
/* ini item handler functions */
|
||||
|
||||
#define cfg_value_ptr(store, meta) \
|
||||
((void *)&(store)->values + (meta)->field_offset)
|
||||
|
||||
static __attribute__((unused)) void
|
||||
cfg_int_item_handler(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *str_value)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
int32_t *store_value = cfg_value_ptr(store, meta);
|
||||
int32_t value;
|
||||
|
||||
status = qdf_int32_parse(str_value, &value);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cfg_err("%s=%s - Invalid format (status %d); Using default %d",
|
||||
meta->name, str_value, status, *store_value);
|
||||
return;
|
||||
}
|
||||
|
||||
QDF_BUG(meta->min <= meta->max);
|
||||
if (meta->min > meta->max) {
|
||||
cfg_err("Invalid config item meta for %s", meta->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >= meta->min && value <= meta->max) {
|
||||
*store_value = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (meta->fallback) {
|
||||
default:
|
||||
QDF_DEBUG_PANIC("Unknown fallback method %d for cfg item '%s'",
|
||||
meta->fallback, meta->name);
|
||||
/* fall through */
|
||||
case CFG_VALUE_OR_DEFAULT:
|
||||
/* store already contains default */
|
||||
break;
|
||||
case CFG_VALUE_OR_CLAMP:
|
||||
*store_value = __cfg_clamp(value, meta->min, meta->max);
|
||||
break;
|
||||
}
|
||||
|
||||
cfg_err("%s=%d - Out of range [%d, %d]; Using %d",
|
||||
meta->name, value, meta->min, meta->max, *store_value);
|
||||
}
|
||||
|
||||
static __attribute__((unused)) void
|
||||
cfg_uint_item_handler(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *str_value)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
uint32_t *store_value = cfg_value_ptr(store, meta);
|
||||
uint32_t value;
|
||||
uint32_t min;
|
||||
uint32_t max;
|
||||
|
||||
/**
|
||||
* Since meta min and max are of type int32_t
|
||||
* We need explicit type casting to avoid
|
||||
* implicit wrap around for uint32_t type cfg data.
|
||||
*/
|
||||
min = (uint32_t)meta->min;
|
||||
max = (uint32_t)meta->max;
|
||||
|
||||
status = qdf_uint32_parse(str_value, &value);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
cfg_err("%s=%s - Invalid format (status %d); Using default %u",
|
||||
meta->name, str_value, status, *store_value);
|
||||
return;
|
||||
}
|
||||
|
||||
QDF_BUG(min <= max);
|
||||
if (min > max) {
|
||||
cfg_err("Invalid config item meta for %s", meta->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value >= min && value <= max) {
|
||||
*store_value = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (meta->fallback) {
|
||||
default:
|
||||
QDF_DEBUG_PANIC("Unknown fallback method %d for cfg item '%s'",
|
||||
meta->fallback, meta->name);
|
||||
/* fall through */
|
||||
case CFG_VALUE_OR_DEFAULT:
|
||||
/* store already contains default */
|
||||
break;
|
||||
case CFG_VALUE_OR_CLAMP:
|
||||
*store_value = __cfg_clamp(value, min, max);
|
||||
break;
|
||||
}
|
||||
|
||||
cfg_err("%s=%u - Out of range [%d, %d]; Using %u",
|
||||
meta->name, value, min, max, *store_value);
|
||||
}
|
||||
|
||||
static __attribute__((unused)) void
|
||||
cfg_bool_item_handler(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *str_value)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
bool *store_value = cfg_value_ptr(store, meta);
|
||||
|
||||
status = qdf_bool_parse(str_value, store_value);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
return;
|
||||
|
||||
cfg_err("%s=%s - Invalid format (status %d); Using default '%s'",
|
||||
meta->name, str_value, status, *store_value ? "true" : "false");
|
||||
}
|
||||
|
||||
static __attribute__((unused)) void
|
||||
cfg_string_item_handler(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *str_value)
|
||||
{
|
||||
char *store_value = cfg_value_ptr(store, meta);
|
||||
qdf_size_t len;
|
||||
|
||||
QDF_BUG(meta->min >= 0);
|
||||
QDF_BUG(meta->min <= meta->max);
|
||||
if (meta->min < 0 || meta->min > meta->max) {
|
||||
cfg_err("Invalid config item meta for %s", meta->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ensure min length */
|
||||
len = qdf_str_nlen(str_value, meta->min);
|
||||
if (len < meta->min) {
|
||||
cfg_err("%s=%s - Too short; Using default '%s'",
|
||||
meta->name, str_value, store_value);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check max length */
|
||||
len += qdf_str_nlen(str_value + meta->min, meta->max - meta->min + 1);
|
||||
if (len > meta->max) {
|
||||
cfg_err("%s=%s - Too long; Using default '%s'",
|
||||
meta->name, str_value, store_value);
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_str_lcopy(store_value, str_value, meta->max + 1);
|
||||
}
|
||||
|
||||
static __attribute__((unused)) void
|
||||
cfg_mac_item_handler(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *str_value)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct qdf_mac_addr *store_value = cfg_value_ptr(store, meta);
|
||||
|
||||
status = qdf_mac_parse(str_value, store_value);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
return;
|
||||
|
||||
cfg_err("%s=%s - Invalid format (status %d); Using default "
|
||||
QDF_MAC_ADDR_FMT, meta->name, str_value, status,
|
||||
QDF_MAC_ADDR_REF(store_value->bytes));
|
||||
}
|
||||
|
||||
static __attribute__((unused)) void
|
||||
cfg_ipv4_item_handler(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *str_value)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct qdf_ipv4_addr *store_value = cfg_value_ptr(store, meta);
|
||||
|
||||
status = qdf_ipv4_parse(str_value, store_value);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
return;
|
||||
|
||||
cfg_err("%s=%s - Invalid format (status %d); Using default "
|
||||
QDF_IPV4_ADDR_STR, meta->name, str_value, status,
|
||||
QDF_IPV4_ADDR_ARRAY(store_value->bytes));
|
||||
}
|
||||
|
||||
static __attribute__((unused)) void
|
||||
cfg_ipv6_item_handler(struct cfg_value_store *store,
|
||||
const struct cfg_meta *meta,
|
||||
const char *str_value)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct qdf_ipv6_addr *store_value = cfg_value_ptr(store, meta);
|
||||
|
||||
status = qdf_ipv6_parse(str_value, store_value);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
return;
|
||||
|
||||
cfg_err("%s=%s - Invalid format (status %d); Using default "
|
||||
QDF_IPV6_ADDR_STR, meta->name, str_value, status,
|
||||
QDF_IPV6_ADDR_ARRAY(store_value->bytes));
|
||||
}
|
||||
|
||||
/* populate metadata lookup table */
|
||||
#undef __CFG_INI
|
||||
#define __CFG_INI(_id, _mtype, _ctype, _name, _min, _max, _fallback, ...) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.field_offset = qdf_offsetof(struct cfg_values, _id##_internal), \
|
||||
.item_handler = cfg_ ## _mtype ## _item_handler, \
|
||||
.min = _min, \
|
||||
.max = _max, \
|
||||
.fallback = _fallback, \
|
||||
},
|
||||
|
||||
#define cfg_INT_item_handler cfg_int_item_handler
|
||||
#define cfg_UINT_item_handler cfg_uint_item_handler
|
||||
#define cfg_BOOL_item_handler cfg_bool_item_handler
|
||||
#define cfg_STRING_item_handler cfg_string_item_handler
|
||||
#define cfg_MAC_item_handler cfg_mac_item_handler
|
||||
#define cfg_IPV4_item_handler cfg_ipv4_item_handler
|
||||
#define cfg_IPV6_item_handler cfg_ipv6_item_handler
|
||||
|
||||
static const struct cfg_meta cfg_meta_lookup_table[] = {
|
||||
CFG_ALL
|
||||
};
|
||||
|
||||
/* default store initializer */
|
||||
|
||||
static void cfg_store_set_defaults(struct cfg_value_store *store)
|
||||
{
|
||||
#undef __CFG_INI
|
||||
#define __CFG_INI(id, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
ctype id = def;
|
||||
|
||||
CFG_ALL
|
||||
|
||||
#undef __CFG_INI_STRING
|
||||
#define __CFG_INI_STRING(id, mtype, ctype, name, min_len, max_len, ...) \
|
||||
qdf_str_lcopy((char *)&store->values.id##_internal, id, (max_len) + 1);
|
||||
|
||||
#undef __CFG_INI
|
||||
#define __CFG_INI(id, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
*(ctype *)&store->values.id##_internal = id;
|
||||
|
||||
CFG_ALL
|
||||
}
|
||||
|
||||
static const struct cfg_meta *cfg_lookup_meta(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
QDF_BUG(name);
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
/* linear search for now; optimize in the future if needed */
|
||||
for (i = 0; i < QDF_ARRAY_SIZE(cfg_meta_lookup_table); i++) {
|
||||
const struct cfg_meta *meta = &cfg_meta_lookup_table[i];
|
||||
|
||||
if (qdf_str_eq(name, meta->name))
|
||||
return meta;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_ini_item_handler(void *context, const char *key, const char *value)
|
||||
{
|
||||
struct cfg_value_store *store = context;
|
||||
const struct cfg_meta *meta;
|
||||
|
||||
meta = cfg_lookup_meta(key);
|
||||
if (!meta) {
|
||||
/* TODO: promote to 'err' or 'warn' once legacy is ported */
|
||||
cfg_debug("Unknown config item '%s'", key);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_BUG(meta->item_handler);
|
||||
if (!meta->item_handler)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
meta->item_handler(store, meta, value);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS cfg_ini_section_handler(void *context, const char *name)
|
||||
{
|
||||
cfg_err("Unexpected section '%s'. Sections are not supported.", name);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#define cfg_assert_success(expr) \
|
||||
do { \
|
||||
QDF_STATUS __assert_status = (expr); \
|
||||
QDF_BUG(QDF_IS_STATUS_SUCCESS(__assert_status)); \
|
||||
} while (0)
|
||||
|
||||
static bool __cfg_is_init;
|
||||
static struct cfg_value_store *__cfg_global_store;
|
||||
static qdf_list_t __cfg_stores_list;
|
||||
static qdf_spinlock_t __cfg_stores_lock;
|
||||
|
||||
struct cfg_psoc_ctx {
|
||||
struct cfg_value_store *store;
|
||||
};
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_store_alloc(const char *path, struct cfg_value_store **out_store)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct cfg_value_store *store;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
store = qdf_mem_malloc(sizeof(*store));
|
||||
if (!store)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
status = qdf_str_dup(&store->path, path);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto free_store;
|
||||
|
||||
status = qdf_atomic_init(&store->users);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto free_path;
|
||||
qdf_atomic_inc(&store->users);
|
||||
|
||||
qdf_spin_lock_bh(&__cfg_stores_lock);
|
||||
status = qdf_list_insert_back(&__cfg_stores_list, &store->node);
|
||||
qdf_spin_unlock_bh(&__cfg_stores_lock);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto free_path;
|
||||
|
||||
*out_store = store;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
free_path:
|
||||
qdf_mem_free(store->path);
|
||||
|
||||
free_store:
|
||||
qdf_mem_free(store);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void cfg_store_free(struct cfg_value_store *store)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
qdf_spin_lock_bh(&__cfg_stores_lock);
|
||||
status = qdf_list_remove_node(&__cfg_stores_list, &store->node);
|
||||
qdf_spin_unlock_bh(&__cfg_stores_lock);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
QDF_DEBUG_PANIC("Failed config store list removal; status:%d",
|
||||
status);
|
||||
|
||||
qdf_mem_free(store->path);
|
||||
qdf_mem_free(store);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_store_get(const char *path, struct cfg_value_store **out_store)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
qdf_list_node_t *node;
|
||||
|
||||
*out_store = NULL;
|
||||
|
||||
qdf_spin_lock_bh(&__cfg_stores_lock);
|
||||
status = qdf_list_peek_front(&__cfg_stores_list, &node);
|
||||
while (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
struct cfg_value_store *store =
|
||||
qdf_container_of(node, struct cfg_value_store, node);
|
||||
|
||||
if (qdf_str_eq(path, store->path)) {
|
||||
qdf_atomic_inc(&store->users);
|
||||
*out_store = store;
|
||||
break;
|
||||
}
|
||||
|
||||
status = qdf_list_peek_next(&__cfg_stores_list, node, &node);
|
||||
}
|
||||
qdf_spin_unlock_bh(&__cfg_stores_lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void cfg_store_put(struct cfg_value_store *store)
|
||||
{
|
||||
if (qdf_atomic_dec_and_test(&store->users))
|
||||
cfg_store_free(store);
|
||||
}
|
||||
|
||||
static struct cfg_psoc_ctx *cfg_psoc_get_ctx(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct cfg_psoc_ctx *psoc_ctx;
|
||||
|
||||
psoc_ctx = cfg_psoc_get_priv(psoc);
|
||||
QDF_BUG(psoc_ctx);
|
||||
|
||||
return psoc_ctx;
|
||||
}
|
||||
|
||||
struct cfg_values *cfg_psoc_get_values(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return &cfg_psoc_get_ctx(psoc)->store->values;
|
||||
}
|
||||
qdf_export_symbol(cfg_psoc_get_values);
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_ini_parse_to_store(const char *path, struct cfg_value_store *store)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
status = qdf_ini_parse(path, store, cfg_ini_item_handler,
|
||||
cfg_ini_section_handler);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
cfg_err("Failed to parse *.ini file @ %s; status:%d",
|
||||
path, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS cfg_parse_to_psoc_store(struct wlan_objmgr_psoc *psoc,
|
||||
const char *path)
|
||||
{
|
||||
return cfg_ini_parse_to_store(path, cfg_psoc_get_ctx(psoc)->store);
|
||||
}
|
||||
|
||||
qdf_export_symbol(cfg_parse_to_psoc_store);
|
||||
|
||||
QDF_STATUS cfg_parse_to_global_store(const char *path)
|
||||
{
|
||||
if (!__cfg_global_store) {
|
||||
cfg_err("Global INI store is not valid");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
return cfg_ini_parse_to_store(path, __cfg_global_store);
|
||||
}
|
||||
|
||||
qdf_export_symbol(cfg_parse_to_global_store);
|
||||
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_store_print(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct cfg_value_store *store;
|
||||
struct cfg_psoc_ctx *psoc_ctx;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
psoc_ctx = cfg_psoc_get_ctx(psoc);
|
||||
if (!psoc_ctx)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
store = psoc_ctx->store;
|
||||
if (!store)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
#undef __CFG_INI_MAC
|
||||
#define __CFG_INI_MAC(id, mtype, ctype, name, desc, def...) \
|
||||
cfg_nofl_debug("%s "QDF_MAC_ADDR_FMT, name, \
|
||||
QDF_MAC_ADDR_REF((&store->values.id##_internal)->bytes));
|
||||
|
||||
#undef __CFG_INI_IPV4
|
||||
#define __CFG_INI_IPV4(id, mtype, ctype, name, desc, def...) \
|
||||
cfg_nofl_debug("%s %pI4", name, (&store->values.id##_internal)->bytes);
|
||||
|
||||
#undef __CFG_INI_IPV6
|
||||
#define __CFG_INI_IPV6(id, mtype, ctype, name, desc, def...) \
|
||||
cfg_nofl_debug("%s %pI6c", name, (&store->values.id##_internal)->bytes);
|
||||
|
||||
#undef __CFG_INI
|
||||
#define __CFG_INI(id, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
cfg_nofl_debug("%s %d", name, *(ctype *)&store->values.id##_internal);
|
||||
|
||||
#undef __CFG_INI_STRING
|
||||
#define __CFG_INI_STRING(id, mtype, ctype, name, min_len, max_len, ...) \
|
||||
cfg_nofl_debug("%s %s", name, (char *)&store->values.id##_internal);
|
||||
|
||||
CFG_ALL
|
||||
|
||||
#undef __CFG_INI_MAC
|
||||
#undef __CFG_INI_IPV4
|
||||
#undef __CFG_INI_IPV6
|
||||
#undef __CFG_INI
|
||||
#undef __CFG_INI_STRING
|
||||
|
||||
cfg_exit();
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_ini_config_print(struct wlan_objmgr_psoc *psoc, uint8_t *buf,
|
||||
ssize_t *plen, ssize_t buflen)
|
||||
{
|
||||
struct cfg_value_store *store;
|
||||
struct cfg_psoc_ctx *psoc_ctx;
|
||||
ssize_t len;
|
||||
ssize_t total_len = buflen;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
psoc_ctx = cfg_psoc_get_ctx(psoc);
|
||||
if (!psoc_ctx)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
store = psoc_ctx->store;
|
||||
if (!store)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
#undef __CFG_INI_MAC
|
||||
#define __CFG_INI_MAC(id, mtype, ctype, name, desc, def...) \
|
||||
do { \
|
||||
len = qdf_scnprintf(buf, buflen, "%s "QDF_MAC_ADDR_FMT"\n", \
|
||||
name, \
|
||||
QDF_MAC_ADDR_REF((&store->values.id##_internal)->bytes)); \
|
||||
buf += len; \
|
||||
buflen -= len; \
|
||||
} while (0);
|
||||
|
||||
#undef __CFG_INI_IPV4
|
||||
#define __CFG_INI_IPV4(id, mtype, ctype, name, desc, def...) \
|
||||
do { \
|
||||
len = qdf_scnprintf(buf, buflen, "%s %pI4\n", name, \
|
||||
(&store->values.id##_internal)->bytes); \
|
||||
buf += len; \
|
||||
buflen -= len; \
|
||||
} while (0);
|
||||
|
||||
#undef __CFG_INI_IPV6
|
||||
#define __CFG_INI_IPV6(id, mtype, ctype, name, desc, def...) \
|
||||
do { \
|
||||
len = qdf_scnprintf(buf, buflen, "%s %pI6c\n", name, \
|
||||
(&store->values.id##_internal)->bytes); \
|
||||
buf += len; \
|
||||
buflen -= len; \
|
||||
} while (0);
|
||||
|
||||
#undef __CFG_INI
|
||||
#define __CFG_INI(id, mtype, ctype, name, min, max, fallback, desc, def...) \
|
||||
do { \
|
||||
len = qdf_scnprintf(buf, buflen, "%s %d\n", name, \
|
||||
*(ctype *)&store->values.id##_internal); \
|
||||
buf += len; \
|
||||
buflen -= len; \
|
||||
} while (0);
|
||||
|
||||
#undef __CFG_INI_STRING
|
||||
#define __CFG_INI_STRING(id, mtype, ctype, name, min_len, max_len, ...) \
|
||||
do { \
|
||||
len = qdf_scnprintf(buf, buflen, "%s %s\n", name, \
|
||||
(char *)&store->values.id##_internal); \
|
||||
buf += len; \
|
||||
buflen -= len; \
|
||||
} while (0);
|
||||
|
||||
CFG_ALL
|
||||
|
||||
#undef __CFG_INI_MAC
|
||||
#undef __CFG_INI_IPV4
|
||||
#undef __CFG_INI_IPV6
|
||||
#undef __CFG_INI
|
||||
#undef __CFG_INI_STRING
|
||||
|
||||
*plen = total_len - buflen;
|
||||
cfg_exit();
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_cfg_store_print(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return cfg_store_print(psoc);
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_cfg_ini_config_print(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t *buf, ssize_t *plen,
|
||||
ssize_t buflen)
|
||||
{
|
||||
return cfg_ini_config_print(psoc, buf, plen, buflen);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_on_psoc_create(struct wlan_objmgr_psoc *psoc, void *context)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct cfg_psoc_ctx *psoc_ctx;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
QDF_BUG(__cfg_global_store);
|
||||
if (!__cfg_global_store)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
psoc_ctx = qdf_mem_malloc(sizeof(*psoc_ctx));
|
||||
if (!psoc_ctx)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
qdf_atomic_inc(&__cfg_global_store->users);
|
||||
psoc_ctx->store = __cfg_global_store;
|
||||
|
||||
status = cfg_psoc_set_priv(psoc, psoc_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto put_store;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
put_store:
|
||||
cfg_store_put(__cfg_global_store);
|
||||
qdf_mem_free(psoc_ctx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
cfg_on_psoc_destroy(struct wlan_objmgr_psoc *psoc, void *context)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct cfg_psoc_ctx *psoc_ctx;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
psoc_ctx = cfg_psoc_get_ctx(psoc);
|
||||
status = cfg_psoc_unset_priv(psoc, psoc_ctx);
|
||||
|
||||
cfg_store_put(psoc_ctx->store);
|
||||
qdf_mem_free(psoc_ctx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS cfg_dispatcher_init(void)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
QDF_BUG(!__cfg_is_init);
|
||||
if (__cfg_is_init)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
qdf_list_create(&__cfg_stores_list, 0);
|
||||
qdf_spinlock_create(&__cfg_stores_lock);
|
||||
|
||||
status = cfg_psoc_register_create(cfg_on_psoc_create);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
status = cfg_psoc_register_destroy(cfg_on_psoc_destroy);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto unreg_create;
|
||||
|
||||
__cfg_is_init = true;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
unreg_create:
|
||||
cfg_assert_success(cfg_psoc_unregister_create(cfg_on_psoc_create));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS cfg_dispatcher_deinit(void)
|
||||
{
|
||||
cfg_enter();
|
||||
|
||||
QDF_BUG(__cfg_is_init);
|
||||
if (!__cfg_is_init)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
__cfg_is_init = false;
|
||||
|
||||
cfg_assert_success(cfg_psoc_unregister_create(cfg_on_psoc_create));
|
||||
cfg_assert_success(cfg_psoc_unregister_destroy(cfg_on_psoc_destroy));
|
||||
|
||||
qdf_spin_lock_bh(&__cfg_stores_lock);
|
||||
QDF_BUG(qdf_list_empty(&__cfg_stores_list));
|
||||
qdf_spin_unlock_bh(&__cfg_stores_lock);
|
||||
|
||||
qdf_spinlock_destroy(&__cfg_stores_lock);
|
||||
qdf_list_destroy(&__cfg_stores_list);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS cfg_parse(const char *path)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct cfg_value_store *store;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
QDF_BUG(!__cfg_global_store);
|
||||
if (__cfg_global_store)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
status = cfg_store_alloc(path, &store);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
cfg_store_set_defaults(store);
|
||||
|
||||
status = cfg_ini_parse_to_store(path, store);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto free_store;
|
||||
|
||||
__cfg_global_store = store;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
free_store:
|
||||
cfg_store_free(store);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void cfg_release(void)
|
||||
{
|
||||
cfg_enter();
|
||||
|
||||
QDF_BUG(__cfg_global_store);
|
||||
if (!__cfg_global_store)
|
||||
return;
|
||||
|
||||
cfg_store_put(__cfg_global_store);
|
||||
__cfg_global_store = NULL;
|
||||
}
|
||||
|
||||
QDF_STATUS cfg_psoc_parse(struct wlan_objmgr_psoc *psoc, const char *path)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct cfg_value_store *store;
|
||||
struct cfg_psoc_ctx *psoc_ctx;
|
||||
|
||||
cfg_enter();
|
||||
|
||||
QDF_BUG(__cfg_global_store);
|
||||
if (!__cfg_global_store)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
QDF_BUG(__cfg_is_init);
|
||||
if (!__cfg_is_init)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
QDF_BUG(psoc);
|
||||
if (!psoc)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
QDF_BUG(path);
|
||||
if (!path)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
psoc_ctx = cfg_psoc_get_ctx(psoc);
|
||||
|
||||
QDF_BUG(psoc_ctx->store == __cfg_global_store);
|
||||
if (psoc_ctx->store != __cfg_global_store)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
/* check if @path has been parsed before */
|
||||
status = cfg_store_get(path, &store);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
status = cfg_store_alloc(path, &store);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return status;
|
||||
|
||||
/* inherit global configuration */
|
||||
qdf_mem_copy(&store->values, &__cfg_global_store->values,
|
||||
sizeof(store->values));
|
||||
|
||||
status = cfg_ini_parse_to_store(path, store);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto put_store;
|
||||
}
|
||||
|
||||
psoc_ctx->store = store;
|
||||
cfg_store_put(__cfg_global_store);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
put_store:
|
||||
cfg_store_put(store);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
qdf_export_symbol(cfg_psoc_parse);
|
||||
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "dp_cal_client_api.h"
|
||||
#include "qdf_module.h"
|
||||
|
||||
/* dp_cal_client_attach - function to attach cal client timer
|
||||
* @cal_client_ctx: cal client timer context
|
||||
* @pdev: pdev handle
|
||||
* @osdev: device pointer
|
||||
* @dp_iterate_peer_list : function pointer to iterate and update peer stats
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx,
|
||||
struct cdp_pdev *pdev,
|
||||
qdf_device_t osdev,
|
||||
void (*dp_iterate_peer_list)(struct cdp_pdev *))
|
||||
{
|
||||
struct cal_client *cal_cl;
|
||||
|
||||
*cal_client_ctx = qdf_mem_malloc(sizeof(struct cal_client));
|
||||
|
||||
if (!(*cal_client_ctx))
|
||||
return;
|
||||
|
||||
cal_cl = (struct cal_client *)(*cal_client_ctx);
|
||||
cal_cl->iterate_update_peer_list = dp_iterate_peer_list;
|
||||
cal_cl->pdev_hdl = pdev;
|
||||
|
||||
qdf_timer_init(osdev, &cal_cl->cal_client_timer,
|
||||
dp_cal_client_stats_timer_fn, *cal_client_ctx,
|
||||
QDF_TIMER_TYPE_WAKE_APPS);
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_cal_client_attach);
|
||||
|
||||
/* dp_cal_client_detach - detach cal client timer
|
||||
* @cal_client_ctx: cal client timer context
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx)
|
||||
{
|
||||
struct cal_client *cal_cl;
|
||||
|
||||
if (*cal_client_ctx) {
|
||||
cal_cl = (struct cal_client *)*cal_client_ctx;
|
||||
|
||||
qdf_timer_stop(&cal_cl->cal_client_timer);
|
||||
qdf_timer_free(&cal_cl->cal_client_timer);
|
||||
qdf_mem_free(cal_cl);
|
||||
*cal_client_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_cal_client_detach);
|
||||
|
||||
/* dp_cal_client_timer_start- api to start cal client timer
|
||||
* @ctx: cal client timer ctx
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_cal_client_timer_start(void *ctx)
|
||||
{
|
||||
struct cal_client *cal_cl;
|
||||
|
||||
if (ctx) {
|
||||
cal_cl = (struct cal_client *)ctx;
|
||||
qdf_timer_start(&cal_cl->cal_client_timer, DP_CAL_CLIENT_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_cal_client_timer_start);
|
||||
|
||||
/* dp_cal_client_timer_stop- api to stop cal client timer
|
||||
* @ctx: cal client timer ctx
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_cal_client_timer_stop(void *ctx)
|
||||
{
|
||||
struct cal_client *cal_cl;
|
||||
|
||||
if (ctx) {
|
||||
cal_cl = (struct cal_client *)ctx;
|
||||
qdf_timer_sync_cancel(&cal_cl->cal_client_timer);
|
||||
qdf_timer_stop(&cal_cl->cal_client_timer);
|
||||
}
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_cal_client_timer_stop);
|
||||
|
||||
/* dp_cal_client_stats_timer_fn- function called on timer interval
|
||||
* @ctx: cal client timer ctx
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_cal_client_stats_timer_fn(void *ctx)
|
||||
{
|
||||
struct cal_client *cal_cl = (struct cal_client *)ctx;
|
||||
|
||||
if (!cal_cl)
|
||||
return;
|
||||
|
||||
cal_cl->iterate_update_peer_list(cal_cl->pdev_hdl);
|
||||
qdf_timer_mod(&cal_cl->cal_client_timer, DP_CAL_CLIENT_TIME);
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_cal_client_stats_timer_fn);
|
||||
|
||||
/*dp_cal_client_update_peer_stats - update peer stats in peer
|
||||
* @peer_stats: cdp peer stats pointer
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void dp_cal_client_update_peer_stats(struct cdp_peer_stats *peer_stats)
|
||||
{
|
||||
uint32_t temp_rx_bytes = peer_stats->rx.to_stack.bytes;
|
||||
uint32_t temp_rx_data = peer_stats->rx.to_stack.num;
|
||||
uint32_t temp_tx_bytes = peer_stats->tx.tx_success.bytes;
|
||||
uint32_t temp_tx_data = peer_stats->tx.tx_success.num;
|
||||
uint32_t temp_tx_ucast_pkts = peer_stats->tx.ucast.num;
|
||||
|
||||
peer_stats->rx.rx_byte_rate = temp_rx_bytes -
|
||||
peer_stats->rx.rx_bytes_success_last;
|
||||
peer_stats->rx.rx_data_rate = temp_rx_data -
|
||||
peer_stats->rx.rx_data_success_last;
|
||||
peer_stats->tx.tx_byte_rate = temp_tx_bytes -
|
||||
peer_stats->tx.tx_bytes_success_last;
|
||||
peer_stats->tx.tx_data_rate = temp_tx_data -
|
||||
peer_stats->tx.tx_data_success_last;
|
||||
peer_stats->tx.tx_data_ucast_rate = temp_tx_ucast_pkts -
|
||||
peer_stats->tx.tx_data_ucast_last;
|
||||
|
||||
/* Check tx and rx packets in last one second, and increment
|
||||
* inactive time for peer
|
||||
*/
|
||||
if (peer_stats->tx.tx_data_rate || peer_stats->rx.rx_data_rate)
|
||||
peer_stats->tx.inactive_time = 0;
|
||||
else
|
||||
peer_stats->tx.inactive_time++;
|
||||
|
||||
peer_stats->rx.rx_bytes_success_last = temp_rx_bytes;
|
||||
peer_stats->rx.rx_data_success_last = temp_rx_data;
|
||||
peer_stats->tx.tx_bytes_success_last = temp_tx_bytes;
|
||||
peer_stats->tx.tx_data_success_last = temp_tx_data;
|
||||
peer_stats->tx.tx_data_ucast_last = temp_tx_ucast_pkts;
|
||||
|
||||
if (peer_stats->tx.tx_data_ucast_rate) {
|
||||
if (peer_stats->tx.tx_data_ucast_rate >
|
||||
peer_stats->tx.tx_data_rate)
|
||||
peer_stats->tx.last_per =
|
||||
((peer_stats->tx.tx_data_ucast_rate -
|
||||
peer_stats->tx.tx_data_rate) * 100) /
|
||||
peer_stats->tx.tx_data_ucast_rate;
|
||||
else
|
||||
peer_stats->tx.last_per = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
qdf_export_symbol(dp_cal_client_update_peer_stats);
|
||||
|
||||
3302
drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.c
Normal file
3302
drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.c
Normal file
File diff suppressed because it is too large
Load diff
172
drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.h
Normal file
172
drivers/staging/qca-wifi-host-cmn/dp/cmn_dp_api/dp_ratetable.h
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _DP_RATES_H_
|
||||
#define _DP_RATES_H_
|
||||
|
||||
#define CMN_DP_ASSERT(__bool)
|
||||
|
||||
/*
|
||||
*Band Width Types
|
||||
*/
|
||||
enum CMN_BW_TYPES {
|
||||
CMN_BW_20MHZ,
|
||||
CMN_BW_40MHZ,
|
||||
CMN_BW_80MHZ,
|
||||
CMN_BW_160MHZ,
|
||||
CMN_BW_CNT,
|
||||
CMN_BW_IDLE = 0xFF, /*default BW state */
|
||||
};
|
||||
|
||||
#define NUM_SPATIAL_STREAMS 8
|
||||
#define MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ 4
|
||||
#define VHT_EXTRA_MCS_SUPPORT
|
||||
#define CONFIG_160MHZ_SUPPORT 1
|
||||
#define NUM_HT_MCS 8
|
||||
#define NUM_VHT_MCS 12
|
||||
|
||||
#define NUM_HE_MCS 14
|
||||
|
||||
#define NUM_SPATIAL_STREAM 4
|
||||
#define NUM_SPATIAL_STREAMS 8
|
||||
#define WHAL_160MHZ_SUPPORT 1
|
||||
#define MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ 4
|
||||
#define RT_GET_RT(_rt) ((const struct DP_CMN_RATE_TABLE *)(_rt))
|
||||
#define RT_GET_INFO(_rt, _index) RT_GET_RT(_rt)->info[(_index)]
|
||||
#define RT_GET_RAW_KBPS(_rt, _index) \
|
||||
(RT_GET_INFO(_rt, (_index)).ratekbps)
|
||||
#define RT_GET_SGI_KBPS(_rt, _index) \
|
||||
(RT_GET_INFO(_rt, (_index)).ratekbpssgi)
|
||||
|
||||
#define HW_RATECODE_CCK_SHORT_PREAM_MASK 0x4
|
||||
#define RT_INVALID_INDEX (0xff)
|
||||
/* pow2 to optimize out * and / */
|
||||
#define DP_ATH_RATE_EP_MULTIPLIER BIT(7)
|
||||
#define DP_ATH_EP_MUL(a, b) ((a) * (b))
|
||||
#define DP_ATH_RATE_LPF_LEN 10 /* Low pass filter length
|
||||
* for averaging rates
|
||||
*/
|
||||
#define DUMMY_MARKER 0
|
||||
#define DP_ATH_RATE_IN(c) (DP_ATH_EP_MUL((c), DP_ATH_RATE_EP_MULTIPLIER))
|
||||
|
||||
static inline int dp_ath_rate_lpf(uint64_t _d, int _e)
|
||||
{
|
||||
_e = DP_ATH_RATE_IN((_e));
|
||||
return (((_d) != DUMMY_MARKER) ? ((((_d) << 3) + (_e) - (_d)) >> 3) :
|
||||
(_e));
|
||||
}
|
||||
|
||||
static inline int dp_ath_rate_out(uint64_t _i)
|
||||
{
|
||||
int _mul = DP_ATH_RATE_EP_MULTIPLIER;
|
||||
|
||||
return (((_i) != DUMMY_MARKER) ?
|
||||
((((_i) % (_mul)) >= ((_mul) / 2)) ?
|
||||
((_i) + ((_mul) - 1)) / (_mul) : (_i) / (_mul)) :
|
||||
DUMMY_MARKER);
|
||||
}
|
||||
|
||||
#define RXDESC_GET_DATA_LEN(rx_desc) \
|
||||
(txrx_pdev->htt_pdev->ar_rx_ops->msdu_desc_msdu_length(rx_desc))
|
||||
#define ASSEMBLE_HW_RATECODE(_rate, _nss, _pream) \
|
||||
(((_pream) << 6) | ((_nss) << 4) | (_rate))
|
||||
#define GET_HW_RATECODE_PREAM(_rcode) (((_rcode) >> 6) & 0x3)
|
||||
#define GET_HW_RATECODE_NSS(_rcode) (((_rcode) >> 4) & 0x3)
|
||||
#define GET_HW_RATECODE_RATE(_rcode) (((_rcode) >> 0) & 0xF)
|
||||
|
||||
#define VHT_INVALID_MCS (0xFF) /* Certain MCSs are not valid in VHT mode */
|
||||
#define VHT_INVALID_BCC_RATE 0
|
||||
#define NUM_HT_SPATIAL_STREAM 4
|
||||
|
||||
#define NUM_HT_RIX_PER_BW (NUM_HT_MCS * NUM_HT_SPATIAL_STREAM)
|
||||
#define NUM_VHT_RIX_PER_BW (NUM_VHT_MCS * NUM_SPATIAL_STREAMS)
|
||||
#define NUM_HE_RIX_PER_BW (NUM_HE_MCS * NUM_SPATIAL_STREAMS)
|
||||
|
||||
#define NUM_VHT_RIX_FOR_160MHZ (NUM_VHT_MCS * \
|
||||
MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ)
|
||||
#define NUM_HE_RIX_FOR_160MHZ (NUM_HE_MCS * \
|
||||
MAX_SPATIAL_STREAMS_SUPPORTED_AT_160MHZ)
|
||||
|
||||
#define CCK_RATE_TABLE_INDEX 0
|
||||
#define CCK_RATE_11M_INDEX 0
|
||||
#define CCK_FALLBACK_MIN_RATE 0x3 /** 1 Mbps */
|
||||
#define CCK_FALLBACK_MAX_RATE 0x2 /** 2 Mbps */
|
||||
|
||||
#define OFDM_RATE_TABLE_INDEX 4
|
||||
#define OFDMA_RATE_54M_INDEX 8
|
||||
|
||||
#define HT_20_RATE_TABLE_INDEX 12
|
||||
#define HT_40_RATE_TABLE_INDEX (HT_20_RATE_TABLE_INDEX + NUM_HT_RIX_PER_BW)
|
||||
|
||||
#define VHT_20_RATE_TABLE_INDEX (HT_40_RATE_TABLE_INDEX + NUM_HT_RIX_PER_BW)
|
||||
#define VHT_40_RATE_TABLE_INDEX (VHT_20_RATE_TABLE_INDEX + NUM_VHT_RIX_PER_BW)
|
||||
#define VHT_80_RATE_TABLE_INDEX (VHT_40_RATE_TABLE_INDEX + NUM_VHT_RIX_PER_BW)
|
||||
|
||||
#define VHT_160_RATE_TABLE_INDEX (VHT_80_RATE_TABLE_INDEX + NUM_VHT_RIX_PER_BW)
|
||||
#define VHT_LAST_RIX_PLUS_ONE (VHT_160_RATE_TABLE_INDEX + \
|
||||
NUM_VHT_RIX_FOR_160MHZ)
|
||||
|
||||
#define HE_20_RATE_TABLE_INDEX VHT_LAST_RIX_PLUS_ONE
|
||||
#define HE_40_RATE_TABLE_INDEX (HE_20_RATE_TABLE_INDEX + NUM_HE_RIX_PER_BW)
|
||||
#define HE_80_RATE_TABLE_INDEX (HE_40_RATE_TABLE_INDEX + NUM_HE_RIX_PER_BW)
|
||||
|
||||
#define HE_160_RATE_TABLE_INDEX (HE_80_RATE_TABLE_INDEX + NUM_HE_RIX_PER_BW)
|
||||
#define DP_RATE_TABLE_SIZE (HE_160_RATE_TABLE_INDEX + NUM_HE_RIX_FOR_160MHZ)
|
||||
|
||||
/* The following would span more than one octet
|
||||
* when 160MHz BW defined for VHT
|
||||
* Also it's important to maintain the ordering of
|
||||
* this enum else it would break other rate adapation functions.
|
||||
*/
|
||||
enum DP_CMN_MODULATION_TYPE {
|
||||
DP_CMN_MOD_IEEE80211_T_DS, /* direct sequence spread spectrum */
|
||||
DP_CMN_MOD_IEEE80211_T_OFDM, /* frequency division multiplexing */
|
||||
DP_CMN_MOD_IEEE80211_T_HT_20,
|
||||
DP_CMN_MOD_IEEE80211_T_HT_40,
|
||||
DP_CMN_MOD_IEEE80211_T_VHT_20,
|
||||
DP_CMN_MOD_IEEE80211_T_VHT_40,
|
||||
DP_CMN_MOD_IEEE80211_T_VHT_80,
|
||||
DP_CMN_MOD_IEEE80211_T_VHT_160,
|
||||
DP_CMN_MOD_IEEE80211_T_HE_20, /* 11AX support enabled */
|
||||
DP_CMN_MOD_IEEE80211_T_HE_40,
|
||||
DP_CMN_MOD_IEEE80211_T_HE_80,
|
||||
DP_CMN_MOD_IEEE80211_T_HE_160,
|
||||
DP_CMN_MOD_IEEE80211_T_MAX_PHY
|
||||
};
|
||||
|
||||
/* more common nomenclature */
|
||||
#define DP_CMN_MOD_IEEE80211_T_CCK DP_CMN_MOD_IEEE80211_T_DS
|
||||
|
||||
enum HW_RATECODE_PREAM_TYPE {
|
||||
HW_RATECODE_PREAM_OFDM,
|
||||
HW_RATECODE_PREAM_CCK,
|
||||
HW_RATECODE_PREAM_HT,
|
||||
HW_RATECODE_PREAM_VHT,
|
||||
};
|
||||
|
||||
enum DP_CMN_MODULATION_TYPE dp_getmodulation(
|
||||
uint16_t pream_type,
|
||||
uint8_t width);
|
||||
|
||||
uint32_t
|
||||
dp_getrateindex(uint32_t gi, uint16_t mcs, uint8_t nss, uint8_t preamble,
|
||||
uint8_t bw, uint32_t *rix, uint16_t *ratecode);
|
||||
|
||||
int dp_rate_idx_to_kbps(uint8_t rate_idx, uint8_t gintval);
|
||||
|
||||
#endif /*_DP_RATES_H_*/
|
||||
117
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_bus.h
Normal file
117
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_bus.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_bus.h
|
||||
* @brief Define the host data path bus related functions
|
||||
*/
|
||||
#ifndef _CDP_TXRX_BUS_H_
|
||||
#define _CDP_TXRX_BUS_H_
|
||||
|
||||
/**
|
||||
* cdp_bus_suspend() - suspend bus
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of dp pdev handle
|
||||
*
|
||||
* suspend bus
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS suspend is not implemented or suspend done
|
||||
*/
|
||||
static inline QDF_STATUS cdp_bus_suspend(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->bus_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->bus_ops->bus_suspend)
|
||||
return soc->ops->bus_ops->bus_suspend(soc, pdev_id);
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_bus_resume() - resume bus
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of dp pdev handle
|
||||
*
|
||||
* resume bus
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS resume is not implemented or suspend done
|
||||
*/
|
||||
static inline QDF_STATUS cdp_bus_resume(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->bus_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->bus_ops->bus_resume)
|
||||
return soc->ops->bus_ops->bus_resume(soc, pdev_id);
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_process_wow_ack() - Process wow ack response
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of dp pdev handle
|
||||
*
|
||||
* Do any required data path operations for target wow ack
|
||||
* suspend response.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void cdp_process_wow_ack_rsp(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->bus_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->bus_ops->process_wow_ack_rsp)
|
||||
return soc->ops->bus_ops->process_wow_ack_rsp(soc, pdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_process_target_suspend_req() - Process target suspend request
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of dp pdev handle
|
||||
*
|
||||
* Complete the datapath specific work before target suspend
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void cdp_process_target_suspend_req(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->bus_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->bus_ops->process_target_suspend_req)
|
||||
return soc->ops->bus_ops->process_target_suspend_req(soc,
|
||||
pdev_id);
|
||||
}
|
||||
#endif /* _CDP_TXRX_BUS_H_ */
|
||||
418
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cfg.h
Normal file
418
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cfg.h
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_cfg.h
|
||||
* @brief Define the host data path configuration API functions
|
||||
*/
|
||||
#ifndef _CDP_TXRX_CFG_H_
|
||||
#define _CDP_TXRX_CFG_H_
|
||||
#include "cdp_txrx_handle.h"
|
||||
/**
|
||||
* cdp_cfg_set_rx_fwd_disabled() - enable/disable rx forwarding
|
||||
* @soc - data path soc handle
|
||||
* @pdev - data path device instance
|
||||
* @disable_rx_fwd - enable or disable rx forwarding
|
||||
*
|
||||
* enable/disable rx forwarding
|
||||
*
|
||||
* return NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_set_rx_fwd_disabled(ol_txrx_soc_handle soc, struct cdp_cfg *cfg_pdev,
|
||||
uint8_t disable_rx_fwd)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_cfg_rx_fwd_disabled)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_cfg_rx_fwd_disabled(cfg_pdev,
|
||||
disable_rx_fwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_set_packet_log_enabled() - enable/disable packet log
|
||||
* @soc - data path soc handle
|
||||
* @pdev - data path device instance
|
||||
* @val - enable or disable packet log
|
||||
*
|
||||
* packet log enable or disable
|
||||
*
|
||||
* return NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_set_packet_log_enabled(ol_txrx_soc_handle soc,
|
||||
struct cdp_cfg *cfg_pdev, uint8_t val)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_cfg_packet_log_enabled)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_cfg_packet_log_enabled(cfg_pdev,
|
||||
val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_attach() - attach config module
|
||||
* @soc - data path soc handle
|
||||
* @osdev - os instance
|
||||
* @cfg_param - configuration parameter should be propagated
|
||||
*
|
||||
* Allocate configuration module instance, and propagate configuration values
|
||||
*
|
||||
* return soc configuration module instance
|
||||
*/
|
||||
static inline struct cdp_cfg
|
||||
*cdp_cfg_attach(ol_txrx_soc_handle soc,
|
||||
qdf_device_t osdev, void *cfg_param)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->cfg_attach)
|
||||
return NULL;
|
||||
|
||||
return soc->ops->cfg_ops->cfg_attach(osdev, cfg_param);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_vdev_rx_set_intrabss_fwd() - enable/disable intra bass forwarding
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface id
|
||||
* @val - enable or disable intra bss forwarding
|
||||
*
|
||||
* ap isolate, do not forward intra bss traffic
|
||||
*
|
||||
* return NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_vdev_rx_set_intrabss_fwd(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, bool val)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->vdev_rx_set_intrabss_fwd)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->vdev_rx_set_intrabss_fwd(soc, vdev_id, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_is_rx_fwd_disabled() - get vdev rx forward
|
||||
* @soc - data path soc handle
|
||||
* @vdev - virtual interface instance
|
||||
*
|
||||
* Return rx forward feature enable status
|
||||
*
|
||||
* return 1 enabled
|
||||
* 0 disabled
|
||||
*/
|
||||
static inline uint8_t
|
||||
cdp_cfg_is_rx_fwd_disabled(ol_txrx_soc_handle soc, struct cdp_vdev *vdev)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->is_rx_fwd_disabled)
|
||||
return 0;
|
||||
|
||||
return soc->ops->cfg_ops->is_rx_fwd_disabled(vdev);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_tx_set_is_mgmt_over_wmi_enabled() - mgmt tx over wmi enable/disable
|
||||
* @soc - data path soc handle
|
||||
* @value - feature enable or disable
|
||||
*
|
||||
* Enable or disable management packet TX over WMI feature
|
||||
*
|
||||
* return None
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_tx_set_is_mgmt_over_wmi_enabled(ol_txrx_soc_handle soc,
|
||||
uint8_t value)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->tx_set_is_mgmt_over_wmi_enabled)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->tx_set_is_mgmt_over_wmi_enabled(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_is_high_latency() - query data path is in high or low latency
|
||||
* @soc - data path soc handle
|
||||
* @pdev - data path device instance
|
||||
*
|
||||
* query data path is in high or low latency
|
||||
*
|
||||
* return 1 high latency data path, usb or sdio
|
||||
* 0 low latency data path
|
||||
*/
|
||||
static inline int
|
||||
cdp_cfg_is_high_latency(ol_txrx_soc_handle soc, struct cdp_cfg *cfg_pdev)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->is_high_latency)
|
||||
return 0;
|
||||
|
||||
return soc->ops->cfg_ops->is_high_latency(cfg_pdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_set_flow_control_parameters() - set flow control params
|
||||
* @soc - data path soc handle
|
||||
* @cfg - dp config module instance
|
||||
* @param - parameters should set
|
||||
*
|
||||
* set flow control params
|
||||
*
|
||||
* return None
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_set_flow_control_parameters(ol_txrx_soc_handle soc,
|
||||
struct cdp_cfg *cfg_pdev, void *param)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_flow_control_parameters)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_flow_control_parameters(cfg_pdev,
|
||||
param);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_set_flow_steering - Set Rx flow steering config based on CFG ini
|
||||
* config.
|
||||
*
|
||||
* @pdev - handle to the physical device
|
||||
* @val - 0 - disable, 1 - enable
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void cdp_cfg_set_flow_steering(ol_txrx_soc_handle soc,
|
||||
struct cdp_cfg *cfg_pdev, uint8_t val)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_flow_steering)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_flow_steering(cfg_pdev, val);
|
||||
}
|
||||
|
||||
static inline void cdp_cfg_get_max_peer_id(ol_txrx_soc_handle soc,
|
||||
struct cdp_cfg *cfg_pdev)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_set_ptp_rx_opt_enabled() - enable/disable ptp rx timestamping
|
||||
* @soc - data path soc handle
|
||||
* @pdev - data path device instance
|
||||
* @val - enable or disable packet log
|
||||
*
|
||||
* ptp rx timestamping enable or disable
|
||||
*
|
||||
* return NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_set_ptp_rx_opt_enabled(ol_txrx_soc_handle soc,
|
||||
struct cdp_cfg *cfg_pdev, uint8_t val)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_ptp_rx_opt_enabled)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_ptp_rx_opt_enabled(cfg_pdev, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_set_new_htt_msg_format() - set htt h2t msg feature
|
||||
* @soc - datapath soc handle
|
||||
* @val - enable or disable new htt h2t msg feature
|
||||
*
|
||||
* Enable whether htt h2t message length includes htc header length
|
||||
*
|
||||
* return NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_set_new_htt_msg_format(ol_txrx_soc_handle soc,
|
||||
uint8_t val)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_new_htt_msg_format)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_new_htt_msg_format(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_set_peer_unmap_conf_support() - set peer unmap conf feature
|
||||
* @soc - datapath soc handle
|
||||
* @val - enable or disable peer unmap conf feature
|
||||
*
|
||||
* Set if peer unmap confirmation feature is supported by both FW and in INI
|
||||
*
|
||||
* return NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_cfg_set_peer_unmap_conf_support(ol_txrx_soc_handle soc, bool val)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_peer_unmap_conf_support)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_peer_unmap_conf_support(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_cfg_get_peer_unmap_conf_support() - check peer unmap conf feature
|
||||
* @soc - datapath soc handle
|
||||
*
|
||||
* Check if peer unmap confirmation feature is enabled
|
||||
*
|
||||
* return true is peer unmap confirmation feature is enabled else false
|
||||
*/
|
||||
static inline bool
|
||||
cdp_cfg_get_peer_unmap_conf_support(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->get_peer_unmap_conf_support)
|
||||
return false;
|
||||
|
||||
return soc->ops->cfg_ops->get_peer_unmap_conf_support();
|
||||
}
|
||||
|
||||
static inline void
|
||||
cdp_cfg_set_tx_compl_tsf64(ol_txrx_soc_handle soc,
|
||||
uint8_t val)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
dp_debug("invalid instance");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->set_tx_compl_tsf64)
|
||||
return;
|
||||
|
||||
soc->ops->cfg_ops->set_tx_compl_tsf64(val);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
cdp_cfg_get_tx_compl_tsf64(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
dp_debug("invalid instance");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soc->ops->cfg_ops ||
|
||||
!soc->ops->cfg_ops->get_tx_compl_tsf64)
|
||||
return false;
|
||||
|
||||
return soc->ops->cfg_ops->get_tx_compl_tsf64();
|
||||
}
|
||||
|
||||
#endif /* _CDP_TXRX_CFG_H_ */
|
||||
2733
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn.h
Normal file
2733
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn.h
Normal file
File diff suppressed because it is too large
Load diff
138
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_reg.h
Normal file
138
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_reg.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_cmn.h
|
||||
* @brief Define the host data path converged API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_CMN_REG_H_
|
||||
#define _CDP_TXRX_CMN_REG_H_
|
||||
|
||||
#include "hif_main.h"
|
||||
|
||||
#define MOB_DRV_LEGACY_DP 0xdeed/*FIXME Add MCL device IDs */
|
||||
#define LITHIUM_DP 0xfffd/*FIXME Add Litium device ID */
|
||||
/* Use these device IDs for attach in future */
|
||||
|
||||
#if defined(DP_TXRX_SOC_ATTACH)
|
||||
static inline ol_txrx_soc_handle
|
||||
ol_txrx_soc_attach(void *scn_handle, struct ol_if_ops *dp_ol_if_ops)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
ol_txrx_soc_handle
|
||||
ol_txrx_soc_attach(void *scn_handle, struct ol_if_ops *dp_ol_if_ops);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_soc_attach_wifi3() - Attach txrx SOC
|
||||
* @ctrl_psoc: Opaque SOC handle from Ctrl plane
|
||||
* @htc_handle: Opaque HTC handle
|
||||
* @hif_handle: Opaque HIF handle
|
||||
* @qdf_osdev: QDF device
|
||||
* @ol_ops: Offload Operations
|
||||
* @device_id: Device ID
|
||||
*
|
||||
* Return: DP SOC handle on success, NULL on failure
|
||||
*/
|
||||
|
||||
/**
|
||||
* dp_soc_init_wifi3() - Initialize txrx SOC
|
||||
* @soc: Opaque DP SOC handle
|
||||
* @ctrl_psoc: Opaque SOC handle from control plane
|
||||
* @hif_handle: Opaque HIF handle
|
||||
* @htc_handle: Opaque HTC handle
|
||||
* @qdf_osdev: QDF device
|
||||
* @ol_ops: Offload Operations
|
||||
* @device_id: Device ID
|
||||
*
|
||||
* Return: DP SOC handle on success, NULL on failure
|
||||
*/
|
||||
#if defined(QCA_WIFI_QCA8074) || defined(QCA_WIFI_QCA6018) || \
|
||||
defined(QCA_WIFI_QCA5018)
|
||||
struct cdp_soc_t *
|
||||
dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
struct hif_opaque_softc *hif_handle,
|
||||
HTC_HANDLE htc_handle, qdf_device_t qdf_osdev,
|
||||
struct ol_if_ops *ol_ops, uint16_t device_id);
|
||||
void *dp_soc_init_wifi3(struct cdp_soc_t *soc,
|
||||
struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
struct hif_opaque_softc *hif_handle,
|
||||
HTC_HANDLE htc_handle, qdf_device_t qdf_osdev,
|
||||
struct ol_if_ops *ol_ops, uint16_t device_id);
|
||||
#else
|
||||
static inline struct cdp_soc_t *
|
||||
dp_soc_attach_wifi3(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
struct hif_opaque_softc *hif_handle,
|
||||
HTC_HANDLE htc_handle,
|
||||
qdf_device_t qdf_osdev,
|
||||
struct ol_if_ops *ol_ops,
|
||||
uint16_t device_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline
|
||||
void *dp_soc_init_wifi3(struct cdp_soc_t *soc,
|
||||
struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
struct hif_opaque_softc *hif_handle,
|
||||
HTC_HANDLE htc_handle, qdf_device_t qdf_osdev,
|
||||
struct ol_if_ops *ol_ops, uint16_t device_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* QCA_WIFI_QCA8074 */
|
||||
|
||||
static inline
|
||||
ol_txrx_soc_handle cdp_soc_attach(u_int16_t devid,
|
||||
struct hif_opaque_softc *hif_handle,
|
||||
struct cdp_ctrl_objmgr_psoc *psoc,
|
||||
HTC_HANDLE htc_handle,
|
||||
qdf_device_t qdf_dev,
|
||||
struct ol_if_ops *dp_ol_if_ops)
|
||||
{
|
||||
switch (devid) {
|
||||
case LITHIUM_DP: /*FIXME Add lithium devide IDs */
|
||||
case QCA8074_DEVICE_ID: /* Hawekeye */
|
||||
case QCA8074V2_DEVICE_ID: /* Hawekeye V2*/
|
||||
case QCA5018_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCN9000_DEVICE_ID:
|
||||
case QCN9100_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case QCA6750_DEVICE_ID:
|
||||
case QCA6390_EMULATION_DEVICE_ID:
|
||||
case RUMIM2M_DEVICE_ID_NODE0: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE1: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE2: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE3: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE4: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE5: /*lithium emulation */
|
||||
return dp_soc_attach_wifi3(psoc, hif_handle, htc_handle,
|
||||
qdf_dev, dp_ol_if_ops, devid);
|
||||
break;
|
||||
default:
|
||||
return ol_txrx_soc_attach(psoc, dp_ol_if_ops);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /*_CDP_TXRX_CMN_REG_H_ */
|
||||
2473
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_struct.h
Normal file
2473
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_cmn_struct.h
Normal file
File diff suppressed because it is too large
Load diff
1220
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl.h
Normal file
1220
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl.h
Normal file
File diff suppressed because it is too large
Load diff
94
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl_def.h
Normal file
94
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ctrl_def.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 2011-2016,2018-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_ctrl.h
|
||||
* @brief Define the host data path control API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
|
||||
#ifndef _CDP_TXRX_CTRL_DEF_H_
|
||||
#define _CDP_TXRX_CTRL_DEF_H_
|
||||
/* TODO: adf need to be replaced with qdf */
|
||||
/*
|
||||
* Cleanups -- Might need cleanup
|
||||
*/
|
||||
#if !QCA_OL_TX_PDEV_LOCK && QCA_NSS_PLATFORM || \
|
||||
(defined QCA_PARTNER_PLATFORM && QCA_PARTNER_SUPPORT_FAST_TX)
|
||||
#define VAP_TX_SPIN_LOCK(_x) spin_lock(_x)
|
||||
#define VAP_TX_SPIN_UNLOCK(_x) spin_unlock(_x)
|
||||
#else /* QCA_OL_TX_PDEV_LOCK */
|
||||
#define VAP_TX_SPIN_LOCK(_x)
|
||||
#define VAP_TX_SPIN_UNLOCK(_x)
|
||||
#endif /* QCA_OL_TX_PDEV_LOCK */
|
||||
|
||||
#if QCA_OL_TX_PDEV_LOCK
|
||||
void ol_ll_pdev_tx_lock(void *);
|
||||
void ol_ll_pdev_tx_unlock(void *);
|
||||
#define OL_TX_LOCK(_x) ol_ll_pdev_tx_lock(_x)
|
||||
#define OL_TX_UNLOCK(_x) ol_ll_pdev_tx_unlock(_x)
|
||||
|
||||
#define OL_TX_PDEV_LOCK(_x) qdf_spin_lock_bh(_x)
|
||||
#define OL_TX_PDEV_UNLOCK(_x) qdf_spin_unlock_bh(_x)
|
||||
#else
|
||||
#define OL_TX_PDEV_LOCK(_x)
|
||||
#define OL_TX_PDEV_UNLOCK(_x)
|
||||
|
||||
#define OL_TX_LOCK(_x)
|
||||
#define OL_TX_UNLOCK(_x)
|
||||
#endif /* QCA_OL_TX_PDEV_LOCK */
|
||||
|
||||
#if !QCA_OL_TX_PDEV_LOCK
|
||||
#define OL_TX_FLOW_CTRL_LOCK(_x) qdf_spin_lock_bh(_x)
|
||||
#define OL_TX_FLOW_CTRL_UNLOCK(_x) qdf_spin_unlock_bh(_x)
|
||||
|
||||
#define OL_TX_DESC_LOCK(_x) qdf_spin_lock_bh(_x)
|
||||
#define OL_TX_DESC_UNLOCK(_x) qdf_spin_unlock_bh(_x)
|
||||
|
||||
#define OSIF_VAP_TX_LOCK(_y, _x) spin_lock(&((_x)->tx_lock))
|
||||
#define OSIF_VAP_TX_UNLOCK(_y, _x) spin_unlock(&((_x)->tx_lock))
|
||||
|
||||
#define OL_TX_PEER_LOCK(_x, _id) qdf_spin_lock_bh(&((_x)->peer_lock[_id]))
|
||||
#define OL_TX_PEER_UNLOCK(_x, _id) qdf_spin_unlock_bh(&((_x)->peer_lock[_id]))
|
||||
|
||||
#define OL_TX_PEER_UPDATE_LOCK(_x, _id) \
|
||||
qdf_spin_lock_bh(&((_x)->peer_lock[_id]))
|
||||
#define OL_TX_PEER_UPDATE_UNLOCK(_x, _id) \
|
||||
qdf_spin_unlock_bh(&((_x)->peer_lock[_id]))
|
||||
|
||||
#else
|
||||
#define OSIF_VAP_TX_LOCK(_y, _x) cdp_vdev_tx_lock( \
|
||||
_y, wlan_vdev_get_id((_x)->ctrl_vdev))
|
||||
#define OSIF_VAP_TX_UNLOCK(_y, _x) cdp_vdev_tx_unlock( \
|
||||
_y, wlan_vdev_get_id((_x)->ctrl_vdev))
|
||||
|
||||
#define OL_TX_FLOW_CTRL_LOCK(_x)
|
||||
#define OL_TX_FLOW_CTRL_UNLOCK(_x)
|
||||
|
||||
#define OL_TX_DESC_LOCK(_x)
|
||||
#define OL_TX_DESC_UNLOCK(_x)
|
||||
|
||||
#define OL_TX_PEER_LOCK(_x, _id)
|
||||
#define OL_TX_PEER_UNLOCK(_x, _id)
|
||||
|
||||
#define OL_TX_PEER_UPDATE_LOCK(_x, _id) qdf_spin_lock_bh(&((_x)->tx_lock))
|
||||
#define OL_TX_PEER_UPDATE_UNLOCK(_x, _id) qdf_spin_unlock_bh(&((_x)->tx_lock))
|
||||
|
||||
#endif /* !QCA_OL_TX_PDEV_LOCK */
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_flow_ctrl_legacy.h
|
||||
* @brief Define the host data path legacy flow control API
|
||||
* functions
|
||||
*/
|
||||
#ifndef _CDP_TXRX_FC_LEG_H_
|
||||
#define _CDP_TXRX_FC_LEG_H_
|
||||
#include <cdp_txrx_mob_def.h>
|
||||
#include "cdp_txrx_handle.h"
|
||||
|
||||
#ifdef QCA_HL_NETDEV_FLOW_CONTROL
|
||||
|
||||
/**
|
||||
* cdp_hl_fc_register() - Register HL flow control callback.
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: datapath pdev identifier
|
||||
* @flowcontrol: callback function pointer to stop/start OS netdev queues
|
||||
*
|
||||
* Register flow control callback.
|
||||
*
|
||||
* Returns: 0 for success
|
||||
*/
|
||||
static inline int
|
||||
cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
tx_pause_callback flowcontrol)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->register_tx_flow_control)
|
||||
return -EINVAL;
|
||||
|
||||
return soc->ops->l_flowctl_ops->register_tx_flow_control(soc, pdev_id,
|
||||
flowcontrol);
|
||||
}
|
||||
|
||||
static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, uint32_t chan_freq)
|
||||
{
|
||||
if (!soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit)
|
||||
return 0;
|
||||
|
||||
return soc->ops->l_flowctl_ops->set_vdev_tx_desc_limit(soc, vdev_id,
|
||||
chan_freq);
|
||||
}
|
||||
|
||||
static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
enum netif_action_type action)
|
||||
{
|
||||
if (!soc->ops->l_flowctl_ops->set_vdev_os_queue_status)
|
||||
return -EINVAL;
|
||||
|
||||
return soc->ops->l_flowctl_ops->set_vdev_os_queue_status(soc,
|
||||
vdev_id,
|
||||
action);
|
||||
}
|
||||
#else
|
||||
static inline int
|
||||
cdp_hl_fc_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
tx_pause_callback flowcontrol)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cdp_hl_fc_set_td_limit(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, uint32_t chan_freq)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cdp_hl_fc_set_os_queue_status(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
enum netif_action_type action)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
|
||||
|
||||
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
|
||||
/**
|
||||
* cdp_fc_register() - Register flow control callback function pointer
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface id to register flow control
|
||||
* @flowControl - callback function pointer
|
||||
* @osif_fc_ctx - client context pointer
|
||||
* @flow_control_is_pause: is vdev paused by flow control
|
||||
*
|
||||
* Register flow control callback function pointer and client context pointer
|
||||
*
|
||||
* return 0 success
|
||||
*/
|
||||
static inline int
|
||||
cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx,
|
||||
ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->register_tx_flow_control)
|
||||
return 0;
|
||||
|
||||
return soc->ops->l_flowctl_ops->register_tx_flow_control(
|
||||
soc, vdev_id, flowcontrol, osif_fc_ctx,
|
||||
flow_control_is_pause);
|
||||
}
|
||||
#else
|
||||
static inline int
|
||||
cdp_fc_register(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
ol_txrx_tx_flow_control_fp flowcontrol, void *osif_fc_ctx,
|
||||
ol_txrx_tx_flow_control_is_pause_fp flow_control_is_pause)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* QCA_LL_LEGACY_TX_FLOW_CONTROL */
|
||||
/**
|
||||
* cdp_fc_deregister() - remove flow control instance
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface id to register flow control
|
||||
*
|
||||
* remove flow control instance
|
||||
*
|
||||
* return 0 success
|
||||
*/
|
||||
static inline int
|
||||
cdp_fc_deregister(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb)
|
||||
return 0;
|
||||
|
||||
return soc->ops->l_flowctl_ops->deregister_tx_flow_control_cb(
|
||||
soc, vdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_fc_get_tx_resource() - get data path resource count
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: datapath pdev ID
|
||||
* @peer_addr: peer mac address
|
||||
* @low_watermark: low resource threshold
|
||||
* @high_watermark_offset: high resource threshold
|
||||
*
|
||||
* get data path resource count
|
||||
*
|
||||
* return true enough data path resource available
|
||||
* false resource is not avaialbe
|
||||
*/
|
||||
static inline bool
|
||||
cdp_fc_get_tx_resource(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
struct qdf_mac_addr peer_addr,
|
||||
unsigned int low_watermark,
|
||||
unsigned int high_watermark_offset)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->get_tx_resource)
|
||||
return false;
|
||||
|
||||
return soc->ops->l_flowctl_ops->get_tx_resource(soc, pdev_id, peer_addr,
|
||||
low_watermark,
|
||||
high_watermark_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_fc_ll_set_tx_pause_q_depth() - set pause queue depth
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface id to register flow control
|
||||
* @pause_q_depth - pending tx queue delth
|
||||
*
|
||||
* set pause queue depth
|
||||
*
|
||||
* return 0 success
|
||||
*/
|
||||
static inline int
|
||||
cdp_fc_ll_set_tx_pause_q_depth(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, int pause_q_depth)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth)
|
||||
return 0;
|
||||
|
||||
return soc->ops->l_flowctl_ops->ll_set_tx_pause_q_depth(
|
||||
soc, vdev_id, pause_q_depth);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_fc_vdev_flush() - flush tx queue
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: id of vdev
|
||||
*
|
||||
* flush tx queue
|
||||
*
|
||||
* return None
|
||||
*/
|
||||
static inline void
|
||||
cdp_fc_vdev_flush(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->vdev_flush)
|
||||
return;
|
||||
|
||||
soc->ops->l_flowctl_ops->vdev_flush(soc, vdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_fc_vdev_pause() - pause tx scheduler on vdev
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: id of vdev
|
||||
* @reason: pause reason
|
||||
* @pause_type: type of pause
|
||||
*
|
||||
* pause tx scheduler on vdev
|
||||
*
|
||||
* return None
|
||||
*/
|
||||
static inline void
|
||||
cdp_fc_vdev_pause(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint32_t reason, uint32_t pause_type)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->vdev_pause)
|
||||
return;
|
||||
|
||||
soc->ops->l_flowctl_ops->vdev_pause(soc, vdev_id, reason, pause_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_fc_vdev_unpause() - resume tx scheduler on vdev
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: id of vdev
|
||||
* @reason: pause reason
|
||||
* @pause_type: type of pause
|
||||
*
|
||||
* resume tx scheduler on vdev
|
||||
*
|
||||
* return None
|
||||
*/
|
||||
static inline void
|
||||
cdp_fc_vdev_unpause(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint32_t reason, uint32_t pause_type)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->l_flowctl_ops ||
|
||||
!soc->ops->l_flowctl_ops->vdev_unpause)
|
||||
return;
|
||||
|
||||
soc->ops->l_flowctl_ops->vdev_unpause(soc, vdev_id, reason,
|
||||
pause_type);
|
||||
}
|
||||
#endif /* _CDP_TXRX_FC_LEG_H_ */
|
||||
132
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_v2.h
Normal file
132
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_flow_ctrl_v2.h
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_flow_ctrl_v2.h
|
||||
* @brief Define the host data path flow control version 2 API
|
||||
* functions
|
||||
*/
|
||||
#ifndef _CDP_TXRX_FC_V2_H_
|
||||
#define _CDP_TXRX_FC_V2_H_
|
||||
#include <cdp_txrx_ops.h>
|
||||
|
||||
/**
|
||||
* cdp_register_pause_cb() - Register flow control callback function pointer
|
||||
* @soc - data path soc handle
|
||||
* @pause_cb - Pause callback intend to register
|
||||
*
|
||||
* Register flow control callback function pointer and client context pointer
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS success
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_register_pause_cb(ol_txrx_soc_handle soc,
|
||||
tx_pause_callback pause_cb)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (!soc->ops->flowctl_ops ||
|
||||
!soc->ops->flowctl_ops->register_pause_cb)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
return soc->ops->flowctl_ops->register_pause_cb(soc, pause_cb);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_set_desc_global_pool_size() - set global device pool size
|
||||
* @soc - data path soc handle
|
||||
* @num_msdu_desc - descriptor pool size
|
||||
*
|
||||
* set global device pool size
|
||||
*
|
||||
* return none
|
||||
*/
|
||||
static inline void
|
||||
cdp_set_desc_global_pool_size(ol_txrx_soc_handle soc,
|
||||
uint32_t num_msdu_desc)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->flowctl_ops ||
|
||||
!soc->ops->flowctl_ops->set_desc_global_pool_size)
|
||||
return;
|
||||
|
||||
soc->ops->flowctl_ops->set_desc_global_pool_size(
|
||||
num_msdu_desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_dump_flow_pool_info() - dump flow pool information
|
||||
* @soc - data path soc handle
|
||||
*
|
||||
* dump flow pool information
|
||||
*
|
||||
* return none
|
||||
*/
|
||||
static inline void
|
||||
cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->flowctl_ops ||
|
||||
!soc->ops->flowctl_ops->dump_flow_pool_info)
|
||||
return;
|
||||
|
||||
soc->ops->flowctl_ops->dump_flow_pool_info(soc);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_tx_desc_thresh_reached() - Check if avail tx desc meet threshold
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: vdev_id corresponding to vdev start
|
||||
*
|
||||
* Return: true if threshold is met, false if not
|
||||
*/
|
||||
static inline bool
|
||||
cdp_tx_desc_thresh_reached(struct cdp_soc_t *soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!soc->ops->flowctl_ops ||
|
||||
!soc->ops->flowctl_ops->tx_desc_thresh_reached)
|
||||
return false;
|
||||
|
||||
return soc->ops->flowctl_ops->tx_desc_thresh_reached(soc, vdev_id);
|
||||
}
|
||||
#endif /* _CDP_TXRX_FC_V2_H_ */
|
||||
65
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_handle.h
Normal file
65
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_handle.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_handle.h
|
||||
* @brief Holds the forward structure declarations for handles
|
||||
* passed from the upper layers
|
||||
*/
|
||||
|
||||
#ifndef CDP_TXRX_HANDLE_H
|
||||
#define CDP_TXRX_HANDLE_H
|
||||
|
||||
struct cdp_cfg;
|
||||
struct cdp_pdev;
|
||||
struct cdp_vdev;
|
||||
struct cdp_peer;
|
||||
struct cdp_raw_ast;
|
||||
struct cdp_soc;
|
||||
|
||||
/**
|
||||
* cdp_ctrl_objmgr_psoc - opaque handle for UMAC psoc object
|
||||
*/
|
||||
struct cdp_ctrl_objmgr_psoc;
|
||||
|
||||
/**
|
||||
* cdp_ctrl_objmgr_pdev - opaque handle for UMAC pdev object
|
||||
*/
|
||||
struct cdp_ctrl_objmgr_pdev;
|
||||
|
||||
/**
|
||||
* cdp_ctrl_objmgr_vdev - opaque handle for UMAC vdev object
|
||||
*/
|
||||
struct cdp_ctrl_objmgr_vdev;
|
||||
|
||||
/**
|
||||
* cdp_ctrl_objmgr_peer - opaque handle for UMAC peer object
|
||||
*/
|
||||
struct cdp_ctrl_objmgr_peer;
|
||||
|
||||
/**
|
||||
* cdp_cal_client - opaque handle for cal client object
|
||||
*/
|
||||
struct cdp_cal_client;
|
||||
|
||||
/**
|
||||
* cdp_ext_vdev - opaque handle for extended vdev data path handle
|
||||
*/
|
||||
struct cdp_ext_vdev;
|
||||
#endif
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_hist_struct.h
|
||||
* @brief Define the host data path histogram data types
|
||||
*/
|
||||
#ifndef _CDP_TXRX_HIST_STRUCT_H_
|
||||
#define _CDP_TXRX_HIST_STRUCT_H_
|
||||
|
||||
/*
|
||||
* cdp_hist_bucket_index : Histogram Bucket
|
||||
* @CDP_HIST_BUCKET_0: Bucket Index 0
|
||||
* @CDP_HIST_BUCKET_1: Bucket Index 1
|
||||
* @CDP_HIST_BUCKET_2: Bucket Index 2
|
||||
* @CDP_HIST_BUCKET_3: Bucket Index 3
|
||||
* @CDP_HIST_BUCKET_4: Bucket Index 4
|
||||
* @CDP_HIST_BUCKET_5: Bucket Index 5
|
||||
* @CDP_HIST_BUCKET_6: Bucket Index 6
|
||||
* @CDP_HIST_BUCKET_7: Bucket Index 7
|
||||
* @CDP_HIST_BUCKET_8: Bucket Index 8
|
||||
* @CDP_HIST_BUCKET_9: Bucket Index 9
|
||||
*/
|
||||
enum cdp_hist_bucket_index {
|
||||
CDP_HIST_BUCKET_0,
|
||||
CDP_HIST_BUCKET_1,
|
||||
CDP_HIST_BUCKET_2,
|
||||
CDP_HIST_BUCKET_3,
|
||||
CDP_HIST_BUCKET_4,
|
||||
CDP_HIST_BUCKET_5,
|
||||
CDP_HIST_BUCKET_6,
|
||||
CDP_HIST_BUCKET_7,
|
||||
CDP_HIST_BUCKET_8,
|
||||
CDP_HIST_BUCKET_9,
|
||||
CDP_HIST_BUCKET_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* cdp_hist_types: Histogram Types
|
||||
* @CDP_HIST_TYPE_SW_ENQEUE_DELAY: From stack to HW enqueue delay
|
||||
* @CDP_HIST_TYPE_HW_COMP_DELAY: From HW enqueue to completion delay
|
||||
* @CDP_HIST_TYPE_REAP_STACK: Rx HW reap to stack deliver delay
|
||||
*/
|
||||
enum cdp_hist_types {
|
||||
CDP_HIST_TYPE_SW_ENQEUE_DELAY,
|
||||
CDP_HIST_TYPE_HW_COMP_DELAY,
|
||||
CDP_HIST_TYPE_REAP_STACK,
|
||||
CDP_HIST_TYPE_MAX,
|
||||
};
|
||||
|
||||
/*
|
||||
* cdp_hist_bucket: Histogram Bucket
|
||||
* @hist_type: Histogram type
|
||||
* @freq: Frequency
|
||||
*/
|
||||
struct cdp_hist_bucket {
|
||||
enum cdp_hist_types hist_type;
|
||||
uint64_t freq[CDP_HIST_BUCKET_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
* cdp_hist_stats : Histogram of a stats type
|
||||
* @hist: Frequency distribution
|
||||
* @max: Max frequency
|
||||
* @min: Minimum frequency
|
||||
* @avg: Average frequency
|
||||
*/
|
||||
struct cdp_hist_stats {
|
||||
struct cdp_hist_bucket hist;
|
||||
int max;
|
||||
int min;
|
||||
int avg;
|
||||
};
|
||||
#endif /* _CDP_TXRX_HIST_STRUCT_H_ */
|
||||
742
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_host_stats.h
Normal file
742
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_host_stats.h
Normal file
|
|
@ -0,0 +1,742 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_host_stats.h
|
||||
* @brief Define the host data path stats API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_HOST_STATS_H_
|
||||
#define _CDP_TXRX_HOST_STATS_H_
|
||||
#include "cdp_txrx_handle.h"
|
||||
#include <wmi_unified_api.h>
|
||||
/**
|
||||
* cdp_host_stats_get: cdp call to get host stats
|
||||
* @soc: SOC handle
|
||||
* @vdev_id: vdev id of vdev
|
||||
* @req: Requirement type
|
||||
*
|
||||
* return: 0 for Success, Failure returns error message
|
||||
*/
|
||||
static inline int cdp_host_stats_get(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
struct ol_txrx_stats_req *req)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_host_stats_get)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_host_stats_get(soc, vdev_id, req);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_host_stats_get_ratekbps: cdp call to get rate in kbps
|
||||
* @soc: SOC handle
|
||||
* @preamb: Preamble
|
||||
* @mcs: Modulation and Coding scheme index
|
||||
* @htflag: Flag to identify HT or VHT
|
||||
* @gintval: Gaurd Interval value
|
||||
*
|
||||
* return: 0 for Failure, Returns rate on Success
|
||||
*/
|
||||
static inline int cdp_host_stats_get_ratekbps(ol_txrx_soc_handle soc,
|
||||
int preamb, int mcs,
|
||||
int htflag, int gintval)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_get_ratekbps)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_get_ratekbps(preamb,
|
||||
mcs, htflag,
|
||||
gintval);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_host_stats_clr: cdp call to clear host stats
|
||||
* @soc: soc handle
|
||||
* @vdev_id: vdev handle id
|
||||
*
|
||||
* return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_host_stats_clr(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_host_stats_clr)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_host_stats_clr(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_host_ce_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_host_ce_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_host_ce_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline int cdp_stats_publish
|
||||
(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
struct cdp_stats_extd *buf)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_stats_publish)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_stats_publish(soc, pdev_id, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable enhanced stats functionality.
|
||||
*
|
||||
* @param soc - the soc object
|
||||
* @param pdev_id - id of the physical device object
|
||||
* @return - QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_enable_enhanced_stats(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_enable_enhanced_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_enable_enhanced_stats
|
||||
(soc, pdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable enhanced stats functionality.
|
||||
*
|
||||
* @param soc - the soc object
|
||||
* @param pdev_id - id of the physical device object
|
||||
* @return - QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_disable_enhanced_stats(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_disable_enhanced_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_disable_enhanced_stats
|
||||
(soc, pdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_tx_print_tso_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->tx_print_tso_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->tx_print_tso_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_tx_rst_tso_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->tx_rst_tso_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->tx_rst_tso_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_tx_print_sg_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->tx_print_sg_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->tx_print_sg_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_tx_rst_sg_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->tx_rst_sg_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->tx_rst_sg_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_print_rx_cksum_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->print_rx_cksum_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->print_rx_cksum_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_rst_rx_cksum_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->rst_rx_cksum_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->rst_rx_cksum_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_host_me_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_host_me_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_host_me_stats(soc, vdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_per_peer_stats(): function to print per peer REO Queue stats
|
||||
* @soc: soc handle
|
||||
* @pdev: physical device
|
||||
* @addr: peer address
|
||||
*
|
||||
* return: status
|
||||
*/
|
||||
static inline QDF_STATUS cdp_per_peer_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t *addr)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_per_peer_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_per_peer_stats(soc, addr);
|
||||
}
|
||||
|
||||
static inline int cdp_host_msdu_ttl_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
struct ol_txrx_stats_req *req)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_host_msdu_ttl_stats)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_host_msdu_ttl_stats
|
||||
(soc, vdev_id, req);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS cdp_update_peer_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, uint8_t *mac,
|
||||
void *stats,
|
||||
uint32_t last_tx_rate_mcs,
|
||||
uint32_t stats_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_update_peer_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_update_peer_stats
|
||||
(soc, vdev_id, mac, stats, last_tx_rate_mcs, stats_id);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS cdp_get_dp_fw_peer_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
uint8_t *mac, uint32_t caps,
|
||||
uint32_t copy_stats)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->get_fw_peer_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->get_fw_peer_stats
|
||||
(soc, pdev_id, mac, caps, copy_stats);
|
||||
}
|
||||
|
||||
static inline QDF_STATUS cdp_get_dp_htt_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
void *data, uint32_t data_len)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->get_htt_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->get_htt_stats(soc, pdev_id, data,
|
||||
data_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update pdev host stats received from firmware
|
||||
* (wmi_host_pdev_stats and wmi_host_pdev_ext_stats) into dp
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param pdev_id - id of the physical device object
|
||||
* @param data - pdev stats
|
||||
* @return - QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_update_pdev_host_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
void *data,
|
||||
uint16_t stats_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_update_pdev_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_update_pdev_stats(soc, pdev_id,
|
||||
data,
|
||||
stats_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update vdev host stats
|
||||
*
|
||||
* @soc: soc handle
|
||||
* @vdev_id: id of the virtual device object
|
||||
* @data: pdev stats
|
||||
* @stats_id: type of stats
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_update_vdev_host_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
void *data,
|
||||
uint16_t stats_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_update_vdev_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_update_vdev_stats(soc, vdev_id,
|
||||
data,
|
||||
stats_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to get specified peer stats
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param vdev_id - vdev_id of vdev object
|
||||
* @param peer_mac - mac address of the peer
|
||||
* @param type - enum of required stats
|
||||
* @param buf - buffer to hold the value
|
||||
* @return - QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_txrx_get_peer_stats_param(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_mac,
|
||||
enum cdp_peer_stats_type type,
|
||||
cdp_peer_stats_param_t *buf)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_get_peer_stats_param)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_get_peer_stats_param(soc,
|
||||
vdev_id,
|
||||
peer_mac,
|
||||
type,
|
||||
buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to get peer stats
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param vdev_id - vdev_id of vdev object
|
||||
* @param peer_mac - mac address of the peer
|
||||
* @return - struct cdp_peer_stats
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_host_get_peer_stats(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_mac,
|
||||
struct cdp_peer_stats *peer_stats)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_get_peer_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_get_peer_stats(soc, vdev_id,
|
||||
peer_mac,
|
||||
peer_stats);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to reset ald stats
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param vdev_id - vdev_id of vdev object
|
||||
* @param peer_mac - mac address of the peer
|
||||
* @return - void
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_host_reset_peer_ald_stats(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_mac)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_reset_peer_ald_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_reset_peer_ald_stats(soc,
|
||||
vdev_id,
|
||||
peer_mac);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to reset peer stats
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param vdev_id - vdev_id of vdev object
|
||||
* @param peer_mac - mac address of the peer
|
||||
* @return - QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_host_reset_peer_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, uint8_t *peer_mac)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_reset_peer_stats)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_reset_peer_stats(soc,
|
||||
vdev_id,
|
||||
peer_mac);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to get vdev stats
|
||||
*
|
||||
* @param soc - dp soc object
|
||||
* @param vdev_id - id of dp vdev object
|
||||
* @param buf - buffer
|
||||
* @return - int
|
||||
*/
|
||||
static inline int
|
||||
cdp_host_get_vdev_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
struct cdp_vdev_stats *buf,
|
||||
bool is_aggregate)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_get_vdev_stats)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_get_vdev_stats(soc, vdev_id,
|
||||
buf,
|
||||
is_aggregate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to update vdev stats received from firmware
|
||||
* (wmi_host_vdev_stats and wmi_host_vdev_extd_stats) into dp
|
||||
*
|
||||
* @param data - stats data to be updated
|
||||
* @param size - size of stats data
|
||||
* @param stats_id - stats id
|
||||
* @return - int
|
||||
*/
|
||||
static inline int
|
||||
cdp_update_host_vdev_stats(ol_txrx_soc_handle soc,
|
||||
void *data,
|
||||
uint32_t size,
|
||||
uint32_t stats_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_process_wmi_host_vdev_stats)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_process_wmi_host_vdev_stats
|
||||
(soc,
|
||||
data,
|
||||
size,
|
||||
stats_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to get vdev extd stats
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param vdev_id - id of dp vdev object
|
||||
* @param buf - buffer
|
||||
* @return - int
|
||||
*/
|
||||
static inline int
|
||||
cdp_get_vdev_extd_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
wmi_host_vdev_extd_stats *buf)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_get_vdev_extd_stats)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_get_vdev_extd_stats(soc, vdev_id,
|
||||
buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to get cdp_pdev_stats
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param pdev_id - id of dp pdev object
|
||||
* @param buf - buffer to hold cdp_pdev_stats
|
||||
* @return - success/failure
|
||||
*/
|
||||
static inline int
|
||||
cdp_host_get_pdev_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id, struct cdp_pdev_stats *buf)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_get_pdev_stats)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_get_pdev_stats(soc, pdev_id, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Call to get radio stats
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param pdev_id - id of dp pdev object
|
||||
* @param scn_stats_user - stats buffer
|
||||
* @return - int
|
||||
*/
|
||||
static inline int
|
||||
cdp_host_get_radio_stats(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
void *buf)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->host_stats_ops ||
|
||||
!soc->ops->host_stats_ops->txrx_get_radio_stats)
|
||||
return 0;
|
||||
|
||||
return soc->ops->host_stats_ops->txrx_get_radio_stats(soc, pdev_id,
|
||||
buf);
|
||||
}
|
||||
#endif /* _CDP_TXRX_HOST_STATS_H_ */
|
||||
689
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ipa.h
Normal file
689
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ipa.h
Normal file
|
|
@ -0,0 +1,689 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_ipa.h
|
||||
* @brief Define the host data path IP Acceleraor API functions
|
||||
*/
|
||||
#ifndef _CDP_TXRX_IPA_H_
|
||||
#define _CDP_TXRX_IPA_H_
|
||||
|
||||
#ifdef IPA_OFFLOAD
|
||||
#ifdef CONFIG_IPA_WDI_UNIFIED_API
|
||||
#include <qdf_ipa_wdi3.h>
|
||||
#else
|
||||
#include <qdf_ipa.h>
|
||||
#endif
|
||||
#include <cdp_txrx_cmn.h>
|
||||
#include "cdp_txrx_handle.h"
|
||||
|
||||
/**
|
||||
* cdp_ipa_get_resource() - Get allocated WLAN resources for IPA data path
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Get allocated WLAN resources for IPA data path
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_get_resource(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_get_resource)
|
||||
return soc->ops->ipa_ops->ipa_get_resource(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_set_doorbell_paddr() - give IPA db paddr to FW
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* give IPA db paddr to FW
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_set_doorbell_paddr(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_set_doorbell_paddr)
|
||||
return soc->ops->ipa_ops->ipa_set_doorbell_paddr(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_set_active() - activate/de-ctivate IPA offload path
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
* @uc_active - activate or de-activate
|
||||
* @is_tx - toggle tx or rx data path
|
||||
*
|
||||
* activate/de-ctivate IPA offload path
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_set_active(ol_txrx_soc_handle soc, uint8_t pdev_id, bool uc_active,
|
||||
bool is_tx)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_set_active)
|
||||
return soc->ops->ipa_ops->ipa_set_active(soc, pdev_id,
|
||||
uc_active, is_tx);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_op_response() - event handler from FW
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
* @op_msg - event contents from firmware
|
||||
*
|
||||
* event handler from FW
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_op_response(ol_txrx_soc_handle soc, uint8_t pdev_id, uint8_t *op_msg)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_op_response)
|
||||
return soc->ops->ipa_ops->ipa_op_response(soc, pdev_id, op_msg);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_register_op_cb() - register event handler function pointer
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
* @op_cb - event handler callback function pointer
|
||||
* @usr_ctxt - user context to registered
|
||||
*
|
||||
* register event handler function pointer
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_register_op_cb(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
ipa_uc_op_cb_type op_cb, void *usr_ctxt)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_register_op_cb)
|
||||
return soc->ops->ipa_ops->ipa_register_op_cb(soc, pdev_id,
|
||||
op_cb, usr_ctxt);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_deregister_op_cb() - deregister event handler function pointer
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Deregister event handler function pointer from pdev
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline
|
||||
void cdp_ipa_deregister_op_cb(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_deregister_op_cb)
|
||||
soc->ops->ipa_ops->ipa_deregister_op_cb(soc, pdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_get_stat() - get IPA data path stats from FW
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* get IPA data path stats from FW async
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_get_stat(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_get_stat)
|
||||
return soc->ops->ipa_ops->ipa_get_stat(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_tx_send_ipa_data_frame() - send IPA data frame
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id: vdev id
|
||||
* @skb: skb
|
||||
*
|
||||
* Return: skb/ NULL is for success
|
||||
*/
|
||||
static inline qdf_nbuf_t cdp_ipa_tx_send_data_frame(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
qdf_nbuf_t skb)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return skb;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_tx_data_frame)
|
||||
return soc->ops->ipa_ops->ipa_tx_data_frame(soc, vdev_id, skb);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_set_uc_tx_partition_base() - set tx packet partition base
|
||||
* @soc - data path soc handle
|
||||
* @cfg_pdev: physical device instance config
|
||||
* @value: partition base value
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_set_uc_tx_partition_base(ol_txrx_soc_handle soc,
|
||||
struct cdp_cfg *cfg_pdev, uint32_t value)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops || !cfg_pdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_set_uc_tx_partition_base)
|
||||
soc->ops->ipa_ops->ipa_set_uc_tx_partition_base(cfg_pdev,
|
||||
value);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_METERING
|
||||
/**
|
||||
* cdp_ipa_uc_get_share_stats() - get Tx/Rx byte stats from FW
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id: physical device instance number
|
||||
* @value: reset stats
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_uc_get_share_stats(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint8_t value)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_uc_get_share_stats)
|
||||
return soc->ops->ipa_ops->ipa_uc_get_share_stats(soc, pdev_id,
|
||||
value);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_uc_set_quota() - set quota limit to FW
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id: physical device instance number
|
||||
* @value: quota limit bytes
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_uc_set_quota(ol_txrx_soc_handle soc, uint8_t pdev_id, uint64_t value)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_uc_set_quota)
|
||||
return soc->ops->ipa_ops->ipa_uc_set_quota(soc, pdev_id, value);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cdp_ipa_enable_autonomy() - Enable autonomy RX data path
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: physical device instance number
|
||||
*
|
||||
* IPA Data path is enabled and resumed.
|
||||
* All autonomy data path elements are ready to deliver packet
|
||||
* All RX packet should routed to IPA_REO ring, then IPA can receive packet
|
||||
* from WLAN
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_enable_autonomy(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_enable_autonomy)
|
||||
return soc->ops->ipa_ops->ipa_enable_autonomy(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_disable_autonomy() - Disable autonomy RX data path
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: physical device instance number
|
||||
*
|
||||
* IPA Data path is enabled and resumed.
|
||||
* All autonomy datapath elements are ready to deliver packet
|
||||
* All RX packet should routed to IPA_REO ring, then IPA can receive packet
|
||||
* from WLAN
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_disable_autonomy(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
if (soc->ops->ipa_ops->ipa_disable_autonomy)
|
||||
return soc->ops->ipa_ops->ipa_disable_autonomy(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPA_WDI_UNIFIED_API
|
||||
/**
|
||||
* cdp_ipa_setup() - Setup and connect IPA pipes
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: handle to the device instance number
|
||||
* @ipa_i2w_cb: IPA to WLAN callback
|
||||
* @ipa_w2i_cb: WLAN to IPA callback
|
||||
* @ipa_wdi_meter_notifier_cb: IPA WDI metering callback
|
||||
* @ipa_desc_size: IPA descriptor size
|
||||
* @ipa_priv: handle to the HTT instance
|
||||
* @is_rm_enabled: Is IPA RM enabled or not
|
||||
* @tx_pipe_handle: pointer to Tx pipe handle
|
||||
* @rx_pipe_handle: pointer to Rx pipe handle
|
||||
* @is_smmu_enabled: Is SMMU enabled or not
|
||||
* @sys_in: parameters to setup sys pipe in mcc mode
|
||||
* @over_gsi: Is IPA using GSI
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_setup(ol_txrx_soc_handle soc, uint8_t pdev_id, void *ipa_i2w_cb,
|
||||
void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
|
||||
uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled,
|
||||
uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle,
|
||||
bool is_smmu_enabled, qdf_ipa_sys_connect_params_t *sys_in,
|
||||
bool over_gsi)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_setup)
|
||||
return soc->ops->ipa_ops->ipa_setup(soc, pdev_id, ipa_i2w_cb,
|
||||
ipa_w2i_cb,
|
||||
ipa_wdi_meter_notifier_cb,
|
||||
ipa_desc_size, ipa_priv,
|
||||
is_rm_enabled,
|
||||
tx_pipe_handle,
|
||||
rx_pipe_handle,
|
||||
is_smmu_enabled,
|
||||
sys_in, over_gsi);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#else /* CONFIG_IPA_WDI_UNIFIED_API */
|
||||
/**
|
||||
* cdp_ipa_setup() - Setup and connect IPA pipes
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: handle to the device instance number
|
||||
* @ipa_i2w_cb: IPA to WLAN callback
|
||||
* @ipa_w2i_cb: WLAN to IPA callback
|
||||
* @ipa_wdi_meter_notifier_cb: IPA WDI metering callback
|
||||
* @ipa_desc_size: IPA descriptor size
|
||||
* @ipa_priv: handle to the HTT instance
|
||||
* @is_rm_enabled: Is IPA RM enabled or not
|
||||
* @tx_pipe_handle: pointer to Tx pipe handle
|
||||
* @rx_pipe_handle: pointer to Rx pipe handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_setup(ol_txrx_soc_handle soc, uint8_t pdev_id, void *ipa_i2w_cb,
|
||||
void *ipa_w2i_cb, void *ipa_wdi_meter_notifier_cb,
|
||||
uint32_t ipa_desc_size, void *ipa_priv, bool is_rm_enabled,
|
||||
uint32_t *tx_pipe_handle, uint32_t *rx_pipe_handle)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_setup)
|
||||
return soc->ops->ipa_ops->ipa_setup(soc, pdev_id, ipa_i2w_cb,
|
||||
ipa_w2i_cb,
|
||||
ipa_wdi_meter_notifier_cb,
|
||||
ipa_desc_size, ipa_priv,
|
||||
is_rm_enabled,
|
||||
tx_pipe_handle,
|
||||
rx_pipe_handle);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* CONFIG_IPA_WDI_UNIFIED_API */
|
||||
|
||||
/**
|
||||
* cdp_ipa_cleanup() - Disconnect IPA pipes
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: handle to the device instance number
|
||||
* @tx_pipe_handle: Tx pipe handle
|
||||
* @rx_pipe_handle: Rx pipe handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_cleanup(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_cleanup)
|
||||
return soc->ops->ipa_ops->ipa_cleanup(soc, pdev_id,
|
||||
tx_pipe_handle,
|
||||
rx_pipe_handle);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_setup_iface() - Setup IPA header and register interface
|
||||
* @soc: data path soc handle
|
||||
* @ifname: Interface name
|
||||
* @mac_addr: Interface MAC address
|
||||
* @prod_client: IPA prod client type
|
||||
* @cons_client: IPA cons client type
|
||||
* @session_id: Session ID
|
||||
* @is_ipv6_enabled: Is IPV6 enabled or not
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_setup_iface(ol_txrx_soc_handle soc, char *ifname, uint8_t *mac_addr,
|
||||
qdf_ipa_client_type_t prod_client,
|
||||
qdf_ipa_client_type_t cons_client,
|
||||
uint8_t session_id, bool is_ipv6_enabled)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_setup_iface)
|
||||
return soc->ops->ipa_ops->ipa_setup_iface(ifname, mac_addr,
|
||||
prod_client,
|
||||
cons_client,
|
||||
session_id,
|
||||
is_ipv6_enabled);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_cleanup_iface() - Cleanup IPA header and deregister interface
|
||||
* @soc: data path soc handle
|
||||
* @ifname: Interface name
|
||||
* @is_ipv6_enabled: Is IPV6 enabled or not
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_cleanup_iface(ol_txrx_soc_handle soc, char *ifname,
|
||||
bool is_ipv6_enabled)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_cleanup_iface)
|
||||
return soc->ops->ipa_ops->ipa_cleanup_iface(ifname,
|
||||
is_ipv6_enabled);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_enable_pipes(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_enable_pipes)
|
||||
return soc->ops->ipa_ops->ipa_enable_pipes(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_uc_disable_pipes() - Suspend traffic and disable Tx/Rx pipes
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_disable_pipes(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_disable_pipes)
|
||||
return soc->ops->ipa_ops->ipa_disable_pipes(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_set_perf_level() - Set IPA clock bandwidth based on data rates
|
||||
* @soc: data path soc handle
|
||||
* @client: WLAN Client ID
|
||||
* @max_supported_bw_mbps: Maximum bandwidth needed (in Mbps)
|
||||
*
|
||||
* Return: 0 on success, negative errno on error
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_set_perf_level(ol_txrx_soc_handle soc, int client,
|
||||
uint32_t max_supported_bw_mbps)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_set_perf_level)
|
||||
return soc->ops->ipa_ops->ipa_set_perf_level(client,
|
||||
max_supported_bw_mbps);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path
|
||||
*
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: vdev id
|
||||
* @nbuf: pointer to skb of ethernet packet received from IPA RX path
|
||||
* @fwd_success: pointer to indicate if skb succeeded in intra-bss TX
|
||||
*
|
||||
* This function performs intra-bss forwarding for WDI 3.0 IPA RX path.
|
||||
*
|
||||
* Return: true if packet is intra-bss fwd-ed and no need to pass to
|
||||
* network stack. false if packet needs to be passed to network stack.
|
||||
*/
|
||||
static inline bool
|
||||
cdp_ipa_rx_intrabss_fwd(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf, bool *fwd_success)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops || !fwd_success) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_rx_intrabss_fwd)
|
||||
return soc->ops->ipa_ops->ipa_rx_intrabss_fwd(soc, vdev_id,
|
||||
nbuf,
|
||||
fwd_success);
|
||||
|
||||
/* Fall back to pass up to stack */
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_tx_buf_smmu_mapping() - Create SMMU mappings for Tx
|
||||
* buffers allocated to IPA
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: device instance id
|
||||
*
|
||||
* Create SMMU mappings for Tx buffers allocated to IPA
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_tx_buf_smmu_mapping(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_tx_buf_smmu_mapping)
|
||||
return soc->ops->ipa_ops->ipa_tx_buf_smmu_mapping(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_ipa_tx_buf_smmu_unmapping() - Release SMMU mappings for Tx
|
||||
* buffers allocated to IPA
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: device instance id
|
||||
*
|
||||
* Release SMMU mappings for Tx buffers allocated to IPA
|
||||
*
|
||||
* return QDF_STATUS_SUCCESS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_ipa_tx_buf_smmu_unmapping(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ipa_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->ipa_ops->ipa_tx_buf_smmu_unmapping)
|
||||
return soc->ops->ipa_ops->ipa_tx_buf_smmu_unmapping(soc,
|
||||
pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif /* IPA_OFFLOAD */
|
||||
|
||||
#endif /* _CDP_TXRX_IPA_H_ */
|
||||
|
||||
85
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_me.h
Normal file
85
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_me.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_me.h
|
||||
* @brief Define the host data path mcast enhance API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_ME_H_
|
||||
#define _CDP_TXRX_ME_H_
|
||||
|
||||
#include <cdp_txrx_ops.h>
|
||||
/* TODO: adf need to be replaced with qdf */
|
||||
#include "cdp_txrx_handle.h"
|
||||
|
||||
static inline void
|
||||
cdp_tx_me_alloc_descriptor(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->me_ops ||
|
||||
!soc->ops->me_ops->tx_me_alloc_descriptor)
|
||||
return;
|
||||
|
||||
soc->ops->me_ops->tx_me_alloc_descriptor(soc, pdev_id);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cdp_tx_me_free_descriptor(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->me_ops ||
|
||||
!soc->ops->me_ops->tx_me_free_descriptor)
|
||||
return;
|
||||
|
||||
soc->ops->me_ops->tx_me_free_descriptor(soc, pdev_id);
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
cdp_tx_me_convert_ucast(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
qdf_nbuf_t wbuf, u_int8_t newmac[][6],
|
||||
uint8_t newmaccnt, uint8_t tid, bool is_igmp)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->me_ops ||
|
||||
!soc->ops->me_ops->tx_me_convert_ucast)
|
||||
return 0;
|
||||
|
||||
return soc->ops->me_ops->tx_me_convert_ucast
|
||||
(soc, vdev_id, wbuf, newmac, newmaccnt, tid, is_igmp);
|
||||
}
|
||||
|
||||
#endif
|
||||
948
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_misc.h
Normal file
948
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_misc.h
Normal file
|
|
@ -0,0 +1,948 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_misc.h
|
||||
* @brief Define the host data path miscellaneous API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_MISC_H_
|
||||
#define _CDP_TXRX_MISC_H_
|
||||
|
||||
#include "cdp_txrx_handle.h"
|
||||
/**
|
||||
* cdp_tx_non_std() - Allow the control-path SW to send data frames
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: id of vdev
|
||||
* @tx_spec: what non-standard handling to apply to the tx data frames
|
||||
* @msdu_list: NULL-terminated list of tx MSDUs
|
||||
*
|
||||
* Generally, all tx data frames come from the OS shim into the txrx layer.
|
||||
* However, there are rare cases such as TDLS messaging where the UMAC
|
||||
* control-path SW creates tx data frames.
|
||||
* This UMAC SW can call this function to provide the tx data frames to
|
||||
* the txrx layer.
|
||||
* The UMAC SW can request a callback for these data frames after their
|
||||
* transmission completes, by using the ol_txrx_data_tx_cb_set function
|
||||
* to register a tx completion callback, and by specifying
|
||||
* ol_tx_spec_no_free as the tx_spec arg when giving the frames to
|
||||
* ol_tx_non_std.
|
||||
* The MSDUs need to have the appropriate L2 header type (802.3 vs. 802.11),
|
||||
* as specified by ol_cfg_frame_type().
|
||||
*
|
||||
* Return: null - success, skb - failure
|
||||
*/
|
||||
static inline qdf_nbuf_t
|
||||
cdp_tx_non_std(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s invalid instance", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->tx_non_std)
|
||||
return soc->ops->misc_ops->tx_non_std(soc, vdev_id, tx_spec,
|
||||
msdu_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_set_ibss_vdev_heart_beat_timer() - Update ibss vdev heart
|
||||
* beat timer
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: id of vdev
|
||||
* @timer_value_sec: new heart beat timer value
|
||||
*
|
||||
* Return: Old timer value set in vdev.
|
||||
*/
|
||||
static inline uint16_t
|
||||
cdp_set_ibss_vdev_heart_beat_timer(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, uint16_t timer_value_sec)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer)
|
||||
return soc->ops->misc_ops->set_ibss_vdev_heart_beat_timer(
|
||||
soc, vdev_id, timer_value_sec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_set_wisa_mode() - set wisa mode
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: vdev_id
|
||||
* @enable: enable or disable
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS mode enable success
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_set_wisa_mode(ol_txrx_soc_handle soc, uint8_t vdev_id, bool enable)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->set_wisa_mode)
|
||||
return soc->ops->misc_ops->set_wisa_mode(soc, vdev_id, enable);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_data_stall_cb_register() - register data stall callback
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @cb: callback function
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS register success
|
||||
*/
|
||||
static inline QDF_STATUS cdp_data_stall_cb_register(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
data_stall_detect_cb cb)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->txrx_data_stall_cb_register)
|
||||
return soc->ops->misc_ops->txrx_data_stall_cb_register(
|
||||
soc, pdev_id, cb);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_data_stall_cb_deregister() - de-register data stall callback
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @cb - callback function
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS de-register success
|
||||
*/
|
||||
static inline QDF_STATUS cdp_data_stall_cb_deregister(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
data_stall_detect_cb cb)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->txrx_data_stall_cb_deregister)
|
||||
return soc->ops->misc_ops->txrx_data_stall_cb_deregister(
|
||||
soc, pdev_id, cb);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_post_data_stall_event() - post data stall event
|
||||
* @soc: data path soc handle
|
||||
* @indicator: Module triggering data stall
|
||||
* @data_stall_type: data stall event type
|
||||
* @pdev_id: pdev id
|
||||
* @vdev_id_bitmap: vdev id bitmap
|
||||
* @recovery_type: data stall recovery type
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
cdp_post_data_stall_event(ol_txrx_soc_handle soc,
|
||||
enum data_stall_log_event_indicator indicator,
|
||||
enum data_stall_log_event_type data_stall_type,
|
||||
uint32_t pdev_id, uint32_t vdev_id_bitmap,
|
||||
enum data_stall_log_recovery_type recovery_type)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!soc->ops->misc_ops ||
|
||||
!soc->ops->misc_ops->txrx_post_data_stall_event)
|
||||
return;
|
||||
|
||||
soc->ops->misc_ops->txrx_post_data_stall_event(
|
||||
soc, indicator, data_stall_type, pdev_id,
|
||||
vdev_id_bitmap, recovery_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_set_wmm_param() - set wmm parameter
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @wmm_param: wmm parameter
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_set_wmm_param(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
struct ol_tx_wmm_param_t wmm_param)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->set_wmm_param)
|
||||
return soc->ops->misc_ops->set_wmm_param(soc, pdev_id,
|
||||
wmm_param);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_runtime_suspend() - suspend
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS suspend success
|
||||
*/
|
||||
static inline QDF_STATUS cdp_runtime_suspend(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->runtime_suspend)
|
||||
return soc->ops->misc_ops->runtime_suspend(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_runtime_resume() - resume
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS suspend success
|
||||
*/
|
||||
static inline QDF_STATUS cdp_runtime_resume(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->runtime_resume)
|
||||
return soc->ops->misc_ops->runtime_resume(soc, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_hl_tdls_flag_reset() - tdls flag reset
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: id of vdev
|
||||
* @flag: flag indicating to set/reset tdls
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_hl_tdls_flag_reset(ol_txrx_soc_handle soc, uint8_t vdev_id, bool flag)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->hl_tdls_flag_reset)
|
||||
return soc->ops->misc_ops->hl_tdls_flag_reset(soc, vdev_id,
|
||||
flag);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_get_opmode() - get vdev operation mode
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: id of vdev
|
||||
*
|
||||
* Return virtual device operational mode
|
||||
* op_mode_ap,
|
||||
* op_mode_ibss,
|
||||
* op_mode_sta,
|
||||
* op_mode_monitor,
|
||||
* op_mode_ocb,
|
||||
*
|
||||
* return interface id
|
||||
* 0 unknown interface
|
||||
*/
|
||||
static inline int
|
||||
cdp_get_opmode(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->get_opmode)
|
||||
return soc->ops->misc_ops->get_opmode(soc, vdev_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_get_vdev_id() - get vdev id
|
||||
* @soc - data path soc handle
|
||||
* @vdev - virtual interface instance
|
||||
*
|
||||
* get virtual interface id
|
||||
*
|
||||
* return interface id
|
||||
* 0 unknown interface
|
||||
*/
|
||||
static inline uint16_t
|
||||
cdp_get_vdev_id(ol_txrx_soc_handle soc, struct cdp_vdev *vdev)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->get_vdev_id)
|
||||
return soc->ops->misc_ops->get_vdev_id(vdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_get_tx_ack_stats() - get tx ack count for vdev
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - vdev id
|
||||
*
|
||||
* return tx ack count
|
||||
* 0 invalid count
|
||||
*/
|
||||
static inline uint32_t
|
||||
cdp_get_tx_ack_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->get_tx_ack_stats)
|
||||
return soc->ops->misc_ops->get_tx_ack_stats(soc, vdev_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_bad_peer_txctl_set_setting() - Set peer timer balance parameters
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of datapath pdev handle
|
||||
* @enable: enable/disable peer balance state
|
||||
* @period: balance timer period for peer
|
||||
* @txq_limit: txp limit for peer
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_bad_peer_txctl_set_setting(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
int enable, int period, int txq_limit)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->bad_peer_txctl_set_setting)
|
||||
return soc->ops->misc_ops->bad_peer_txctl_set_setting(
|
||||
soc, pdev_id, enable, period,
|
||||
txq_limit);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_bad_peer_txctl_update_threshold() - TBD
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @level: index of the threshold configuration
|
||||
* @tput_thresh: peer balance throughput threshold
|
||||
* @tx_limit: peer balance tx limit threshold
|
||||
*
|
||||
* TBD
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_bad_peer_txctl_update_threshold(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id, int level,
|
||||
int tput_thresh, int tx_limit)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->bad_peer_txctl_update_threshold)
|
||||
return soc->ops->misc_ops->bad_peer_txctl_update_threshold(
|
||||
soc, pdev_id, level, tput_thresh, tx_limit);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_mark_first_wakeup_packet() - set flag to indicate that
|
||||
* fw is compatible for marking first packet after wow wakeup
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @value: 1 for enabled/ 0 for disabled
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void cdp_mark_first_wakeup_packet(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id, uint8_t value)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->mark_first_wakeup_packet)
|
||||
return soc->ops->misc_ops->mark_first_wakeup_packet(
|
||||
soc, pdev_id, value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* cds_update_mac_id() - update mac_id for vdev
|
||||
* @psoc: data path soc handle
|
||||
* @vdev_id: vdev id
|
||||
* @mac_id: mac id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void cdp_update_mac_id(void *psoc, uint8_t vdev_id,
|
||||
uint8_t mac_id)
|
||||
{
|
||||
ol_txrx_soc_handle soc = psoc;
|
||||
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->update_mac_id)
|
||||
return soc->ops->misc_ops->update_mac_id(soc, vdev_id, mac_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_flush_rx_frames() - flush cached rx frames
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: datapath pdev identifier
|
||||
* @peer_mac: peer mac address
|
||||
* @drop: set flag to drop frames
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void cdp_flush_rx_frames(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint8_t *peer_mac, bool drop)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->flush_rx_frames)
|
||||
return soc->ops->misc_ops->flush_rx_frames(soc, pdev_id,
|
||||
peer_mac, drop);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* cdp_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets
|
||||
* that has been forwarded from txrx layer without going to upper layers.
|
||||
* @soc: Datapath soc handle
|
||||
* @vdev_id: vdev id
|
||||
* @fwd_tx_packets: pointer to forwarded tx packets count parameter
|
||||
* @fwd_rx_packets: pointer to forwarded rx packets count parameter
|
||||
*
|
||||
* Return: status -> A_OK - success, A_ERROR - failure
|
||||
*/
|
||||
static inline A_STATUS cdp_get_intra_bss_fwd_pkts_count(
|
||||
ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint64_t *fwd_tx_packets, uint64_t *fwd_rx_packets)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->get_intra_bss_fwd_pkts_count)
|
||||
return soc->ops->misc_ops->get_intra_bss_fwd_pkts_count(
|
||||
soc, vdev_id, fwd_tx_packets, fwd_rx_packets);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_pkt_log_init() - API to initialize packet log
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @scn: HIF context
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void cdp_pkt_log_init(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id, void *scn)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->pkt_log_init)
|
||||
return soc->ops->misc_ops->pkt_log_init(soc, pdev_id, scn);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_pkt_log_con_service() - API to connect packet log service
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @scn: HIF context
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void cdp_pkt_log_con_service(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id, void *scn)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->pkt_log_con_service)
|
||||
return soc->ops->misc_ops->pkt_log_con_service(
|
||||
soc, pdev_id, scn);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_pkt_log_exit() - API to cleanup packet log info
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void cdp_pkt_log_exit(ol_txrx_soc_handle soc, uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->pkt_log_exit)
|
||||
return soc->ops->misc_ops->pkt_log_exit(soc, pdev_id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_get_num_rx_contexts() - API to get the number of RX contexts
|
||||
* @soc: soc handle
|
||||
*
|
||||
* Return: number of RX contexts
|
||||
*/
|
||||
static inline int cdp_get_num_rx_contexts(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->get_num_rx_contexts)
|
||||
return soc->ops->misc_ops->get_num_rx_contexts(soc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_register_packetdump_cb() - API to register packetdump callback
|
||||
*
|
||||
* Register TX/RX callback for data packets, during connection. And per packet
|
||||
* stats will be passed to user-space by @tx_cb/@rx_cb.
|
||||
*
|
||||
* @soc: soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @tx_cb: tx packet callback
|
||||
* @rx_cb: rx packet callback
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void cdp_register_packetdump_cb(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
ol_txrx_pktdump_cb tx_cb,
|
||||
ol_txrx_pktdump_cb rx_cb)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->register_pktdump_cb)
|
||||
return soc->ops->misc_ops->register_pktdump_cb(
|
||||
soc, pdev_id, tx_cb, rx_cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_deregister_packetdump_cb() - API to unregister packetdump callback
|
||||
*
|
||||
* Deregister callback for TX/RX data packets.
|
||||
*
|
||||
* @soc: soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void cdp_deregister_packetdump_cb(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->unregister_pktdump_cb)
|
||||
return soc->ops->misc_ops->unregister_pktdump_cb(soc, pdev_id);
|
||||
}
|
||||
|
||||
typedef void (*rx_mic_error_callback)(struct cdp_ctrl_objmgr_psoc *psoc,
|
||||
uint8_t pdev_id,
|
||||
struct cdp_rx_mic_err_info *info);
|
||||
|
||||
/**
|
||||
* cdp_register_rx_mic_error_ind_handler() - API to register mic error
|
||||
* indication handler
|
||||
*
|
||||
* @soc: soc handle
|
||||
* @rx_mic_cb: rx mic error indication callback
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
cdp_register_rx_mic_error_ind_handler(ol_txrx_soc_handle soc,
|
||||
rx_mic_error_callback rx_mic_cb)
|
||||
{
|
||||
if (!soc || !soc->ol_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
soc->ol_ops->rx_mic_error = rx_mic_cb;
|
||||
}
|
||||
|
||||
typedef void (*rx_refill_thread_sched_cb)(ol_txrx_soc_handle soc);
|
||||
|
||||
/**
|
||||
* cdp_register_rx_refill_thread_sched_handler() - API to register RX refill
|
||||
* thread schedule handler
|
||||
*
|
||||
* @soc: soc handle
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
cdp_register_rx_refill_thread_sched_handler(ol_txrx_soc_handle soc,
|
||||
rx_refill_thread_sched_cb rx_sched_cb)
|
||||
{
|
||||
if (!soc || !soc->ol_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
soc->ol_ops->dp_rx_sched_refill_thread = rx_sched_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_pdev_reset_driver_del_ack() - reset driver TCP delayed ack flag
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: pdev id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void cdp_pdev_reset_driver_del_ack(void *psoc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
ol_txrx_soc_handle soc = psoc;
|
||||
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->pdev_reset_driver_del_ack)
|
||||
return soc->ops->misc_ops->pdev_reset_driver_del_ack(soc,
|
||||
pdev_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* cdp_vdev_set_driver_del_ack_enable() - set driver delayed ack enabled flag
|
||||
* @soc: data path soc handle
|
||||
* @vdev_id: vdev id
|
||||
* @rx_packets: number of rx packets
|
||||
* @time_in_ms: time in ms
|
||||
* @high_th: high threshold
|
||||
* @low_th: low threshold
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void cdp_vdev_set_driver_del_ack_enable(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
unsigned long rx_packets,
|
||||
uint32_t time_in_ms,
|
||||
uint32_t high_th,
|
||||
uint32_t low_th)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->vdev_set_driver_del_ack_enable)
|
||||
return soc->ops->misc_ops->vdev_set_driver_del_ack_enable(
|
||||
soc, vdev_id, rx_packets, time_in_ms, high_th, low_th);
|
||||
}
|
||||
|
||||
static inline void cdp_vdev_set_bundle_require_flag(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
unsigned long tx_bytes,
|
||||
uint32_t time_in_ms,
|
||||
uint32_t high_th,
|
||||
uint32_t low_th)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->vdev_set_bundle_require_flag)
|
||||
return soc->ops->misc_ops->vdev_set_bundle_require_flag(
|
||||
vdev_id, tx_bytes, time_in_ms, high_th, low_th);
|
||||
}
|
||||
|
||||
static inline void cdp_pdev_reset_bundle_require_flag(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->pdev_reset_bundle_require_flag)
|
||||
return soc->ops->misc_ops->pdev_reset_bundle_require_flag(
|
||||
soc, pdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_txrx_ext_stats_request(): request dp tx and rx extended stats
|
||||
* @soc: soc handle
|
||||
* @pdev_id: pdev id
|
||||
* @req: stats request structure to fill
|
||||
*
|
||||
* return: status
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_txrx_ext_stats_request(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
struct cdp_txrx_ext_stats *req)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops || !req) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance:", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->txrx_ext_stats_request)
|
||||
return soc->ops->misc_ops->txrx_ext_stats_request(soc, pdev_id,
|
||||
req);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_request_rx_hw_stats(): request rx hw stats
|
||||
* @soc: soc handle
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* return: none
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_request_rx_hw_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance:", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->request_rx_hw_stats)
|
||||
return soc->ops->misc_ops->request_rx_hw_stats(soc, vdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_reset_rx_hw_ext_stats(): reset rx hw ext stats
|
||||
* @soc: soc handle
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_reset_rx_hw_ext_stats(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance:", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->reset_rx_hw_ext_stats)
|
||||
soc->ops->misc_ops->reset_rx_hw_ext_stats(soc);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_vdev_inform_ll_conn() - Inform DP about the low latency connection
|
||||
* @soc: soc handle
|
||||
* @vdev_id: vdev id
|
||||
* @action: Action to be performed (Add/Delete)
|
||||
*
|
||||
* Returns: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_vdev_inform_ll_conn(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
enum vdev_ll_conn_actions action)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance:", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->vdev_inform_ll_conn)
|
||||
return soc->ops->misc_ops->vdev_inform_ll_conn(soc, vdev_id,
|
||||
action);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_soc_set_swlm_enable() - Enable or disable software latency manager
|
||||
* @soc: soc handle
|
||||
* @value: value (enable/disable)
|
||||
*
|
||||
* Returns: QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_soc_set_swlm_enable(ol_txrx_soc_handle soc, uint8_t value)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance:", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->set_swlm_enable)
|
||||
return soc->ops->misc_ops->set_swlm_enable(soc, value);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_soc_is_swlm_enabled() - Check if the software latency manager is
|
||||
* enabled or not
|
||||
* @soc: soc handle
|
||||
*
|
||||
* Returns: 1 if enabled, 0 if disabled
|
||||
*/
|
||||
static inline uint8_t
|
||||
cdp_soc_is_swlm_enabled(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance:", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->is_swlm_enabled)
|
||||
return soc->ops->misc_ops->is_swlm_enabled(soc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_display_txrx_hw_info() - Dump the DP rings info
|
||||
* @soc: soc handle
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_display_txrx_hw_info(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->misc_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance:", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->misc_ops->display_txrx_hw_info)
|
||||
return soc->ops->misc_ops->display_txrx_hw_info(soc);
|
||||
}
|
||||
#endif /* _CDP_TXRX_MISC_H_ */
|
||||
500
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mob_def.h
Normal file
500
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mob_def.h
Normal file
|
|
@ -0,0 +1,500 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __CDP_TXRX_MOB_DEF_H
|
||||
#define __CDP_TXRX_MOB_DEF_H
|
||||
#include <sir_types.h>
|
||||
#include <htt.h>
|
||||
|
||||
#define TX_WMM_AC_NUM 4
|
||||
#define ENABLE_DP_HIST_STATS
|
||||
#define DP_MEMORY_OPT
|
||||
#define DP_RX_DISABLE_NDI_MDNS_FORWARDING
|
||||
|
||||
#define OL_TXQ_PAUSE_REASON_FW (1 << 0)
|
||||
#define OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED (1 << 1)
|
||||
#define OL_TXQ_PAUSE_REASON_TX_ABORT (1 << 2)
|
||||
#define OL_TXQ_PAUSE_REASON_VDEV_STOP (1 << 3)
|
||||
#define OL_TXQ_PAUSE_REASON_THERMAL_MITIGATION (1 << 4)
|
||||
|
||||
#define OL_TXRX_INVALID_NUM_PEERS (-1)
|
||||
|
||||
|
||||
/* Maximum number of station supported by data path, including BC. */
|
||||
#define WLAN_MAX_STA_COUNT (HAL_NUM_STA)
|
||||
|
||||
/* The symbolic station ID return to HDD to specify the packet is bc/mc */
|
||||
#define WLAN_RX_BCMC_STA_ID (WLAN_MAX_STA_COUNT + 1)
|
||||
|
||||
/* The symbolic station ID return to HDD to specify the packet is
|
||||
to soft-AP itself */
|
||||
#define WLAN_RX_SAP_SELF_STA_ID (WLAN_MAX_STA_COUNT + 2)
|
||||
|
||||
/* is 802.11 address multicast/broadcast? */
|
||||
#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01)
|
||||
|
||||
#define MAX_PEERS 32
|
||||
|
||||
/*
|
||||
* Bins used for reporting delay histogram:
|
||||
* bin 0: 0 - 10 ms delay
|
||||
* bin 1: 10 - 20 ms delay
|
||||
* bin 2: 20 - 40 ms delay
|
||||
* bin 3: 40 - 80 ms delay
|
||||
* bin 4: 80 - 160 ms delay
|
||||
* bin 5: > 160 ms delay
|
||||
*/
|
||||
#define QCA_TX_DELAY_HIST_REPORT_BINS 6
|
||||
|
||||
/* BA actions */
|
||||
#define IEEE80211_ACTION_BA_ADDBA_REQUEST 0 /* ADDBA request */
|
||||
#define IEEE80211_ACTION_BA_ADDBA_RESPONSE 1 /* ADDBA response */
|
||||
#define IEEE80211_ACTION_BA_DELBA 2 /* DELBA */
|
||||
|
||||
#define IEEE80211_BA_POLICY_DELAYED 0
|
||||
#define IEEE80211_BA_POLICY_IMMEDIATE 1
|
||||
#define IEEE80211_BA_AMSDU_SUPPORTED 1
|
||||
|
||||
/**
|
||||
* enum netif_action_type - Type of actions on netif queues
|
||||
* @WLAN_STOP_ALL_NETIF_QUEUE: stop all netif queues
|
||||
* @WLAN_START_ALL_NETIF_QUEUE: start all netif queues
|
||||
* @WLAN_WAKE_ALL_NETIF_QUEUE: wake all netif queues
|
||||
* @WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER: stop all queues and off carrier
|
||||
* @WLAN_START_ALL_NETIF_QUEUE_N_CARRIER: start all queues and on carrier
|
||||
* @WLAN_NETIF_TX_DISABLE: disable tx
|
||||
* @WLAN_NETIF_TX_DISABLE_N_CARRIER: disable tx and off carrier
|
||||
* @WLAN_NETIF_CARRIER_ON: on carrier
|
||||
* @WLAN_NETIF_CARRIER_OFF: off carrier
|
||||
* @WLAN_NETIF_PRIORITY_QUEUE_ON: start priority netif queues
|
||||
* @WLAN_NETIF_PRIORITY_QUEUE_OFF: stop priority netif queues
|
||||
* @WLAN_WAKE_NON_PRIORITY_QUEUE: wake non priority netif queues
|
||||
* @WLAN_STOP_NON_PRIORITY_QUEUE: stop non priority netif queues
|
||||
*/
|
||||
enum netif_action_type {
|
||||
WLAN_NETIF_ACTION_TYPE_NONE = 0,
|
||||
WLAN_STOP_ALL_NETIF_QUEUE = 1,
|
||||
WLAN_START_ALL_NETIF_QUEUE = 2,
|
||||
WLAN_WAKE_ALL_NETIF_QUEUE = 3,
|
||||
WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER = 4,
|
||||
WLAN_START_ALL_NETIF_QUEUE_N_CARRIER = 5,
|
||||
WLAN_NETIF_TX_DISABLE = 6,
|
||||
WLAN_NETIF_TX_DISABLE_N_CARRIER = 7,
|
||||
WLAN_NETIF_CARRIER_ON = 8,
|
||||
WLAN_NETIF_CARRIER_OFF = 9,
|
||||
WLAN_NETIF_PRIORITY_QUEUE_ON = 10,
|
||||
WLAN_NETIF_PRIORITY_QUEUE_OFF = 11,
|
||||
WLAN_NETIF_VO_QUEUE_ON = 12,
|
||||
WLAN_NETIF_VO_QUEUE_OFF = 13,
|
||||
WLAN_NETIF_VI_QUEUE_ON = 14,
|
||||
WLAN_NETIF_VI_QUEUE_OFF = 15,
|
||||
WLAN_NETIF_BE_BK_QUEUE_OFF = 16,
|
||||
WLAN_WAKE_NON_PRIORITY_QUEUE = 17,
|
||||
WLAN_STOP_NON_PRIORITY_QUEUE = 18,
|
||||
WLAN_NETIF_ACTION_TYPE_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum netif_reason_type - reason for netif queue action
|
||||
* @WLAN_CONTROL_PATH: action from control path
|
||||
* @WLAN_DATA_FLOW_CONTROL: because of flow control
|
||||
* @WLAN_FW_PAUSE: because of firmware pause
|
||||
* @WLAN_TX_ABORT: because of tx abort
|
||||
* @WLAN_VDEV_STOP: because of vdev stop
|
||||
* @WLAN_PEER_UNAUTHORISED: because of peer is unauthorised
|
||||
* @WLAN_THERMAL_MITIGATION: because of thermal mitigation
|
||||
*/
|
||||
enum netif_reason_type {
|
||||
WLAN_CONTROL_PATH = 1,
|
||||
WLAN_DATA_FLOW_CONTROL,
|
||||
WLAN_FW_PAUSE,
|
||||
WLAN_TX_ABORT,
|
||||
WLAN_VDEV_STOP,
|
||||
WLAN_PEER_UNAUTHORISED,
|
||||
WLAN_THERMAL_MITIGATION,
|
||||
WLAN_DATA_FLOW_CONTROL_PRIORITY,
|
||||
WLAN_REASON_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum ol_rx_err_type {
|
||||
OL_RX_ERR_DEFRAG_MIC,
|
||||
OL_RX_ERR_PN,
|
||||
OL_RX_ERR_UNKNOWN_PEER,
|
||||
OL_RX_ERR_MALFORMED,
|
||||
OL_RX_ERR_TKIP_MIC,
|
||||
OL_RX_ERR_DECRYPT,
|
||||
OL_RX_ERR_MPDU_LENGTH,
|
||||
OL_RX_ERR_ENCRYPT_REQUIRED,
|
||||
OL_RX_ERR_DUP,
|
||||
OL_RX_ERR_UNKNOWN,
|
||||
OL_RX_ERR_FCS,
|
||||
OL_RX_ERR_PRIVACY,
|
||||
OL_RX_ERR_NONE_FRAG,
|
||||
OL_RX_ERR_NONE = 0xFF
|
||||
};
|
||||
|
||||
enum throttle_level {
|
||||
THROTTLE_LEVEL_0,
|
||||
THROTTLE_LEVEL_1,
|
||||
THROTTLE_LEVEL_2,
|
||||
THROTTLE_LEVEL_3,
|
||||
/* Invalid */
|
||||
THROTTLE_LEVEL_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
OL_TX_WMM_AC_BE,
|
||||
OL_TX_WMM_AC_BK,
|
||||
OL_TX_WMM_AC_VI,
|
||||
OL_TX_WMM_AC_VO,
|
||||
OL_TX_NUM_WMM_AC
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum ol_tx_spec
|
||||
* @brief indicate what non-standard transmission actions to apply
|
||||
* @details
|
||||
* Indicate one or more of the following:
|
||||
* - The tx frame already has a complete 802.11 header.
|
||||
* Thus, skip 802.3/native-WiFi to 802.11 header encapsulation and
|
||||
* A-MSDU aggregation.
|
||||
* - The tx frame should not be aggregated (A-MPDU or A-MSDU)
|
||||
* - The tx frame is already encrypted - don't attempt encryption.
|
||||
* - The tx frame is a segment of a TCP jumbo frame.
|
||||
* - This tx frame should not be unmapped and freed by the txrx layer
|
||||
* after transmission, but instead given to a registered tx completion
|
||||
* callback.
|
||||
* More than one of these specification can apply, though typically
|
||||
* only a single specification is applied to a tx frame.
|
||||
* A compound specification can be created, as a bit-OR of these
|
||||
* specifications.
|
||||
*/
|
||||
enum ol_tx_spec {
|
||||
OL_TX_SPEC_STD = 0x0, /* do regular processing */
|
||||
OL_TX_SPEC_RAW = 0x1, /* skip encap + A-MSDU aggr */
|
||||
OL_TX_SPEC_NO_AGGR = 0x2, /* skip encap + all aggr */
|
||||
OL_TX_SPEC_NO_ENCRYPT = 0x4, /* skip encap + encrypt */
|
||||
OL_TX_SPEC_TSO = 0x8, /* TCP segmented */
|
||||
OL_TX_SPEC_NWIFI_NO_ENCRYPT = 0x10, /* skip encrypt for nwifi */
|
||||
OL_TX_SPEC_NO_FREE = 0x20, /* give to cb rather than free */
|
||||
};
|
||||
|
||||
/**
|
||||
* @enum peer_debug_id_type: debug ids to track peer get_ref and release_ref
|
||||
* @brief Unique peer debug IDs to track the callers. Each new usage can add to
|
||||
* this enum list to create a new "PEER_DEBUG_ID_".
|
||||
* @PEER_DEBUG_ID_OL_INTERNAL: debug id for OL internal usage
|
||||
* @PEER_DEBUG_ID_WMA_PKT_DROP: debug id for wma_is_pkt_drop_candidate API
|
||||
* @PEER_DEBUG_ID_WMA_ADDBA_REQ: debug id for ADDBA request
|
||||
* @PEER_DEBUG_ID_WMA_DELBA_REQ: debug id for DELBA request
|
||||
* @PEER_DEBUG_ID_LIM_SEND_ADDBA_RESP: debug id for send ADDBA response
|
||||
* @PEER_DEBUG_ID_OL_RX_THREAD: debug id for rx thread
|
||||
* @PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK: debug id for CCMP replay
|
||||
* @PEER_DEBUG_ID_WMA_DEL_BSS:debug id for remove BSS
|
||||
* @PEER_DEBUG_ID_WMA_VDEV_STOP_RESP:debug id for vdev stop response handler
|
||||
* @PEER_DEBUG_ID_OL_PEER_MAP:debug id for peer map/unmap
|
||||
* @PEER_DEBUG_ID_OL_PEER_ATTACH: debug id for peer attach/detach
|
||||
* @PEER_DEBUG_ID_OL_TXQ_VDEV_FL: debug id for vdev flush
|
||||
* @PEER_DEBUG_ID_OL_HASH_ERS:debug id for peer find hash erase
|
||||
* @PEER_DEBUG_ID_MAX: debug id MAX
|
||||
*/
|
||||
enum peer_debug_id_type {
|
||||
PEER_DEBUG_ID_OL_INTERNAL,
|
||||
PEER_DEBUG_ID_WMA_PKT_DROP,
|
||||
PEER_DEBUG_ID_WMA_ADDBA_REQ,
|
||||
PEER_DEBUG_ID_WMA_DELBA_REQ,
|
||||
PEER_DEBUG_ID_LIM_SEND_ADDBA_RESP,
|
||||
PEER_DEBUG_ID_OL_RX_THREAD,
|
||||
PEER_DEBUG_ID_WMA_CCMP_REPLAY_ATTACK,
|
||||
PEER_DEBUG_ID_WMA_DEL_BSS,
|
||||
PEER_DEBUG_ID_WMA_VDEV_STOP_RESP,
|
||||
PEER_DEBUG_ID_OL_PEER_MAP,
|
||||
PEER_DEBUG_ID_OL_PEER_ATTACH,
|
||||
PEER_DEBUG_ID_OL_TXQ_VDEV_FL,
|
||||
PEER_DEBUG_ID_OL_HASH_ERS,
|
||||
PEER_DEBUG_ID_OL_UNMAP_TIMER_WORK,
|
||||
PEER_DEBUG_ID_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ol_txrx_desc_type - txrx descriptor type
|
||||
* @is_qos_enabled: is station qos enabled
|
||||
* @is_wapi_supported: is station wapi supported
|
||||
* @peer_addr: peer mac address
|
||||
*/
|
||||
struct ol_txrx_desc_type {
|
||||
uint8_t is_qos_enabled;
|
||||
uint8_t is_wapi_supported;
|
||||
struct qdf_mac_addr peer_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ol_tx_sched_wrr_ac_specs_t - the wrr ac specs params structure
|
||||
* @wrr_skip_weight: map to ol_tx_sched_wrr_adv_category_info_t.specs.
|
||||
* wrr_skip_weight
|
||||
* @credit_threshold: map to ol_tx_sched_wrr_adv_category_info_t.specs.
|
||||
* credit_threshold
|
||||
* @send_limit: map to ol_tx_sched_wrr_adv_category_info_t.specs.
|
||||
* send_limit
|
||||
* @credit_reserve: map to ol_tx_sched_wrr_adv_category_info_t.specs.
|
||||
* credit_reserve
|
||||
* @discard_weight: map to ol_tx_sched_wrr_adv_category_info_t.specs.
|
||||
* discard_weight
|
||||
*
|
||||
* This structure is for wrr ac specs params set from user, it will update
|
||||
* its content corresponding to the ol_tx_sched_wrr_adv_category_info_t.specs.
|
||||
*/
|
||||
struct ol_tx_sched_wrr_ac_specs_t {
|
||||
int wrr_skip_weight;
|
||||
uint32_t credit_threshold;
|
||||
uint16_t send_limit;
|
||||
int credit_reserve;
|
||||
int discard_weight;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct txrx_pdev_cfg_param_t - configuration information
|
||||
* passed to the data path
|
||||
*/
|
||||
struct txrx_pdev_cfg_param_t {
|
||||
uint8_t is_full_reorder_offload;
|
||||
/* IPA Micro controller data path offload enable flag */
|
||||
uint8_t is_uc_offload_enabled;
|
||||
/* IPA Micro controller data path offload TX buffer count */
|
||||
uint32_t uc_tx_buffer_count;
|
||||
/* IPA Micro controller data path offload TX buffer size */
|
||||
uint32_t uc_tx_buffer_size;
|
||||
/* IPA Micro controller data path offload RX indication ring count */
|
||||
uint32_t uc_rx_indication_ring_count;
|
||||
/* IPA Micro controller data path offload TX partition base */
|
||||
uint32_t uc_tx_partition_base;
|
||||
/* IP, TCP and UDP checksum offload */
|
||||
bool ip_tcp_udp_checksum_offload;
|
||||
/* IP, TCP and UDP checksum offload for NAN Mode */
|
||||
bool nan_ip_tcp_udp_checksum_offload;
|
||||
/* IP, TCP and UDP checksum offload for P2P Mode*/
|
||||
bool p2p_ip_tcp_udp_checksum_offload;
|
||||
/* Checksum offload override flag for Legcay modes */
|
||||
bool legacy_mode_csum_disable;
|
||||
/* Rx processing in thread from TXRX */
|
||||
bool enable_rxthread;
|
||||
/* CE classification enabled through INI */
|
||||
bool ce_classify_enabled;
|
||||
#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
|
||||
/* Threshold to stop queue in percentage */
|
||||
uint32_t tx_flow_stop_queue_th;
|
||||
/* Start queue offset in percentage */
|
||||
uint32_t tx_flow_start_queue_offset;
|
||||
#endif
|
||||
|
||||
#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
|
||||
/* enable the tcp delay ack feature in the driver */
|
||||
bool del_ack_enable;
|
||||
/* timeout if no more tcp ack frames, unit is ms */
|
||||
uint16_t del_ack_timer_value;
|
||||
/* the maximum number of replaced tcp ack frames */
|
||||
uint16_t del_ack_pkt_count;
|
||||
#endif
|
||||
|
||||
struct ol_tx_sched_wrr_ac_specs_t ac_specs[TX_WMM_AC_NUM];
|
||||
bool gro_enable;
|
||||
bool tso_enable;
|
||||
bool lro_enable;
|
||||
bool enable_data_stall_detection;
|
||||
bool enable_flow_steering;
|
||||
bool disable_intra_bss_fwd;
|
||||
|
||||
#ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE
|
||||
uint16_t bundle_timer_value;
|
||||
uint16_t bundle_size;
|
||||
#endif
|
||||
uint8_t pktlog_buffer_size;
|
||||
};
|
||||
|
||||
#ifdef IPA_OFFLOAD
|
||||
/**
|
||||
* ol_txrx_ipa_resources - Resources needed for IPA
|
||||
*/
|
||||
struct ol_txrx_ipa_resources {
|
||||
qdf_shared_mem_t *ce_sr;
|
||||
uint32_t ce_sr_ring_size;
|
||||
qdf_dma_addr_t ce_reg_paddr;
|
||||
|
||||
qdf_shared_mem_t *tx_comp_ring;
|
||||
uint32_t tx_num_alloc_buffer;
|
||||
|
||||
qdf_shared_mem_t *rx_rdy_ring;
|
||||
qdf_shared_mem_t *rx_proc_done_idx;
|
||||
|
||||
qdf_shared_mem_t *rx2_rdy_ring;
|
||||
qdf_shared_mem_t *rx2_proc_done_idx;
|
||||
|
||||
/* IPA UC doorbell registers paddr */
|
||||
qdf_dma_addr_t tx_comp_doorbell_dmaaddr;
|
||||
qdf_dma_addr_t rx_ready_doorbell_dmaaddr;
|
||||
|
||||
uint32_t tx_pipe_handle;
|
||||
uint32_t rx_pipe_handle;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct ol_txrx_ocb_chan_info {
|
||||
uint32_t chan_freq;
|
||||
uint16_t disable_rx_stats_hdr:1;
|
||||
};
|
||||
|
||||
/**
|
||||
* ol_mic_error_info - carries the information associated with
|
||||
* a MIC error
|
||||
* @vdev_id: virtual device ID
|
||||
* @key_id: Key ID
|
||||
* @pn: packet number
|
||||
* @sa: source address
|
||||
* @da: destination address
|
||||
* @ta: transmitter address
|
||||
*/
|
||||
struct ol_mic_error_info {
|
||||
uint8_t vdev_id;
|
||||
uint32_t key_id;
|
||||
uint64_t pn;
|
||||
uint8_t sa[QDF_MAC_ADDR_SIZE];
|
||||
uint8_t da[QDF_MAC_ADDR_SIZE];
|
||||
uint8_t ta[QDF_MAC_ADDR_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* ol_error_info - carries the information associated with an
|
||||
* error indicated by the firmware
|
||||
* @mic_err: MIC error information
|
||||
*/
|
||||
struct ol_error_info {
|
||||
union {
|
||||
struct ol_mic_error_info mic_err;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct ol_txrx_ocb_set_chan - txrx OCB channel info
|
||||
* @ocb_channel_count: Channel count
|
||||
* @ocb_channel_info: OCB channel info
|
||||
*/
|
||||
struct ol_txrx_ocb_set_chan {
|
||||
uint32_t ocb_channel_count;
|
||||
struct ol_txrx_ocb_chan_info *ocb_channel_info;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parameter type to pass WMM setting to ol_txrx_set_wmm_param
|
||||
* @details
|
||||
* The struct is used to specify informaiton to update TX WMM scheduler.
|
||||
*/
|
||||
struct ol_tx_ac_param_t {
|
||||
uint32_t aifs;
|
||||
uint32_t cwmin;
|
||||
uint32_t cwmax;
|
||||
};
|
||||
|
||||
struct ol_tx_wmm_param_t {
|
||||
struct ol_tx_ac_param_t ac[OL_TX_NUM_WMM_AC];
|
||||
};
|
||||
|
||||
struct ieee80211_ba_parameterset {
|
||||
#if _BYTE_ORDER == _BIG_ENDIAN
|
||||
uint16_t buffersize:10, /* B6-15 buffer size */
|
||||
tid:4, /* B2-5 TID */
|
||||
bapolicy:1, /* B1 block ack policy */
|
||||
amsdusupported:1; /* B0 amsdu supported */
|
||||
#else
|
||||
uint16_t amsdusupported:1, /* B0 amsdu supported */
|
||||
bapolicy:1, /* B1 block ack policy */
|
||||
tid:4, /* B2-5 TID */
|
||||
buffersize:10; /* B6-15 buffer size */
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_ba_seqctrl {
|
||||
#if _BYTE_ORDER == _BIG_ENDIAN
|
||||
uint16_t startseqnum:12, /* B4-15 starting sequence number */
|
||||
fragnum:4; /* B0-3 fragment number */
|
||||
#else
|
||||
uint16_t fragnum:4, /* B0-3 fragment number */
|
||||
startseqnum:12; /* B4-15 starting sequence number */
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_delba_parameterset {
|
||||
#if _BYTE_ORDER == _BIG_ENDIAN
|
||||
uint16_t tid:4, /* B12-15 tid */
|
||||
initiator:1, /* B11 initiator */
|
||||
reserved0:11; /* B0-10 reserved */
|
||||
#else
|
||||
uint16_t reserved0:11, /* B0-10 reserved */
|
||||
initiator:1, /* B11 initiator */
|
||||
tid:4; /* B12-15 tid */
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* ol_txrx_vdev_peer_remove_cb - wma_remove_peer callback
|
||||
*/
|
||||
typedef void (*ol_txrx_vdev_peer_remove_cb)(void *handle, uint8_t *bssid,
|
||||
uint8_t vdev_id, void *peer);
|
||||
|
||||
/**
|
||||
* @typedef tx_pause_callback
|
||||
* @brief OSIF function registered with the data path
|
||||
*/
|
||||
typedef void (*tx_pause_callback)(uint8_t vdev_id,
|
||||
enum netif_action_type action,
|
||||
enum netif_reason_type reason);
|
||||
|
||||
typedef void (*ipa_uc_op_cb_type)(uint8_t *op_msg,
|
||||
void *osif_ctxt);
|
||||
|
||||
/**
|
||||
* struct ol_rx_inv_peer_params - rx invalid peer data parameters
|
||||
* @vdev_id: Virtual device ID
|
||||
* @ra: RX data receiver MAC address
|
||||
* @ta: RX data transmitter MAC address
|
||||
*/
|
||||
struct ol_rx_inv_peer_params {
|
||||
uint8_t vdev_id;
|
||||
uint8_t ra[QDF_MAC_ADDR_SIZE];
|
||||
uint8_t ta[QDF_MAC_ADDR_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* cdp_txrx_ext_stats: dp extended stats
|
||||
* tx_msdu_enqueue: tx msdu queued to hw
|
||||
* tx_msdu_overflow: tx msdu overflow
|
||||
* rx_mpdu_received: rx mpdu processed by hw
|
||||
* rx_mpdu_delivered: rx mpdu received from hw
|
||||
* rx_mpdu_error: rx mpdu error count
|
||||
* rx_mpdu_missed: rx mpdu missed by hw
|
||||
*/
|
||||
struct cdp_txrx_ext_stats {
|
||||
uint32_t tx_msdu_enqueue;
|
||||
uint32_t tx_msdu_overflow;
|
||||
uint32_t rx_mpdu_received;
|
||||
uint32_t rx_mpdu_delivered;
|
||||
uint32_t rx_mpdu_error;
|
||||
uint32_t rx_mpdu_missed;
|
||||
};
|
||||
|
||||
#endif /* __CDP_TXRX_MOB_DEF_H */
|
||||
72
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon.h
Normal file
72
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_mon.h
|
||||
* @brief Define the monitor mode API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
|
||||
#ifndef _CDP_TXRX_MON_H_
|
||||
#define _CDP_TXRX_MON_H_
|
||||
#include "cdp_txrx_handle.h"
|
||||
|
||||
static inline QDF_STATUS cdp_reset_monitor_mode(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
u_int8_t smart_monitor)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->mon_ops ||
|
||||
!soc->ops->mon_ops->txrx_reset_monitor_mode)
|
||||
return 0;
|
||||
|
||||
return soc->ops->mon_ops->txrx_reset_monitor_mode(soc, pdev_id,
|
||||
smart_monitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_deliver_tx_mgmt() - Deliver mgmt frame for tx capture
|
||||
* @soc: Datapath SOC handle
|
||||
* @pdev_id: id of datapath PDEV handle
|
||||
* @nbuf: Management frame buffer
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_deliver_tx_mgmt(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->mon_ops ||
|
||||
!soc->ops->mon_ops->txrx_deliver_tx_mgmt)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->mon_ops->txrx_deliver_tx_mgmt(soc, pdev_id, nbuf);
|
||||
}
|
||||
|
||||
#endif
|
||||
266
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon_struct.h
Normal file
266
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mon_struct.h
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_mon_struct.h
|
||||
* @brief Define the monitor mode API structure
|
||||
* shared by data path and the OS interface module
|
||||
*/
|
||||
|
||||
#ifndef _CDP_TXRX_MON_STRUCT_H_
|
||||
#define _CDP_TXRX_MON_STRUCT_H_
|
||||
/* XXX not really a mode; there are really multiple PHY's */
|
||||
enum cdp_mon_phymode {
|
||||
/* autoselect */
|
||||
CDP_IEEE80211_MODE_AUTO = 0,
|
||||
/* 5GHz, OFDM */
|
||||
CDP_IEEE80211_MODE_11A = 1,
|
||||
/* 2GHz, CCK */
|
||||
CDP_IEEE80211_MODE_11B = 2,
|
||||
/* 2GHz, OFDM */
|
||||
CDP_IEEE80211_MODE_11G = 3,
|
||||
/* 2GHz, GFSK */
|
||||
CDP_IEEE80211_MODE_FH = 4,
|
||||
/* 5GHz, OFDM, 2x clock dynamic turbo */
|
||||
CDP_IEEE80211_MODE_TURBO_A = 5,
|
||||
/* 2GHz, OFDM, 2x clock dynamic turbo */
|
||||
CDP_IEEE80211_MODE_TURBO_G = 6,
|
||||
/* 5Ghz, HT20 */
|
||||
CDP_IEEE80211_MODE_11NA_HT20 = 7,
|
||||
/* 2Ghz, HT20 */
|
||||
CDP_IEEE80211_MODE_11NG_HT20 = 8,
|
||||
/* 5Ghz, HT40 (ext ch +1) */
|
||||
CDP_IEEE80211_MODE_11NA_HT40PLUS = 9,
|
||||
/* 5Ghz, HT40 (ext ch -1) */
|
||||
CDP_IEEE80211_MODE_11NA_HT40MINUS = 10,
|
||||
/* 2Ghz, HT40 (ext ch +1) */
|
||||
CDP_IEEE80211_MODE_11NG_HT40PLUS = 11,
|
||||
/* 2Ghz, HT40 (ext ch -1) */
|
||||
CDP_IEEE80211_MODE_11NG_HT40MINUS = 12,
|
||||
/* 2Ghz, Auto HT40 */
|
||||
CDP_IEEE80211_MODE_11NG_HT40 = 13,
|
||||
/* 5Ghz, Auto HT40 */
|
||||
CDP_IEEE80211_MODE_11NA_HT40 = 14,
|
||||
/* 5Ghz, VHT20 */
|
||||
CDP_IEEE80211_MODE_11AC_VHT20 = 15,
|
||||
/* 5Ghz, VHT40 (Ext ch +1) */
|
||||
CDP_IEEE80211_MODE_11AC_VHT40PLUS = 16,
|
||||
/* 5Ghz VHT40 (Ext ch -1) */
|
||||
CDP_IEEE80211_MODE_11AC_VHT40MINUS = 17,
|
||||
/* 5Ghz, VHT40 */
|
||||
CDP_IEEE80211_MODE_11AC_VHT40 = 18,
|
||||
/* 5Ghz, VHT80 */
|
||||
CDP_IEEE80211_MODE_11AC_VHT80 = 19,
|
||||
/* 5Ghz, VHT160 */
|
||||
CDP_IEEE80211_MODE_11AC_VHT160 = 20,
|
||||
/* 5Ghz, VHT80_80 */
|
||||
CDP_IEEE80211_MODE_11AC_VHT80_80 = 21,
|
||||
};
|
||||
|
||||
enum {
|
||||
CDP_PKT_TYPE_OFDM = 0,
|
||||
CDP_PKT_TYPE_CCK,
|
||||
CDP_PKT_TYPE_HT,
|
||||
CDP_PKT_TYPE_VHT,
|
||||
CDP_PKT_TYPE_HE,
|
||||
};
|
||||
|
||||
enum {
|
||||
CDP_SGI_0_8_US = 0,
|
||||
CDP_SGI_0_4_US,
|
||||
CDP_SGI_1_6_US,
|
||||
CDP_SGI_3_2_US,
|
||||
};
|
||||
|
||||
enum {
|
||||
CDP_RX_TYPE_SU = 0,
|
||||
CDP_RX_TYPE_MU_MIMO,
|
||||
CDP_RX_TYPE_MU_OFDMA,
|
||||
CDP_RX_TYPE_MU_OFDMA_MIMO,
|
||||
};
|
||||
|
||||
enum {
|
||||
CDP_FULL_RX_BW_20 = 0,
|
||||
CDP_FULL_RX_BW_40,
|
||||
CDP_FULL_RX_BW_80,
|
||||
CDP_FULL_RX_BW_160,
|
||||
};
|
||||
|
||||
struct cdp_mon_status {
|
||||
/* bss color value 1-63 used for update on ppdu_desc bsscolor */
|
||||
uint8_t bsscolor;
|
||||
int rs_numchains;
|
||||
int rs_flags;
|
||||
#define IEEE80211_RX_FCS_ERROR 0x01
|
||||
#define IEEE80211_RX_MIC_ERROR 0x02
|
||||
#define IEEE80211_RX_DECRYPT_ERROR 0x04
|
||||
/* holes in flags here between, ATH_RX_XXXX to IEEE80211_RX_XXX */
|
||||
#define IEEE80211_RX_KEYMISS 0x200
|
||||
int rs_rssi; /* RSSI (noise floor ajusted) */
|
||||
int rs_abs_rssi; /* absolute RSSI */
|
||||
int rs_datarate; /* data rate received */
|
||||
int rs_rateieee;
|
||||
int rs_ratephy1;
|
||||
int rs_ratephy2;
|
||||
int rs_ratephy3;
|
||||
|
||||
/* Keep the same as ATH_MAX_ANTENNA */
|
||||
#define IEEE80211_MAX_ANTENNA 3
|
||||
/* RSSI (noise floor ajusted) */
|
||||
u_int8_t rs_rssictl[IEEE80211_MAX_ANTENNA];
|
||||
/* RSSI (noise floor ajusted) */
|
||||
u_int8_t rs_rssiextn[IEEE80211_MAX_ANTENNA];
|
||||
/* rs_rssi is valid or not */
|
||||
u_int8_t rs_isvalidrssi;
|
||||
|
||||
enum cdp_mon_phymode rs_phymode;
|
||||
int rs_freq;
|
||||
|
||||
union {
|
||||
u_int8_t data[8];
|
||||
u_int64_t tsf;
|
||||
} rs_tstamp;
|
||||
|
||||
/*
|
||||
* Detail channel structure of recv frame.
|
||||
* It could be NULL if not available
|
||||
*/
|
||||
|
||||
|
||||
#ifdef ATH_SUPPORT_AOW
|
||||
u_int16_t rs_rxseq; /* WLAN Sequence number */
|
||||
#endif
|
||||
#ifdef ATH_VOW_EXT_STATS
|
||||
/* Lower 16 bits holds the udp checksum offset in the data pkt */
|
||||
u_int32_t vow_extstats_offset;
|
||||
/* Higher 16 bits contains offset in the data pkt at which vow
|
||||
* ext stats are embedded
|
||||
*/
|
||||
#endif
|
||||
u_int8_t rs_isaggr;
|
||||
u_int8_t rs_isapsd;
|
||||
int16_t rs_noisefloor;
|
||||
u_int16_t rs_channel;
|
||||
#ifdef ATH_SUPPORT_TxBF
|
||||
u_int32_t rs_rpttstamp; /* txbf report time stamp*/
|
||||
#endif
|
||||
|
||||
/* The following counts are meant to assist in stats calculation.
|
||||
* These variables are incremented only in specific situations, and
|
||||
* should not be relied upon for any purpose other than the original
|
||||
* stats related purpose they have been introduced for.
|
||||
*/
|
||||
|
||||
u_int16_t rs_cryptodecapcount; /* Crypto bytes decapped/demic'ed. */
|
||||
u_int8_t rs_padspace; /* No. of padding bytes present after
|
||||
header in wbuf. */
|
||||
u_int8_t rs_qosdecapcount; /* QoS/HTC bytes decapped. */
|
||||
|
||||
/* End of stats calculation related counts. */
|
||||
|
||||
/*
|
||||
* uint8_t rs_lsig[IEEE80211_LSIG_LEN];
|
||||
* uint8_t rs_htsig[IEEE80211_HTSIG_LEN];
|
||||
* uint8_t rs_servicebytes[IEEE80211_SB_LEN];
|
||||
* uint8_t rs_fcs_error;
|
||||
*/
|
||||
|
||||
/* cdp convergence monitor mode status */
|
||||
union {
|
||||
u_int8_t cdp_data[8];
|
||||
u_int64_t cdp_tsf;
|
||||
} cdp_rs_tstamp;
|
||||
|
||||
uint8_t cdp_rs_pream_type;
|
||||
uint32_t cdp_rs_user_rssi;
|
||||
uint8_t cdp_rs_stbc;
|
||||
uint8_t cdp_rs_sgi;
|
||||
uint32_t cdf_rs_rate_mcs;
|
||||
uint32_t cdp_rs_reception_type;
|
||||
uint32_t cdp_rs_bw;
|
||||
uint32_t cdp_rs_nss;
|
||||
uint8_t cdp_rs_fcs_err;
|
||||
bool cdp_rs_rxdma_err;
|
||||
};
|
||||
|
||||
enum {
|
||||
CDP_MON_PPDU_START = 0,
|
||||
CDP_MON_PPDU_END,
|
||||
};
|
||||
|
||||
#define MAX_PPDU_ID_HIST 128
|
||||
|
||||
/**
|
||||
* struct cdp_pdev_mon_stats
|
||||
* @status_ppdu_state: state on PPDU start and end
|
||||
* @status_ppdu_start: status ring PPDU start TLV count
|
||||
* @status_ppdu_end: status ring PPDU end TLV count
|
||||
* @status_ppdu_compl: status ring matching start and end count on PPDU
|
||||
* @status_ppdu_start_mis: status ring missing start TLV count on PPDU
|
||||
* @status_ppdu_end_mis: status ring missing end TLV count on PPDU
|
||||
* @status_ppdu_done: status ring PPDU done TLV count
|
||||
* @dest_ppdu_done: destination ring PPDU count
|
||||
* @dest_mpdu_done: destination ring MPDU count
|
||||
* @dup_mon_linkdesc_cnt: duplicate link descriptor indications from HW
|
||||
* @dup_mon_buf_cnt: duplicate buffer indications from HW
|
||||
* @tlv_tag_status_err: status not correct in the tlv tag
|
||||
* @status_buf_done_war: Number of status ring buffers for which DMA not done
|
||||
* WAR is applied.
|
||||
* @mon_rx_bufs_replenished_dest: Rx buffers replenish count
|
||||
* @mon_rx_bufs_reaped_dest: Rx buffer reap count
|
||||
* @ppdu_id_mismatch: counter to track ppdu id mismatch in
|
||||
* mointor status and monitor destination ring
|
||||
* @ppdu_id_match: counter to track ppdu id match in
|
||||
* mointor status and monitor destination ring
|
||||
* @status_ppdu_drop: Number of ppdu dropped from monitor status ring
|
||||
* @dest_ppdu_drop: Number of ppdu dropped from monitor destination ring
|
||||
* @mon_link_desc_invalid: msdu link desc invalid count
|
||||
* @mon_rx_desc_invalid: rx_desc invalid count
|
||||
*/
|
||||
struct cdp_pdev_mon_stats {
|
||||
#ifndef REMOVE_MON_DBG_STATS
|
||||
uint32_t status_ppdu_state;
|
||||
uint32_t status_ppdu_start;
|
||||
uint32_t status_ppdu_end;
|
||||
uint32_t status_ppdu_compl;
|
||||
uint32_t status_ppdu_start_mis;
|
||||
uint32_t status_ppdu_end_mis;
|
||||
#endif
|
||||
uint32_t status_ppdu_done;
|
||||
uint32_t dest_ppdu_done;
|
||||
uint32_t dest_mpdu_done;
|
||||
uint32_t dest_mpdu_drop;
|
||||
uint32_t dup_mon_linkdesc_cnt;
|
||||
uint32_t dup_mon_buf_cnt;
|
||||
uint32_t stat_ring_ppdu_id_hist[MAX_PPDU_ID_HIST];
|
||||
uint32_t dest_ring_ppdu_id_hist[MAX_PPDU_ID_HIST];
|
||||
uint32_t ppdu_id_hist_idx;
|
||||
uint32_t mon_rx_dest_stuck;
|
||||
uint32_t tlv_tag_status_err;
|
||||
uint32_t status_buf_done_war;
|
||||
uint32_t mon_rx_bufs_replenished_dest;
|
||||
uint32_t mon_rx_bufs_reaped_dest;
|
||||
uint32_t ppdu_id_mismatch;
|
||||
uint32_t ppdu_id_match;
|
||||
uint32_t status_ppdu_drop;
|
||||
uint32_t dest_ppdu_drop;
|
||||
uint32_t mon_link_desc_invalid;
|
||||
uint32_t mon_rx_desc_invalid;
|
||||
uint32_t mon_nbuf_sanity_err;
|
||||
};
|
||||
#endif
|
||||
55
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mscs.h
Normal file
55
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_mscs.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_mscs.h
|
||||
* @brief Define the host data path MSCS API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_MSCS_H_
|
||||
#define _CDP_TXRX_MSCS_H_
|
||||
#include "cdp_txrx_handle.h"
|
||||
#ifdef WLAN_SUPPORT_MSCS
|
||||
/**
|
||||
* @brief find MSCS enabled peer for this mac address and validate priority
|
||||
* @details
|
||||
* This function checks if there is a peer for this mac adress with MSCS
|
||||
* enabled flag set and nbuf priority is valid from user priority bitmap.
|
||||
*
|
||||
* @param peer_mac - mac address of peer
|
||||
* @param nbuf - nbuf pointer
|
||||
* @return - 0 for non error case, 1 for failure
|
||||
*/
|
||||
static inline int
|
||||
cdp_mscs_peer_lookup_n_get_priority(ol_txrx_soc_handle soc,
|
||||
uint8_t *peer_mac,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->mscs_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (soc->ops->mscs_ops->mscs_peer_lookup_n_get_priority)
|
||||
soc->ops->mscs_ops->mscs_peer_lookup_n_get_priority(soc,
|
||||
peer_mac, nbuf);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
67
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ocb.h
Normal file
67
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ocb.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _CDP_TXRX_OCB_H_
|
||||
#define _CDP_TXRX_OCB_H_
|
||||
#include <cdp_txrx_mob_def.h>
|
||||
#include "cdp_txrx_handle.h"
|
||||
/**
|
||||
* cdp_set_ocb_chan_info() - set OCB channel info to vdev.
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id: vdev_id corresponding to vdev start
|
||||
* @ocb_set_chan: OCB channel information to be set in vdev.
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_set_ocb_chan_info(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
struct ol_txrx_ocb_set_chan ocb_set_chan)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ocb_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->ocb_ops->set_ocb_chan_info)
|
||||
soc->ops->ocb_ops->set_ocb_chan_info(soc, vdev_id,
|
||||
ocb_set_chan);
|
||||
|
||||
}
|
||||
/**
|
||||
* cdp_get_ocb_chan_info() - return handle to vdev ocb_channel_info
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id: vdev_id corresponding to vdev start
|
||||
*
|
||||
* Return: handle to struct ol_txrx_ocb_chan_info
|
||||
*/
|
||||
static inline struct ol_txrx_ocb_chan_info *
|
||||
cdp_get_ocb_chan_info(ol_txrx_soc_handle soc, uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->ocb_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (soc->ops->ocb_ops->get_ocb_chan_info)
|
||||
return soc->ops->ocb_ops->get_ocb_chan_info(soc, vdev_id);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* _CDP_TXRX_OCB_H_ */
|
||||
1774
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ops.h
Normal file
1774
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_ops.h
Normal file
File diff suppressed because it is too large
Load diff
592
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h
Normal file
592
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_peer_ops.h
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_peer.h
|
||||
* @brief Define the host data path peer API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_PEER_H_
|
||||
#define _CDP_TXRX_PEER_H_
|
||||
#include <cdp_txrx_ops.h>
|
||||
#include "cdp_txrx_handle.h"
|
||||
|
||||
/**
|
||||
* cdp_peer_register() - Register peer into physical device
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - data path device instance id
|
||||
* @sta_desc - peer description
|
||||
*
|
||||
* Register peer into physical device
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS registration success
|
||||
* QDF_STATUS_E_NOSUPPORT not support this feature
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_peer_register(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
struct ol_txrx_desc_type *sta_desc)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->register_peer)
|
||||
return soc->ops->peer_ops->register_peer(soc, pdev_id,
|
||||
sta_desc);
|
||||
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_clear_peer() - remove peer from physical device
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - data path device instance id
|
||||
* @peer_addr - peer mac address
|
||||
*
|
||||
* remove peer from physical device
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS registration success
|
||||
* QDF_STATUS_E_NOSUPPORT not support this feature
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_clear_peer(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
struct qdf_mac_addr peer_addr)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->clear_peer)
|
||||
return soc->ops->peer_ops->clear_peer(soc, pdev_id, peer_addr);
|
||||
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_register_ocb_peer() - register ocb peer from physical device
|
||||
* @soc - data path soc handle
|
||||
* @cds_ctx - cds void context
|
||||
* @mac_addr - mac address for ocb self peer
|
||||
*
|
||||
* register ocb peer from physical device
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS registration success
|
||||
* QDF_STATUS_E_NOSUPPORT not support this feature
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_peer_register_ocb_peer(ol_txrx_soc_handle soc,
|
||||
uint8_t *mac_addr)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->register_ocb_peer)
|
||||
return soc->ops->peer_ops->register_ocb_peer(mac_addr);
|
||||
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_find_peer_exist - Find if peer already exists
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - data path device instance id
|
||||
* @peer_addr - peer mac address
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
static inline bool
|
||||
cdp_find_peer_exist(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint8_t *peer_addr)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->find_peer_exist)
|
||||
return soc->ops->peer_ops->find_peer_exist(soc, pdev_id,
|
||||
peer_addr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_find_peer_exist_on_vdev - Find if duplicate peer exists
|
||||
* on the given vdev
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - data path virtual interface id
|
||||
* @peer_addr - peer mac address
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
static inline bool
|
||||
cdp_find_peer_exist_on_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_addr)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->find_peer_exist_on_vdev)
|
||||
return soc->ops->peer_ops->find_peer_exist_on_vdev(soc, vdev_id,
|
||||
peer_addr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_find_peer_exist_on_other_vdev - Find if duplicate peer exists
|
||||
* on other than the given vdev
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - data path virtual interface id
|
||||
* @peer_addr - peer mac address
|
||||
* @max_bssid - max number of bssids
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
static inline bool
|
||||
cdp_find_peer_exist_on_other_vdev(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_addr, uint16_t max_bssid)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->find_peer_exist_on_other_vdev)
|
||||
return soc->ops->peer_ops->find_peer_exist_on_other_vdev(
|
||||
soc, vdev_id,
|
||||
peer_addr,
|
||||
max_bssid);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_state_update() - update peer local state
|
||||
* @soc - data path soc handle
|
||||
* @peer_addr - peer mac address
|
||||
* @state - new peer local state
|
||||
*
|
||||
* update peer local state
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS registration success
|
||||
* QDF_STATUS_E_NOSUPPORT not support this feature
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_peer_state_update(ol_txrx_soc_handle soc, uint8_t *peer_addr,
|
||||
enum ol_txrx_peer_state state)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->peer_state_update)
|
||||
return soc->ops->peer_ops->peer_state_update(soc, peer_addr,
|
||||
state);
|
||||
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_state_get() - Get local peer state
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface id
|
||||
* @peer_mac - peer mac addr
|
||||
*
|
||||
* Get local peer state
|
||||
*
|
||||
* Return: peer status
|
||||
*/
|
||||
static inline int
|
||||
cdp_peer_state_get(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->get_peer_state)
|
||||
return soc->ops->peer_ops->get_peer_state(soc, vdev_id,
|
||||
peer_mac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_get_vdevid() - Get virtual interface id which peer registered
|
||||
* @soc - data path soc handle
|
||||
* @peer_mac - peer mac address
|
||||
* @vdev_id - virtual interface id which peer registered
|
||||
*
|
||||
* Get virtual interface id which peer registered
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS registration success
|
||||
* QDF_STATUS_E_NOSUPPORT not support this feature
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_peer_get_vdevid(ol_txrx_soc_handle soc,
|
||||
uint8_t *peer_mac, uint8_t *vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->get_vdevid)
|
||||
return soc->ops->peer_ops->get_vdevid(soc, peer_mac, vdev_id);
|
||||
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_get_vdev_by_sta_id() - Get vdev instance by local peer id
|
||||
* @soc - data path soc handle
|
||||
* @pdev - data path device instance
|
||||
* @peer_addr - peer mac address
|
||||
*
|
||||
* Get virtual interface id by local peer id
|
||||
*
|
||||
* Return: Virtual interface instance
|
||||
* NULL in case cannot find
|
||||
*/
|
||||
static inline struct cdp_vdev
|
||||
*cdp_peer_get_vdev_by_peer_addr(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
|
||||
struct qdf_mac_addr peer_addr)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->get_vdev_by_peer_addr)
|
||||
return soc->ops->peer_ops->get_vdev_by_peer_addr(pdev,
|
||||
peer_addr);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_get_peer_mac_addr() - Get peer mac address
|
||||
* @soc - data path soc handle
|
||||
* @peer - peer instance
|
||||
*
|
||||
* Get peer mac address
|
||||
*
|
||||
* Return: peer mac address pointer
|
||||
* NULL in case cannot find
|
||||
*/
|
||||
static inline uint8_t
|
||||
*cdp_peer_get_peer_mac_addr(ol_txrx_soc_handle soc, void *peer)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->peer_get_peer_mac_addr)
|
||||
return soc->ops->peer_ops->peer_get_peer_mac_addr(peer);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_update_ibss_add_peer_num_of_vdev() - update number of peer
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface instance id
|
||||
* @peer_num_delta - number of peer should be updated
|
||||
*
|
||||
* update number of peer
|
||||
*
|
||||
* Return: updated number of peer
|
||||
* 0 fail
|
||||
*/
|
||||
static inline int16_t
|
||||
cdp_peer_update_ibss_add_peer_num_of_vdev(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
int16_t peer_num_delta)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->update_ibss_add_peer_num_of_vdev)
|
||||
return soc->ops->peer_ops->update_ibss_add_peer_num_of_vdev(
|
||||
soc, vdev_id,
|
||||
peer_num_delta);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_copy_mac_addr_raw() - copy peer mac address
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface instance id
|
||||
* @bss_addr - mac address should be copied
|
||||
*
|
||||
* copy peer mac address
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_peer_copy_mac_addr_raw(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, uint8_t *bss_addr)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->copy_mac_addr_raw)
|
||||
return soc->ops->peer_ops->copy_mac_addr_raw(soc, vdev_id,
|
||||
bss_addr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_add_last_real_peer() - Add peer with last peer marking
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - data path device instance id
|
||||
* @vdev_id - virtual interface instance id
|
||||
*
|
||||
* copy peer mac address
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_peer_add_last_real_peer(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->add_last_real_peer)
|
||||
return soc->ops->peer_ops->add_last_real_peer(soc, pdev_id,
|
||||
vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_is_vdev_restore_last_peer() - restore last peer
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface id
|
||||
* @peer_mac - peer mac address
|
||||
*
|
||||
* restore last peer
|
||||
*
|
||||
* Return: true, restore success
|
||||
* fasle, restore fail
|
||||
*/
|
||||
static inline bool
|
||||
cdp_peer_is_vdev_restore_last_peer(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_mac)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->is_vdev_restore_last_peer)
|
||||
return soc->ops->peer_ops->is_vdev_restore_last_peer(soc,
|
||||
vdev_id,
|
||||
peer_mac);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_update_last_real_peer() - update last real peer
|
||||
* @soc - data path soc handle
|
||||
* @pdev_id - data path device instance id
|
||||
* @vdev_id - virtual interface id
|
||||
* @restore_last_peer - restore last peer or not
|
||||
*
|
||||
* update last real peer
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_peer_update_last_real_peer(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint8_t vdev_id, bool restore_last_peer)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->update_last_real_peer)
|
||||
return soc->ops->peer_ops->update_last_real_peer(
|
||||
soc, pdev_id, vdev_id,
|
||||
restore_last_peer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* ol_txrx_peer_detach_force_delete() - Detach and delete a peer's data object
|
||||
* @peer - the object to detach
|
||||
*
|
||||
* Detach a peer and force the peer object to be removed. It is called during
|
||||
* roaming scenario when the firmware has already deleted a peer.
|
||||
* Peer object is freed immediately to avoid duplicate peers during roam sync
|
||||
* indication processing.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void cdp_peer_detach_force_delete(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
uint8_t *peer_mac)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->peer_detach_force_delete)
|
||||
return soc->ops->peer_ops->peer_detach_force_delete(soc,
|
||||
vdev_id,
|
||||
peer_mac);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_cdp_peer_detach_force_delete_supported() - To check if force delete
|
||||
* operation is supported
|
||||
* @soc: pointer to SOC handle
|
||||
*
|
||||
* Some of the platforms support force delete operation and some of them
|
||||
* don't. This API returns true if API which handles force delete operation
|
||||
* is registered and false otherwise.
|
||||
*
|
||||
* Return: true if API which handles force delete operation is registered
|
||||
* false in all other cases
|
||||
*/
|
||||
static inline bool
|
||||
is_cdp_peer_detach_force_delete_supported(ol_txrx_soc_handle soc)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->peer_detach_force_delete)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* cdp_peer_set_peer_as_tdls() - To set peer as tdls peer
|
||||
* @soc: pointer to SOC handle
|
||||
* @vdev_id: virtual interface id
|
||||
* @peer_mac: peer mac address
|
||||
* @var: true or false
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
cdp_peer_set_peer_as_tdls(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_mac, bool val)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->set_peer_as_tdls_peer)
|
||||
soc->ops->peer_ops->set_peer_as_tdls_peer(soc, vdev_id,
|
||||
peer_mac, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_set_tdls_offchan_enabled() - Set tdls offchan operation as enabled
|
||||
* @soc: pointer to SOC handle
|
||||
* @vdev_id: virtual interface id
|
||||
* @peer_mac: peer mac address
|
||||
* @val: true or false
|
||||
*
|
||||
* update tdls_offchan_enabled
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
cdp_peer_set_tdls_offchan_enabled(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
uint8_t *peer_mac, bool val)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->set_tdls_offchan_enabled)
|
||||
soc->ops->peer_ops->set_tdls_offchan_enabled(soc, vdev_id,
|
||||
peer_mac, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_peer_flush_frags() - Flush frags on peer
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - virtual interface id
|
||||
* @peer_mac - peer mac addr
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
cdp_peer_flush_frags(ol_txrx_soc_handle soc, uint8_t vdev_id, uint8_t *peer_mac)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->peer_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->peer_ops->peer_flush_frags)
|
||||
soc->ops->peer_ops->peer_flush_frags(soc, vdev_id, peer_mac);
|
||||
}
|
||||
#endif /* _CDP_TXRX_PEER_H_ */
|
||||
49
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pflow.h
Normal file
49
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pflow.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017,2019-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_pflow.h
|
||||
* @brief Define the host data path peer flow API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_PFLOW_H_
|
||||
#define _CDP_TXRX_PFLOW_H_
|
||||
|
||||
#include <cdp_txrx_stats_struct.h>
|
||||
#include "cdp_txrx_ops.h"
|
||||
#include "cdp_txrx_handle.h"
|
||||
|
||||
static inline uint32_t cdp_pflow_update_pdev_params
|
||||
(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
enum _dp_param_t param, uint32_t val, void *ctx)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->pflow_ops ||
|
||||
!soc->ops->pflow_ops->pflow_update_pdev_params)
|
||||
return 0;
|
||||
|
||||
return soc->ops->pflow_ops->pflow_update_pdev_params
|
||||
(soc, pdev_id, param, val, ctx);
|
||||
}
|
||||
#endif
|
||||
51
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pmf.h
Normal file
51
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_pmf.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _CDP_TXRX_PMF_H_
|
||||
#define _CDP_TXRX_PMF_H_
|
||||
|
||||
/**
|
||||
* cdp_get_pn_info() - Returns pn info from peer
|
||||
* @soc - data path soc handle
|
||||
* @peer_mac: peer mac address
|
||||
* @vdev_id: virtual device/interface id
|
||||
* @last_pn_valid: return last_rmf_pn_valid value from peer.
|
||||
* @last_pn: return last_rmf_pn value from peer.
|
||||
* @rmf_pn_replays: return rmf_pn_replays value from peer.
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_get_pn_info(ol_txrx_soc_handle soc, uint8_t *peer_mac, uint8_t vdev_id,
|
||||
uint8_t **last_pn_valid, uint64_t **last_pn,
|
||||
uint32_t **rmf_pn_replays)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->pmf_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->pmf_ops->get_pn_info)
|
||||
return soc->ops->pmf_ops->get_pn_info(soc, peer_mac, vdev_id,
|
||||
last_pn_valid,
|
||||
last_pn, rmf_pn_replays);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif /* _CDP_TXRX_PMF_H_ */
|
||||
80
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_raw.h
Normal file
80
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_raw.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_raw.h
|
||||
* @brief Define the host data path raw mode API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_RAW_H_
|
||||
#define _CDP_TXRX_RAW_H_
|
||||
|
||||
#include "cdp_txrx_handle.h"
|
||||
#include "cdp_txrx_ops.h"
|
||||
/* TODO: adf need to be replaced with qdf */
|
||||
static inline int cdp_get_nwifi_mode(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->raw_ops ||
|
||||
!soc->ops->raw_ops->txrx_get_nwifi_mode)
|
||||
return 0;
|
||||
|
||||
return soc->ops->raw_ops->txrx_get_nwifi_mode(soc, vdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief finds the ast entry for the packet
|
||||
* @details: Finds the ast entry i.e 4th address for the packet based on the
|
||||
* details in the netbuf.
|
||||
*
|
||||
* @param soc - soc handle
|
||||
* @param vdev_id - id of the data virtual device object
|
||||
* @param pnbuf - pointer to nbuf
|
||||
* @param raw_ast - pointer to fill ast information
|
||||
*
|
||||
* @return - 0 on success, -1 on error, 1 if more nbufs need to be consumed.
|
||||
*/
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_rawsim_get_astentry(ol_txrx_soc_handle soc, uint8_t vdev_id,
|
||||
qdf_nbuf_t *pnbuf, struct cdp_raw_ast *raw_ast)
|
||||
{
|
||||
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!soc->ops->raw_ops ||
|
||||
!soc->ops->raw_ops->rsim_get_astentry)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return soc->ops->raw_ops->rsim_get_astentry(soc, vdev_id,
|
||||
pnbuf, raw_ast);
|
||||
}
|
||||
|
||||
#endif
|
||||
64
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats.h
Normal file
64
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017,2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_stats.h
|
||||
* @brief Define the host data path statistics API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_STATS_H_
|
||||
#define _CDP_TXRX_STATS_H_
|
||||
#include <cdp_txrx_ops.h>
|
||||
|
||||
static inline QDF_STATUS
|
||||
cdp_clear_stats(ol_txrx_soc_handle soc, uint8_t pdev_id, uint8_t bitmap)
|
||||
{
|
||||
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (!soc->ops->mob_stats_ops ||
|
||||
!soc->ops->mob_stats_ops->clear_stats)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
return soc->ops->mob_stats_ops->clear_stats(soc, pdev_id, bitmap);
|
||||
}
|
||||
|
||||
static inline int
|
||||
cdp_stats(ol_txrx_soc_handle soc, uint8_t vdev_id, char *buffer,
|
||||
unsigned int buf_len)
|
||||
{
|
||||
if (!soc || !soc->ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s: Invalid Instance", __func__);
|
||||
QDF_BUG(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!soc->ops->mob_stats_ops ||
|
||||
!soc->ops->mob_stats_ops->stats)
|
||||
return 0;
|
||||
|
||||
return soc->ops->mob_stats_ops->stats(vdev_id, buffer, buf_len);
|
||||
}
|
||||
|
||||
#endif /* _CDP_TXRX_STATS_H_ */
|
||||
2020
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats_struct.h
Normal file
2020
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_stats_struct.h
Normal file
File diff suppressed because it is too large
Load diff
129
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_delay.h
Normal file
129
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_tx_delay.h
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_tx_delay.h
|
||||
* @brief Define the host data path histogram API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_COMPUTE_TX_DELAY_H_
|
||||
#define _CDP_TXRX_COMPUTE_TX_DELAY_H_
|
||||
#include "cdp_txrx_handle.h"
|
||||
/**
|
||||
* cdp_tx_delay() - get tx packet delay
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @queue_delay_microsec: tx packet delay within queue, usec
|
||||
* @tx_delay_microsec: tx packet delay, usec
|
||||
* @category: packet category
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_tx_delay(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint32_t *queue_delay_microsec, uint32_t *tx_delay_microsec,
|
||||
int category)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->delay_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->delay_ops->tx_delay)
|
||||
return soc->ops->delay_ops->tx_delay(soc, pdev_id,
|
||||
queue_delay_microsec, tx_delay_microsec, category);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_tx_delay_hist() - get tx packet delay histogram
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @bin_values: bin
|
||||
* @category: packet category
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_tx_delay_hist(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint16_t *bin_values, int category)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->delay_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->delay_ops->tx_delay_hist)
|
||||
return soc->ops->delay_ops->tx_delay_hist(soc, pdev_id,
|
||||
bin_values, category);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_tx_packet_count() - get tx packet count
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @out_packet_loss_count: packet loss count
|
||||
* @category: packet category
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_tx_packet_count(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint16_t *out_packet_count, uint16_t *out_packet_loss_count,
|
||||
int category)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->delay_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->delay_ops->tx_packet_count)
|
||||
return soc->ops->delay_ops->tx_packet_count(soc, pdev_id,
|
||||
out_packet_count, out_packet_loss_count, category);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_tx_set_compute_interval() - set tx packet stat compute interval
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @interval: compute interval
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_tx_set_compute_interval(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
uint32_t interval)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->delay_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->delay_ops->tx_set_compute_interval)
|
||||
return soc->ops->delay_ops->tx_set_compute_interval(soc,
|
||||
pdev_id,
|
||||
interval);
|
||||
return;
|
||||
}
|
||||
#endif /* _CDP_TXRX_COMPUTE_TX_DELAY_H_ */
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_tx_throttle.h
|
||||
* @brief Define the host data path transmit throttle API
|
||||
* functions called by the host control SW and the OS interface
|
||||
* module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_TX_THROTTLE_H_
|
||||
#define _CDP_TXRX_TX_THROTTLE_H_
|
||||
#include <cdp_txrx_ops.h>
|
||||
#include "cdp_txrx_handle.h"
|
||||
/**
|
||||
* cdp_throttle_init_period() - init tx throttle period
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @period: throttle period
|
||||
* @dutycycle_level: duty cycle level
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_throttle_init_period(ol_txrx_soc_handle soc, uint8_t pdev_id,
|
||||
int period, uint8_t *dutycycle_level)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->throttle_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->throttle_ops->throttle_init_period)
|
||||
return soc->ops->throttle_ops->throttle_init_period(
|
||||
soc, pdev_id, period, dutycycle_level);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_throttle_init_period() - init tx throttle period
|
||||
* @soc: data path soc handle
|
||||
* @pdev_id: id of data path pdev handle
|
||||
* @level: throttle level
|
||||
*
|
||||
* Return: NONE
|
||||
*/
|
||||
static inline void
|
||||
cdp_throttle_set_level(ol_txrx_soc_handle soc, uint8_t pdev_id, int level)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->throttle_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (soc->ops->throttle_ops->throttle_set_level)
|
||||
return soc->ops->throttle_ops->throttle_set_level(soc, pdev_id,
|
||||
level);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* _CDP_TXRX_TX_THROTTLE_H_ */
|
||||
100
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_wds.h
Normal file
100
drivers/staging/qca-wifi-host-cmn/dp/inc/cdp_txrx_wds.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cdp_txrx_wds.h
|
||||
* @brief Define the host data path WDS API functions
|
||||
* called by the host control SW and the OS interface module
|
||||
*/
|
||||
#ifndef _CDP_TXRX_WDS_H_
|
||||
#define _CDP_TXRX_WDS_H_
|
||||
#include "cdp_txrx_handle.h"
|
||||
/**
|
||||
* @brief set the wds rx filter policy of the device
|
||||
* @details
|
||||
* This flag sets the wds rx policy on the vdev. Rx frames not compliant
|
||||
* with the policy will be dropped.
|
||||
*
|
||||
* @param vdev_id - id of the data virtual device object
|
||||
* @param val - the wds rx policy bitmask
|
||||
* @return - QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_set_wds_rx_policy(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id,
|
||||
u_int32_t val)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->wds_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->wds_ops->txrx_set_wds_rx_policy)
|
||||
soc->ops->wds_ops->txrx_set_wds_rx_policy(soc, vdev_id, val);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the wds rx filter policy of the device
|
||||
* @details
|
||||
* This flag sets the wds rx policy on the vdev. Rx frames not compliant
|
||||
* with the policy will be dropped.
|
||||
*
|
||||
* @param psoc - psoc object
|
||||
* @param vdev_id - id of the data virtual device object
|
||||
* @param peer_mac - peer mac address
|
||||
* @param val - the wds rx policy bitmask
|
||||
* @return - QDF_STATUS
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
cdp_set_wds_tx_policy_update(ol_txrx_soc_handle soc,
|
||||
uint8_t vdev_id, uint8_t *peer_mac,
|
||||
int wds_tx_ucast, int wds_tx_mcast)
|
||||
{
|
||||
if (!soc || !soc->ops || !soc->ops->wds_ops) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"%s invalid instance", __func__);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (soc->ops->wds_ops->txrx_wds_peer_tx_policy_update)
|
||||
soc->ops->wds_ops->txrx_wds_peer_tx_policy_update(
|
||||
soc, vdev_id, peer_mac, wds_tx_ucast,
|
||||
wds_tx_mcast);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* cdp_vdev_set_wds() - Set/unset wds_enable flag in vdev
|
||||
* @soc - data path soc handle
|
||||
* @vdev_id - id of data path vap handle
|
||||
* @val - value to be set in wds_en flag
|
||||
*
|
||||
* This flag enables WDS source port learning feature on a vdev
|
||||
*
|
||||
* return 1 on success
|
||||
*/
|
||||
static inline int
|
||||
cdp_vdev_set_wds(ol_txrx_soc_handle soc, uint8_t vdev_id, uint32_t val)
|
||||
{
|
||||
if (soc->ops->wds_ops->vdev_set_wds)
|
||||
return soc->ops->wds_ops->vdev_set_wds(soc, vdev_id, val);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cal_client_api.h
|
||||
* @brief: define timer to update DP stats
|
||||
*/
|
||||
#ifndef _DP_CAL_CLIENT_H_
|
||||
#define _DP_CAL_CLIENT_H_
|
||||
|
||||
#include<cdp_txrx_stats_struct.h>
|
||||
#include <qdf_timer.h>
|
||||
#include <qdf_mem.h>
|
||||
#include <cdp_txrx_handle.h>
|
||||
|
||||
/*timer will run every 1 sec*/
|
||||
#define DP_CAL_CLIENT_TIME 1000
|
||||
|
||||
struct cal_client {
|
||||
qdf_timer_t cal_client_timer;
|
||||
void (*iterate_update_peer_list)(struct cdp_pdev *ctx);
|
||||
struct cdp_pdev *pdev_hdl;
|
||||
};
|
||||
|
||||
void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx,
|
||||
struct cdp_pdev *pdev, qdf_device_t osdev,
|
||||
void (*iterate_peer_list)(struct cdp_pdev *));
|
||||
void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx);
|
||||
void dp_cal_client_timer_start(void *ctx);
|
||||
void dp_cal_client_timer_stop(void *ctx);
|
||||
void dp_cal_client_stats_timer_fn(void *pdev_hdl);
|
||||
void dp_cal_client_update_peer_stats(struct cdp_peer_stats *peer_stats);
|
||||
|
||||
#ifndef ATH_SUPPORT_EXT_STAT
|
||||
void dp_cal_client_attach(struct cdp_cal_client **cal_client_ctx,
|
||||
struct cdp_pdev *pdev, qdf_device_t osdev,
|
||||
void (*iterate_peer_list)(struct cdp_pdev *))
|
||||
{
|
||||
}
|
||||
|
||||
void dp_cal_client_detach(struct cdp_cal_client **cal_client_ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void dp_cal_client_timer_start(void *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void dp_cal_client_timer_stop(void *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
void dp_cal_client_stats_timer_fn(void *pdev_hdl)
|
||||
{
|
||||
}
|
||||
|
||||
void dp_cal_client_update_peer_stats(struct cdp_peer_stats *peer_stats)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_DP_CAL_CLIENT_H_*/
|
||||
216
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_hist.c
Normal file
216
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_hist.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <qdf_util.h>
|
||||
#include <qdf_mem.h>
|
||||
#include <cdp_txrx_hist_struct.h>
|
||||
#include "dp_hist.h"
|
||||
|
||||
/*
|
||||
* dp_hist_sw_enq_dbucket: Sofware enqueue delay bucket in ms
|
||||
* @index_0 = 0_1 ms
|
||||
* @index_1 = 1_2 ms
|
||||
* @index_2 = 2_3 ms
|
||||
* @index_3 = 3_4 ms
|
||||
* @index_4 = 4_5 ms
|
||||
* @index_5 = 5_6 ms
|
||||
* @index_6 = 6_7 ms
|
||||
* @index_7 = 7_8 ms
|
||||
* @index_8 = 8_9 ms
|
||||
* @index_8 = 9+ ms
|
||||
*/
|
||||
static uint16_t dp_hist_sw_enq_dbucket[CDP_HIST_BUCKET_MAX] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
|
||||
/*
|
||||
* cdp_hist_fw2hw_dbucket: HW enqueue to Completion Delay
|
||||
* @index_0 = 0_10 ms
|
||||
* @index_1 = 10_20 ms
|
||||
* @index_2 = 20_30ms
|
||||
* @index_3 = 30_40 ms
|
||||
* @index_4 = 40_50 ms
|
||||
* @index_5 = 50_60 ms
|
||||
* @index_6 = 60_70 ms
|
||||
* @index_7 = 70_80 ms
|
||||
* @index_8 = 80_90 ms
|
||||
* @index_9 = 90+ ms
|
||||
*/
|
||||
static uint16_t dp_hist_fw2hw_dbucket[CDP_HIST_BUCKET_MAX] = {
|
||||
0, 10, 20, 30, 40, 50, 60, 70, 80, 90};
|
||||
|
||||
/*
|
||||
* dp_hist_reap2stack_bucket: Reap to stack bucket
|
||||
* @index_0 = 0_5 ms
|
||||
* @index_1 = 5_10 ms
|
||||
* @index_2 = 10_15 ms
|
||||
* @index_3 = 15_20 ms
|
||||
* @index_4 = 20_25 ms
|
||||
* @index_5 = 25_30 ms
|
||||
* @index_6 = 30_35 ms
|
||||
* @index_7 = 35_40 ms
|
||||
* @index_8 = 40_45 ms
|
||||
* @index_9 = 45+ ms
|
||||
*/
|
||||
static uint16_t dp_hist_reap2stack_bucket[CDP_HIST_BUCKET_MAX] = {
|
||||
0, 5, 10, 15, 20, 25, 30, 35, 40, 45};
|
||||
|
||||
/*
|
||||
* dp_hist_find_bucket_idx: Find the bucket index
|
||||
* @bucket_array: Bucket array
|
||||
* @value: Frequency value
|
||||
*
|
||||
* Return: The bucket index
|
||||
*/
|
||||
static int dp_hist_find_bucket_idx(int16_t *bucket_array, int value)
|
||||
{
|
||||
uint8_t idx = CDP_HIST_BUCKET_0;
|
||||
|
||||
for (; idx < (CDP_HIST_BUCKET_MAX - 1); idx++) {
|
||||
if (value < bucket_array[idx + 1])
|
||||
break;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_hist_fill_buckets: Fill the histogram frequency buckets
|
||||
* @hist_bucket: Histogram bukcets
|
||||
* @value: Frequency value
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void dp_hist_fill_buckets(struct cdp_hist_bucket *hist_bucket, int value)
|
||||
{
|
||||
enum cdp_hist_types hist_type;
|
||||
int idx = CDP_HIST_BUCKET_MAX;
|
||||
|
||||
if (qdf_unlikely(!hist_bucket))
|
||||
return;
|
||||
|
||||
hist_type = hist_bucket->hist_type;
|
||||
|
||||
/* Identify the bucket the bucket and update. */
|
||||
switch (hist_type) {
|
||||
case CDP_HIST_TYPE_SW_ENQEUE_DELAY:
|
||||
idx = dp_hist_find_bucket_idx(&dp_hist_sw_enq_dbucket[0],
|
||||
value);
|
||||
break;
|
||||
case CDP_HIST_TYPE_HW_COMP_DELAY:
|
||||
idx = dp_hist_find_bucket_idx(&dp_hist_fw2hw_dbucket[0],
|
||||
value);
|
||||
break;
|
||||
case CDP_HIST_TYPE_REAP_STACK:
|
||||
idx = dp_hist_find_bucket_idx(
|
||||
&dp_hist_reap2stack_bucket[0], value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx == CDP_HIST_BUCKET_MAX)
|
||||
return;
|
||||
|
||||
hist_bucket->freq[idx]++;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_hist_update_stats: Update histogram stats
|
||||
* @hist_stats: Hist stats object
|
||||
* @value: Delay value
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_hist_update_stats(struct cdp_hist_stats *hist_stats, int value)
|
||||
{
|
||||
if (qdf_unlikely(!hist_stats))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Fill the histogram buckets according to the delay
|
||||
*/
|
||||
dp_hist_fill_buckets(&hist_stats->hist, value);
|
||||
|
||||
/*
|
||||
* Compute the min, max and average. Average computed is weighted
|
||||
* average
|
||||
*/
|
||||
if (value < hist_stats->min)
|
||||
hist_stats->min = value;
|
||||
|
||||
if (value > hist_stats->max)
|
||||
hist_stats->max = value;
|
||||
|
||||
if (qdf_unlikely(!hist_stats->avg))
|
||||
hist_stats->avg = value;
|
||||
else
|
||||
hist_stats->avg = hist_stats->avg +
|
||||
((value - hist_stats->avg) >> HIST_AVG_WEIGHT_DENOM);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_copy_hist_stats(): Copy the histogram stats
|
||||
* @src_hist_stats: Source histogram stats
|
||||
* @dst_hist_stats: Destination histogram stats
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_copy_hist_stats(struct cdp_hist_stats *src_hist_stats,
|
||||
struct cdp_hist_stats *dst_hist_stats)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < CDP_HIST_BUCKET_MAX; index++)
|
||||
dst_hist_stats->hist.freq[index] =
|
||||
src_hist_stats->hist.freq[index];
|
||||
dst_hist_stats->min = src_hist_stats->min;
|
||||
dst_hist_stats->max = src_hist_stats->max;
|
||||
dst_hist_stats->avg = src_hist_stats->avg;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_accumulate_hist_stats(): Accumulate the hist src to dst
|
||||
* @src_hist_stats: Source histogram stats
|
||||
* @dst_hist_stats: Destination histogram stats
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_accumulate_hist_stats(struct cdp_hist_stats *src_hist_stats,
|
||||
struct cdp_hist_stats *dst_hist_stats)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
for (index = 0; index < CDP_HIST_BUCKET_MAX; index++)
|
||||
dst_hist_stats->hist.freq[index] +=
|
||||
src_hist_stats->hist.freq[index];
|
||||
dst_hist_stats->min = QDF_MIN(src_hist_stats->min, dst_hist_stats->min);
|
||||
dst_hist_stats->max = QDF_MAX(src_hist_stats->max, dst_hist_stats->max);
|
||||
dst_hist_stats->avg = (src_hist_stats->avg + dst_hist_stats->avg) >> 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_hist_init(): Initialize the histogram object
|
||||
* @hist_stats: Hist stats object
|
||||
* @hist_type: Histogram type
|
||||
*/
|
||||
void dp_hist_init(struct cdp_hist_stats *hist_stats,
|
||||
enum cdp_hist_types hist_type)
|
||||
{
|
||||
qdf_mem_zero(hist_stats, sizeof(*hist_stats));
|
||||
hist_stats->hist.hist_type = hist_type;
|
||||
}
|
||||
43
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_hist.h
Normal file
43
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_hist.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file dp_hist.h
|
||||
* @brief: histogram header file
|
||||
*/
|
||||
|
||||
#ifndef __DP_HIST_H_
|
||||
#define __DP_HIST_H_
|
||||
|
||||
#define HIST_AVG_WEIGHT_DENOM 4
|
||||
|
||||
/*
|
||||
* dp_hist_update_stats: Update histogram stats
|
||||
* @hist_delay: Delay histogram
|
||||
* @value: Delay value
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void dp_hist_update_stats(struct cdp_hist_stats *hist_stats, int value);
|
||||
void dp_hist_init(struct cdp_hist_stats *hist_stats,
|
||||
enum cdp_hist_types hist_type);
|
||||
void dp_accumulate_hist_stats(struct cdp_hist_stats *src_hist_stats,
|
||||
struct cdp_hist_stats *dst_hist_stats);
|
||||
void dp_copy_hist_stats(struct cdp_hist_stats *src_hist_stats,
|
||||
struct cdp_hist_stats *dst_hist_stats);
|
||||
#endif /* __DP_HIST_H_ */
|
||||
5835
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.c
Normal file
5835
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.c
Normal file
File diff suppressed because it is too large
Load diff
490
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.h
Normal file
490
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.h
Normal file
|
|
@ -0,0 +1,490 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _DP_HTT_H_
|
||||
#define _DP_HTT_H_
|
||||
|
||||
#include <qdf_types.h>
|
||||
#include <qdf_lock.h>
|
||||
#include <qdf_nbuf.h>
|
||||
#include <htc_api.h>
|
||||
|
||||
#include "cdp_txrx_cmn_struct.h"
|
||||
#include "dp_types.h"
|
||||
#ifdef HTT_LOGGER
|
||||
#include "dp_htt_logger.h"
|
||||
#else
|
||||
struct htt_logger;
|
||||
static inline
|
||||
void htt_interface_logging_init(struct htt_logger **htt_logger_handle)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
void htt_interface_logging_deinit(struct htt_logger *htt_logger_handle)
|
||||
{
|
||||
}
|
||||
|
||||
static inline
|
||||
int htt_command_record(struct htt_logger *h, uint8_t msg_type,
|
||||
uint8_t *msg_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int htt_event_record(struct htt_logger *h, uint8_t msg_type,
|
||||
uint8_t *msg_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int htt_wbm_event_record(struct htt_logger *h, uint8_t tx_status,
|
||||
uint8_t *msg_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void htt_htc_pkt_pool_free(struct htt_soc *soc);
|
||||
|
||||
#define HTT_TX_MUTEX_TYPE qdf_spinlock_t
|
||||
|
||||
#define HTT_TX_MUTEX_INIT(_mutex) \
|
||||
qdf_spinlock_create(_mutex)
|
||||
|
||||
#define HTT_TX_MUTEX_ACQUIRE(_mutex) \
|
||||
qdf_spin_lock_bh(_mutex)
|
||||
|
||||
#define HTT_TX_MUTEX_RELEASE(_mutex) \
|
||||
qdf_spin_unlock_bh(_mutex)
|
||||
|
||||
#define HTT_TX_MUTEX_DESTROY(_mutex) \
|
||||
qdf_spinlock_destroy(_mutex)
|
||||
|
||||
#define DP_HTT_MAX_SEND_QUEUE_DEPTH 64
|
||||
|
||||
#ifndef HTT_MAC_ADDR_LEN
|
||||
#define HTT_MAC_ADDR_LEN 6
|
||||
#endif
|
||||
|
||||
#define HTT_FRAMECTRL_TYPE_MASK 0x0C
|
||||
#define HTT_GET_FRAME_CTRL_TYPE(_val) \
|
||||
(((_val) & HTT_FRAMECTRL_TYPE_MASK) >> 2)
|
||||
#define FRAME_CTRL_TYPE_MGMT 0x0
|
||||
#define FRAME_CTRL_TYPE_CTRL 0x1
|
||||
#define FRAME_CTRL_TYPE_DATA 0x2
|
||||
#define FRAME_CTRL_TYPE_RESV 0x3
|
||||
|
||||
#define HTT_FRAMECTRL_DATATYPE 0x08
|
||||
#define HTT_PPDU_DESC_MAX_DEPTH 16
|
||||
#define DP_SCAN_PEER_ID 0xFFFF
|
||||
|
||||
#define HTT_RX_DELBA_WIN_SIZE_M 0x0000FC00
|
||||
#define HTT_RX_DELBA_WIN_SIZE_S 10
|
||||
|
||||
#define HTT_RX_DELBA_WIN_SIZE_GET(word) \
|
||||
(((word) & HTT_RX_DELBA_WIN_SIZE_M) >> HTT_RX_DELBA_WIN_SIZE_S)
|
||||
|
||||
/*
|
||||
* Set the base misclist size to HTT copy engine source ring size
|
||||
* to guarantee that a packet on the misclist wont be freed while it
|
||||
* is sitting in the copy engine.
|
||||
*/
|
||||
#define DP_HTT_HTC_PKT_MISCLIST_SIZE 2048
|
||||
#define HTT_T2H_MAX_MSG_SIZE 2048
|
||||
|
||||
#define HTT_T2H_EXT_STATS_TLV_START_OFFSET 3
|
||||
|
||||
/*
|
||||
* Below offset are based on htt_ppdu_stats_common_tlv
|
||||
* defined in htt_ppdu_stats.h
|
||||
*/
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_TLV_HDR_OFFSET 0
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_PPDU_ID_OFFSET 1
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_RING_ID_SCH_CMD_ID_OFFSET 2
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_QTYPE_FRM_TYPE_OFFSET 3
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_CHAIN_MASK_OFFSET 4
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_FES_DUR_US_OFFSET 5
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_SCH_EVAL_START_TSTMP_L32_US_OFFSET 6
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_SCH_END_TSTMP_US_OFFSET 7
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_START_TSTMP_L32_US_OFFSET 8
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_CHAN_MHZ_PHY_MODE_OFFSET 9
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_CCA_DELTA_TIME_US_OFFSET 10
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_RXFRM_DELTA_TIME_US_OFFSET 11
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_TXFRM_DELTA_TIME_US_OFFSET 12
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_RESV_NUM_UL_BEAM_OFFSET 13
|
||||
#define HTT_PPDU_STATS_COMMON_TLV_START_TSTMP_U32_US_OFFSET 14
|
||||
|
||||
/* get index for field in htt_ppdu_stats_common_tlv */
|
||||
#define HTT_GET_STATS_CMN_INDEX(index) \
|
||||
HTT_PPDU_STATS_COMMON_TLV_##index##_OFFSET
|
||||
|
||||
#define MAX_SCHED_STARVE 100000
|
||||
#define WRAP_DROP_TSF_DELTA 10000
|
||||
#define MAX_TSF_32 0xFFFFFFFF
|
||||
|
||||
/**
|
||||
* enum dp_full_mon_config - enum to enable/disable full monitor mode
|
||||
*
|
||||
* @DP_FULL_MON_DISABLE: Disable full monitor mode
|
||||
* @DP_FULL_MON_ENABLE: Enable full monitor mode
|
||||
*/
|
||||
enum dp_full_mon_config {
|
||||
DP_FULL_MON_DISABLE,
|
||||
DP_FULL_MON_ENABLE,
|
||||
};
|
||||
|
||||
struct dp_htt_htc_pkt {
|
||||
void *soc_ctxt;
|
||||
qdf_dma_addr_t nbuf_paddr;
|
||||
HTC_PACKET htc_pkt;
|
||||
};
|
||||
|
||||
struct dp_htt_htc_pkt_union {
|
||||
union {
|
||||
struct dp_htt_htc_pkt pkt;
|
||||
struct dp_htt_htc_pkt_union *next;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct dp_htt_timestamp {
|
||||
long *umac_ttt;
|
||||
long *lmac_ttt;
|
||||
};
|
||||
|
||||
struct htt_soc {
|
||||
struct cdp_ctrl_objmgr_psoc *ctrl_psoc;
|
||||
struct dp_soc *dp_soc;
|
||||
hal_soc_handle_t hal_soc;
|
||||
struct dp_htt_timestamp pdevid_tt[MAX_PDEV_CNT];
|
||||
/* htt_logger handle */
|
||||
struct htt_logger *htt_logger_handle;
|
||||
HTC_HANDLE htc_soc;
|
||||
qdf_device_t osdev;
|
||||
HTC_ENDPOINT_ID htc_endpoint;
|
||||
struct dp_htt_htc_pkt_union *htt_htc_pkt_freelist;
|
||||
struct dp_htt_htc_pkt_union *htt_htc_pkt_misclist;
|
||||
struct {
|
||||
u_int8_t major;
|
||||
u_int8_t minor;
|
||||
} tgt_ver;
|
||||
struct {
|
||||
u_int8_t major;
|
||||
u_int8_t minor;
|
||||
} wifi_ip_ver;
|
||||
|
||||
struct {
|
||||
int htc_err_cnt;
|
||||
int htc_pkt_free;
|
||||
int skip_count;
|
||||
int fail_count;
|
||||
/* rtpm put skip count for ver req msg */
|
||||
int htt_ver_req_put_skip;
|
||||
} stats;
|
||||
|
||||
HTT_TX_MUTEX_TYPE htt_tx_mutex;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct htt_rx_ring_tlv_filter - Rx ring TLV filter
|
||||
* enable/disable.
|
||||
* @mpdu_start: enable/disable MPDU start TLV
|
||||
* @msdu_start: enable/disable MSDU start TLV
|
||||
* @packet: enable/disable PACKET TLV
|
||||
* @msdu_end: enable/disable MSDU end TLV
|
||||
* @mpdu_end: enable/disable MPDU end TLV
|
||||
* @packet_header: enable/disable PACKET header TLV
|
||||
* @attention: enable/disable ATTENTION TLV
|
||||
* @ppdu_start: enable/disable PPDU start TLV
|
||||
* @ppdu_end: enable/disable PPDU end TLV
|
||||
* @ppdu_end_user_stats: enable/disable PPDU user stats TLV
|
||||
* @ppdu_end_user_stats_ext: enable/disable PPDU user stats ext TLV
|
||||
* @ppdu_end_status_done: enable/disable PPDU end status done TLV
|
||||
* @enable_fp: enable/disable FP packet
|
||||
* @enable_md: enable/disable MD packet
|
||||
* @enable_mo: enable/disable MO packet
|
||||
* @enable_mgmt: enable/disable MGMT packet
|
||||
* @enable_ctrl: enable/disable CTRL packet
|
||||
* @enable_data: enable/disable DATA packet
|
||||
* @offset_valid: Flag to indicate if below offsets are valid
|
||||
* @rx_packet_offset: Offset of packet payload
|
||||
* @rx_header_offset: Offset of rx_header tlv
|
||||
* @rx_mpdu_end_offset: Offset of rx_mpdu_end tlv
|
||||
* @rx_mpdu_start_offset: Offset of rx_mpdu_start tlv
|
||||
* @rx_msdu_end_offset: Offset of rx_msdu_end tlv
|
||||
* @rx_msdu_start_offset: Offset of rx_msdu_start tlv
|
||||
* @rx_attn_offset: Offset of rx_attention tlv
|
||||
*
|
||||
* NOTE: Do not change the layout of this structure
|
||||
*/
|
||||
struct htt_rx_ring_tlv_filter {
|
||||
u_int32_t mpdu_start:1,
|
||||
msdu_start:1,
|
||||
packet:1,
|
||||
msdu_end:1,
|
||||
mpdu_end:1,
|
||||
packet_header:1,
|
||||
attention:1,
|
||||
ppdu_start:1,
|
||||
ppdu_end:1,
|
||||
ppdu_end_user_stats:1,
|
||||
ppdu_end_user_stats_ext:1,
|
||||
ppdu_end_status_done:1,
|
||||
header_per_msdu:1,
|
||||
enable_fp:1,
|
||||
enable_md:1,
|
||||
enable_mo:1;
|
||||
u_int32_t fp_mgmt_filter:16,
|
||||
mo_mgmt_filter:16;
|
||||
u_int32_t fp_ctrl_filter:16,
|
||||
mo_ctrl_filter:16;
|
||||
u_int32_t fp_data_filter:16,
|
||||
mo_data_filter:16;
|
||||
u_int16_t md_data_filter;
|
||||
u_int16_t md_mgmt_filter;
|
||||
u_int16_t md_ctrl_filter;
|
||||
bool offset_valid;
|
||||
uint16_t rx_packet_offset;
|
||||
uint16_t rx_header_offset;
|
||||
uint16_t rx_mpdu_end_offset;
|
||||
uint16_t rx_mpdu_start_offset;
|
||||
uint16_t rx_msdu_end_offset;
|
||||
uint16_t rx_msdu_start_offset;
|
||||
uint16_t rx_attn_offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_htt_rx_flow_fst_setup - Rx FST setup message
|
||||
* @pdev_id: DP Pdev identifier
|
||||
* @max_entries: Size of Rx FST in number of entries
|
||||
* @max_search: Number of collisions allowed
|
||||
* @base_addr_lo: lower 32-bit physical address
|
||||
* @base_addr_hi: upper 32-bit physical address
|
||||
* @ip_da_sa_prefix: IPv4 prefix to map to IPv6 address scheme
|
||||
* @hash_key_len: Rx FST hash key size
|
||||
* @hash_key: Rx FST Toeplitz hash key
|
||||
*/
|
||||
struct dp_htt_rx_flow_fst_setup {
|
||||
uint8_t pdev_id;
|
||||
uint32_t max_entries;
|
||||
uint32_t max_search;
|
||||
uint32_t base_addr_lo;
|
||||
uint32_t base_addr_hi;
|
||||
uint32_t ip_da_sa_prefix;
|
||||
uint32_t hash_key_len;
|
||||
uint8_t *hash_key;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dp_htt_flow_fst_operation - FST related operations allowed
|
||||
* @DP_HTT_FST_CACHE_OP_NONE: Cache no-op
|
||||
* @DP_HTT_FST_CACHE_INVALIDATE_ENTRY: Invalidate single cache entry
|
||||
* @DP_HTT_FST_CACHE_INVALIDATE_FULL: Invalidate entire cache
|
||||
* @DP_HTT_FST_ENABLE: Bypass FST is enabled
|
||||
* @DP_HTT_FST_DISABLE: Disable bypass FST
|
||||
*/
|
||||
enum dp_htt_flow_fst_operation {
|
||||
DP_HTT_FST_CACHE_OP_NONE,
|
||||
DP_HTT_FST_CACHE_INVALIDATE_ENTRY,
|
||||
DP_HTT_FST_CACHE_INVALIDATE_FULL,
|
||||
DP_HTT_FST_ENABLE,
|
||||
DP_HTT_FST_DISABLE
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_htt_rx_flow_fst_setup - Rx FST setup message
|
||||
* @pdev_id: DP Pdev identifier
|
||||
* @op_code: FST operation to be performed by FW/HW
|
||||
* @rx_flow: Rx Flow information on which operation is to be performed
|
||||
*/
|
||||
struct dp_htt_rx_flow_fst_operation {
|
||||
uint8_t pdev_id;
|
||||
enum dp_htt_flow_fst_operation op_code;
|
||||
struct cdp_rx_flow_info *rx_flow;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_htt_rx_fisa_config - Rx fisa config
|
||||
* @pdev_id: DP Pdev identifier
|
||||
* @fisa_timeout: fisa aggregation timeout
|
||||
*/
|
||||
struct dp_htt_rx_fisa_cfg {
|
||||
uint8_t pdev_id;
|
||||
uint32_t fisa_timeout;
|
||||
};
|
||||
|
||||
QDF_STATUS dp_htt_rx_fisa_config(struct dp_pdev *pdev,
|
||||
struct dp_htt_rx_fisa_cfg *fisa_config);
|
||||
|
||||
/*
|
||||
* htt_soc_initialize() - SOC level HTT initialization
|
||||
* @htt_soc: Opaque htt SOC handle
|
||||
* @ctrl_psoc: Opaque ctrl SOC handle
|
||||
* @htc_soc: SOC level HTC handle
|
||||
* @hal_soc: Opaque HAL SOC handle
|
||||
* @osdev: QDF device
|
||||
*
|
||||
* Return: HTT handle on success; NULL on failure
|
||||
*/
|
||||
void *
|
||||
htt_soc_initialize(struct htt_soc *htt_soc,
|
||||
struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
HTC_HANDLE htc_soc,
|
||||
hal_soc_handle_t hal_soc_hdl, qdf_device_t osdev);
|
||||
|
||||
/*
|
||||
* htt_soc_attach() - attach DP and HTT SOC
|
||||
* @soc: DP SOC handle
|
||||
* @htc_hdl: HTC handle
|
||||
*
|
||||
* Return: htt_soc handle on Success, NULL on Failure
|
||||
*/
|
||||
struct htt_soc *htt_soc_attach(struct dp_soc *soc, HTC_HANDLE htc_hdl);
|
||||
|
||||
/*
|
||||
* htt_set_htc_handle_() - set HTC handle
|
||||
* @htt_hdl: HTT handle/SOC
|
||||
* @htc_soc: HTC handle
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void htt_set_htc_handle(struct htt_soc *htt_hdl, HTC_HANDLE htc_soc);
|
||||
|
||||
/*
|
||||
* htt_get_htc_handle_() - set HTC handle
|
||||
* @htt_hdl: HTT handle/SOC
|
||||
*
|
||||
* Return: HTC_HANDLE
|
||||
*/
|
||||
HTC_HANDLE htt_get_htc_handle(struct htt_soc *htt_hdl);
|
||||
|
||||
/*
|
||||
* htt_soc_htc_dealloc() - HTC memory de-alloc
|
||||
* @htt_soc: SOC level HTT handle
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void htt_soc_htc_dealloc(struct htt_soc *htt_handle);
|
||||
|
||||
/*
|
||||
* htt_soc_htc_prealloc() - HTC memory prealloc
|
||||
* @htt_soc: SOC level HTT handle
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success or
|
||||
* QDF_STATUS_E_NO_MEM on allocation failure
|
||||
*/
|
||||
QDF_STATUS htt_soc_htc_prealloc(struct htt_soc *htt_soc);
|
||||
|
||||
void htt_soc_detach(struct htt_soc *soc);
|
||||
|
||||
int htt_srng_setup(struct htt_soc *htt_soc, int pdev_id,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
int hal_ring_type);
|
||||
|
||||
int htt_soc_attach_target(struct htt_soc *htt_soc);
|
||||
|
||||
/*
|
||||
* htt_h2t_rx_ring_cfg() - Send SRNG packet and TLV filter
|
||||
* config message to target
|
||||
* @htt_soc: HTT SOC handle
|
||||
* @pdev_id: PDEV Id
|
||||
* @hal_srng: Opaque HAL SRNG pointer
|
||||
* @hal_ring_type: SRNG ring type
|
||||
* @ring_buf_size: SRNG buffer size
|
||||
* @htt_tlv_filter: Rx SRNG TLV and filter setting
|
||||
*
|
||||
* Return: 0 on success; error code on failure
|
||||
*/
|
||||
int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
int hal_ring_type, int ring_buf_size,
|
||||
struct htt_rx_ring_tlv_filter *htt_tlv_filter);
|
||||
|
||||
/*
|
||||
* htt_t2h_stats_handler() - target to host stats work handler
|
||||
* @context: context (dp soc context)
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void htt_t2h_stats_handler(void *context);
|
||||
|
||||
/**
|
||||
* struct htt_stats_context - htt stats information
|
||||
* @soc: Size of each descriptor in the pool
|
||||
* @msg: T2H Ext stats message queue
|
||||
* @msg_len: T2H Ext stats message length
|
||||
*/
|
||||
struct htt_stats_context {
|
||||
struct dp_soc *soc;
|
||||
qdf_nbuf_queue_t msg;
|
||||
uint32_t msg_len;
|
||||
};
|
||||
|
||||
int
|
||||
dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap);
|
||||
|
||||
/**
|
||||
* dp_ppdu_desc_user_stats_update(): Function to update TX user stats
|
||||
* @pdev: DP pdev handle
|
||||
* @ppdu_info: per PPDU TLV descriptor
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
void
|
||||
dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
|
||||
struct ppdu_info *ppdu_info);
|
||||
|
||||
/**
|
||||
* dp_htt_rx_flow_fst_setup(): Send HTT Rx FST setup message to FW
|
||||
* @pdev: DP pdev handle
|
||||
* @fse_setup_info: FST setup parameters
|
||||
*
|
||||
* Return: Success when HTT message is sent, error on failure
|
||||
*/
|
||||
QDF_STATUS
|
||||
dp_htt_rx_flow_fst_setup(struct dp_pdev *pdev,
|
||||
struct dp_htt_rx_flow_fst_setup *setup_info);
|
||||
|
||||
/**
|
||||
* dp_htt_rx_flow_fse_operation(): Send HTT Flow Search Entry msg to
|
||||
* add/del a flow in HW
|
||||
* @pdev: DP pdev handle
|
||||
* @fse_op_info: Flow entry parameters
|
||||
*
|
||||
* Return: Success when HTT message is sent, error on failure
|
||||
*/
|
||||
QDF_STATUS
|
||||
dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev,
|
||||
struct dp_htt_rx_flow_fst_operation *op_info);
|
||||
|
||||
/**
|
||||
* htt_h2t_full_mon_cfg() - Send full monitor configuarion msg to FW
|
||||
*
|
||||
* @htt_soc: HTT Soc handle
|
||||
* @pdev_id: Radio id
|
||||
* @dp_full_mon_config: enabled/disable configuration
|
||||
*
|
||||
* Return: Success when HTT message is sent, error on failure
|
||||
*/
|
||||
int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
|
||||
uint8_t pdev_id,
|
||||
enum dp_full_mon_config);
|
||||
#endif /* _DP_HTT_H_ */
|
||||
2745
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_internal.h
Normal file
2745
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_internal.h
Normal file
File diff suppressed because it is too large
Load diff
2223
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.c
Normal file
2223
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.c
Normal file
File diff suppressed because it is too large
Load diff
411
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.h
Normal file
411
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_ipa.h
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _DP_IPA_H_
|
||||
#define _DP_IPA_H_
|
||||
|
||||
#define IPA_TCL_DATA_RING_IDX 2
|
||||
#ifdef IPA_OFFLOAD
|
||||
|
||||
#define DP_IPA_MAX_IFACE 3
|
||||
#define IPA_REO_DEST_RING_IDX 3
|
||||
#define IPA_RX_REFILL_BUF_RING_IDX 2
|
||||
|
||||
/* Adding delay before disabling ipa pipes if any Tx Completions are pending */
|
||||
#define TX_COMP_DRAIN_WAIT_MS 50
|
||||
#define TX_COMP_DRAIN_WAIT_TIMEOUT_MS 100
|
||||
|
||||
/**
|
||||
* struct dp_ipa_uc_tx_hdr - full tx header registered to IPA hardware
|
||||
* @eth: ether II header
|
||||
*/
|
||||
struct dp_ipa_uc_tx_hdr {
|
||||
struct ethhdr eth;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct dp_ipa_uc_rx_hdr - full rx header registered to IPA hardware
|
||||
* @eth: ether II header
|
||||
*/
|
||||
struct dp_ipa_uc_rx_hdr {
|
||||
struct ethhdr eth;
|
||||
} __packed;
|
||||
|
||||
#define DP_IPA_UC_WLAN_TX_HDR_LEN sizeof(struct dp_ipa_uc_tx_hdr)
|
||||
#define DP_IPA_UC_WLAN_RX_HDR_LEN sizeof(struct dp_ipa_uc_rx_hdr)
|
||||
#define DP_IPA_UC_WLAN_HDR_DES_MAC_OFFSET 0
|
||||
|
||||
/**
|
||||
* dp_ipa_get_resource() - Client request resource information
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* IPA client will request IPA UC related resource information
|
||||
* Resource information will be distributed to IPA module
|
||||
* All of the required resources should be pre-allocated
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* dp_ipa_set_doorbell_paddr () - Set doorbell register physical address to SRNG
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Set TX_COMP_DOORBELL register physical address to WBM Head_Ptr_MemAddr_LSB
|
||||
* Set RX_READ_DOORBELL register physical address to REO Head_Ptr_MemAddr_LSB
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl,
|
||||
uint8_t pdev_id);
|
||||
QDF_STATUS dp_ipa_uc_set_active(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
bool uc_active, bool is_tx);
|
||||
|
||||
/**
|
||||
* dp_ipa_op_response() - Handle OP command response from firmware
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
* @op_msg: op response message from firmware
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_ipa_op_response(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
uint8_t *op_msg);
|
||||
|
||||
/**
|
||||
* dp_ipa_register_op_cb() - Register OP handler function
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
* @op_cb: handler function pointer
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_ipa_register_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
ipa_uc_op_cb_type op_cb, void *usr_ctxt);
|
||||
|
||||
/**
|
||||
* dp_ipa_register_op_cb() - Deregister OP handler function
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_ipa_deregister_op_cb(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* dp_ipa_get_stat() - Get firmware wdi status
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_ipa_get_stat(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* dp_tx_send_ipa_data_frame() - send IPA data frame
|
||||
* @soc_hdl: datapath soc handle
|
||||
* @vdev_id: virtual device/interface id
|
||||
* @skb: skb
|
||||
*
|
||||
* Return: skb/ NULL is for success
|
||||
*/
|
||||
qdf_nbuf_t dp_tx_send_ipa_data_frame(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
qdf_nbuf_t skb);
|
||||
|
||||
/**
|
||||
* dp_ipa_enable_autonomy() – Enable autonomy RX path
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Set all RX packet route to IPA REO ring
|
||||
* Program Destination_Ring_Ctrl_IX_0 REO register to point IPA REO ring
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_ipa_enable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* dp_ipa_disable_autonomy() – Disable autonomy RX path
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
*
|
||||
* Disable RX packet routing to IPA REO
|
||||
* Program Destination_Ring_Ctrl_IX_0 REO register to disable
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_ipa_disable_autonomy(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
#ifdef CONFIG_IPA_WDI_UNIFIED_API
|
||||
/**
|
||||
* dp_ipa_setup() - Setup and connect IPA pipes
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
* @ipa_i2w_cb: IPA to WLAN callback
|
||||
* @ipa_w2i_cb: WLAN to IPA callback
|
||||
* @ipa_wdi_meter_notifier_cb: IPA WDI metering callback
|
||||
* @ipa_desc_size: IPA descriptor size
|
||||
* @ipa_priv: handle to the HTT instance
|
||||
* @is_rm_enabled: Is IPA RM enabled or not
|
||||
* @tx_pipe_handle: pointer to Tx pipe handle
|
||||
* @rx_pipe_handle: pointer to Rx pipe handle
|
||||
* @is_smmu_enabled: Is SMMU enabled or not
|
||||
* @sys_in: parameters to setup sys pipe in mcc mode
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
void *ipa_i2w_cb, void *ipa_w2i_cb,
|
||||
void *ipa_wdi_meter_notifier_cb,
|
||||
uint32_t ipa_desc_size, void *ipa_priv,
|
||||
bool is_rm_enabled, uint32_t *tx_pipe_handle,
|
||||
uint32_t *rx_pipe_handle,
|
||||
bool is_smmu_enabled,
|
||||
qdf_ipa_sys_connect_params_t *sys_in, bool over_gsi);
|
||||
#else /* CONFIG_IPA_WDI_UNIFIED_API */
|
||||
/**
|
||||
* dp_ipa_setup() - Setup and connect IPA pipes
|
||||
* @soc_hdl - data path soc handle
|
||||
* @pdev_id - device instance id
|
||||
* @ipa_i2w_cb: IPA to WLAN callback
|
||||
* @ipa_w2i_cb: WLAN to IPA callback
|
||||
* @ipa_wdi_meter_notifier_cb: IPA WDI metering callback
|
||||
* @ipa_desc_size: IPA descriptor size
|
||||
* @ipa_priv: handle to the HTT instance
|
||||
* @is_rm_enabled: Is IPA RM enabled or not
|
||||
* @tx_pipe_handle: pointer to Tx pipe handle
|
||||
* @rx_pipe_handle: pointer to Rx pipe handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
void *ipa_i2w_cb, void *ipa_w2i_cb,
|
||||
void *ipa_wdi_meter_notifier_cb,
|
||||
uint32_t ipa_desc_size, void *ipa_priv,
|
||||
bool is_rm_enabled, uint32_t *tx_pipe_handle,
|
||||
uint32_t *rx_pipe_handle);
|
||||
#endif /* CONFIG_IPA_WDI_UNIFIED_API */
|
||||
QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
|
||||
uint32_t tx_pipe_handle,
|
||||
uint32_t rx_pipe_handle);
|
||||
QDF_STATUS dp_ipa_remove_header(char *name);
|
||||
int dp_ipa_add_header_info(char *ifname, uint8_t *mac_addr,
|
||||
uint8_t session_id, bool is_ipv6_enabled);
|
||||
int dp_ipa_register_interface(char *ifname, bool is_ipv6_enabled);
|
||||
QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
|
||||
qdf_ipa_client_type_t prod_client,
|
||||
qdf_ipa_client_type_t cons_client,
|
||||
uint8_t session_id, bool is_ipv6_enabled);
|
||||
QDF_STATUS dp_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled);
|
||||
|
||||
/**
|
||||
* dp_ipa_uc_enable_pipes() - Enable and resume traffic on Tx/Rx pipes
|
||||
* @soc_hdl - handle to the soc
|
||||
* @pdev_id - pdev id number, to get the handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* dp_ipa_disable_pipes() – Suspend traffic and disable Tx/Rx pipes
|
||||
* @soc_hdl - handle to the soc
|
||||
* @pdev_id - pdev id number, to get the handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_ipa_disable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
QDF_STATUS dp_ipa_set_perf_level(int client,
|
||||
uint32_t max_supported_bw_mbps);
|
||||
|
||||
/**
|
||||
* dp_ipa_rx_intrabss_fwd() - Perform intra-bss fwd for IPA RX path
|
||||
*
|
||||
* @soc_hdl: data path soc handle
|
||||
* @vdev_id: virtual device/interface id
|
||||
* @nbuf: pointer to skb of ethernet packet received from IPA RX path
|
||||
* @fwd_success: pointer to indicate if skb succeeded in intra-bss TX
|
||||
*
|
||||
* This function performs intra-bss forwarding for WDI 3.0 IPA RX path.
|
||||
*
|
||||
* Return: true if packet is intra-bss fwd-ed and no need to pass to
|
||||
* network stack. false if packet needs to be passed to network stack.
|
||||
*/
|
||||
bool dp_ipa_rx_intrabss_fwd(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf, bool *fwd_success);
|
||||
int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev);
|
||||
int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev);
|
||||
int dp_ipa_ring_resource_setup(struct dp_soc *soc,
|
||||
struct dp_pdev *pdev);
|
||||
QDF_STATUS dp_ipa_handle_rx_buf_smmu_mapping(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf,
|
||||
uint32_t size,
|
||||
bool create);
|
||||
|
||||
bool dp_reo_remap_config(struct dp_soc *soc, uint32_t *remap1,
|
||||
uint32_t *remap2);
|
||||
bool dp_ipa_is_mdm_platform(void);
|
||||
|
||||
qdf_nbuf_t dp_ipa_handle_rx_reo_reinject(struct dp_soc *soc, qdf_nbuf_t nbuf);
|
||||
|
||||
/**
|
||||
* dp_ipa_tx_buf_smmu_mapping() - Create SMMU mappings for IPA
|
||||
* allocated TX buffers
|
||||
* @soc_hdl: handle to the soc
|
||||
* @pdev_id: pdev id number, to get the handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_ipa_tx_buf_smmu_mapping(
|
||||
struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* dp_ipa_tx_buf_smmu_unmapping() - Release SMMU mappings for IPA
|
||||
* allocated TX buffers
|
||||
* @soc_hdl: handle to the soc
|
||||
* @pdev_id: pdev id number, to get the handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_ipa_tx_buf_smmu_unmapping(
|
||||
struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
|
||||
|
||||
#ifndef QCA_OL_DP_SRNG_LOCK_LESS_ACCESS
|
||||
static inline void
|
||||
dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc)
|
||||
{
|
||||
if (soc->ipa_rx_buf_map_lock_initialized)
|
||||
qdf_spin_lock_bh(&soc->ipa_rx_buf_map_lock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc)
|
||||
{
|
||||
if (soc->ipa_rx_buf_map_lock_initialized)
|
||||
qdf_spin_unlock_bh(&soc->ipa_rx_buf_map_lock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc,
|
||||
uint32_t reo_ring_num)
|
||||
{
|
||||
if (!soc->ipa_reo_ctx_lock_required[reo_ring_num])
|
||||
return;
|
||||
|
||||
qdf_spin_lock_bh(&soc->ipa_rx_buf_map_lock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc,
|
||||
uint32_t reo_ring_num)
|
||||
{
|
||||
if (!soc->ipa_reo_ctx_lock_required[reo_ring_num])
|
||||
return;
|
||||
|
||||
qdf_spin_unlock_bh(&soc->ipa_rx_buf_map_lock);
|
||||
}
|
||||
#else
|
||||
|
||||
static inline void
|
||||
dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc,
|
||||
uint32_t reo_ring_num)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc,
|
||||
uint32_t reo_ring_num)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
static inline int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int dp_ipa_ring_resource_setup(struct dp_soc *soc,
|
||||
struct dp_pdev *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS dp_ipa_handle_rx_buf_smmu_mapping(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf,
|
||||
uint32_t size,
|
||||
bool create)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc,
|
||||
uint32_t reo_ring_num)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc,
|
||||
uint32_t reo_ring_num)
|
||||
{
|
||||
}
|
||||
|
||||
static inline qdf_nbuf_t dp_ipa_handle_rx_reo_reinject(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS dp_ipa_tx_buf_smmu_mapping(struct cdp_soc_t *soc_hdl,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS dp_ipa_tx_buf_smmu_unmapping(struct cdp_soc_t *soc_hdl,
|
||||
uint8_t pdev_id)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* _DP_IPA_H_ */
|
||||
14250
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_main.c
Normal file
14250
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_main.c
Normal file
File diff suppressed because it is too large
Load diff
1213
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.c
Normal file
1213
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.c
Normal file
File diff suppressed because it is too large
Load diff
262
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.h
Normal file
262
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_mon_filter.h
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _DP_MON_FILTER_H_
|
||||
#define _DP_MON_FILTER_H_
|
||||
|
||||
/**
|
||||
* Accessor Macros to access the software
|
||||
* defined HTT filter htt_rx_ring_tlv_filter.
|
||||
*/
|
||||
#define DP_MON_FILTER_TLV_OFFSET 0x00000000
|
||||
#define DP_MON_FILTER_TLV_MASK 0xffffffff
|
||||
#define DP_MON_FILTER_TLV_LSB 0
|
||||
|
||||
#define DP_MON_FILTER_FP_MGMT_OFFSET 0x00000004
|
||||
#define DP_MON_FILTER_FP_MGMT_MASK 0x0000ffff
|
||||
#define DP_MON_FILTER_FP_MGMT_LSB 0
|
||||
|
||||
#define DP_MON_FILTER_MO_MGMT_OFFSET 0x00000004
|
||||
#define DP_MON_FILTER_MO_MGMT_MASK 0xffff0000
|
||||
#define DP_MON_FILTER_MO_MGMT_LSB 16
|
||||
|
||||
#define DP_MON_FILTER_FP_CTRL_OFFSET 0x00000008
|
||||
#define DP_MON_FILTER_FP_CTRL_MASK 0x0000ffff
|
||||
#define DP_MON_FILTER_FP_CTRL_LSB 0
|
||||
|
||||
#define DP_MON_FILTER_MO_CTRL_OFFSET 0x00000008
|
||||
#define DP_MON_FILTER_MO_CTRL_MASK 0xffff0000
|
||||
#define DP_MON_FILTER_MO_CTRL_LSB 16
|
||||
|
||||
#define DP_MON_FILTER_FP_DATA_OFFSET 0x0000000c
|
||||
#define DP_MON_FILTER_FP_DATA_MASK 0x0000ffff
|
||||
#define DP_MON_FILTER_FP_DATA_LSB 0
|
||||
|
||||
#define DP_MON_FILTER_MO_DATA_OFFSET 0x0000000c
|
||||
#define DP_MON_FILTER_MO_DATA_MASK 0xffff0000
|
||||
#define DP_MON_FILTER_MO_DATA_LSB 16
|
||||
|
||||
#define DP_MON_FILTER_MD_DATA_OFFSET 0x00000010
|
||||
#define DP_MON_FILTER_MD_DATA_MASK 0x0000ffff
|
||||
#define DP_MON_FILTER_MD_DATA_LSB 0
|
||||
|
||||
#define DP_MON_FILTER_MD_MGMT_OFFSET 0x00000010
|
||||
#define DP_MON_FILTER_MD_MGMT_MASK 0xffff0000
|
||||
#define DP_MON_FILTER_MD_MGMT_LSB 16
|
||||
|
||||
#define DP_MON_FILTER_MD_CTRL_OFFSET 0x00000014
|
||||
#define DP_MON_FILTER_MD_CTRL_MASK 0x0000ffff
|
||||
#define DP_MON_FILTER_MD_CTRL_LSB 0
|
||||
|
||||
#define DP_MON_FILTER_GET(src, field) \
|
||||
((*((uint32_t *)((uint8_t *)(src) + DP_MON_ ## field ## _OFFSET)) & \
|
||||
(DP_MON_ ## field ## _MASK)) >> DP_MON_ ## field ## _LSB) \
|
||||
|
||||
#define DP_MON_FILTER_SET(dst, field, value) \
|
||||
do { \
|
||||
uint32_t *val = \
|
||||
((uint32_t *)((uint8_t *)(dst) + DP_MON_ ## field ## _OFFSET)); \
|
||||
*val &= ~(DP_MON_ ## field ## _MASK); \
|
||||
*val |= ((value) << DP_MON_ ## field ## _LSB); \
|
||||
} while (0)
|
||||
|
||||
#define DP_MON_FILTER_PRINT(fmt, args ...) \
|
||||
QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_DEBUG, \
|
||||
fmt, ## args)
|
||||
/**
|
||||
* struct dp_mon_filter - Monitor TLV filter
|
||||
* @valid: enable/disable TLV filter
|
||||
* @tlv_filter: Rx ring TLV filter
|
||||
*/
|
||||
struct dp_mon_filter {
|
||||
bool valid;
|
||||
struct htt_rx_ring_tlv_filter tlv_filter;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dp_mon_filter_mode - Different modes for SRNG filters
|
||||
* @DP_MON_FILTER_ENHACHED_STATS_MODE: PPDU enhanced stats mode
|
||||
* @DP_MON_FILTER_SMART_MONITOR_MODE: Smart monitor mode
|
||||
* @DP_MON_FILTER_MCOPY_MODE: AM copy mode
|
||||
* @DP_MON_FILTER_MONITOR_MODE: Monitor mode
|
||||
* @DP_MON_FILTER_RX_CAPTURE_MODE: Rx Capture mode
|
||||
* @DP_MON_FILTER_PKT_LOG_FULL_MODE: Packet log full mode
|
||||
* @DP_MON_FILTER_PKT_LOG_LITE_MODE: Packet log lite mode
|
||||
*/
|
||||
enum dp_mon_filter_mode {
|
||||
#ifdef FEATURE_PERPKT_INFO
|
||||
DP_MON_FILTER_ENHACHED_STATS_MODE,
|
||||
DP_MON_FILTER_MCOPY_MODE,
|
||||
#endif /* FEATURE_PERPKT_INFO */
|
||||
#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
|
||||
DP_MON_FILTER_SMART_MONITOR_MODE,
|
||||
#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
|
||||
DP_MON_FILTER_MONITOR_MODE,
|
||||
#ifdef WLAN_RX_PKT_CAPTURE_ENH
|
||||
DP_MON_FILTER_RX_CAPTURE_MODE,
|
||||
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
|
||||
|
||||
#ifdef WDI_EVENT_ENABLE
|
||||
DP_MON_FILTER_PKT_LOG_FULL_MODE,
|
||||
DP_MON_FILTER_PKT_LOG_LITE_MODE,
|
||||
#endif /* WDI_EVENT_ENABLE */
|
||||
DP_MON_FILTER_MAX_MODE
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dp_mon_filter_srng_type - Srng types dynamic mode filter
|
||||
* settings.
|
||||
* @DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF: RXDMA srng type
|
||||
* @DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS: RxDMA monitor status srng
|
||||
* @DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF: RxDMA destination srng
|
||||
* @DP_MON_FILTER_SRNG_TYPE_MAX: Srng max type
|
||||
*/
|
||||
enum dp_mon_filter_srng_type {
|
||||
DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF,
|
||||
DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS,
|
||||
DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF,
|
||||
DP_MON_FILTER_SRNG_TYPE_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* enum dp_mon_filter_action - Action for storing the filters
|
||||
* into the radio structure.
|
||||
* @DP_MON_FILTER_CLEAR - Clears the filter for a mode
|
||||
* @DP_MON_FILTER_SET - Set the filtes for a mode
|
||||
*/
|
||||
enum dp_mon_filter_action {
|
||||
DP_MON_FILTER_CLEAR,
|
||||
DP_MON_FILTER_SET,
|
||||
};
|
||||
|
||||
#ifdef FEATURE_PERPKT_INFO
|
||||
/**
|
||||
* dp_mon_filter_setup_enhanced_stats() - Setup the enhanced stats filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev);
|
||||
|
||||
/***
|
||||
* dp_mon_filter_reset_enhanced_stats() - Reset the enhanced stats filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_setup_mcopy_mode() - Setup the m_copy mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_reset_mcopy_mode() - Reset the m_copy mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev);
|
||||
#endif /* FEATURE_PERPKT_INFO */
|
||||
|
||||
#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
|
||||
/**
|
||||
* dp_mon_filter_setup_smart_monitor() - Setup the smart monitor mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_reset_smart_monitor() - Reset the smart monitor mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev);
|
||||
#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
|
||||
|
||||
#ifdef WLAN_RX_PKT_CAPTURE_ENH
|
||||
/**
|
||||
* dp_mon_filter_setup_rx_enh_capture() - Setup the Rx capture mode filters
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_reset_rx_enh_capture() - Reset the Rx capture mode filters
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev);
|
||||
#endif /* WLAN_RX_PKT_CAPTURE_ENH */
|
||||
|
||||
/**
|
||||
* dp_mon_filter_setup_mon_mode() - Setup the Rx monitor mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_reset_mon_mode() - Reset the Rx monitor mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev);
|
||||
|
||||
#ifdef WDI_EVENT_ENABLE
|
||||
/**
|
||||
* dp_mon_filter_setup_rx_pkt_log_full() - Setup the Rx pktlog full mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_reset_rx_pkt_log_full() - Reset the Rx pktlog full mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_setup_rx_pkt_log_lite() - Setup the Rx pktlog lite mode filter
|
||||
* in the radio object.
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_reset_rx_pkt_log_lite() - Reset the Rx pktlog lite mode filter
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev);
|
||||
#endif /* WDI_EVENT_ENABLE */
|
||||
|
||||
/**
|
||||
* dp_mon_filter_update() - Setup the monitor filter setting for a srng
|
||||
* type
|
||||
* @pdev: DP pdev handle
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_dealloc() - Deallocate the filter objects to be stored in
|
||||
* the radio object.
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
void dp_mon_filter_dealloc(struct dp_pdev *pdev);
|
||||
|
||||
/**
|
||||
* dp_mon_filter_alloc() - Allocate the filter objects to be stored in
|
||||
* the radio object.
|
||||
* @pdev: DP pdev handle
|
||||
*/
|
||||
struct dp_mon_filter **dp_mon_filter_alloc(struct dp_pdev *pdev);
|
||||
#endif /* #ifndef _DP_MON_FILTER_H_ */
|
||||
4682
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.c
Normal file
4682
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.c
Normal file
File diff suppressed because it is too large
Load diff
954
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.h
Normal file
954
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_peer.h
Normal file
|
|
@ -0,0 +1,954 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef _DP_PEER_H_
|
||||
#define _DP_PEER_H_
|
||||
|
||||
#include <qdf_types.h>
|
||||
#include <qdf_lock.h>
|
||||
#include "dp_types.h"
|
||||
|
||||
#ifdef DUMP_REO_QUEUE_INFO_IN_DDR
|
||||
#include "hal_reo.h"
|
||||
#endif
|
||||
|
||||
#define DP_INVALID_PEER_ID 0xffff
|
||||
|
||||
#define DP_FW_PEER_STATS_CMP_TIMEOUT_MSEC 5000
|
||||
|
||||
#ifdef REO_QDESC_HISTORY
|
||||
enum reo_qdesc_event_type {
|
||||
REO_QDESC_UPDATE_CB = 0,
|
||||
REO_QDESC_FREE,
|
||||
};
|
||||
|
||||
struct reo_qdesc_event {
|
||||
qdf_dma_addr_t qdesc_addr;
|
||||
uint64_t ts;
|
||||
enum reo_qdesc_event_type type;
|
||||
uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef void dp_peer_iter_func(struct dp_soc *soc, struct dp_peer *peer,
|
||||
void *arg);
|
||||
void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id id);
|
||||
|
||||
/**
|
||||
* dp_peer_get_ref() - Returns peer object given the peer id
|
||||
*
|
||||
* @soc : core DP soc context
|
||||
* @peer : DP peer
|
||||
* @mod_id : id of module requesting the reference
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS if reference held successfully
|
||||
* else QDF_STATUS_E_INVAL
|
||||
*/
|
||||
static inline
|
||||
QDF_STATUS dp_peer_get_ref(struct dp_soc *soc,
|
||||
struct dp_peer *peer,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
if (!qdf_atomic_inc_not_zero(&peer->ref_cnt))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
if (mod_id > DP_MOD_ID_RX)
|
||||
qdf_atomic_inc(&peer->mod_refs[mod_id]);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* __dp_peer_get_ref_by_id() - Returns peer object given the peer id
|
||||
*
|
||||
* @soc : core DP soc context
|
||||
* @peer_id : peer id from peer object can be retrieved
|
||||
* @mod_id : module id
|
||||
*
|
||||
* Return: struct dp_peer*: Pointer to DP peer object
|
||||
*/
|
||||
static inline struct dp_peer *
|
||||
__dp_peer_get_ref_by_id(struct dp_soc *soc,
|
||||
uint16_t peer_id,
|
||||
enum dp_mod_id mod_id)
|
||||
|
||||
{
|
||||
struct dp_peer *peer;
|
||||
|
||||
qdf_spin_lock_bh(&soc->peer_map_lock);
|
||||
peer = (peer_id >= soc->max_peers) ? NULL :
|
||||
soc->peer_id_to_obj_map[peer_id];
|
||||
if (!peer ||
|
||||
(dp_peer_get_ref(soc, peer, mod_id) != QDF_STATUS_SUCCESS)) {
|
||||
qdf_spin_unlock_bh(&soc->peer_map_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdf_spin_unlock_bh(&soc->peer_map_lock);
|
||||
return peer;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_get_ref_by_id() - Returns peer object given the peer id
|
||||
* if peer state is active
|
||||
*
|
||||
* @soc : core DP soc context
|
||||
* @peer_id : peer id from peer object can be retrieved
|
||||
* @mod_id : ID ot module requesting reference
|
||||
*
|
||||
* Return: struct dp_peer*: Pointer to DP peer object
|
||||
*/
|
||||
static inline
|
||||
struct dp_peer *dp_peer_get_ref_by_id(struct dp_soc *soc,
|
||||
uint16_t peer_id,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
struct dp_peer *peer;
|
||||
|
||||
qdf_spin_lock_bh(&soc->peer_map_lock);
|
||||
peer = (peer_id >= soc->max_peers) ? NULL :
|
||||
soc->peer_id_to_obj_map[peer_id];
|
||||
|
||||
if (!peer || peer->peer_state >= DP_PEER_STATE_LOGICAL_DELETE ||
|
||||
(dp_peer_get_ref(soc, peer, mod_id) != QDF_STATUS_SUCCESS)) {
|
||||
qdf_spin_unlock_bh(&soc->peer_map_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdf_spin_unlock_bh(&soc->peer_map_lock);
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
||||
#ifdef PEER_CACHE_RX_PKTS
|
||||
/**
|
||||
* dp_rx_flush_rx_cached() - flush cached rx frames
|
||||
* @peer: peer
|
||||
* @drop: set flag to drop frames
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop);
|
||||
#else
|
||||
static inline void dp_rx_flush_rx_cached(struct dp_peer *peer, bool drop)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
dp_clear_peer_internal(struct dp_soc *soc, struct dp_peer *peer)
|
||||
{
|
||||
qdf_spin_lock_bh(&peer->peer_info_lock);
|
||||
peer->state = OL_TXRX_PEER_STATE_DISC;
|
||||
qdf_spin_unlock_bh(&peer->peer_info_lock);
|
||||
|
||||
dp_rx_flush_rx_cached(peer, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_vdev_iterate_peer() - API to iterate through vdev peer list
|
||||
*
|
||||
* @vdev : DP vdev context
|
||||
* @func : function to be called for each peer
|
||||
* @arg : argument need to be passed to func
|
||||
* @mod_id : module_id
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
dp_vdev_iterate_peer(struct dp_vdev *vdev, dp_peer_iter_func *func, void *arg,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
struct dp_peer *peer;
|
||||
struct dp_peer *tmp_peer;
|
||||
struct dp_soc *soc = NULL;
|
||||
|
||||
if (!vdev || !vdev->pdev || !vdev->pdev->soc)
|
||||
return;
|
||||
|
||||
soc = vdev->pdev->soc;
|
||||
|
||||
qdf_spin_lock_bh(&vdev->peer_list_lock);
|
||||
TAILQ_FOREACH_SAFE(peer, &vdev->peer_list,
|
||||
peer_list_elem,
|
||||
tmp_peer) {
|
||||
if (dp_peer_get_ref(soc, peer, mod_id) ==
|
||||
QDF_STATUS_SUCCESS) {
|
||||
(*func)(soc, peer, arg);
|
||||
dp_peer_unref_delete(peer, mod_id);
|
||||
}
|
||||
}
|
||||
qdf_spin_unlock_bh(&vdev->peer_list_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_pdev_iterate_peer() - API to iterate through all peers of pdev
|
||||
*
|
||||
* @pdev : DP pdev context
|
||||
* @func : function to be called for each peer
|
||||
* @arg : argument need to be passed to func
|
||||
* @mod_id : module_id
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
dp_pdev_iterate_peer(struct dp_pdev *pdev, dp_peer_iter_func *func, void *arg,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
struct dp_vdev *vdev;
|
||||
|
||||
if (!pdev)
|
||||
return;
|
||||
|
||||
qdf_spin_lock_bh(&pdev->vdev_list_lock);
|
||||
DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev)
|
||||
dp_vdev_iterate_peer(vdev, func, arg, mod_id);
|
||||
qdf_spin_unlock_bh(&pdev->vdev_list_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_soc_iterate_peer() - API to iterate through all peers of soc
|
||||
*
|
||||
* @soc : DP soc context
|
||||
* @func : function to be called for each peer
|
||||
* @arg : argument need to be passed to func
|
||||
* @mod_id : module_id
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
dp_soc_iterate_peer(struct dp_soc *soc, dp_peer_iter_func *func, void *arg,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
struct dp_pdev *pdev;
|
||||
int i;
|
||||
|
||||
if (!soc)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) {
|
||||
pdev = soc->pdev_list[i];
|
||||
dp_pdev_iterate_peer(pdev, func, arg, mod_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_vdev_iterate_peer_lock_safe() - API to iterate through vdev list
|
||||
*
|
||||
* This API will cache the peers in local allocated memory and calls
|
||||
* iterate function outside the lock.
|
||||
*
|
||||
* As this API is allocating new memory it is suggested to use this
|
||||
* only when lock cannot be held
|
||||
*
|
||||
* @vdev : DP vdev context
|
||||
* @func : function to be called for each peer
|
||||
* @arg : argument need to be passed to func
|
||||
* @mod_id : module_id
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
dp_vdev_iterate_peer_lock_safe(struct dp_vdev *vdev,
|
||||
dp_peer_iter_func *func,
|
||||
void *arg,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
struct dp_peer *peer;
|
||||
struct dp_peer *tmp_peer;
|
||||
struct dp_soc *soc = NULL;
|
||||
struct dp_peer **peer_array = NULL;
|
||||
int i = 0;
|
||||
uint32_t num_peers = 0;
|
||||
|
||||
if (!vdev || !vdev->pdev || !vdev->pdev->soc)
|
||||
return;
|
||||
|
||||
num_peers = vdev->num_peers;
|
||||
|
||||
soc = vdev->pdev->soc;
|
||||
|
||||
peer_array = qdf_mem_malloc(num_peers * sizeof(struct dp_peer *));
|
||||
if (!peer_array)
|
||||
return;
|
||||
|
||||
qdf_spin_lock_bh(&vdev->peer_list_lock);
|
||||
TAILQ_FOREACH_SAFE(peer, &vdev->peer_list,
|
||||
peer_list_elem,
|
||||
tmp_peer) {
|
||||
if (i >= num_peers)
|
||||
break;
|
||||
|
||||
if (dp_peer_get_ref(soc, peer, mod_id) == QDF_STATUS_SUCCESS) {
|
||||
peer_array[i] = peer;
|
||||
i = (i + 1);
|
||||
}
|
||||
}
|
||||
qdf_spin_unlock_bh(&vdev->peer_list_lock);
|
||||
|
||||
for (i = 0; i < num_peers; i++) {
|
||||
peer = peer_array[i];
|
||||
|
||||
if (!peer)
|
||||
continue;
|
||||
|
||||
(*func)(soc, peer, arg);
|
||||
dp_peer_unref_delete(peer, mod_id);
|
||||
}
|
||||
|
||||
qdf_mem_free(peer_array);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_pdev_iterate_peer_lock_safe() - API to iterate through all peers of pdev
|
||||
*
|
||||
* This API will cache the peers in local allocated memory and calls
|
||||
* iterate function outside the lock.
|
||||
*
|
||||
* As this API is allocating new memory it is suggested to use this
|
||||
* only when lock cannot be held
|
||||
*
|
||||
* @pdev : DP pdev context
|
||||
* @func : function to be called for each peer
|
||||
* @arg : argument need to be passed to func
|
||||
* @mod_id : module_id
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
dp_pdev_iterate_peer_lock_safe(struct dp_pdev *pdev,
|
||||
dp_peer_iter_func *func,
|
||||
void *arg,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
struct dp_peer *peer;
|
||||
struct dp_peer *tmp_peer;
|
||||
struct dp_soc *soc = NULL;
|
||||
struct dp_vdev *vdev = NULL;
|
||||
struct dp_peer **peer_array[DP_PDEV_MAX_VDEVS] = {0};
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
uint32_t num_peers[DP_PDEV_MAX_VDEVS] = {0};
|
||||
|
||||
if (!pdev || !pdev->soc)
|
||||
return;
|
||||
|
||||
soc = pdev->soc;
|
||||
|
||||
qdf_spin_lock_bh(&pdev->vdev_list_lock);
|
||||
DP_PDEV_ITERATE_VDEV_LIST(pdev, vdev) {
|
||||
num_peers[i] = vdev->num_peers;
|
||||
peer_array[i] = qdf_mem_malloc(num_peers[i] *
|
||||
sizeof(struct dp_peer *));
|
||||
if (!peer_array[i])
|
||||
break;
|
||||
|
||||
qdf_spin_lock_bh(&vdev->peer_list_lock);
|
||||
TAILQ_FOREACH_SAFE(peer, &vdev->peer_list,
|
||||
peer_list_elem,
|
||||
tmp_peer) {
|
||||
if (j >= num_peers[i])
|
||||
break;
|
||||
|
||||
if (dp_peer_get_ref(soc, peer, mod_id) ==
|
||||
QDF_STATUS_SUCCESS) {
|
||||
peer_array[i][j] = peer;
|
||||
|
||||
j = (j + 1);
|
||||
}
|
||||
}
|
||||
qdf_spin_unlock_bh(&vdev->peer_list_lock);
|
||||
i = (i + 1);
|
||||
}
|
||||
qdf_spin_unlock_bh(&pdev->vdev_list_lock);
|
||||
|
||||
for (i = 0; i < DP_PDEV_MAX_VDEVS; i++) {
|
||||
if (!peer_array[i])
|
||||
break;
|
||||
|
||||
for (j = 0; j < num_peers[i]; j++) {
|
||||
peer = peer_array[i][j];
|
||||
|
||||
if (!peer)
|
||||
continue;
|
||||
|
||||
(*func)(soc, peer, arg);
|
||||
dp_peer_unref_delete(peer, mod_id);
|
||||
}
|
||||
|
||||
qdf_mem_free(peer_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_soc_iterate_peer_lock_safe() - API to iterate through all peers of soc
|
||||
*
|
||||
* This API will cache the peers in local allocated memory and calls
|
||||
* iterate function outside the lock.
|
||||
*
|
||||
* As this API is allocating new memory it is suggested to use this
|
||||
* only when lock cannot be held
|
||||
*
|
||||
* @soc : DP soc context
|
||||
* @func : function to be called for each peer
|
||||
* @arg : argument need to be passed to func
|
||||
* @mod_id : module_id
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void
|
||||
dp_soc_iterate_peer_lock_safe(struct dp_soc *soc,
|
||||
dp_peer_iter_func *func,
|
||||
void *arg,
|
||||
enum dp_mod_id mod_id)
|
||||
{
|
||||
struct dp_pdev *pdev;
|
||||
int i;
|
||||
|
||||
if (!soc)
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_PDEV_CNT && soc->pdev_list[i]; i++) {
|
||||
pdev = soc->pdev_list[i];
|
||||
dp_pdev_iterate_peer_lock_safe(pdev, func, arg, mod_id);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DP_PEER_STATE_DEBUG
|
||||
#define DP_PEER_STATE_ASSERT(_peer, _new_state, _condition) \
|
||||
do { \
|
||||
if (!(_condition)) { \
|
||||
dp_alert("Invalid state shift from %u to %u peer " \
|
||||
QDF_MAC_ADDR_FMT, \
|
||||
(_peer)->peer_state, (_new_state), \
|
||||
QDF_MAC_ADDR_REF((_peer)->mac_addr.raw)); \
|
||||
QDF_ASSERT(0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define DP_PEER_STATE_ASSERT(_peer, _new_state, _condition) \
|
||||
do { \
|
||||
if (!(_condition)) { \
|
||||
dp_alert("Invalid state shift from %u to %u peer " \
|
||||
QDF_MAC_ADDR_FMT, \
|
||||
(_peer)->peer_state, (_new_state), \
|
||||
QDF_MAC_ADDR_REF((_peer)->mac_addr.raw)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_peer_state_cmp() - compare dp peer state
|
||||
*
|
||||
* @peer : DP peer
|
||||
* @state : state
|
||||
*
|
||||
* Return: true if state matches with peer state
|
||||
* false if it does not match
|
||||
*/
|
||||
static inline bool
|
||||
dp_peer_state_cmp(struct dp_peer *peer,
|
||||
enum dp_peer_state state)
|
||||
{
|
||||
bool is_status_equal = false;
|
||||
|
||||
qdf_spin_lock_bh(&peer->peer_state_lock);
|
||||
is_status_equal = (peer->peer_state == state);
|
||||
qdf_spin_unlock_bh(&peer->peer_state_lock);
|
||||
|
||||
return is_status_equal;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_update_state() - update dp peer state
|
||||
*
|
||||
* @soc : core DP soc context
|
||||
* @peer : DP peer
|
||||
* @state : new state
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
dp_peer_update_state(struct dp_soc *soc,
|
||||
struct dp_peer *peer,
|
||||
enum dp_peer_state state)
|
||||
{
|
||||
uint8_t peer_state;
|
||||
|
||||
qdf_spin_lock_bh(&peer->peer_state_lock);
|
||||
peer_state = peer->peer_state;
|
||||
|
||||
switch (state) {
|
||||
case DP_PEER_STATE_INIT:
|
||||
DP_PEER_STATE_ASSERT
|
||||
(peer, state, (peer_state != DP_PEER_STATE_ACTIVE) ||
|
||||
(peer_state != DP_PEER_STATE_LOGICAL_DELETE));
|
||||
break;
|
||||
|
||||
case DP_PEER_STATE_ACTIVE:
|
||||
DP_PEER_STATE_ASSERT(peer, state,
|
||||
(peer_state == DP_PEER_STATE_INIT));
|
||||
break;
|
||||
|
||||
case DP_PEER_STATE_LOGICAL_DELETE:
|
||||
DP_PEER_STATE_ASSERT(peer, state,
|
||||
(peer_state == DP_PEER_STATE_ACTIVE) ||
|
||||
(peer_state == DP_PEER_STATE_INIT));
|
||||
break;
|
||||
|
||||
case DP_PEER_STATE_INACTIVE:
|
||||
DP_PEER_STATE_ASSERT
|
||||
(peer, state,
|
||||
(peer_state == DP_PEER_STATE_LOGICAL_DELETE));
|
||||
break;
|
||||
|
||||
case DP_PEER_STATE_FREED:
|
||||
if (peer->sta_self_peer)
|
||||
DP_PEER_STATE_ASSERT
|
||||
(peer, state, (peer_state == DP_PEER_STATE_INIT));
|
||||
else
|
||||
DP_PEER_STATE_ASSERT
|
||||
(peer, state,
|
||||
(peer_state == DP_PEER_STATE_INACTIVE) ||
|
||||
(peer_state == DP_PEER_STATE_LOGICAL_DELETE));
|
||||
break;
|
||||
|
||||
default:
|
||||
qdf_spin_unlock_bh(&peer->peer_state_lock);
|
||||
dp_alert("Invalid peer state %u for peer "QDF_MAC_ADDR_FMT,
|
||||
state, QDF_MAC_ADDR_REF(peer->mac_addr.raw));
|
||||
return;
|
||||
}
|
||||
peer->peer_state = state;
|
||||
qdf_spin_unlock_bh(&peer->peer_state_lock);
|
||||
dp_info("Updating peer state from %u to %u mac "QDF_MAC_ADDR_FMT"\n",
|
||||
peer_state, state,
|
||||
QDF_MAC_ADDR_REF(peer->mac_addr.raw));
|
||||
}
|
||||
|
||||
void dp_print_ast_stats(struct dp_soc *soc);
|
||||
QDF_STATUS dp_rx_peer_map_handler(struct dp_soc *soc, uint16_t peer_id,
|
||||
uint16_t hw_peer_id, uint8_t vdev_id,
|
||||
uint8_t *peer_mac_addr, uint16_t ast_hash,
|
||||
uint8_t is_wds);
|
||||
void dp_rx_peer_unmap_handler(struct dp_soc *soc, uint16_t peer_id,
|
||||
uint8_t vdev_id, uint8_t *peer_mac_addr,
|
||||
uint8_t is_wds, uint32_t free_wds_count);
|
||||
void dp_rx_sec_ind_handler(struct dp_soc *soc, uint16_t peer_id,
|
||||
enum cdp_sec_type sec_type, int is_unicast,
|
||||
u_int32_t *michael_key, u_int32_t *rx_pn);
|
||||
|
||||
QDF_STATUS dp_rx_delba_ind_handler(void *soc_handle, uint16_t peer_id,
|
||||
uint8_t tid, uint16_t win_sz);
|
||||
|
||||
uint8_t dp_get_peer_mac_addr_frm_id(struct cdp_soc_t *soc_handle,
|
||||
uint16_t peer_id, uint8_t *peer_mac);
|
||||
|
||||
QDF_STATUS dp_peer_add_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||
uint8_t *mac_addr, enum cdp_txrx_ast_entry_type type,
|
||||
uint32_t flags);
|
||||
|
||||
void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry);
|
||||
|
||||
void dp_peer_ast_unmap_handler(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ast_entry);
|
||||
|
||||
int dp_peer_update_ast(struct dp_soc *soc, struct dp_peer *peer,
|
||||
struct dp_ast_entry *ast_entry, uint32_t flags);
|
||||
|
||||
struct dp_ast_entry *dp_peer_ast_hash_find_by_pdevid(struct dp_soc *soc,
|
||||
uint8_t *ast_mac_addr,
|
||||
uint8_t pdev_id);
|
||||
|
||||
struct dp_ast_entry *dp_peer_ast_hash_find_by_vdevid(struct dp_soc *soc,
|
||||
uint8_t *ast_mac_addr,
|
||||
uint8_t vdev_id);
|
||||
|
||||
struct dp_ast_entry *dp_peer_ast_hash_find_soc(struct dp_soc *soc,
|
||||
uint8_t *ast_mac_addr);
|
||||
|
||||
uint8_t dp_peer_ast_get_pdev_id(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ast_entry);
|
||||
|
||||
|
||||
uint8_t dp_peer_ast_get_next_hop(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ast_entry);
|
||||
|
||||
void dp_peer_ast_set_type(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ast_entry,
|
||||
enum cdp_txrx_ast_entry_type type);
|
||||
|
||||
void dp_peer_ast_send_wds_del(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ast_entry,
|
||||
struct dp_peer *peer);
|
||||
|
||||
void dp_peer_free_hmwds_cb(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
struct cdp_soc *dp_soc,
|
||||
void *cookie,
|
||||
enum cdp_ast_free_status status);
|
||||
|
||||
void dp_peer_ast_hash_remove(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ase);
|
||||
|
||||
void dp_peer_free_ast_entry(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ast_entry);
|
||||
|
||||
void dp_peer_unlink_ast_entry(struct dp_soc *soc,
|
||||
struct dp_ast_entry *ast_entry,
|
||||
struct dp_peer *peer);
|
||||
|
||||
#define DP_AST_ASSERT(_condition) \
|
||||
do { \
|
||||
if (!(_condition)) { \
|
||||
dp_print_ast_stats(soc);\
|
||||
QDF_BUG(_condition); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* dp_peer_update_inactive_time - Update inactive time for peer
|
||||
* @pdev: pdev object
|
||||
* @tag_type: htt_tlv_tag type
|
||||
* #tag_buf: buf message
|
||||
*/
|
||||
void
|
||||
dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type,
|
||||
uint32_t *tag_buf);
|
||||
|
||||
#ifndef QCA_MULTIPASS_SUPPORT
|
||||
/**
|
||||
* dp_peer_set_vlan_id: set vlan_id for this peer
|
||||
* @cdp_soc: soc handle
|
||||
* @vdev_id: id of vdev object
|
||||
* @peer_mac: mac address
|
||||
* @vlan_id: vlan id for peer
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static inline
|
||||
void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc,
|
||||
uint8_t vdev_id, uint8_t *peer_mac,
|
||||
uint16_t vlan_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_set_vlan_groupkey: set vlan map for vdev
|
||||
* @soc: pointer to soc
|
||||
* @vdev_id: id of vdev handle
|
||||
* @vlan_id: vlan_id
|
||||
* @group_key: group key for vlan
|
||||
*
|
||||
* return: set success/failure
|
||||
*/
|
||||
static inline
|
||||
QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
uint16_t vlan_id, uint16_t group_key)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_multipass_list_init: initialize multipass peer list
|
||||
* @vdev: pointer to vdev
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static inline
|
||||
void dp_peer_multipass_list_init(struct dp_vdev *vdev)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_multipass_list_remove: remove peer from special peer list
|
||||
* @peer: peer handle
|
||||
*
|
||||
* return: void
|
||||
*/
|
||||
static inline
|
||||
void dp_peer_multipass_list_remove(struct dp_peer *peer)
|
||||
{
|
||||
}
|
||||
#else
|
||||
void dp_peer_set_vlan_id(struct cdp_soc_t *cdp_soc,
|
||||
uint8_t vdev_id, uint8_t *peer_mac,
|
||||
uint16_t vlan_id);
|
||||
QDF_STATUS dp_set_vlan_groupkey(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
uint16_t vlan_id, uint16_t group_key);
|
||||
void dp_peer_multipass_list_init(struct dp_vdev *vdev);
|
||||
void dp_peer_multipass_list_remove(struct dp_peer *peer);
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef QCA_PEER_MULTIQ_SUPPORT
|
||||
/**
|
||||
* dp_peer_reset_flowq_map() - reset peer flowq map table
|
||||
* @peer - dp peer handle
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline
|
||||
void dp_peer_reset_flowq_map(struct dp_peer *peer)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_ast_index_flow_queue_map_create() - create ast index flow queue map
|
||||
* @soc - genereic soc handle
|
||||
* @is_wds - flag to indicate if peer is wds
|
||||
* @peer_id - peer_id from htt peer map message
|
||||
* @peer_mac_addr - mac address of the peer
|
||||
* @ast_info - ast flow override information from peer map
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline
|
||||
void dp_peer_ast_index_flow_queue_map_create(void *soc_hdl,
|
||||
bool is_wds, uint16_t peer_id, uint8_t *peer_mac_addr,
|
||||
struct dp_ast_flow_override_info *ast_info)
|
||||
{
|
||||
}
|
||||
#else
|
||||
void dp_peer_reset_flowq_map(struct dp_peer *peer);
|
||||
void dp_peer_ast_index_flow_queue_map_create(void *soc_hdl,
|
||||
bool is_wds, uint16_t peer_id, uint8_t *peer_mac_addr,
|
||||
struct dp_ast_flow_override_info *ast_info);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_peer_update_pkt_capture_params: Set Rx & Tx Capture flags for a peer
|
||||
* @soc: DP SOC handle
|
||||
* @pdev_id: id of DP pdev handle
|
||||
* @is_rx_pkt_cap_enable: enable/disable Rx packet capture in monitor mode
|
||||
* @is_tx_pkt_cap_enable: enable/disable/delete/print
|
||||
* Tx packet capture in monitor mode
|
||||
* Tx packet capture in monitor mode
|
||||
* @peer_mac: MAC address for which the above need to be enabled/disabled
|
||||
*
|
||||
* Return: Success if Rx & Tx capture is enabled for peer, false otherwise
|
||||
*/
|
||||
QDF_STATUS
|
||||
dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,
|
||||
uint8_t pdev_id,
|
||||
bool is_rx_pkt_cap_enable,
|
||||
uint8_t is_tx_pkt_cap_enable,
|
||||
uint8_t *peer_mac);
|
||||
|
||||
/*
|
||||
* dp_rx_tid_delete_cb() - Callback to flush reo descriptor HW cache
|
||||
* after deleting the entries (ie., setting valid=0)
|
||||
*
|
||||
* @soc: DP SOC handle
|
||||
* @cb_ctxt: Callback context
|
||||
* @reo_status: REO command status
|
||||
*/
|
||||
void dp_rx_tid_delete_cb(struct dp_soc *soc,
|
||||
void *cb_ctxt,
|
||||
union hal_reo_status *reo_status);
|
||||
|
||||
#ifndef WLAN_TX_PKT_CAPTURE_ENH
|
||||
/**
|
||||
* dp_peer_tid_queue_init() – Initialize ppdu stats queue per TID
|
||||
* @peer: Datapath peer
|
||||
*
|
||||
*/
|
||||
static inline void dp_peer_tid_queue_init(struct dp_peer *peer)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_tid_peer_id_update() – update peer_id to tid structure
|
||||
* @peer: Datapath peer
|
||||
* @peer_id: peer_id
|
||||
*
|
||||
*/
|
||||
static inline
|
||||
void dp_peer_tid_peer_id_update(struct dp_peer *peer, uint16_t peer_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_tid_queue_cleanup() – remove ppdu stats queue per TID
|
||||
* @peer: Datapath peer
|
||||
*
|
||||
*/
|
||||
static inline void dp_peer_tid_queue_cleanup(struct dp_peer *peer)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_peer_update_80211_hdr() – dp peer update 80211 hdr
|
||||
* @vdev: Datapath vdev
|
||||
* @peer: Datapath peer
|
||||
*
|
||||
*/
|
||||
static inline void
|
||||
dp_peer_update_80211_hdr(struct dp_vdev *vdev, struct dp_peer *peer)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef QCA_PEER_EXT_STATS
|
||||
QDF_STATUS dp_peer_ext_stats_ctx_alloc(struct dp_soc *soc,
|
||||
struct dp_peer *peer);
|
||||
void dp_peer_ext_stats_ctx_dealloc(struct dp_soc *soc,
|
||||
struct dp_peer *peer);
|
||||
#else
|
||||
static inline QDF_STATUS dp_peer_ext_stats_ctx_alloc(struct dp_soc *soc,
|
||||
struct dp_peer *peer)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void dp_peer_ext_stats_ctx_dealloc(struct dp_soc *soc,
|
||||
struct dp_peer *peer)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
struct dp_peer *dp_vdev_bss_peer_ref_n_get(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
enum dp_mod_id mod_id);
|
||||
struct dp_peer *dp_sta_vdev_self_peer_ref_n_get(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
enum dp_mod_id mod_id);
|
||||
|
||||
#ifdef FEATURE_AST
|
||||
/*
|
||||
* dp_peer_delete_ast_entries(): Delete all AST entries for a peer
|
||||
* @soc - datapath soc handle
|
||||
* @peer - datapath peer handle
|
||||
*
|
||||
* Delete the AST entries belonging to a peer
|
||||
*/
|
||||
static inline void dp_peer_delete_ast_entries(struct dp_soc *soc,
|
||||
struct dp_peer *peer)
|
||||
{
|
||||
struct dp_ast_entry *ast_entry, *temp_ast_entry;
|
||||
|
||||
dp_debug("peer: %pK, self_ast: %pK", peer, peer->self_ast_entry);
|
||||
/*
|
||||
* Delete peer self ast entry. This is done to handle scenarios
|
||||
* where peer is freed before peer map is received(for ex in case
|
||||
* of auth disallow due to ACL) in such cases self ast is not added
|
||||
* to peer->ast_list.
|
||||
*/
|
||||
if (peer->self_ast_entry) {
|
||||
dp_peer_del_ast(soc, peer->self_ast_entry);
|
||||
peer->self_ast_entry = NULL;
|
||||
}
|
||||
|
||||
DP_PEER_ITERATE_ASE_LIST(peer, ast_entry, temp_ast_entry)
|
||||
dp_peer_del_ast(soc, ast_entry);
|
||||
}
|
||||
#else
|
||||
static inline void dp_peer_delete_ast_entries(struct dp_soc *soc,
|
||||
struct dp_peer *peer)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_MEC
|
||||
/**
|
||||
* dp_peer_mec_spinlock_create() - Create the MEC spinlock
|
||||
* @soc: SoC handle
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_peer_mec_spinlock_create(struct dp_soc *soc);
|
||||
|
||||
/**
|
||||
* dp_peer_mec_spinlock_destroy() - Destroy the MEC spinlock
|
||||
* @soc: SoC handle
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_peer_mec_spinlock_destroy(struct dp_soc *soc);
|
||||
|
||||
/**
|
||||
* dp_peer_mec_flush_entries() - Delete all mec entries in table
|
||||
* @soc: Datapath SOC
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_peer_mec_flush_entries(struct dp_soc *soc);
|
||||
#else
|
||||
static inline void dp_peer_mec_spinlock_create(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void dp_peer_mec_spinlock_destroy(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void dp_peer_mec_flush_entries(struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DUMP_REO_QUEUE_INFO_IN_DDR
|
||||
/**
|
||||
* dp_send_cache_flush_for_rx_tid() - Send cache flush cmd to REO per tid
|
||||
* @soc : dp_soc handle
|
||||
* @peer: peer
|
||||
*
|
||||
* This function is used to send cache flush cmd to reo and
|
||||
* to register the callback to handle the dumping of the reo
|
||||
* queue stas from DDR
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_send_cache_flush_for_rx_tid(
|
||||
struct dp_soc *soc, struct dp_peer *peer);
|
||||
|
||||
/**
|
||||
* dp_get_rx_reo_queue_info() - Handler to get rx tid info
|
||||
* @soc : cdp_soc_t handle
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* Handler to get rx tid info from DDR after h/w cache is
|
||||
* invalidated first using the cache flush cmd.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_get_rx_reo_queue_info(
|
||||
struct cdp_soc_t *soc_hdl, uint8_t vdev_id);
|
||||
|
||||
/**
|
||||
* dp_dump_rx_reo_queue_info() - Callback function to dump reo queue stats
|
||||
* @soc : dp_soc handle
|
||||
* @cb_ctxt - callback context
|
||||
* @reo_status: vdev id
|
||||
*
|
||||
* This is the callback function registered after sending the reo cmd
|
||||
* to flush the h/w cache and invalidate it. In the callback the reo
|
||||
* queue desc info is dumped from DDR.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_dump_rx_reo_queue_info(
|
||||
struct dp_soc *soc, void *cb_ctxt, union hal_reo_status *reo_status);
|
||||
|
||||
#else /* DUMP_REO_QUEUE_INFO_IN_DDR */
|
||||
|
||||
static inline void dp_get_rx_reo_queue_info(
|
||||
struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
|
||||
{
|
||||
}
|
||||
#endif /* DUMP_REO_QUEUE_INFO_IN_DDR */
|
||||
#endif /* _DP_PEER_H_ */
|
||||
239
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_reo.c
Normal file
239
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_reo.c
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "dp_types.h"
|
||||
#include "hal_reo.h"
|
||||
#include "dp_internal.h"
|
||||
#include <qdf_time.h>
|
||||
|
||||
#ifdef WLAN_FEATURE_DP_EVENT_HISTORY
|
||||
/**
|
||||
* dp_reo_cmd_srng_event_record() - Record reo cmds posted
|
||||
* to the reo cmd ring
|
||||
* @soc: dp soc handle
|
||||
* @type: reo cmd type
|
||||
* @post_status: command error status
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static
|
||||
void dp_reo_cmd_srng_event_record(struct dp_soc *soc,
|
||||
enum hal_reo_cmd_type type,
|
||||
int post_status)
|
||||
{
|
||||
struct reo_cmd_event_history *cmd_event_history =
|
||||
&soc->stats.cmd_event_history;
|
||||
struct reo_cmd_event_record *record = cmd_event_history->cmd_record;
|
||||
int record_index;
|
||||
|
||||
record_index = (qdf_atomic_inc_return(&cmd_event_history->index)) &
|
||||
(REO_CMD_EVENT_HIST_MAX - 1);
|
||||
|
||||
record[record_index].cmd_type = type;
|
||||
record[record_index].cmd_return_status = post_status;
|
||||
record[record_index].timestamp = qdf_get_log_timestamp();
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
void dp_reo_cmd_srng_event_record(struct dp_soc *soc,
|
||||
enum hal_reo_cmd_type type,
|
||||
int post_status)
|
||||
{
|
||||
}
|
||||
#endif /*WLAN_FEATURE_DP_EVENT_HISTORY */
|
||||
|
||||
QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc, enum hal_reo_cmd_type type,
|
||||
struct hal_reo_cmd_params *params,
|
||||
void (*callback_fn), void *data)
|
||||
{
|
||||
struct dp_reo_cmd_info *reo_cmd;
|
||||
int num;
|
||||
|
||||
switch (type) {
|
||||
case CMD_GET_QUEUE_STATS:
|
||||
num = hal_reo_cmd_queue_stats(soc->reo_cmd_ring.hal_srng,
|
||||
soc->hal_soc, params);
|
||||
break;
|
||||
case CMD_FLUSH_QUEUE:
|
||||
num = hal_reo_cmd_flush_queue(soc->reo_cmd_ring.hal_srng,
|
||||
soc->hal_soc, params);
|
||||
break;
|
||||
case CMD_FLUSH_CACHE:
|
||||
num = hal_reo_cmd_flush_cache(soc->reo_cmd_ring.hal_srng,
|
||||
soc->hal_soc, params);
|
||||
break;
|
||||
case CMD_UNBLOCK_CACHE:
|
||||
num = hal_reo_cmd_unblock_cache(soc->reo_cmd_ring.hal_srng,
|
||||
soc->hal_soc, params);
|
||||
break;
|
||||
case CMD_FLUSH_TIMEOUT_LIST:
|
||||
num = hal_reo_cmd_flush_timeout_list(soc->reo_cmd_ring.hal_srng,
|
||||
soc->hal_soc, params);
|
||||
break;
|
||||
case CMD_UPDATE_RX_REO_QUEUE:
|
||||
num = hal_reo_cmd_update_rx_queue(soc->reo_cmd_ring.hal_srng,
|
||||
soc->hal_soc, params);
|
||||
break;
|
||||
default:
|
||||
dp_err_log("Invalid REO command type: %d", type);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
};
|
||||
|
||||
dp_reo_cmd_srng_event_record(soc, type, num);
|
||||
|
||||
if (num < 0) {
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (callback_fn) {
|
||||
reo_cmd = qdf_mem_malloc(sizeof(*reo_cmd));
|
||||
if (!reo_cmd) {
|
||||
dp_err_log("alloc failed for REO cmd:%d!!",
|
||||
type);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
reo_cmd->cmd = num;
|
||||
reo_cmd->cmd_type = type;
|
||||
reo_cmd->handler = callback_fn;
|
||||
reo_cmd->data = data;
|
||||
qdf_spin_lock_bh(&soc->rx.reo_cmd_lock);
|
||||
TAILQ_INSERT_TAIL(&soc->rx.reo_cmd_list, reo_cmd,
|
||||
reo_cmd_list_elem);
|
||||
qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock);
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t dp_reo_status_ring_handler(struct dp_intr *int_ctx, struct dp_soc *soc)
|
||||
{
|
||||
uint32_t *reo_desc;
|
||||
struct dp_reo_cmd_info *reo_cmd = NULL;
|
||||
union hal_reo_status reo_status;
|
||||
int num;
|
||||
int processed_count = 0;
|
||||
|
||||
if (dp_srng_access_start(int_ctx, soc, soc->reo_status_ring.hal_srng)) {
|
||||
return processed_count;
|
||||
}
|
||||
reo_desc = hal_srng_dst_get_next(soc->hal_soc,
|
||||
soc->reo_status_ring.hal_srng);
|
||||
|
||||
while (reo_desc) {
|
||||
uint16_t tlv = HAL_GET_TLV(reo_desc);
|
||||
processed_count++;
|
||||
|
||||
switch (tlv) {
|
||||
case HAL_REO_QUEUE_STATS_STATUS_TLV:
|
||||
hal_reo_queue_stats_status(reo_desc,
|
||||
&reo_status.queue_status,
|
||||
soc->hal_soc);
|
||||
num = reo_status.queue_status.header.cmd_num;
|
||||
break;
|
||||
case HAL_REO_FLUSH_QUEUE_STATUS_TLV:
|
||||
hal_reo_flush_queue_status(reo_desc,
|
||||
&reo_status.fl_queue_status,
|
||||
soc->hal_soc);
|
||||
num = reo_status.fl_queue_status.header.cmd_num;
|
||||
break;
|
||||
case HAL_REO_FLUSH_CACHE_STATUS_TLV:
|
||||
hal_reo_flush_cache_status(reo_desc,
|
||||
&reo_status.fl_cache_status,
|
||||
soc->hal_soc);
|
||||
num = reo_status.fl_cache_status.header.cmd_num;
|
||||
break;
|
||||
case HAL_REO_UNBLK_CACHE_STATUS_TLV:
|
||||
hal_reo_unblock_cache_status(reo_desc, soc->hal_soc,
|
||||
&reo_status.unblk_cache_status);
|
||||
num = reo_status.unblk_cache_status.header.cmd_num;
|
||||
break;
|
||||
case HAL_REO_TIMOUT_LIST_STATUS_TLV:
|
||||
hal_reo_flush_timeout_list_status(reo_desc,
|
||||
&reo_status.fl_timeout_status,
|
||||
soc->hal_soc);
|
||||
num = reo_status.fl_timeout_status.header.cmd_num;
|
||||
break;
|
||||
case HAL_REO_DESC_THRES_STATUS_TLV:
|
||||
hal_reo_desc_thres_reached_status(reo_desc,
|
||||
&reo_status.thres_status,
|
||||
soc->hal_soc);
|
||||
num = reo_status.thres_status.header.cmd_num;
|
||||
break;
|
||||
case HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV:
|
||||
hal_reo_rx_update_queue_status(reo_desc,
|
||||
&reo_status.rx_queue_status,
|
||||
soc->hal_soc);
|
||||
num = reo_status.rx_queue_status.header.cmd_num;
|
||||
break;
|
||||
default:
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_WARN,
|
||||
"%s, no handler for TLV:%d", __func__, tlv);
|
||||
goto next;
|
||||
} /* switch */
|
||||
|
||||
qdf_spin_lock_bh(&soc->rx.reo_cmd_lock);
|
||||
TAILQ_FOREACH(reo_cmd, &soc->rx.reo_cmd_list,
|
||||
reo_cmd_list_elem) {
|
||||
if (reo_cmd->cmd == num) {
|
||||
TAILQ_REMOVE(&soc->rx.reo_cmd_list, reo_cmd,
|
||||
reo_cmd_list_elem);
|
||||
break;
|
||||
}
|
||||
}
|
||||
qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock);
|
||||
|
||||
if (reo_cmd) {
|
||||
reo_cmd->handler(soc, reo_cmd->data,
|
||||
&reo_status);
|
||||
qdf_mem_free(reo_cmd);
|
||||
}
|
||||
|
||||
next:
|
||||
reo_desc = hal_srng_dst_get_next(soc,
|
||||
soc->reo_status_ring.hal_srng);
|
||||
} /* while */
|
||||
|
||||
dp_srng_access_end(int_ctx, soc, soc->reo_status_ring.hal_srng);
|
||||
return processed_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_reo_cmdlist_destroy - Free REO commands in the queue
|
||||
* @soc: DP SoC hanle
|
||||
*
|
||||
*/
|
||||
void dp_reo_cmdlist_destroy(struct dp_soc *soc)
|
||||
{
|
||||
struct dp_reo_cmd_info *reo_cmd = NULL;
|
||||
struct dp_reo_cmd_info *tmp_cmd = NULL;
|
||||
union hal_reo_status reo_status;
|
||||
|
||||
reo_status.queue_status.header.status =
|
||||
HAL_REO_CMD_DRAIN;
|
||||
|
||||
qdf_spin_lock_bh(&soc->rx.reo_cmd_lock);
|
||||
TAILQ_FOREACH_SAFE(reo_cmd, &soc->rx.reo_cmd_list,
|
||||
reo_cmd_list_elem, tmp_cmd) {
|
||||
TAILQ_REMOVE(&soc->rx.reo_cmd_list, reo_cmd,
|
||||
reo_cmd_list_elem);
|
||||
reo_cmd->handler(soc, reo_cmd->data, &reo_status);
|
||||
qdf_mem_free(reo_cmd);
|
||||
}
|
||||
qdf_spin_unlock_bh(&soc->rx.reo_cmd_lock);
|
||||
}
|
||||
3540
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.c
Normal file
3540
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.c
Normal file
File diff suppressed because it is too large
Load diff
1639
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.h
Normal file
1639
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx.h
Normal file
File diff suppressed because it is too large
Load diff
395
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_buffer_pool.c
Normal file
395
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_buffer_pool.c
Normal file
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "dp_rx_buffer_pool.h"
|
||||
#include "dp_ipa.h"
|
||||
|
||||
#ifndef DP_RX_BUFFER_POOL_SIZE
|
||||
#define DP_RX_BUFFER_POOL_SIZE 128
|
||||
#endif
|
||||
|
||||
#ifndef DP_RX_BUFF_POOL_ALLOC_THRES
|
||||
#define DP_RX_BUFF_POOL_ALLOC_THRES 1
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL
|
||||
bool dp_rx_buffer_pool_refill(struct dp_soc *soc, qdf_nbuf_t nbuf, u8 mac_id)
|
||||
{
|
||||
struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
|
||||
struct rx_desc_pool *rx_desc_pool = &soc->rx_desc_buf[mac_id];
|
||||
struct rx_buff_pool *bufpool = &soc->rx_buff_pool[mac_id];
|
||||
qdf_nbuf_t next_nbuf, first_nbuf, refill_nbuf;
|
||||
bool consumed = false;
|
||||
|
||||
if (!bufpool->is_initialized || !pdev)
|
||||
return consumed;
|
||||
|
||||
/* process only buffers of RXDMA ring */
|
||||
if (qdf_unlikely(rx_desc_pool !=
|
||||
dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id)))
|
||||
return consumed;
|
||||
|
||||
first_nbuf = nbuf;
|
||||
|
||||
while (nbuf) {
|
||||
next_nbuf = qdf_nbuf_next(nbuf);
|
||||
|
||||
if (qdf_likely(qdf_nbuf_queue_head_qlen(&bufpool->emerg_nbuf_q) >=
|
||||
DP_RX_BUFFER_POOL_SIZE))
|
||||
break;
|
||||
|
||||
refill_nbuf = qdf_nbuf_alloc(soc->osdev, rx_desc_pool->buf_size,
|
||||
RX_BUFFER_RESERVATION,
|
||||
rx_desc_pool->buf_alignment,
|
||||
FALSE);
|
||||
|
||||
/* Failed to allocate new nbuf, reset and place it back
|
||||
* in to the pool.
|
||||
*/
|
||||
if (!refill_nbuf) {
|
||||
DP_STATS_INC(pdev,
|
||||
rx_buffer_pool.num_bufs_consumed, 1);
|
||||
consumed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Successful allocation!! */
|
||||
DP_STATS_INC(pdev,
|
||||
rx_buffer_pool.num_bufs_alloc_success, 1);
|
||||
qdf_nbuf_queue_head_enqueue_tail(&bufpool->emerg_nbuf_q,
|
||||
refill_nbuf);
|
||||
nbuf = next_nbuf;
|
||||
}
|
||||
|
||||
nbuf = first_nbuf;
|
||||
if (consumed) {
|
||||
/* Free the MSDU/scattered MSDU */
|
||||
while (nbuf) {
|
||||
next_nbuf = qdf_nbuf_next(nbuf);
|
||||
dp_rx_buffer_pool_nbuf_free(soc, nbuf, mac_id);
|
||||
nbuf = next_nbuf;
|
||||
}
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
void dp_rx_buffer_pool_nbuf_free(struct dp_soc *soc, qdf_nbuf_t nbuf, u8 mac_id)
|
||||
{
|
||||
struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
|
||||
struct rx_desc_pool *rx_desc_pool;
|
||||
struct rx_buff_pool *buff_pool;
|
||||
|
||||
if (!wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx))
|
||||
mac_id = dp_pdev->lmac_id;
|
||||
|
||||
rx_desc_pool = &soc->rx_desc_buf[mac_id];
|
||||
buff_pool = &soc->rx_buff_pool[mac_id];
|
||||
|
||||
if (qdf_likely(qdf_nbuf_queue_head_qlen(&buff_pool->emerg_nbuf_q) >=
|
||||
DP_RX_BUFFER_POOL_SIZE) ||
|
||||
!buff_pool->is_initialized)
|
||||
return qdf_nbuf_free(nbuf);
|
||||
|
||||
qdf_nbuf_reset(nbuf, RX_BUFFER_RESERVATION,
|
||||
rx_desc_pool->buf_alignment);
|
||||
qdf_nbuf_queue_head_enqueue_tail(&buff_pool->emerg_nbuf_q, nbuf);
|
||||
}
|
||||
|
||||
void dp_rx_refill_buff_pool_enqueue(struct dp_soc *soc)
|
||||
{
|
||||
struct rx_desc_pool *rx_desc_pool;
|
||||
struct rx_refill_buff_pool *buff_pool;
|
||||
qdf_device_t dev;
|
||||
qdf_nbuf_t nbuf;
|
||||
QDF_STATUS ret;
|
||||
int count, i;
|
||||
uint16_t num_refill;
|
||||
uint16_t total_num_refill;
|
||||
uint16_t total_count = 0;
|
||||
uint16_t head, tail;
|
||||
|
||||
if (!soc)
|
||||
return;
|
||||
|
||||
dev = soc->osdev;
|
||||
buff_pool = &soc->rx_refill_buff_pool;
|
||||
rx_desc_pool = &soc->rx_desc_buf[0];
|
||||
if (!buff_pool->is_initialized)
|
||||
return;
|
||||
|
||||
head = buff_pool->head;
|
||||
tail = buff_pool->tail;
|
||||
if (tail > head)
|
||||
total_num_refill = (tail - head - 1);
|
||||
else
|
||||
total_num_refill = (DP_RX_REFILL_BUFF_POOL_SIZE - head +
|
||||
tail - 1);
|
||||
|
||||
while (total_num_refill) {
|
||||
if (total_num_refill > DP_RX_REFILL_BUFF_POOL_BURST)
|
||||
num_refill = DP_RX_REFILL_BUFF_POOL_BURST;
|
||||
else
|
||||
num_refill = total_num_refill;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < num_refill; i++) {
|
||||
nbuf = qdf_nbuf_alloc(dev, rx_desc_pool->buf_size,
|
||||
RX_BUFFER_RESERVATION,
|
||||
rx_desc_pool->buf_alignment,
|
||||
FALSE);
|
||||
if (qdf_unlikely(!nbuf))
|
||||
continue;
|
||||
|
||||
ret = qdf_nbuf_map_nbytes_single(dev, nbuf,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
rx_desc_pool->buf_size);
|
||||
if (qdf_unlikely(QDF_IS_STATUS_ERROR(ret))) {
|
||||
qdf_nbuf_free(nbuf);
|
||||
continue;
|
||||
}
|
||||
|
||||
buff_pool->buf_elem[head++] = nbuf;
|
||||
head &= (DP_RX_REFILL_BUFF_POOL_SIZE - 1);
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count) {
|
||||
buff_pool->head = head;
|
||||
total_num_refill -= count;
|
||||
total_count += count;
|
||||
}
|
||||
}
|
||||
|
||||
DP_STATS_INC(buff_pool->dp_pdev,
|
||||
rx_refill_buff_pool.num_bufs_refilled,
|
||||
total_count);
|
||||
}
|
||||
|
||||
static inline qdf_nbuf_t dp_rx_refill_buff_pool_dequeue_nbuf(struct dp_soc *soc)
|
||||
{
|
||||
struct rx_refill_buff_pool *buff_pool = &soc->rx_refill_buff_pool;
|
||||
qdf_nbuf_t nbuf = NULL;
|
||||
uint16_t head, tail;
|
||||
|
||||
head = buff_pool->head;
|
||||
tail = buff_pool->tail;
|
||||
|
||||
if (head == tail)
|
||||
return NULL;
|
||||
|
||||
nbuf = buff_pool->buf_elem[tail++];
|
||||
tail &= (DP_RX_REFILL_BUFF_POOL_SIZE - 1);
|
||||
buff_pool->tail = tail;
|
||||
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
qdf_nbuf_t
|
||||
dp_rx_buffer_pool_nbuf_alloc(struct dp_soc *soc, uint32_t mac_id,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
uint32_t num_available_buffers)
|
||||
{
|
||||
struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
|
||||
struct rx_buff_pool *buff_pool;
|
||||
struct dp_srng *dp_rxdma_srng;
|
||||
qdf_nbuf_t nbuf;
|
||||
|
||||
nbuf = dp_rx_refill_buff_pool_dequeue_nbuf(soc);
|
||||
if (qdf_likely(nbuf)) {
|
||||
DP_STATS_INC(dp_pdev,
|
||||
rx_refill_buff_pool.num_bufs_allocated, 1);
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
if (!wlan_cfg_per_pdev_lmac_ring(soc->wlan_cfg_ctx))
|
||||
mac_id = dp_pdev->lmac_id;
|
||||
|
||||
buff_pool = &soc->rx_buff_pool[mac_id];
|
||||
dp_rxdma_srng = &soc->rx_refill_buf_ring[mac_id];
|
||||
|
||||
nbuf = qdf_nbuf_alloc(soc->osdev, rx_desc_pool->buf_size,
|
||||
RX_BUFFER_RESERVATION,
|
||||
rx_desc_pool->buf_alignment,
|
||||
FALSE);
|
||||
|
||||
if (!buff_pool->is_initialized)
|
||||
return nbuf;
|
||||
|
||||
if (qdf_likely(nbuf)) {
|
||||
buff_pool->nbuf_fail_cnt = 0;
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
buff_pool->nbuf_fail_cnt++;
|
||||
|
||||
/* Allocate buffer from the buffer pool */
|
||||
if (buff_pool->nbuf_fail_cnt >= DP_RX_BUFFER_POOL_ALLOC_THRES ||
|
||||
(num_available_buffers < dp_rxdma_srng->num_entries / 10)) {
|
||||
nbuf = qdf_nbuf_queue_head_dequeue(&buff_pool->emerg_nbuf_q);
|
||||
if (nbuf)
|
||||
DP_STATS_INC(dp_pdev,
|
||||
rx_buffer_pool.num_pool_bufs_replenish, 1);
|
||||
}
|
||||
|
||||
return nbuf;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
dp_rx_buffer_pool_nbuf_map(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
struct dp_rx_nbuf_frag_info *nbuf_frag_info_t)
|
||||
{
|
||||
QDF_STATUS ret = QDF_STATUS_SUCCESS;
|
||||
|
||||
if (!QDF_NBUF_CB_PADDR((nbuf_frag_info_t->virt_addr).nbuf))
|
||||
ret = qdf_nbuf_map_nbytes_single(soc->osdev,
|
||||
(nbuf_frag_info_t->virt_addr).nbuf,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
rx_desc_pool->buf_size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dp_rx_refill_buff_pool_init(struct dp_soc *soc, u8 mac_id)
|
||||
{
|
||||
struct rx_desc_pool *rx_desc_pool = &soc->rx_desc_buf[mac_id];
|
||||
qdf_nbuf_t nbuf;
|
||||
struct rx_refill_buff_pool *buff_pool = &soc->rx_refill_buff_pool;
|
||||
QDF_STATUS ret;
|
||||
uint16_t head = 0;
|
||||
int i;
|
||||
|
||||
if (!wlan_cfg_is_rx_refill_buffer_pool_enabled(soc->wlan_cfg_ctx)) {
|
||||
dp_err("RX refill buffer pool support is disabled");
|
||||
buff_pool->is_initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
buff_pool->max_bufq_len = DP_RX_REFILL_BUFF_POOL_SIZE;
|
||||
buff_pool->dp_pdev = dp_get_pdev_for_lmac_id(soc, 0);
|
||||
buff_pool->tail = 0;
|
||||
|
||||
for (i = 0; i < (buff_pool->max_bufq_len - 1); i++) {
|
||||
nbuf = qdf_nbuf_alloc(soc->osdev, rx_desc_pool->buf_size,
|
||||
RX_BUFFER_RESERVATION,
|
||||
rx_desc_pool->buf_alignment, FALSE);
|
||||
if (!nbuf)
|
||||
continue;
|
||||
|
||||
ret = qdf_nbuf_map_nbytes_single(soc->osdev, nbuf,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
rx_desc_pool->buf_size);
|
||||
if (qdf_unlikely(QDF_IS_STATUS_ERROR(ret))) {
|
||||
qdf_nbuf_free(nbuf);
|
||||
continue;
|
||||
}
|
||||
|
||||
buff_pool->buf_elem[head] = nbuf;
|
||||
head++;
|
||||
}
|
||||
|
||||
buff_pool->head = head;
|
||||
|
||||
dp_info("RX refill buffer pool required allocation: %u actual allocation: %u",
|
||||
buff_pool->max_bufq_len,
|
||||
buff_pool->head);
|
||||
|
||||
buff_pool->is_initialized = true;
|
||||
}
|
||||
|
||||
void dp_rx_buffer_pool_init(struct dp_soc *soc, u8 mac_id)
|
||||
{
|
||||
struct rx_desc_pool *rx_desc_pool = &soc->rx_desc_buf[mac_id];
|
||||
struct rx_buff_pool *buff_pool = &soc->rx_buff_pool[mac_id];
|
||||
qdf_nbuf_t nbuf;
|
||||
int i;
|
||||
|
||||
dp_rx_refill_buff_pool_init(soc, mac_id);
|
||||
|
||||
if (!wlan_cfg_is_rx_buffer_pool_enabled(soc->wlan_cfg_ctx)) {
|
||||
dp_err("RX buffer pool support is disabled");
|
||||
buff_pool->is_initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (buff_pool->is_initialized)
|
||||
return;
|
||||
|
||||
qdf_nbuf_queue_head_init(&buff_pool->emerg_nbuf_q);
|
||||
|
||||
for (i = 0; i < DP_RX_BUFFER_POOL_SIZE; i++) {
|
||||
nbuf = qdf_nbuf_alloc(soc->osdev, rx_desc_pool->buf_size,
|
||||
RX_BUFFER_RESERVATION,
|
||||
rx_desc_pool->buf_alignment, FALSE);
|
||||
if (!nbuf)
|
||||
continue;
|
||||
qdf_nbuf_queue_head_enqueue_tail(&buff_pool->emerg_nbuf_q,
|
||||
nbuf);
|
||||
}
|
||||
|
||||
dp_info("RX buffer pool required allocation: %u actual allocation: %u",
|
||||
DP_RX_BUFFER_POOL_SIZE,
|
||||
qdf_nbuf_queue_head_qlen(&buff_pool->emerg_nbuf_q));
|
||||
|
||||
buff_pool->is_initialized = true;
|
||||
}
|
||||
|
||||
static void dp_rx_refill_buff_pool_deinit(struct dp_soc *soc, u8 mac_id)
|
||||
{
|
||||
struct rx_refill_buff_pool *buff_pool = &soc->rx_refill_buff_pool;
|
||||
struct rx_desc_pool *rx_desc_pool = &soc->rx_desc_buf[mac_id];
|
||||
qdf_nbuf_t nbuf;
|
||||
uint32_t count = 0;
|
||||
|
||||
if (!buff_pool->is_initialized)
|
||||
return;
|
||||
|
||||
while ((nbuf = dp_rx_refill_buff_pool_dequeue_nbuf(soc))) {
|
||||
qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf,
|
||||
QDF_DMA_BIDIRECTIONAL,
|
||||
rx_desc_pool->buf_size);
|
||||
qdf_nbuf_free(nbuf);
|
||||
count++;
|
||||
}
|
||||
|
||||
dp_info("Rx refill buffers freed during deinit %u head: %u, tail: %u",
|
||||
count, buff_pool->head, buff_pool->tail);
|
||||
|
||||
buff_pool->is_initialized = false;
|
||||
}
|
||||
|
||||
void dp_rx_buffer_pool_deinit(struct dp_soc *soc, u8 mac_id)
|
||||
{
|
||||
struct rx_buff_pool *buff_pool = &soc->rx_buff_pool[mac_id];
|
||||
qdf_nbuf_t nbuf;
|
||||
|
||||
dp_rx_refill_buff_pool_deinit(soc, mac_id);
|
||||
|
||||
if (!buff_pool->is_initialized)
|
||||
return;
|
||||
|
||||
dp_info("buffers in the RX buffer pool during deinit: %u",
|
||||
qdf_nbuf_queue_head_qlen(&buff_pool->emerg_nbuf_q));
|
||||
|
||||
while ((nbuf = qdf_nbuf_queue_head_dequeue(&buff_pool->emerg_nbuf_q)))
|
||||
qdf_nbuf_free(nbuf);
|
||||
|
||||
buff_pool->is_initialized = false;
|
||||
}
|
||||
#endif /* WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL */
|
||||
225
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_buffer_pool.h
Normal file
225
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_buffer_pool.h
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _DP_RX_BUFFER_POOL_H_
|
||||
#define _DP_RX_BUFFER_POOL_H_
|
||||
|
||||
#include "dp_types.h"
|
||||
#include "qdf_nbuf.h"
|
||||
#include "qdf_module.h"
|
||||
#include "athdefs.h"
|
||||
#include "wlan_cfg.h"
|
||||
#include "dp_internal.h"
|
||||
#include "dp_rx.h"
|
||||
#include "dp_rx_mon.h"
|
||||
|
||||
#ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL
|
||||
/**
|
||||
* dp_rx_buffer_pool_init() - Initialize emergency buffer pool
|
||||
* @soc: SoC handle
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_rx_buffer_pool_init(struct dp_soc *soc, u8 mac_id);
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_deinit() - De-Initialize emergency buffer pool
|
||||
* @soc: SoC handle
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_rx_buffer_pool_deinit(struct dp_soc *soc, u8 mac_id);
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_refill() - Process the rx nbuf list and
|
||||
* refill the emergency buffer pool
|
||||
* @soc: SoC handle
|
||||
* @nbuf: RX buffer
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: Whether the rx nbuf is consumed into the pool or not.
|
||||
*/
|
||||
bool dp_rx_buffer_pool_refill(struct dp_soc *soc, qdf_nbuf_t nbuf, u8 mac_id);
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_nbuf_free() - Free the nbuf or queue it
|
||||
* back into the pool
|
||||
* @soc: SoC handle
|
||||
* @nbuf: RX buffer
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_rx_buffer_pool_nbuf_free(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
||||
u8 mac_id);
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_nbuf_alloc() - Allocate nbuf for buffer replenish,
|
||||
* give nbuf from the pool if allocation fails
|
||||
* @soc: SoC handle
|
||||
* @mac_id: MAC ID
|
||||
* @rx_desc_pool: RX descriptor pool
|
||||
* @num_available_buffers: number of available buffers in the ring.
|
||||
*
|
||||
* Return: nbuf
|
||||
*/
|
||||
qdf_nbuf_t dp_rx_buffer_pool_nbuf_alloc(struct dp_soc *soc, uint32_t mac_id,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
uint32_t num_available_buffers);
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_nbuf_map() - Map nbuff for buffer replenish
|
||||
* @soc: SoC handle
|
||||
* @rx_desc_pool: RX descriptor pool
|
||||
* @nbuf_frag_info_t: nbuf frag info
|
||||
*
|
||||
* Return: nbuf
|
||||
*/
|
||||
QDF_STATUS
|
||||
dp_rx_buffer_pool_nbuf_map(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
struct dp_rx_nbuf_frag_info *nbuf_frag_info_t);
|
||||
|
||||
/**
|
||||
* dp_rx_schedule_refill_thread() - Schedule RX refill thread to enqueue
|
||||
* buffers in refill pool
|
||||
* @soc: SoC handle
|
||||
*
|
||||
*/
|
||||
static inline void dp_rx_schedule_refill_thread(struct dp_soc *soc)
|
||||
{
|
||||
struct rx_refill_buff_pool *buff_pool = &soc->rx_refill_buff_pool;
|
||||
uint16_t head = buff_pool->head;
|
||||
uint16_t tail = buff_pool->tail;
|
||||
uint16_t num_refill;
|
||||
|
||||
if (!buff_pool->is_initialized)
|
||||
return;
|
||||
|
||||
if (tail > head)
|
||||
num_refill = (tail - head - 1);
|
||||
else
|
||||
num_refill = (DP_RX_REFILL_BUFF_POOL_SIZE - head + tail - 1);
|
||||
|
||||
if (soc->cdp_soc.ol_ops->dp_rx_sched_refill_thread &&
|
||||
num_refill >= DP_RX_REFILL_THRD_THRESHOLD)
|
||||
soc->cdp_soc.ol_ops->dp_rx_sched_refill_thread(
|
||||
dp_soc_to_cdp_soc_t(soc));
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* dp_rx_buffer_pool_init() - Initialize emergency buffer pool
|
||||
* @soc: SoC handle
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void dp_rx_buffer_pool_init(struct dp_soc *soc, u8 mac_id)
|
||||
{
|
||||
soc->rx_buff_pool[mac_id].is_initialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_deinit() - De-Initialize emergency buffer pool
|
||||
* @soc: SoC handle
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void dp_rx_buffer_pool_deinit(struct dp_soc *soc, u8 mac_id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_refill() - Process the rx nbuf list and
|
||||
* refill the emergency buffer pool
|
||||
* @soc: SoC handle
|
||||
* @nbuf: RX buffer
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: Whether the rx nbuf is consumed into the pool or not.
|
||||
*/
|
||||
static inline
|
||||
bool dp_rx_buffer_pool_refill(struct dp_soc *soc, qdf_nbuf_t nbuf, u8 mac_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_nbuf_free() - Free the nbuf or queue it
|
||||
* back into the pool
|
||||
* @soc: SoC handle
|
||||
* @nbuf: RX buffer
|
||||
* @mac_id: MAC ID
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline
|
||||
void dp_rx_buffer_pool_nbuf_free(struct dp_soc *soc, qdf_nbuf_t nbuf,
|
||||
u8 mac_id)
|
||||
{
|
||||
qdf_nbuf_free(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_nbuf_alloc() - Allocate nbuf for buffer replenish,
|
||||
* give nbuf from the pool if allocation fails
|
||||
* @soc: SoC handle
|
||||
* @mac_id: MAC ID
|
||||
* @rx_desc_pool: RX descriptor pool
|
||||
* @num_available_buffers: number of available buffers in the ring.
|
||||
*
|
||||
* Return: nbuf
|
||||
*/
|
||||
static inline qdf_nbuf_t
|
||||
dp_rx_buffer_pool_nbuf_alloc(struct dp_soc *soc, uint32_t mac_id,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
uint32_t num_available_buffers)
|
||||
{
|
||||
return qdf_nbuf_alloc(soc->osdev, rx_desc_pool->buf_size,
|
||||
RX_BUFFER_RESERVATION,
|
||||
rx_desc_pool->buf_alignment, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_buffer_pool_nbuf_map() - Map nbuff for buffer replenish
|
||||
* @soc: SoC handle
|
||||
* @rx_desc_pool: RX descriptor pool
|
||||
* @nbuf_frag_info_t: nbuf frag info
|
||||
*
|
||||
* Return: nbuf
|
||||
*/
|
||||
static inline QDF_STATUS
|
||||
dp_rx_buffer_pool_nbuf_map(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
struct dp_rx_nbuf_frag_info *nbuf_frag_info_t)
|
||||
{
|
||||
return qdf_nbuf_map_nbytes_single(soc->osdev,
|
||||
(nbuf_frag_info_t->virt_addr).nbuf,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
rx_desc_pool->buf_size);
|
||||
}
|
||||
|
||||
static inline void dp_rx_schedule_refill_thread(struct dp_soc *soc) { }
|
||||
|
||||
#endif /* WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL */
|
||||
#endif /* _DP_RX_BUFFER_POOL_H_ */
|
||||
2183
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.c
Normal file
2183
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.c
Normal file
File diff suppressed because it is too large
Load diff
144
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.h
Normal file
144
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_defrag.h
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _DP_RX_DEFRAG_H
|
||||
#define _DP_RX_DEFRAG_H
|
||||
|
||||
#include "hal_rx.h"
|
||||
|
||||
#define DEFRAG_IEEE80211_KEY_LEN 8
|
||||
#define DEFRAG_IEEE80211_FCS_LEN 4
|
||||
|
||||
#define DP_RX_DEFRAG_IEEE80211_ADDR_COPY(dst, src) \
|
||||
qdf_mem_copy(dst, src, QDF_MAC_ADDR_SIZE)
|
||||
|
||||
#define DP_RX_DEFRAG_IEEE80211_QOS_HAS_SEQ(wh) \
|
||||
(((wh) & \
|
||||
(IEEE80211_FC0_TYPE_MASK | QDF_IEEE80211_FC0_SUBTYPE_QOS)) == \
|
||||
(IEEE80211_FC0_TYPE_DATA | QDF_IEEE80211_FC0_SUBTYPE_QOS))
|
||||
|
||||
#define UNI_DESC_OWNER_SW 0x1
|
||||
#define UNI_DESC_BUF_TYPE_RX_MSDU_LINK 0x6
|
||||
/**
|
||||
* struct dp_rx_defrag_cipher: structure to indicate cipher header
|
||||
* @ic_name: Name
|
||||
* @ic_header: header length
|
||||
* @ic_trailer: trail length
|
||||
* @ic_miclen: MIC length
|
||||
*/
|
||||
struct dp_rx_defrag_cipher {
|
||||
const char *ic_name;
|
||||
uint16_t ic_header;
|
||||
uint8_t ic_trailer;
|
||||
uint8_t ic_miclen;
|
||||
};
|
||||
|
||||
uint32_t dp_rx_frag_handle(struct dp_soc *soc, hal_ring_desc_t ring_desc,
|
||||
struct hal_rx_mpdu_desc_info *mpdu_desc_info,
|
||||
struct dp_rx_desc *rx_desc,
|
||||
uint8_t *mac_id,
|
||||
uint32_t quota);
|
||||
|
||||
/*
|
||||
* dp_rx_frag_get_mac_hdr() - Return pointer to the mac hdr
|
||||
* @rx_desc_info: Pointer to the pkt_tlvs in the
|
||||
* nbuf (pkt_tlvs->mac_hdr->data)
|
||||
*
|
||||
* It is inefficient to peek into the packet for received
|
||||
* frames but these APIs are required to get to some of
|
||||
* 802.11 fields that hardware does not populate in the
|
||||
* rx meta data.
|
||||
*
|
||||
* Returns: pointer to ieee80211_frame
|
||||
*/
|
||||
static inline
|
||||
struct ieee80211_frame *dp_rx_frag_get_mac_hdr(uint8_t *rx_desc_info)
|
||||
{
|
||||
int rx_desc_len = SIZE_OF_DATA_RX_TLV;
|
||||
return (struct ieee80211_frame *)(rx_desc_info + rx_desc_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_frag_get_mpdu_seq_number() - Get mpdu sequence number
|
||||
* @rx_desc_info: Pointer to the pkt_tlvs in the
|
||||
* nbuf (pkt_tlvs->mac_hdr->data)
|
||||
*
|
||||
* Returns: uint16_t, rx sequence number
|
||||
*/
|
||||
static inline
|
||||
uint16_t dp_rx_frag_get_mpdu_seq_number(uint8_t *rx_desc_info)
|
||||
{
|
||||
struct ieee80211_frame *mac_hdr;
|
||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
||||
|
||||
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) >>
|
||||
IEEE80211_SEQ_SEQ_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_frag_get_mpdu_frag_number() - Get mpdu fragment number
|
||||
* @rx_desc_info: Pointer to the pkt_tlvs in the
|
||||
* nbuf (pkt_tlvs->mac_hdr->data)
|
||||
*
|
||||
* Returns: uint8_t, receive fragment number
|
||||
*/
|
||||
static inline
|
||||
uint8_t dp_rx_frag_get_mpdu_frag_number(uint8_t *rx_desc_info)
|
||||
{
|
||||
struct ieee80211_frame *mac_hdr;
|
||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
||||
|
||||
return qdf_le16_to_cpu(*(uint16_t *) mac_hdr->i_seq) &
|
||||
IEEE80211_SEQ_FRAG_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_frag_get_more_frag_bit() - Get more fragment bit
|
||||
* @rx_desc_info: Pointer to the pkt_tlvs in the
|
||||
* nbuf (pkt_tlvs->mac_hdr->data)
|
||||
*
|
||||
* Returns: uint8_t, get more fragment bit
|
||||
*/
|
||||
static inline
|
||||
uint8_t dp_rx_frag_get_more_frag_bit(uint8_t *rx_desc_info)
|
||||
{
|
||||
struct ieee80211_frame *mac_hdr;
|
||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
||||
|
||||
return (mac_hdr->i_fc[1] & IEEE80211_FC1_MORE_FRAG) >> 2;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint8_t dp_rx_get_pkt_dir(uint8_t *rx_desc_info)
|
||||
{
|
||||
struct ieee80211_frame *mac_hdr;
|
||||
mac_hdr = dp_rx_frag_get_mac_hdr(rx_desc_info);
|
||||
|
||||
return mac_hdr->i_fc[1] & IEEE80211_FC1_DIR_MASK;
|
||||
}
|
||||
|
||||
void dp_rx_defrag_waitlist_flush(struct dp_soc *soc);
|
||||
void dp_rx_reorder_flush_frag(struct dp_peer *peer,
|
||||
unsigned int tid);
|
||||
void dp_rx_defrag_waitlist_remove(struct dp_peer *peer, unsigned tid);
|
||||
void dp_rx_defrag_cleanup(struct dp_peer *peer, unsigned tid);
|
||||
|
||||
QDF_STATUS dp_rx_defrag_add_last_frag(struct dp_soc *soc,
|
||||
struct dp_peer *peer, uint16_t tid,
|
||||
uint16_t rxseq, qdf_nbuf_t nbuf);
|
||||
#endif /* _DP_RX_DEFRAG_H */
|
||||
535
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_desc.c
Normal file
535
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_desc.c
Normal file
|
|
@ -0,0 +1,535 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "dp_types.h"
|
||||
#include "dp_rx.h"
|
||||
#include "dp_ipa.h"
|
||||
|
||||
#ifdef RX_DESC_MULTI_PAGE_ALLOC
|
||||
A_COMPILE_TIME_ASSERT(cookie_size_check,
|
||||
PAGE_SIZE / sizeof(union dp_rx_desc_list_elem_t) <=
|
||||
1 << DP_RX_DESC_PAGE_ID_SHIFT);
|
||||
|
||||
/*
|
||||
* dp_rx_desc_pool_is_allocated() - check if memory is allocated for the
|
||||
* rx descriptor pool
|
||||
*
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
* Return: QDF_STATUS QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
*/
|
||||
QDF_STATUS dp_rx_desc_pool_is_allocated(struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
if (!rx_desc_pool->desc_pages.num_pages) {
|
||||
dp_err("Multi page alloc fail, size=%d, elem=%d",
|
||||
rx_desc_pool->elem_size, rx_desc_pool->pool_size);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_desc_pool_alloc() - Allocate a memory pool for software rx
|
||||
* descriptors
|
||||
*
|
||||
* @soc: core txrx main context
|
||||
* @num_elem: number of rx descriptors (size of the pool)
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
*
|
||||
* Return: QDF_STATUS QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
* QDF_STATUS_E_FAULT
|
||||
*/
|
||||
QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc,
|
||||
uint32_t num_elem,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
uint32_t desc_size;
|
||||
union dp_rx_desc_list_elem_t *rx_desc_elem;
|
||||
|
||||
desc_size = sizeof(*rx_desc_elem);
|
||||
rx_desc_pool->elem_size = desc_size;
|
||||
|
||||
dp_desc_multi_pages_mem_alloc(soc, rx_desc_pool->desc_type,
|
||||
&rx_desc_pool->desc_pages,
|
||||
desc_size, num_elem, 0, true);
|
||||
if (!rx_desc_pool->desc_pages.num_pages) {
|
||||
qdf_err("Multi page alloc fail,size=%d, elem=%d",
|
||||
desc_size, num_elem);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
if (qdf_mem_multi_page_link(soc->osdev,
|
||||
&rx_desc_pool->desc_pages,
|
||||
desc_size, num_elem, true)) {
|
||||
qdf_err("overflow num link,size=%d, elem=%d",
|
||||
desc_size, num_elem);
|
||||
goto free_rx_desc_pool;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
free_rx_desc_pool:
|
||||
dp_rx_desc_pool_free(soc, rx_desc_pool);
|
||||
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_desc_pool_init() - Initialize the software RX descriptor pool
|
||||
* convert the pool of memory into a list of
|
||||
* rx descriptors and create locks to access this
|
||||
* list of rx descriptors.
|
||||
*
|
||||
* @soc: core txrx main context
|
||||
* @pool_id: pool_id which is one of 3 mac_ids
|
||||
* @pool_size: size of the rx descriptor pool
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
*/
|
||||
void dp_rx_desc_pool_init(struct dp_soc *soc, uint32_t pool_id,
|
||||
uint32_t pool_size, struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
uint32_t id, page_id, offset, num_desc_per_page;
|
||||
uint32_t count = 0;
|
||||
union dp_rx_desc_list_elem_t *rx_desc_elem;
|
||||
|
||||
/* Initialize the lock */
|
||||
qdf_spinlock_create(&rx_desc_pool->lock);
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
rx_desc_pool->pool_size = pool_size;
|
||||
|
||||
num_desc_per_page = rx_desc_pool->desc_pages.num_element_per_page;
|
||||
rx_desc_pool->freelist = (union dp_rx_desc_list_elem_t *)
|
||||
*rx_desc_pool->desc_pages.cacheable_pages;
|
||||
|
||||
rx_desc_elem = rx_desc_pool->freelist;
|
||||
while (rx_desc_elem) {
|
||||
page_id = count / num_desc_per_page;
|
||||
offset = count % num_desc_per_page;
|
||||
/*
|
||||
* Below cookie size is from REO destination ring
|
||||
* reo_destination_ring -> buffer_addr_info -> sw_buffer_cookie
|
||||
* cookie size = 21 bits
|
||||
* 8 bits - offset
|
||||
* 8 bits - page ID
|
||||
* 4 bits - pool ID
|
||||
*/
|
||||
id = ((pool_id << DP_RX_DESC_POOL_ID_SHIFT) |
|
||||
(page_id << DP_RX_DESC_PAGE_ID_SHIFT) |
|
||||
offset);
|
||||
rx_desc_elem->rx_desc.cookie = id;
|
||||
rx_desc_elem->rx_desc.pool_id = pool_id;
|
||||
rx_desc_elem->rx_desc.in_use = 0;
|
||||
rx_desc_elem = rx_desc_elem->next;
|
||||
count++;
|
||||
}
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
}
|
||||
|
||||
union dp_rx_desc_list_elem_t *dp_rx_desc_find(uint16_t page_id, uint16_t offset,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
return rx_desc_pool->desc_pages.cacheable_pages[page_id] +
|
||||
rx_desc_pool->elem_size * offset;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_rx_desc_nbuf_collect(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
qdf_nbuf_t *nbuf_unmap_list,
|
||||
qdf_nbuf_t *nbuf_free_list)
|
||||
{
|
||||
uint32_t i, num_desc, page_id, offset, num_desc_per_page;
|
||||
union dp_rx_desc_list_elem_t *rx_desc_elem;
|
||||
struct dp_rx_desc *rx_desc;
|
||||
|
||||
if (qdf_unlikely(!(rx_desc_pool->desc_pages.cacheable_pages))) {
|
||||
qdf_err("No pages found on this desc pool");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
num_desc = rx_desc_pool->pool_size;
|
||||
num_desc_per_page = rx_desc_pool->desc_pages.num_element_per_page;
|
||||
for (i = 0; i < num_desc; i++) {
|
||||
page_id = i / num_desc_per_page;
|
||||
offset = i % num_desc_per_page;
|
||||
rx_desc_elem = dp_rx_desc_find(page_id, offset, rx_desc_pool);
|
||||
rx_desc = &rx_desc_elem->rx_desc;
|
||||
dp_rx_desc_free_dbg_info(rx_desc);
|
||||
if (rx_desc->in_use) {
|
||||
if (!rx_desc->unmapped) {
|
||||
DP_RX_HEAD_APPEND(*nbuf_unmap_list,
|
||||
rx_desc->nbuf);
|
||||
rx_desc->unmapped = 1;
|
||||
} else {
|
||||
DP_RX_HEAD_APPEND(*nbuf_free_list,
|
||||
rx_desc->nbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void dp_rx_desc_nbuf_cleanup(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf_unmap_list,
|
||||
qdf_nbuf_t nbuf_free_list,
|
||||
uint16_t buf_size)
|
||||
{
|
||||
qdf_nbuf_t nbuf = nbuf_unmap_list;
|
||||
qdf_nbuf_t next;
|
||||
|
||||
while (nbuf) {
|
||||
next = nbuf->next;
|
||||
if (dp_ipa_handle_rx_buf_smmu_mapping(soc, nbuf, buf_size,
|
||||
false))
|
||||
dp_info_rl("Unable to unmap nbuf: %pK", nbuf);
|
||||
qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf,
|
||||
QDF_DMA_BIDIRECTIONAL, buf_size);
|
||||
qdf_nbuf_free(nbuf);
|
||||
nbuf = next;
|
||||
}
|
||||
|
||||
nbuf = nbuf_free_list;
|
||||
while (nbuf) {
|
||||
next = nbuf->next;
|
||||
qdf_nbuf_free(nbuf);
|
||||
nbuf = next;
|
||||
}
|
||||
}
|
||||
|
||||
void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_nbuf_t nbuf_unmap_list = NULL;
|
||||
qdf_nbuf_t nbuf_free_list = NULL;
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
dp_rx_desc_nbuf_collect(soc, rx_desc_pool,
|
||||
&nbuf_unmap_list, &nbuf_free_list);
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
dp_rx_desc_nbuf_cleanup(soc, nbuf_unmap_list, nbuf_free_list,
|
||||
rx_desc_pool->buf_size);
|
||||
qdf_spinlock_destroy(&rx_desc_pool->lock);
|
||||
}
|
||||
|
||||
void dp_rx_desc_nbuf_free(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_nbuf_t nbuf_unmap_list = NULL;
|
||||
qdf_nbuf_t nbuf_free_list = NULL;
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
dp_rx_desc_nbuf_collect(soc, rx_desc_pool,
|
||||
&nbuf_unmap_list, &nbuf_free_list);
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
dp_rx_desc_nbuf_cleanup(soc, nbuf_unmap_list, nbuf_free_list,
|
||||
rx_desc_pool->buf_size);
|
||||
}
|
||||
|
||||
void dp_rx_desc_pool_free(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
if (qdf_unlikely(!(rx_desc_pool->desc_pages.cacheable_pages)))
|
||||
return;
|
||||
|
||||
dp_desc_multi_pages_mem_free(soc, rx_desc_pool->desc_type,
|
||||
&rx_desc_pool->desc_pages, 0, true);
|
||||
}
|
||||
|
||||
void dp_rx_desc_pool_deinit(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
|
||||
rx_desc_pool->freelist = NULL;
|
||||
rx_desc_pool->pool_size = 0;
|
||||
|
||||
/* Deinitialize rx mon desr frag flag */
|
||||
rx_desc_pool->rx_mon_dest_frag_enable = false;
|
||||
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
qdf_spinlock_destroy(&rx_desc_pool->lock);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* dp_rx_desc_pool_is_allocated() - check if memory is allocated for the
|
||||
* rx descriptor pool
|
||||
*
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
*
|
||||
* Return: QDF_STATUS QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
*/
|
||||
QDF_STATUS dp_rx_desc_pool_is_allocated(struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
if (!rx_desc_pool->array) {
|
||||
dp_err("nss-wifi<4> skip Rx refil");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_desc_pool_alloc() - Allocate a memory pool for software rx
|
||||
* descriptors
|
||||
*
|
||||
* @soc: core txrx main context
|
||||
* @num_elem: number of rx descriptors (size of the pool)
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
*
|
||||
* Return: QDF_STATUS QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
* QDF_STATUS_E_FAULT
|
||||
*/
|
||||
QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc,
|
||||
uint32_t pool_size,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
rx_desc_pool->array = qdf_mem_malloc(pool_size *
|
||||
sizeof(union dp_rx_desc_list_elem_t));
|
||||
|
||||
if (!(rx_desc_pool->array)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
|
||||
"RX Desc Pool allocation failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_desc_pool_init() - Initialize the software RX descriptor pool
|
||||
* convert the pool of memory into a list of
|
||||
* rx descriptors and create locks to access this
|
||||
* list of rx descriptors.
|
||||
*
|
||||
* @soc: core txrx main context
|
||||
* @pool_id: pool_id which is one of 3 mac_ids
|
||||
* @pool_size: size of the rx descriptor pool
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
*/
|
||||
void dp_rx_desc_pool_init(struct dp_soc *soc, uint32_t pool_id,
|
||||
uint32_t pool_size, struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
int i;
|
||||
/* Initialize the lock */
|
||||
qdf_spinlock_create(&rx_desc_pool->lock);
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
rx_desc_pool->pool_size = pool_size;
|
||||
|
||||
/* link SW rx descs into a freelist */
|
||||
rx_desc_pool->freelist = &rx_desc_pool->array[0];
|
||||
qdf_mem_zero(rx_desc_pool->freelist, rx_desc_pool->pool_size);
|
||||
for (i = 0; i <= rx_desc_pool->pool_size - 1; i++) {
|
||||
if (i == rx_desc_pool->pool_size - 1)
|
||||
rx_desc_pool->array[i].next = NULL;
|
||||
else
|
||||
rx_desc_pool->array[i].next =
|
||||
&rx_desc_pool->array[i + 1];
|
||||
rx_desc_pool->array[i].rx_desc.cookie = i | (pool_id << 18);
|
||||
rx_desc_pool->array[i].rx_desc.pool_id = pool_id;
|
||||
rx_desc_pool->array[i].rx_desc.in_use = 0;
|
||||
}
|
||||
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
}
|
||||
|
||||
void dp_rx_desc_nbuf_and_pool_free(struct dp_soc *soc, uint32_t pool_id,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_nbuf_t nbuf;
|
||||
int i;
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
for (i = 0; i < rx_desc_pool->pool_size; i++) {
|
||||
if (rx_desc_pool->array[i].rx_desc.in_use) {
|
||||
nbuf = rx_desc_pool->array[i].rx_desc.nbuf;
|
||||
|
||||
if (!(rx_desc_pool->array[i].rx_desc.unmapped)) {
|
||||
dp_ipa_handle_rx_buf_smmu_mapping(
|
||||
soc, nbuf,
|
||||
rx_desc_pool->buf_size,
|
||||
false);
|
||||
qdf_nbuf_unmap_nbytes_single(
|
||||
soc->osdev, nbuf,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
rx_desc_pool->buf_size);
|
||||
rx_desc_pool->array[i].rx_desc.unmapped = 1;
|
||||
}
|
||||
qdf_nbuf_free(nbuf);
|
||||
}
|
||||
}
|
||||
qdf_mem_free(rx_desc_pool->array);
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
qdf_spinlock_destroy(&rx_desc_pool->lock);
|
||||
}
|
||||
|
||||
void dp_rx_desc_nbuf_free(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_nbuf_t nbuf;
|
||||
int i;
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
for (i = 0; i < rx_desc_pool->pool_size; i++) {
|
||||
if (rx_desc_pool->array[i].rx_desc.in_use) {
|
||||
nbuf = rx_desc_pool->array[i].rx_desc.nbuf;
|
||||
|
||||
if (!(rx_desc_pool->array[i].rx_desc.unmapped)) {
|
||||
dp_ipa_handle_rx_buf_smmu_mapping(
|
||||
soc, nbuf,
|
||||
rx_desc_pool->buf_size,
|
||||
false);
|
||||
qdf_nbuf_unmap_nbytes_single(
|
||||
soc->osdev, nbuf,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
rx_desc_pool->buf_size);
|
||||
rx_desc_pool->array[i].rx_desc.unmapped = 1;
|
||||
}
|
||||
qdf_nbuf_free(nbuf);
|
||||
}
|
||||
}
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_rx_desc_frag_free() - Free desc frag buffer
|
||||
*
|
||||
* @soc: core txrx main context
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#ifdef DP_RX_MON_MEM_FRAG
|
||||
void dp_rx_desc_frag_free(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_dma_addr_t paddr;
|
||||
qdf_frag_t vaddr;
|
||||
int i;
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
for (i = 0; i < rx_desc_pool->pool_size; i++) {
|
||||
if (rx_desc_pool->array[i].rx_desc.in_use) {
|
||||
paddr = rx_desc_pool->array[i].rx_desc.paddr_buf_start;
|
||||
vaddr = rx_desc_pool->array[i].rx_desc.rx_buf_start;
|
||||
|
||||
if (!(rx_desc_pool->array[i].rx_desc.unmapped)) {
|
||||
qdf_mem_unmap_page(soc->osdev, paddr,
|
||||
rx_desc_pool->buf_size,
|
||||
QDF_DMA_FROM_DEVICE);
|
||||
rx_desc_pool->array[i].rx_desc.unmapped = 1;
|
||||
}
|
||||
qdf_frag_free(vaddr);
|
||||
}
|
||||
}
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
void dp_rx_desc_pool_free(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_mem_free(rx_desc_pool->array);
|
||||
}
|
||||
|
||||
void dp_rx_desc_pool_deinit(struct dp_soc *soc,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
|
||||
rx_desc_pool->freelist = NULL;
|
||||
rx_desc_pool->pool_size = 0;
|
||||
|
||||
/* Deinitialize rx mon desr frag flag */
|
||||
rx_desc_pool->rx_mon_dest_frag_enable = false;
|
||||
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
qdf_spinlock_destroy(&rx_desc_pool->lock);
|
||||
}
|
||||
|
||||
#endif /* RX_DESC_MULTI_PAGE_ALLOC */
|
||||
|
||||
/*
|
||||
* dp_rx_get_free_desc_list() - provide a list of descriptors from
|
||||
* the free rx desc pool.
|
||||
*
|
||||
* @soc: core txrx main context
|
||||
* @pool_id: pool_id which is one of 3 mac_ids
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
* @num_descs: number of descs requested from freelist
|
||||
* @desc_list: attach the descs to this list (output parameter)
|
||||
* @tail: attach the point to last desc of free list (output parameter)
|
||||
*
|
||||
* Return: number of descs allocated from free list.
|
||||
*/
|
||||
uint16_t dp_rx_get_free_desc_list(struct dp_soc *soc, uint32_t pool_id,
|
||||
struct rx_desc_pool *rx_desc_pool,
|
||||
uint16_t num_descs,
|
||||
union dp_rx_desc_list_elem_t **desc_list,
|
||||
union dp_rx_desc_list_elem_t **tail)
|
||||
{
|
||||
uint16_t count;
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
|
||||
*desc_list = *tail = rx_desc_pool->freelist;
|
||||
|
||||
for (count = 0; count < num_descs; count++) {
|
||||
|
||||
if (qdf_unlikely(!rx_desc_pool->freelist)) {
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
return count;
|
||||
}
|
||||
*tail = rx_desc_pool->freelist;
|
||||
rx_desc_pool->freelist = rx_desc_pool->freelist->next;
|
||||
}
|
||||
(*tail)->next = NULL;
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_rx_add_desc_list_to_free_list() - append unused desc_list back to
|
||||
* freelist.
|
||||
*
|
||||
* @soc: core txrx main context
|
||||
* @local_desc_list: local desc list provided by the caller
|
||||
* @tail: attach the point to last desc of local desc list
|
||||
* @pool_id: pool_id which is one of 3 mac_ids
|
||||
* @rx_desc_pool: rx descriptor pool pointer
|
||||
*/
|
||||
void dp_rx_add_desc_list_to_free_list(struct dp_soc *soc,
|
||||
union dp_rx_desc_list_elem_t **local_desc_list,
|
||||
union dp_rx_desc_list_elem_t **tail,
|
||||
uint16_t pool_id,
|
||||
struct rx_desc_pool *rx_desc_pool)
|
||||
{
|
||||
union dp_rx_desc_list_elem_t *temp_list = NULL;
|
||||
|
||||
qdf_spin_lock_bh(&rx_desc_pool->lock);
|
||||
|
||||
|
||||
temp_list = rx_desc_pool->freelist;
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"temp_list: %pK, *local_desc_list: %pK, *tail: %pK (*tail)->next: %pK",
|
||||
temp_list, *local_desc_list, *tail, (*tail)->next);
|
||||
rx_desc_pool->freelist = *local_desc_list;
|
||||
(*tail)->next = temp_list;
|
||||
*tail = NULL;
|
||||
*local_desc_list = NULL;
|
||||
|
||||
qdf_spin_unlock_bh(&rx_desc_pool->lock);
|
||||
}
|
||||
2951
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_err.c
Normal file
2951
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_err.c
Normal file
File diff suppressed because it is too large
Load diff
1131
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon.h
Normal file
1131
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon.h
Normal file
File diff suppressed because it is too large
Load diff
2211
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_dest.c
Normal file
2211
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_dest.c
Normal file
File diff suppressed because it is too large
Load diff
2576
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_status.c
Normal file
2576
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_rx_mon_status.c
Normal file
File diff suppressed because it is too large
Load diff
6812
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_stats.c
Normal file
6812
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_stats.c
Normal file
File diff suppressed because it is too large
Load diff
5679
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.c
Normal file
5679
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.c
Normal file
File diff suppressed because it is too large
Load diff
545
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.h
Normal file
545
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx.h
Normal file
|
|
@ -0,0 +1,545 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __DP_TX_H
|
||||
#define __DP_TX_H
|
||||
|
||||
#include <qdf_types.h>
|
||||
#include <qdf_nbuf.h>
|
||||
#include "dp_types.h"
|
||||
|
||||
|
||||
#define DP_INVALID_VDEV_ID 0xFF
|
||||
|
||||
#define DP_TX_MAX_NUM_FRAGS 6
|
||||
|
||||
#define DP_TX_DESC_FLAG_SIMPLE 0x1
|
||||
#define DP_TX_DESC_FLAG_TO_FW 0x2
|
||||
#define DP_TX_DESC_FLAG_FRAG 0x4
|
||||
#define DP_TX_DESC_FLAG_RAW 0x8
|
||||
#define DP_TX_DESC_FLAG_MESH 0x10
|
||||
#define DP_TX_DESC_FLAG_QUEUED_TX 0x20
|
||||
#define DP_TX_DESC_FLAG_COMPLETED_TX 0x40
|
||||
#define DP_TX_DESC_FLAG_ME 0x80
|
||||
#define DP_TX_DESC_FLAG_TDLS_FRAME 0x100
|
||||
#define DP_TX_DESC_FLAG_ALLOCATED 0x200
|
||||
#define DP_TX_DESC_FLAG_MESH_MODE 0x400
|
||||
#define DP_TX_DESC_FLAG_TX_COMP_ERR 0x1000
|
||||
#define DP_TX_DESC_FLAG_FLUSH 0x2000
|
||||
|
||||
#define DP_TX_EXT_DESC_FLAG_METADATA_VALID 0x1
|
||||
|
||||
#define DP_TX_FREE_SINGLE_BUF(soc, buf) \
|
||||
do { \
|
||||
qdf_nbuf_unmap(soc->osdev, buf, QDF_DMA_TO_DEVICE); \
|
||||
qdf_nbuf_free(buf); \
|
||||
} while (0)
|
||||
|
||||
#define OCB_HEADER_VERSION 1
|
||||
|
||||
#ifdef TX_PER_PDEV_DESC_POOL
|
||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
#define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->vdev_id)
|
||||
#else /* QCA_LL_TX_FLOW_CONTROL_V2 */
|
||||
#define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->pdev->pdev_id)
|
||||
#endif /* QCA_LL_TX_FLOW_CONTROL_V2 */
|
||||
#define DP_TX_GET_RING_ID(vdev) (vdev->pdev->pdev_id)
|
||||
#else
|
||||
#ifdef TX_PER_VDEV_DESC_POOL
|
||||
#define DP_TX_GET_DESC_POOL_ID(vdev) (vdev->vdev_id)
|
||||
#define DP_TX_GET_RING_ID(vdev) (vdev->pdev->pdev_id)
|
||||
#endif /* TX_PER_VDEV_DESC_POOL */
|
||||
#endif /* TX_PER_PDEV_DESC_POOL */
|
||||
#define DP_TX_QUEUE_MASK 0x3
|
||||
|
||||
/* number of dwords for htt_tx_msdu_desc_ext2_t */
|
||||
#define DP_TX_MSDU_INFO_META_DATA_DWORDS 7
|
||||
|
||||
/**
|
||||
* struct dp_tx_frag_info_s
|
||||
* @vaddr: hlos vritual address for buffer
|
||||
* @paddr_lo: physical address lower 32bits
|
||||
* @paddr_hi: physical address higher bits
|
||||
* @len: length of the buffer
|
||||
*/
|
||||
struct dp_tx_frag_info_s {
|
||||
uint8_t *vaddr;
|
||||
uint32_t paddr_lo;
|
||||
uint16_t paddr_hi;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_tx_seg_info_s - Segmentation Descriptor
|
||||
* @nbuf: NBUF pointer if segment corresponds to separate nbuf
|
||||
* @frag_cnt: Fragment count in this segment
|
||||
* @total_len: Total length of segment
|
||||
* @frags: per-Fragment information
|
||||
* @next: pointer to next MSDU segment
|
||||
*/
|
||||
struct dp_tx_seg_info_s {
|
||||
qdf_nbuf_t nbuf;
|
||||
uint16_t frag_cnt;
|
||||
uint16_t total_len;
|
||||
struct dp_tx_frag_info_s frags[DP_TX_MAX_NUM_FRAGS];
|
||||
struct dp_tx_seg_info_s *next;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_tx_sg_info_s - Scatter Gather Descriptor
|
||||
* @num_segs: Number of segments (TSO/ME) in the frame
|
||||
* @total_len: Total length of the frame
|
||||
* @curr_seg: Points to current segment descriptor to be processed. Chain of
|
||||
* descriptors for SG frames/multicast-unicast converted packets.
|
||||
*
|
||||
* Used for SG (802.3 or Raw) frames and Multicast-Unicast converted frames to
|
||||
* carry fragmentation information
|
||||
* Raw Frames will be handed over to driver as an SKB chain with MPDU boundaries
|
||||
* indicated through flags in SKB CB (first_msdu and last_msdu). This will be
|
||||
* converted into set of skb sg (nr_frags) structures.
|
||||
*/
|
||||
struct dp_tx_sg_info_s {
|
||||
uint32_t num_segs;
|
||||
uint32_t total_len;
|
||||
struct dp_tx_seg_info_s *curr_seg;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_tx_queue - Tx queue
|
||||
* @desc_pool_id: Descriptor Pool to be used for the tx queue
|
||||
* @ring_id: TCL descriptor ring ID corresponding to the tx queue
|
||||
*
|
||||
* Tx queue contains information of the software (Descriptor pool)
|
||||
* and hardware resources (TCL ring id) to be used for a particular
|
||||
* transmit queue (obtained from skb_queue_mapping in case of linux)
|
||||
*/
|
||||
struct dp_tx_queue {
|
||||
uint8_t desc_pool_id;
|
||||
uint8_t ring_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_tx_msdu_info_s - MSDU Descriptor
|
||||
* @frm_type: Frame type - Regular/TSO/SG/Multicast enhancement
|
||||
* @tx_queue: Tx queue on which this MSDU should be transmitted
|
||||
* @num_seg: Number of segments (TSO)
|
||||
* @tid: TID (override) that is sent from HLOS
|
||||
* @u.tso_info: TSO information for TSO frame types
|
||||
* (chain of the TSO segments, number of segments)
|
||||
* @u.sg_info: Scatter Gather information for non-TSO SG frames
|
||||
* @meta_data: Mesh meta header information
|
||||
* @exception_fw: Duplicate frame to be sent to firmware
|
||||
* @ppdu_cookie: 16-bit ppdu_cookie that has to be replayed back in completions
|
||||
* @ix_tx_sniffer: Indicates if the packet has to be sniffed
|
||||
*
|
||||
* This structure holds the complete MSDU information needed to program the
|
||||
* Hardware TCL and MSDU extension descriptors for different frame types
|
||||
*
|
||||
*/
|
||||
struct dp_tx_msdu_info_s {
|
||||
enum dp_tx_frm_type frm_type;
|
||||
struct dp_tx_queue tx_queue;
|
||||
uint32_t num_seg;
|
||||
uint8_t tid;
|
||||
uint8_t exception_fw;
|
||||
uint8_t is_tx_sniffer;
|
||||
uint8_t search_type;
|
||||
union {
|
||||
struct qdf_tso_info_t tso_info;
|
||||
struct dp_tx_sg_info_s sg_info;
|
||||
} u;
|
||||
uint32_t meta_data[DP_TX_MSDU_INFO_META_DATA_DWORDS];
|
||||
uint16_t ppdu_cookie;
|
||||
uint16_t ast_idx;
|
||||
uint16_t ast_hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* dp_tx_deinit_pair_by_index() - Deinit TX rings based on index
|
||||
* @soc: core txrx context
|
||||
* @index: index of ring to deinit
|
||||
*
|
||||
* Deinit 1 TCL and 1 WBM2SW release ring on as needed basis using
|
||||
* index of the respective TCL/WBM2SW release in soc structure.
|
||||
* For example, if the index is 2 then &soc->tcl_data_ring[2]
|
||||
* and &soc->tx_comp_ring[2] will be deinitialized.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_tx_deinit_pair_by_index(struct dp_soc *soc, int index);
|
||||
|
||||
QDF_STATUS dp_tx_vdev_attach(struct dp_vdev *vdev);
|
||||
QDF_STATUS dp_tx_vdev_detach(struct dp_vdev *vdev);
|
||||
void dp_tx_vdev_update_search_flags(struct dp_vdev *vdev);
|
||||
void dp_tx_tso_cmn_desc_pool_deinit(struct dp_soc *soc, uint8_t num_pool);
|
||||
void dp_tx_tso_cmn_desc_pool_free(struct dp_soc *soc, uint8_t num_pool);
|
||||
QDF_STATUS dp_tx_tso_cmn_desc_pool_alloc(struct dp_soc *soc,
|
||||
uint8_t num_pool,
|
||||
uint16_t num_desc);
|
||||
QDF_STATUS dp_tx_tso_cmn_desc_pool_init(struct dp_soc *soc,
|
||||
uint8_t num_pool,
|
||||
uint16_t num_desc);
|
||||
|
||||
void dp_tx_tso_cmn_desc_pool_deinit(struct dp_soc *soc, uint8_t num_pool);
|
||||
void dp_tx_tso_cmn_desc_pool_free(struct dp_soc *soc, uint8_t num_pool);
|
||||
void dp_soc_tx_desc_sw_pools_free(struct dp_soc *soc);
|
||||
void dp_soc_tx_desc_sw_pools_deinit(struct dp_soc *soc);
|
||||
QDF_STATUS dp_tx_tso_cmn_desc_pool_alloc(struct dp_soc *soc,
|
||||
uint8_t num_pool,
|
||||
uint16_t num_desc);
|
||||
QDF_STATUS dp_tx_tso_cmn_desc_pool_init(struct dp_soc *soc,
|
||||
uint8_t num_pool,
|
||||
uint16_t num_desc);
|
||||
QDF_STATUS dp_soc_tx_desc_sw_pools_alloc(struct dp_soc *soc);
|
||||
QDF_STATUS dp_soc_tx_desc_sw_pools_init(struct dp_soc *soc);
|
||||
|
||||
/**
|
||||
* dp_tso_attach() - TSO Attach handler
|
||||
* @txrx_soc: Opaque Dp handle
|
||||
*
|
||||
* Reserve TSO descriptor buffers
|
||||
*
|
||||
* Return: QDF_STATUS_E_FAILURE on failure or
|
||||
* QDF_STATUS_SUCCESS on success
|
||||
*/
|
||||
QDF_STATUS dp_tso_soc_attach(struct cdp_soc_t *txrx_soc);
|
||||
|
||||
/**
|
||||
* dp_tso_detach() - TSO Detach handler
|
||||
* @txrx_soc: Opaque Dp handle
|
||||
*
|
||||
* Deallocate TSO descriptor buffers
|
||||
*
|
||||
* Return: QDF_STATUS_E_FAILURE on failure or
|
||||
* QDF_STATUS_SUCCESS on success
|
||||
*/
|
||||
QDF_STATUS dp_tso_soc_detach(struct cdp_soc_t *txrx_soc);
|
||||
|
||||
QDF_STATUS dp_tx_pdev_init(struct dp_pdev *pdev);
|
||||
|
||||
qdf_nbuf_t dp_tx_send(struct cdp_soc_t *soc, uint8_t vdev_id, qdf_nbuf_t nbuf);
|
||||
|
||||
qdf_nbuf_t dp_tx_send_vdev_id_check(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf);
|
||||
|
||||
qdf_nbuf_t dp_tx_send_exception(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf,
|
||||
struct cdp_tx_exception_metadata *tx_exc);
|
||||
|
||||
qdf_nbuf_t dp_tx_send_exception_vdev_id_check(struct cdp_soc_t *soc,
|
||||
uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf,
|
||||
struct cdp_tx_exception_metadata *tx_exc);
|
||||
|
||||
qdf_nbuf_t dp_tx_send_mesh(struct cdp_soc_t *soc, uint8_t vdev_id,
|
||||
qdf_nbuf_t nbuf);
|
||||
qdf_nbuf_t
|
||||
dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
struct dp_tx_msdu_info_s *msdu_info, uint16_t peer_id,
|
||||
struct cdp_tx_exception_metadata *tx_exc_metadata);
|
||||
|
||||
#if QDF_LOCK_STATS
|
||||
noinline qdf_nbuf_t
|
||||
dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
struct dp_tx_msdu_info_s *msdu_info);
|
||||
#else
|
||||
qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
struct dp_tx_msdu_info_s *msdu_info);
|
||||
#endif
|
||||
#ifdef FEATURE_WLAN_TDLS
|
||||
/**
|
||||
* dp_tx_non_std() - Allow the control-path SW to send data frames
|
||||
* @soc_hdl: Datapath soc handle
|
||||
* @vdev_id: id of vdev
|
||||
* @tx_spec: what non-standard handling to apply to the tx data frames
|
||||
* @msdu_list: NULL-terminated list of tx MSDUs
|
||||
*
|
||||
* Return: NULL on success,
|
||||
* nbuf when it fails to send
|
||||
*/
|
||||
qdf_nbuf_t dp_tx_non_std(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
|
||||
enum ol_tx_spec tx_spec, qdf_nbuf_t msdu_list);
|
||||
#endif
|
||||
int dp_tx_frame_is_drop(struct dp_vdev *vdev, uint8_t *srcmac, uint8_t *dstmac);
|
||||
|
||||
/**
|
||||
* dp_tx_comp_handler() - Tx completion handler
|
||||
* @int_ctx: pointer to DP interrupt context
|
||||
* @soc: core txrx main context
|
||||
* @hal_srng: Opaque HAL SRNG pointer
|
||||
* @ring_id: completion ring id
|
||||
* @quota: No. of packets/descriptors that can be serviced in one loop
|
||||
*
|
||||
* This function will collect hardware release ring element contents and
|
||||
* handle descriptor contents. Based on contents, free packet or handle error
|
||||
* conditions
|
||||
*
|
||||
* Return: Number of TX completions processed
|
||||
*/
|
||||
uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_srng, uint8_t ring_id,
|
||||
uint32_t quota);
|
||||
|
||||
QDF_STATUS
|
||||
dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
|
||||
|
||||
QDF_STATUS
|
||||
dp_tx_prepare_send_igmp_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
|
||||
|
||||
#ifndef FEATURE_WDS
|
||||
static inline void dp_tx_mec_handler(struct dp_vdev *vdev, uint8_t *status)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ATH_SUPPORT_IQUE
|
||||
static inline void dp_tx_me_exit(struct dp_pdev *pdev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef QCA_MULTIPASS_SUPPORT
|
||||
static inline
|
||||
bool dp_tx_multipass_process(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
qdf_nbuf_t nbuf,
|
||||
struct dp_tx_msdu_info_s *msdu_info)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline
|
||||
void dp_tx_vdev_multipass_deinit(struct dp_vdev *vdev)
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
bool dp_tx_multipass_process(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
qdf_nbuf_t nbuf,
|
||||
struct dp_tx_msdu_info_s *msdu_info);
|
||||
|
||||
void dp_tx_vdev_multipass_deinit(struct dp_vdev *vdev);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_tx_get_queue() - Returns Tx queue IDs to be used for this Tx frame
|
||||
* @vdev: DP Virtual device handle
|
||||
* @nbuf: Buffer pointer
|
||||
* @queue: queue ids container for nbuf
|
||||
*
|
||||
* TX packet queue has 2 instances, software descriptors id and dma ring id
|
||||
* Based on tx feature and hardware configuration queue id combination could be
|
||||
* different.
|
||||
* For example -
|
||||
* With XPS enabled,all TX descriptor pools and dma ring are assigned per cpu id
|
||||
* With no XPS,lock based resource protection, Descriptor pool ids are different
|
||||
* for each vdev, dma ring id will be same as single pdev id
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#ifdef QCA_OL_TX_MULTIQ_SUPPORT
|
||||
static inline void dp_tx_get_queue(struct dp_vdev *vdev,
|
||||
qdf_nbuf_t nbuf, struct dp_tx_queue *queue)
|
||||
{
|
||||
uint16_t queue_offset = qdf_nbuf_get_queue_mapping(nbuf) &
|
||||
DP_TX_QUEUE_MASK;
|
||||
|
||||
queue->desc_pool_id = queue_offset;
|
||||
queue->ring_id = qdf_get_cpu();
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s, pool_id:%d ring_id: %d",
|
||||
__func__, queue->desc_pool_id, queue->ring_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_tx_get_hal_ring_hdl()- Get the hal_tx_ring_hdl for data transmission
|
||||
* @dp_soc - DP soc structure pointer
|
||||
* @ring_id - Transmit Queue/ring_id to be used when XPS is enabled
|
||||
*
|
||||
* Return - HAL ring handle
|
||||
*/
|
||||
static inline hal_ring_handle_t dp_tx_get_hal_ring_hdl(struct dp_soc *soc,
|
||||
uint8_t ring_id)
|
||||
{
|
||||
if (ring_id == soc->num_tcl_data_rings)
|
||||
return soc->tcl_cmd_credit_ring.hal_srng;
|
||||
|
||||
return soc->tcl_data_ring[ring_id].hal_srng;
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_tx_get_rbm_id()- Get the RBM ID for data transmission completion.
|
||||
* @dp_soc - DP soc structure pointer
|
||||
* @ring_id - Transmit Queue/ring_id to be used when XPS is enabled
|
||||
*
|
||||
* Return - HAL ring handle
|
||||
*/
|
||||
static inline uint8_t dp_tx_get_rbm_id(struct dp_soc *doc,
|
||||
uint8_t ring_id)
|
||||
{
|
||||
return (ring_id ? HAL_WBM_SW0_BM_ID + (ring_id - 1) :
|
||||
HAL_WBM_SW2_BM_ID);
|
||||
}
|
||||
|
||||
#else /* QCA_OL_TX_MULTIQ_SUPPORT */
|
||||
static inline void dp_tx_get_queue(struct dp_vdev *vdev,
|
||||
qdf_nbuf_t nbuf, struct dp_tx_queue *queue)
|
||||
{
|
||||
/* get flow id */
|
||||
queue->desc_pool_id = DP_TX_GET_DESC_POOL_ID(vdev);
|
||||
queue->ring_id = DP_TX_GET_RING_ID(vdev);
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"%s, pool_id:%d ring_id: %d",
|
||||
__func__, queue->desc_pool_id, queue->ring_id);
|
||||
}
|
||||
|
||||
static inline hal_ring_handle_t dp_tx_get_hal_ring_hdl(struct dp_soc *soc,
|
||||
uint8_t ring_id)
|
||||
{
|
||||
return soc->tcl_data_ring[ring_id].hal_srng;
|
||||
}
|
||||
|
||||
static inline uint8_t dp_tx_get_rbm_id(struct dp_soc *soc,
|
||||
uint8_t ring_id)
|
||||
{
|
||||
return (ring_id + HAL_WBM_SW0_BM_ID);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef QCA_OL_TX_LOCK_LESS_ACCESS
|
||||
/*
|
||||
* dp_tx_hal_ring_access_start()- hal_tx_ring access for data transmission
|
||||
* @dp_soc - DP soc structure pointer
|
||||
* @hal_ring_hdl - HAL ring handle
|
||||
*
|
||||
* Return - None
|
||||
*/
|
||||
static inline int dp_tx_hal_ring_access_start(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl)
|
||||
{
|
||||
return hal_srng_access_start_unlocked(soc->hal_soc, hal_ring_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_tx_hal_ring_access_end()- hal_tx_ring access for data transmission
|
||||
* @dp_soc - DP soc structure pointer
|
||||
* @hal_ring_hdl - HAL ring handle
|
||||
*
|
||||
* Return - None
|
||||
*/
|
||||
static inline void dp_tx_hal_ring_access_end(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl)
|
||||
{
|
||||
hal_srng_access_end_unlocked(soc->hal_soc, hal_ring_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_tx_hal_ring_access_reap()- hal_tx_ring access for data transmission
|
||||
* @dp_soc - DP soc structure pointer
|
||||
* @hal_ring_hdl - HAL ring handle
|
||||
*
|
||||
* Return - None
|
||||
*/
|
||||
static inline void dp_tx_hal_ring_access_end_reap(struct dp_soc *soc,
|
||||
hal_ring_handle_t
|
||||
hal_ring_hdl)
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int dp_tx_hal_ring_access_start(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl)
|
||||
{
|
||||
return hal_srng_access_start(soc->hal_soc, hal_ring_hdl);
|
||||
}
|
||||
|
||||
static inline void dp_tx_hal_ring_access_end(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl)
|
||||
{
|
||||
hal_srng_access_end(soc->hal_soc, hal_ring_hdl);
|
||||
}
|
||||
|
||||
static inline void dp_tx_hal_ring_access_end_reap(struct dp_soc *soc,
|
||||
hal_ring_handle_t
|
||||
hal_ring_hdl)
|
||||
{
|
||||
hal_srng_access_end_reap(soc->hal_soc, hal_ring_hdl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_PERPKT_INFO
|
||||
QDF_STATUS
|
||||
dp_get_completion_indication_for_stack(struct dp_soc *soc,
|
||||
struct dp_pdev *pdev,
|
||||
struct dp_peer *peer,
|
||||
struct hal_tx_completion_status *ts,
|
||||
qdf_nbuf_t netbuf,
|
||||
uint64_t time_latency);
|
||||
|
||||
void dp_send_completion_to_stack(struct dp_soc *soc, struct dp_pdev *pdev,
|
||||
uint16_t peer_id, uint32_t ppdu_id,
|
||||
qdf_nbuf_t netbuf);
|
||||
#endif
|
||||
|
||||
void dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl);
|
||||
|
||||
#ifdef ATH_TX_PRI_OVERRIDE
|
||||
#define DP_TX_TID_OVERRIDE(_msdu_info, _nbuf) \
|
||||
((_msdu_info)->tid = qdf_nbuf_get_priority(_nbuf))
|
||||
#else
|
||||
#define DP_TX_TID_OVERRIDE(_msdu_info, _nbuf)
|
||||
#endif
|
||||
|
||||
void
|
||||
dp_handle_wbm_internal_error(struct dp_soc *soc, void *hal_desc,
|
||||
uint32_t buf_type);
|
||||
|
||||
/* TODO TX_FEATURE_NOT_YET */
|
||||
static inline void dp_tx_comp_process_exception(struct dp_tx_desc_s *tx_desc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* TODO TX_FEATURE_NOT_YET */
|
||||
|
||||
#ifndef WLAN_TX_PKT_CAPTURE_ENH
|
||||
static inline
|
||||
QDF_STATUS dp_peer_set_tx_capture_enabled(struct dp_pdev *pdev,
|
||||
struct dp_peer *peer_handle,
|
||||
uint8_t value, uint8_t *peer_mac)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
void dp_tx_desc_flush(struct dp_pdev *pdev, struct dp_vdev *vdev,
|
||||
bool force_free);
|
||||
|
||||
#ifdef WLAN_FEATURE_PKT_CAPTURE_V2
|
||||
void dp_send_completion_to_pkt_capture(struct dp_soc *soc,
|
||||
struct dp_tx_desc_s *desc,
|
||||
struct hal_tx_completion_status *ts);
|
||||
#else
|
||||
static inline void
|
||||
dp_send_completion_to_pkt_capture(struct dp_soc *soc,
|
||||
struct dp_tx_desc_s *desc,
|
||||
struct hal_tx_completion_status *ts)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
716
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.c
Normal file
716
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.c
Normal file
|
|
@ -0,0 +1,716 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hal_hw_headers.h"
|
||||
#include "dp_types.h"
|
||||
#include "dp_tx_desc.h"
|
||||
|
||||
#ifndef DESC_PARTITION
|
||||
#define DP_TX_DESC_SIZE(a) qdf_get_pwr2(a)
|
||||
#define DP_TX_DESC_PAGE_DIVIDER(soc, num_desc_per_page, pool_id) \
|
||||
do { \
|
||||
uint8_t sig_bit; \
|
||||
soc->tx_desc[pool_id].offset_filter = num_desc_per_page - 1; \
|
||||
/* Calculate page divider to find page number */ \
|
||||
sig_bit = 0; \
|
||||
while (num_desc_per_page) { \
|
||||
sig_bit++; \
|
||||
num_desc_per_page = num_desc_per_page >> 1; \
|
||||
} \
|
||||
soc->tx_desc[pool_id].page_divider = (sig_bit - 1); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DP_TX_DESC_SIZE(a) a
|
||||
#define DP_TX_DESC_PAGE_DIVIDER(soc, num_desc_per_page, pool_id) {}
|
||||
#endif /* DESC_PARTITION */
|
||||
|
||||
/**
|
||||
* dp_tx_desc_pool_counter_initialize() - Initialize counters
|
||||
* @tx_desc_pool Handle to DP tx_desc_pool structure
|
||||
* @num_elem Number of descriptor elements per pool
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
static void
|
||||
dp_tx_desc_pool_counter_initialize(struct dp_tx_desc_pool_s *tx_desc_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
}
|
||||
#else
|
||||
static void
|
||||
dp_tx_desc_pool_counter_initialize(struct dp_tx_desc_pool_s *tx_desc_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
tx_desc_pool->num_free = num_elem;
|
||||
tx_desc_pool->num_allocated = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_tx_desc_pool_alloc() - Allocate Tx Descriptor pool(s)
|
||||
* @soc Handle to DP SoC structure
|
||||
* @pool_id pool to allocate
|
||||
* @num_elem Number of descriptor elements per pool
|
||||
*
|
||||
* This function allocates memory for SW tx descriptors
|
||||
* (used within host for tx data path).
|
||||
* The number of tx descriptors required will be large
|
||||
* since based on number of clients (1024 clients x 3 radios),
|
||||
* outstanding MSDUs stored in TQM queues and LMAC queues will be significantly
|
||||
* large.
|
||||
*
|
||||
* To avoid allocating a large contiguous memory, it uses multi_page_alloc qdf
|
||||
* function to allocate memory
|
||||
* in multiple pages. It then iterates through the memory allocated across pages
|
||||
* and links each descriptor
|
||||
* to next descriptor, taking care of page boundaries.
|
||||
*
|
||||
* Since WiFi 3.0 HW supports multiple Tx rings, multiple pools are allocated,
|
||||
* one for each ring;
|
||||
* This minimizes lock contention when hard_start_xmit is called
|
||||
* from multiple CPUs.
|
||||
* Alternately, multiple pools can be used for multiple VDEVs for VDEV level
|
||||
* flow control.
|
||||
*
|
||||
* Return: Status code. 0 for success.
|
||||
*/
|
||||
QDF_STATUS dp_tx_desc_pool_alloc(struct dp_soc *soc, uint8_t pool_id,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
uint32_t desc_size;
|
||||
struct dp_tx_desc_pool_s *tx_desc_pool;
|
||||
|
||||
desc_size = DP_TX_DESC_SIZE(sizeof(struct dp_tx_desc_s));
|
||||
tx_desc_pool = &((soc)->tx_desc[(pool_id)]);
|
||||
dp_desc_multi_pages_mem_alloc(soc, DP_TX_DESC_TYPE,
|
||||
&tx_desc_pool->desc_pages,
|
||||
desc_size, num_elem,
|
||||
0, true);
|
||||
|
||||
if (!tx_desc_pool->desc_pages.num_pages) {
|
||||
dp_err("Multi page alloc fail, tx desc");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_desc_pool_free() - Free the tx dexcriptor pools
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @pool_id: pool to free
|
||||
*
|
||||
*/
|
||||
void dp_tx_desc_pool_free(struct dp_soc *soc, uint8_t pool_id)
|
||||
{
|
||||
struct dp_tx_desc_pool_s *tx_desc_pool;
|
||||
|
||||
tx_desc_pool = &((soc)->tx_desc[pool_id]);
|
||||
|
||||
if (tx_desc_pool->desc_pages.num_pages)
|
||||
dp_desc_multi_pages_mem_free(soc, DP_TX_DESC_TYPE,
|
||||
&tx_desc_pool->desc_pages, 0,
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_desc_pool_init() - Initialize Tx Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @pool_id: pool to allocate
|
||||
* @num_elem: Number of descriptor elements per pool
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_FAULT
|
||||
*/
|
||||
QDF_STATUS dp_tx_desc_pool_init(struct dp_soc *soc, uint8_t pool_id,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
uint32_t id, count, page_id, offset, pool_id_32;
|
||||
struct dp_tx_desc_pool_s *tx_desc_pool;
|
||||
struct dp_tx_desc_s *tx_desc_elem;
|
||||
uint16_t num_desc_per_page;
|
||||
uint32_t desc_size;
|
||||
|
||||
desc_size = DP_TX_DESC_SIZE(sizeof(*tx_desc_elem));
|
||||
|
||||
tx_desc_pool = &((soc)->tx_desc[(pool_id)]);
|
||||
if (qdf_mem_multi_page_link(soc->osdev,
|
||||
&tx_desc_pool->desc_pages,
|
||||
desc_size, num_elem, true)) {
|
||||
dp_err("invalid tx desc allocation -overflow num link");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
tx_desc_pool->freelist = (struct dp_tx_desc_s *)
|
||||
*tx_desc_pool->desc_pages.cacheable_pages;
|
||||
/* Set unique IDs for each Tx descriptor */
|
||||
tx_desc_elem = tx_desc_pool->freelist;
|
||||
count = 0;
|
||||
pool_id_32 = (uint32_t)pool_id;
|
||||
num_desc_per_page = tx_desc_pool->desc_pages.num_element_per_page;
|
||||
while (tx_desc_elem) {
|
||||
page_id = count / num_desc_per_page;
|
||||
offset = count % num_desc_per_page;
|
||||
id = ((pool_id_32 << DP_TX_DESC_ID_POOL_OS) |
|
||||
(page_id << DP_TX_DESC_ID_PAGE_OS) | offset);
|
||||
|
||||
tx_desc_elem->id = id;
|
||||
tx_desc_elem->pool_id = pool_id;
|
||||
tx_desc_elem = tx_desc_elem->next;
|
||||
count++;
|
||||
}
|
||||
|
||||
tx_desc_pool->elem_size = DP_TX_DESC_SIZE(sizeof(*tx_desc_elem));
|
||||
|
||||
dp_tx_desc_pool_counter_initialize(tx_desc_pool, num_elem);
|
||||
TX_DESC_LOCK_CREATE(&tx_desc_pool->lock);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_desc_pool_deinit() - de-initialize Tx Descriptor pool(s)
|
||||
* @soc Handle to DP SoC structure
|
||||
* @pool_id: pool to de-initialize
|
||||
*
|
||||
*/
|
||||
void dp_tx_desc_pool_deinit(struct dp_soc *soc, uint8_t pool_id)
|
||||
{
|
||||
struct dp_tx_desc_pool_s *tx_desc_pool;
|
||||
|
||||
tx_desc_pool = &((soc)->tx_desc[(pool_id)]);
|
||||
TX_DESC_POOL_MEMBER_CLEAN(tx_desc_pool);
|
||||
TX_DESC_LOCK_DESTROY(&tx_desc_pool->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_ext_desc_pool_alloc() - allocate Tx extenstion Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to allocate
|
||||
* @num_elem: Number of descriptor elements per pool
|
||||
*
|
||||
* Return - QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
*/
|
||||
QDF_STATUS dp_tx_ext_desc_pool_alloc(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
qdf_dma_context_t memctx = 0;
|
||||
uint8_t pool_id, count;
|
||||
uint16_t elem_size = HAL_TX_EXT_DESC_WITH_META_DATA;
|
||||
struct dp_tx_ext_desc_pool_s *dp_tx_ext_desc_pool;
|
||||
uint16_t link_elem_size = sizeof(struct dp_tx_ext_desc_elem_s);
|
||||
|
||||
/* Coherent tx extension descriptor alloc */
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
dp_tx_ext_desc_pool = &((soc)->tx_ext_desc[pool_id]);
|
||||
memctx = qdf_get_dma_mem_context(dp_tx_ext_desc_pool, memctx);
|
||||
dp_desc_multi_pages_mem_alloc(
|
||||
soc, DP_TX_EXT_DESC_TYPE,
|
||||
&dp_tx_ext_desc_pool->desc_pages,
|
||||
elem_size,
|
||||
num_elem,
|
||||
memctx, false);
|
||||
|
||||
if (!dp_tx_ext_desc_pool->desc_pages.num_pages) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"ext desc page alloc fail");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto fail_exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cacheable ext descriptor link alloc
|
||||
* This structure also large size already
|
||||
* single element is 24bytes, 2K elements are 48Kbytes
|
||||
* Have to alloc multi page cacheable memory
|
||||
*/
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
dp_tx_ext_desc_pool = &((soc)->tx_ext_desc[pool_id]);
|
||||
dp_desc_multi_pages_mem_alloc(
|
||||
soc,
|
||||
DP_TX_EXT_DESC_LINK_TYPE,
|
||||
&dp_tx_ext_desc_pool->desc_link_pages,
|
||||
link_elem_size,
|
||||
num_elem,
|
||||
0, true);
|
||||
|
||||
if (!dp_tx_ext_desc_pool->desc_link_pages.num_pages) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"ext link desc page alloc fail");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto free_ext_desc_page;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
|
||||
free_ext_desc_page:
|
||||
for (count = 0; count < pool_id; pool_id++) {
|
||||
dp_tx_ext_desc_pool = &((soc)->tx_ext_desc[pool_id]);
|
||||
dp_desc_multi_pages_mem_free(
|
||||
soc, DP_TX_EXT_DESC_LINK_TYPE,
|
||||
&dp_tx_ext_desc_pool->desc_link_pages,
|
||||
0, true);
|
||||
}
|
||||
pool_id = num_pool;
|
||||
|
||||
fail_exit:
|
||||
for (count = 0; count < pool_id; pool_id++) {
|
||||
dp_tx_ext_desc_pool = &((soc)->tx_ext_desc[pool_id]);
|
||||
memctx = qdf_get_dma_mem_context(dp_tx_ext_desc_pool, memctx);
|
||||
dp_desc_multi_pages_mem_free(
|
||||
soc, DP_TX_EXT_DESC_TYPE,
|
||||
&dp_tx_ext_desc_pool->desc_pages,
|
||||
memctx, false);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_ext_desc_pool_init() - initialize Tx extenstion Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to initialize
|
||||
* @num_elem: Number of descriptor elements per pool
|
||||
*
|
||||
* Return - QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
*/
|
||||
QDF_STATUS dp_tx_ext_desc_pool_init(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
uint32_t i;
|
||||
struct dp_tx_ext_desc_elem_s *c_elem, *p_elem;
|
||||
struct qdf_mem_dma_page_t *page_info;
|
||||
struct qdf_mem_multi_page_t *pages;
|
||||
struct dp_tx_ext_desc_pool_s *dp_tx_ext_desc_pool;
|
||||
uint8_t pool_id;
|
||||
QDF_STATUS status;
|
||||
|
||||
/* link tx descriptors into a freelist */
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
dp_tx_ext_desc_pool = &((soc)->tx_ext_desc[pool_id]);
|
||||
soc->tx_ext_desc[pool_id].elem_size =
|
||||
HAL_TX_EXT_DESC_WITH_META_DATA;
|
||||
soc->tx_ext_desc[pool_id].link_elem_size =
|
||||
sizeof(struct dp_tx_ext_desc_elem_s);
|
||||
soc->tx_ext_desc[pool_id].elem_count = num_elem;
|
||||
|
||||
dp_tx_ext_desc_pool->freelist = (struct dp_tx_ext_desc_elem_s *)
|
||||
*dp_tx_ext_desc_pool->desc_link_pages.cacheable_pages;
|
||||
|
||||
if (qdf_mem_multi_page_link(soc->osdev,
|
||||
&dp_tx_ext_desc_pool->
|
||||
desc_link_pages,
|
||||
dp_tx_ext_desc_pool->link_elem_size,
|
||||
dp_tx_ext_desc_pool->elem_count,
|
||||
true)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"ext link desc page linking fail");
|
||||
status = QDF_STATUS_E_FAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Assign coherent memory pointer into linked free list */
|
||||
pages = &dp_tx_ext_desc_pool->desc_pages;
|
||||
page_info = dp_tx_ext_desc_pool->desc_pages.dma_pages;
|
||||
c_elem = dp_tx_ext_desc_pool->freelist;
|
||||
p_elem = c_elem;
|
||||
for (i = 0; i < dp_tx_ext_desc_pool->elem_count; i++) {
|
||||
if (!(i % pages->num_element_per_page)) {
|
||||
/**
|
||||
* First element for new page,
|
||||
* should point next page
|
||||
*/
|
||||
if (!pages->dma_pages->page_v_addr_start) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||
QDF_TRACE_LEVEL_ERROR,
|
||||
"link over flow");
|
||||
status = QDF_STATUS_E_FAULT;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
c_elem->vaddr =
|
||||
(void *)page_info->page_v_addr_start;
|
||||
c_elem->paddr = page_info->page_p_addr;
|
||||
page_info++;
|
||||
} else {
|
||||
c_elem->vaddr = (void *)(p_elem->vaddr +
|
||||
dp_tx_ext_desc_pool->elem_size);
|
||||
c_elem->paddr = (p_elem->paddr +
|
||||
dp_tx_ext_desc_pool->elem_size);
|
||||
}
|
||||
p_elem = c_elem;
|
||||
c_elem = c_elem->next;
|
||||
if (!c_elem)
|
||||
break;
|
||||
}
|
||||
dp_tx_ext_desc_pool->num_free = num_elem;
|
||||
qdf_spinlock_create(&dp_tx_ext_desc_pool->lock);
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_ext_desc_pool_free() - free Tx extenstion Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to free
|
||||
*
|
||||
*/
|
||||
void dp_tx_ext_desc_pool_free(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
uint8_t pool_id;
|
||||
struct dp_tx_ext_desc_pool_s *dp_tx_ext_desc_pool;
|
||||
qdf_dma_context_t memctx = 0;
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
dp_tx_ext_desc_pool = &((soc)->tx_ext_desc[pool_id]);
|
||||
memctx = qdf_get_dma_mem_context(dp_tx_ext_desc_pool, memctx);
|
||||
|
||||
dp_desc_multi_pages_mem_free(
|
||||
soc, DP_TX_EXT_DESC_LINK_TYPE,
|
||||
&dp_tx_ext_desc_pool->desc_link_pages,
|
||||
0, true);
|
||||
|
||||
dp_desc_multi_pages_mem_free(
|
||||
soc, DP_TX_EXT_DESC_TYPE,
|
||||
&dp_tx_ext_desc_pool->desc_pages,
|
||||
memctx, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_ext_desc_pool_deinit() - deinit Tx extenstion Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to de-initialize
|
||||
*
|
||||
*/
|
||||
void dp_tx_ext_desc_pool_deinit(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
uint8_t pool_id;
|
||||
struct dp_tx_ext_desc_pool_s *dp_tx_ext_desc_pool;
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
dp_tx_ext_desc_pool = &((soc)->tx_ext_desc[pool_id]);
|
||||
qdf_spinlock_destroy(&dp_tx_ext_desc_pool->lock);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FEATURE_TSO)
|
||||
/**
|
||||
* dp_tx_tso_desc_pool_alloc() - allocate TSO Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to allocate
|
||||
* @num_elem: Number of descriptor elements per pool
|
||||
*
|
||||
* Return - QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
*/
|
||||
QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
struct dp_tx_tso_seg_pool_s *tso_desc_pool;
|
||||
uint32_t desc_size, pool_id, i;
|
||||
|
||||
desc_size = DP_TX_DESC_SIZE(sizeof(struct qdf_tso_seg_elem_t));
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_desc_pool = &soc->tx_tso_desc[pool_id];
|
||||
tso_desc_pool->num_free = 0;
|
||||
dp_desc_multi_pages_mem_alloc(
|
||||
soc,
|
||||
DP_TX_TSO_DESC_TYPE,
|
||||
&tso_desc_pool->desc_pages,
|
||||
desc_size,
|
||||
num_elem, 0, true);
|
||||
|
||||
if (!tso_desc_pool->desc_pages.num_pages) {
|
||||
dp_err("Multi page alloc fail, tx desc");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < pool_id; i++) {
|
||||
tso_desc_pool = &soc->tx_tso_desc[i];
|
||||
dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_DESC_TYPE,
|
||||
&tso_desc_pool->desc_pages,
|
||||
0, true);
|
||||
}
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_tso_desc_pool_free() - free TSO Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to free
|
||||
*
|
||||
*/
|
||||
void dp_tx_tso_desc_pool_free(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
struct dp_tx_tso_seg_pool_s *tso_desc_pool;
|
||||
uint32_t pool_id;
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_desc_pool = &soc->tx_tso_desc[pool_id];
|
||||
dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_DESC_TYPE,
|
||||
&tso_desc_pool->desc_pages,
|
||||
0, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_tso_desc_pool_init() - initialize TSO Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to initialize
|
||||
* @num_elem: Number of descriptor elements per pool
|
||||
*
|
||||
* Return - QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
*/
|
||||
QDF_STATUS dp_tx_tso_desc_pool_init(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
struct dp_tx_tso_seg_pool_s *tso_desc_pool;
|
||||
uint32_t desc_size, pool_id;
|
||||
|
||||
desc_size = DP_TX_DESC_SIZE(sizeof(struct qdf_tso_seg_elem_t));
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_desc_pool = &soc->tx_tso_desc[pool_id];
|
||||
|
||||
if (qdf_mem_multi_page_link(soc->osdev,
|
||||
&tso_desc_pool->desc_pages,
|
||||
desc_size,
|
||||
num_elem, true)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"invalid tso desc allocation - overflow num link");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
tso_desc_pool->freelist = (struct qdf_tso_seg_elem_t *)
|
||||
*tso_desc_pool->desc_pages.cacheable_pages;
|
||||
tso_desc_pool->num_free = num_elem;
|
||||
|
||||
TSO_DEBUG("Number of free descriptors: %u\n",
|
||||
tso_desc_pool->num_free);
|
||||
tso_desc_pool->pool_size = num_elem;
|
||||
qdf_spinlock_create(&tso_desc_pool->lock);
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_tso_desc_pool_deinit() - deinitialize TSO Descriptor pool(s)
|
||||
* @soc: Handle to DP SoC structure
|
||||
* @num_pool: Number of pools to free
|
||||
*
|
||||
*/
|
||||
void dp_tx_tso_desc_pool_deinit(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
struct dp_tx_tso_seg_pool_s *tso_desc_pool;
|
||||
uint32_t pool_id;
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_desc_pool = &soc->tx_tso_desc[pool_id];
|
||||
qdf_spin_lock_bh(&tso_desc_pool->lock);
|
||||
|
||||
tso_desc_pool->freelist = NULL;
|
||||
tso_desc_pool->num_free = 0;
|
||||
tso_desc_pool->pool_size = 0;
|
||||
qdf_spin_unlock_bh(&tso_desc_pool->lock);
|
||||
qdf_spinlock_destroy(&tso_desc_pool->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_tso_num_seg_pool_alloc() - Allocate descriptors that tracks the
|
||||
* fragments in each tso segment
|
||||
*
|
||||
* @soc: handle to dp soc structure
|
||||
* @num_pool: number of pools to allocate
|
||||
* @num_elem: total number of descriptors to be allocated
|
||||
*
|
||||
* Return - QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_NOMEM
|
||||
*/
|
||||
QDF_STATUS dp_tx_tso_num_seg_pool_alloc(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
struct dp_tx_tso_num_seg_pool_s *tso_num_seg_pool;
|
||||
uint32_t desc_size, pool_id, i;
|
||||
|
||||
desc_size = DP_TX_DESC_SIZE(sizeof(struct qdf_tso_num_seg_elem_t));
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_num_seg_pool = &soc->tx_tso_num_seg[pool_id];
|
||||
tso_num_seg_pool->num_free = 0;
|
||||
dp_desc_multi_pages_mem_alloc(soc, DP_TX_TSO_NUM_SEG_TYPE,
|
||||
&tso_num_seg_pool->desc_pages,
|
||||
desc_size,
|
||||
num_elem, 0, true);
|
||||
|
||||
if (!tso_num_seg_pool->desc_pages.num_pages) {
|
||||
dp_err("Multi page alloc fail, tso_num_seg_pool");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
for (i = 0; i < pool_id; i++) {
|
||||
tso_num_seg_pool = &soc->tx_tso_num_seg[i];
|
||||
dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_NUM_SEG_TYPE,
|
||||
&tso_num_seg_pool->desc_pages,
|
||||
0, true);
|
||||
}
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_tso_num_seg_pool_free() - free descriptors that tracks the
|
||||
* fragments in each tso segment
|
||||
*
|
||||
* @soc: handle to dp soc structure
|
||||
* @num_pool: number of pools to free
|
||||
*/
|
||||
void dp_tx_tso_num_seg_pool_free(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
struct dp_tx_tso_num_seg_pool_s *tso_num_seg_pool;
|
||||
uint32_t pool_id;
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_num_seg_pool = &soc->tx_tso_num_seg[pool_id];
|
||||
dp_desc_multi_pages_mem_free(soc, DP_TX_TSO_NUM_SEG_TYPE,
|
||||
&tso_num_seg_pool->desc_pages,
|
||||
0, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_tso_num_seg_pool_init() - Initialize descriptors that tracks the
|
||||
* fragments in each tso segment
|
||||
*
|
||||
* @soc: handle to dp soc structure
|
||||
* @num_pool: number of pools to initialize
|
||||
* @num_elem: total number of descriptors to be initialized
|
||||
*
|
||||
* Return - QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_FAULT
|
||||
*/
|
||||
QDF_STATUS dp_tx_tso_num_seg_pool_init(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
struct dp_tx_tso_num_seg_pool_s *tso_num_seg_pool;
|
||||
uint32_t desc_size, pool_id;
|
||||
|
||||
desc_size = DP_TX_DESC_SIZE(sizeof(struct qdf_tso_num_seg_elem_t));
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_num_seg_pool = &soc->tx_tso_num_seg[pool_id];
|
||||
if (qdf_mem_multi_page_link(soc->osdev,
|
||||
&tso_num_seg_pool->desc_pages,
|
||||
desc_size,
|
||||
num_elem, true)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"invalid tso desc allocation - overflow num link");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
tso_num_seg_pool->freelist = (struct qdf_tso_num_seg_elem_t *)
|
||||
*tso_num_seg_pool->desc_pages.cacheable_pages;
|
||||
tso_num_seg_pool->num_free = num_elem;
|
||||
tso_num_seg_pool->num_seg_pool_size = num_elem;
|
||||
|
||||
qdf_spinlock_create(&tso_num_seg_pool->lock);
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_tso_num_seg_pool_deinit() - de-initialize descriptors that tracks the
|
||||
* fragments in each tso segment
|
||||
*
|
||||
* @soc: handle to dp soc structure
|
||||
* @num_pool: number of pools to de-initialize
|
||||
*
|
||||
* Return - QDF_STATUS_SUCCESS
|
||||
* QDF_STATUS_E_FAULT
|
||||
*/
|
||||
void dp_tx_tso_num_seg_pool_deinit(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
struct dp_tx_tso_num_seg_pool_s *tso_num_seg_pool;
|
||||
uint32_t pool_id;
|
||||
|
||||
for (pool_id = 0; pool_id < num_pool; pool_id++) {
|
||||
tso_num_seg_pool = &soc->tx_tso_num_seg[pool_id];
|
||||
qdf_spin_lock_bh(&tso_num_seg_pool->lock);
|
||||
|
||||
tso_num_seg_pool->freelist = NULL;
|
||||
tso_num_seg_pool->num_free = 0;
|
||||
tso_num_seg_pool->num_seg_pool_size = 0;
|
||||
qdf_spin_unlock_bh(&tso_num_seg_pool->lock);
|
||||
qdf_spinlock_destroy(&tso_num_seg_pool->lock);
|
||||
}
|
||||
}
|
||||
#else
|
||||
QDF_STATUS dp_tx_tso_desc_pool_alloc(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS dp_tx_tso_desc_pool_init(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void dp_tx_tso_desc_pool_free(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
}
|
||||
|
||||
void dp_tx_tso_desc_pool_deinit(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
}
|
||||
|
||||
QDF_STATUS dp_tx_tso_num_seg_pool_alloc(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void dp_tx_tso_num_seg_pool_free(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
}
|
||||
|
||||
QDF_STATUS dp_tx_tso_num_seg_pool_init(struct dp_soc *soc, uint8_t num_pool,
|
||||
uint16_t num_elem)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void dp_tx_tso_num_seg_pool_deinit(struct dp_soc *soc, uint8_t num_pool)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
1021
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.h
Normal file
1021
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_tx_desc.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,622 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <cds_api.h>
|
||||
|
||||
/* OS abstraction libraries */
|
||||
#include <qdf_nbuf.h> /* qdf_nbuf_t, etc. */
|
||||
#include <qdf_atomic.h> /* qdf_atomic_read, etc. */
|
||||
#include <qdf_util.h> /* qdf_unlikely */
|
||||
#include "dp_types.h"
|
||||
#include "dp_tx_desc.h"
|
||||
|
||||
#include <cdp_txrx_handle.h>
|
||||
#include "dp_internal.h"
|
||||
#define INVALID_FLOW_ID 0xFF
|
||||
#define MAX_INVALID_BIN 3
|
||||
|
||||
#ifdef QCA_AC_BASED_FLOW_CONTROL
|
||||
/**
|
||||
* dp_tx_initialize_threshold() - Threshold of flow Pool initialization
|
||||
* @pool: flow_pool
|
||||
* @stop_threshold: stop threshold of certian AC
|
||||
* @start_threshold: start threshold of certian AC
|
||||
* @flow_pool_size: flow pool size
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
dp_tx_initialize_threshold(struct dp_tx_desc_pool_s *pool,
|
||||
uint32_t start_threshold,
|
||||
uint32_t stop_threshold,
|
||||
uint16_t flow_pool_size)
|
||||
{
|
||||
/* BE_BK threshold is same as previous threahold */
|
||||
pool->start_th[DP_TH_BE_BK] = (start_threshold
|
||||
* flow_pool_size) / 100;
|
||||
pool->stop_th[DP_TH_BE_BK] = (stop_threshold
|
||||
* flow_pool_size) / 100;
|
||||
|
||||
/* Update VI threshold based on BE_BK threashold */
|
||||
pool->start_th[DP_TH_VI] = (pool->start_th[DP_TH_BE_BK]
|
||||
* FL_TH_VI_PERCENTAGE) / 100;
|
||||
pool->stop_th[DP_TH_VI] = (pool->stop_th[DP_TH_BE_BK]
|
||||
* FL_TH_VI_PERCENTAGE) / 100;
|
||||
|
||||
/* Update VO threshold based on BE_BK threashold */
|
||||
pool->start_th[DP_TH_VO] = (pool->start_th[DP_TH_BE_BK]
|
||||
* FL_TH_VO_PERCENTAGE) / 100;
|
||||
pool->stop_th[DP_TH_VO] = (pool->stop_th[DP_TH_BE_BK]
|
||||
* FL_TH_VO_PERCENTAGE) / 100;
|
||||
|
||||
/* Update High Priority threshold based on BE_BK threashold */
|
||||
pool->start_th[DP_TH_HI] = (pool->start_th[DP_TH_BE_BK]
|
||||
* FL_TH_HI_PERCENTAGE) / 100;
|
||||
pool->stop_th[DP_TH_HI] = (pool->stop_th[DP_TH_BE_BK]
|
||||
* FL_TH_HI_PERCENTAGE) / 100;
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: tx flow control threshold is set, pool size is %d",
|
||||
__func__, flow_pool_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_pool_reattach() - Reattach flow_pool
|
||||
* @pool: flow_pool
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
dp_tx_flow_pool_reattach(struct dp_tx_desc_pool_s *pool)
|
||||
{
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: flow pool already allocated, attached %d times",
|
||||
__func__, pool->pool_create_cnt);
|
||||
|
||||
if (pool->avail_desc > pool->start_th[DP_TH_BE_BK])
|
||||
pool->status = FLOW_POOL_ACTIVE_UNPAUSED;
|
||||
else if (pool->avail_desc <= pool->start_th[DP_TH_BE_BK] &&
|
||||
pool->avail_desc > pool->start_th[DP_TH_VI])
|
||||
pool->status = FLOW_POOL_BE_BK_PAUSED;
|
||||
else if (pool->avail_desc <= pool->start_th[DP_TH_VI] &&
|
||||
pool->avail_desc > pool->start_th[DP_TH_VO])
|
||||
pool->status = FLOW_POOL_VI_PAUSED;
|
||||
else if (pool->avail_desc <= pool->start_th[DP_TH_VO] &&
|
||||
pool->avail_desc > pool->start_th[DP_TH_HI])
|
||||
pool->status = FLOW_POOL_VO_PAUSED;
|
||||
else
|
||||
pool->status = FLOW_POOL_ACTIVE_PAUSED;
|
||||
|
||||
pool->pool_create_cnt++;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_pool_dump_threshold() - Dump threshold of the flow_pool
|
||||
* @pool: flow_pool
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void
|
||||
dp_tx_flow_pool_dump_threshold(struct dp_tx_desc_pool_s *pool)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FL_TH_MAX; i++) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Level %d :: Start threshold %d :: Stop threshold %d",
|
||||
i, pool->start_th[i], pool->stop_th[i]);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Level %d :: Maximun pause time %lu ms",
|
||||
i, pool->max_pause_time[i]);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Level %d :: Latest pause timestamp %lu",
|
||||
i, pool->latest_pause_time[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void
|
||||
dp_tx_initialize_threshold(struct dp_tx_desc_pool_s *pool,
|
||||
uint32_t start_threshold,
|
||||
uint32_t stop_threshold,
|
||||
uint16_t flow_pool_size)
|
||||
|
||||
{
|
||||
/* INI is in percentage so divide by 100 */
|
||||
pool->start_th = (start_threshold * flow_pool_size) / 100;
|
||||
pool->stop_th = (stop_threshold * flow_pool_size) / 100;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_tx_flow_pool_reattach(struct dp_tx_desc_pool_s *pool)
|
||||
{
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: flow pool already allocated, attached %d times",
|
||||
__func__, pool->pool_create_cnt);
|
||||
if (pool->avail_desc > pool->start_th)
|
||||
pool->status = FLOW_POOL_ACTIVE_UNPAUSED;
|
||||
else
|
||||
pool->status = FLOW_POOL_ACTIVE_PAUSED;
|
||||
|
||||
pool->pool_create_cnt++;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_tx_flow_pool_dump_threshold(struct dp_tx_desc_pool_s *pool)
|
||||
{
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Start threshold %d :: Stop threshold %d",
|
||||
pool->start_th, pool->stop_th);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_tx_dump_flow_pool_info() - dump global_pool and flow_pool info
|
||||
*
|
||||
* @ctx: Handle to struct dp_soc.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_tx_dump_flow_pool_info(struct cdp_soc_t *soc_hdl)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_txrx_pool_stats *pool_stats = &soc->pool_stats;
|
||||
struct dp_tx_desc_pool_s *pool = NULL;
|
||||
struct dp_tx_desc_pool_s tmp_pool;
|
||||
int i;
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"No of pool map received %d", pool_stats->pool_map_count);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"No of pool unmap received %d", pool_stats->pool_unmap_count);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Pkt dropped due to unavailablity of pool %d",
|
||||
pool_stats->pkt_drop_no_pool);
|
||||
|
||||
/*
|
||||
* Nested spin lock.
|
||||
* Always take in below order.
|
||||
* flow_pool_array_lock -> flow_pool_lock
|
||||
*/
|
||||
qdf_spin_lock_bh(&soc->flow_pool_array_lock);
|
||||
for (i = 0; i < MAX_TXDESC_POOLS; i++) {
|
||||
pool = &soc->tx_desc[i];
|
||||
if (pool->status > FLOW_POOL_INVALID)
|
||||
continue;
|
||||
qdf_spin_lock_bh(&pool->flow_pool_lock);
|
||||
qdf_mem_copy(&tmp_pool, pool, sizeof(tmp_pool));
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
qdf_spin_unlock_bh(&soc->flow_pool_array_lock);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, "\n");
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Flow_pool_id %d :: status %d",
|
||||
tmp_pool.flow_pool_id, tmp_pool.status);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Total %d :: Available %d",
|
||||
tmp_pool.pool_size, tmp_pool.avail_desc);
|
||||
dp_tx_flow_pool_dump_threshold(&tmp_pool);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Member flow_id %d :: flow_type %d",
|
||||
tmp_pool.flow_pool_id, tmp_pool.flow_type);
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Pkt dropped due to unavailablity of descriptors %d",
|
||||
tmp_pool.pkt_drop_no_desc);
|
||||
qdf_spin_lock_bh(&soc->flow_pool_array_lock);
|
||||
}
|
||||
qdf_spin_unlock_bh(&soc->flow_pool_array_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_clear_flow_pool_stats() - clear flow pool statistics
|
||||
*
|
||||
* @soc: Handle to struct dp_soc.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_clear_flow_pool_stats(struct dp_soc *soc)
|
||||
{
|
||||
|
||||
if (!soc) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: soc is null", __func__);
|
||||
return;
|
||||
}
|
||||
qdf_mem_zero(&soc->pool_stats, sizeof(soc->pool_stats));
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_create_flow_pool() - create flow pool
|
||||
* @soc: Handle to struct dp_soc
|
||||
* @flow_pool_id: flow pool id
|
||||
* @flow_pool_size: flow pool size
|
||||
*
|
||||
* Return: flow_pool pointer / NULL for error
|
||||
*/
|
||||
struct dp_tx_desc_pool_s *dp_tx_create_flow_pool(struct dp_soc *soc,
|
||||
uint8_t flow_pool_id, uint16_t flow_pool_size)
|
||||
{
|
||||
struct dp_tx_desc_pool_s *pool;
|
||||
uint32_t stop_threshold;
|
||||
uint32_t start_threshold;
|
||||
|
||||
if (flow_pool_id >= MAX_TXDESC_POOLS) {
|
||||
dp_err("invalid flow_pool_id %d", flow_pool_id);
|
||||
return NULL;
|
||||
}
|
||||
pool = &soc->tx_desc[flow_pool_id];
|
||||
qdf_spin_lock_bh(&pool->flow_pool_lock);
|
||||
if ((pool->status != FLOW_POOL_INACTIVE) || pool->pool_create_cnt) {
|
||||
dp_tx_flow_pool_reattach(pool);
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
dp_err("cannot alloc desc, status=%d, create_cnt=%d",
|
||||
pool->status, pool->pool_create_cnt);
|
||||
return pool;
|
||||
}
|
||||
|
||||
if (dp_tx_desc_pool_alloc(soc, flow_pool_id, flow_pool_size)) {
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dp_tx_desc_pool_init(soc, flow_pool_id, flow_pool_size)) {
|
||||
dp_tx_desc_pool_free(soc, flow_pool_id);
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stop_threshold = wlan_cfg_get_tx_flow_stop_queue_th(soc->wlan_cfg_ctx);
|
||||
start_threshold = stop_threshold +
|
||||
wlan_cfg_get_tx_flow_start_queue_offset(soc->wlan_cfg_ctx);
|
||||
|
||||
pool->flow_pool_id = flow_pool_id;
|
||||
pool->pool_size = flow_pool_size;
|
||||
pool->avail_desc = flow_pool_size;
|
||||
pool->status = FLOW_POOL_ACTIVE_UNPAUSED;
|
||||
dp_tx_initialize_threshold(pool, start_threshold, stop_threshold,
|
||||
flow_pool_size);
|
||||
pool->pool_create_cnt++;
|
||||
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_delete_flow_pool() - delete flow pool
|
||||
* @soc: Handle to struct dp_soc
|
||||
* @pool: flow pool pointer
|
||||
* @force: free pool forcefully
|
||||
*
|
||||
* Delete flow_pool if all tx descriptors are available.
|
||||
* Otherwise put it in FLOW_POOL_INVALID state.
|
||||
* If force is set then pull all available descriptors to
|
||||
* global pool.
|
||||
*
|
||||
* Return: 0 for success or error
|
||||
*/
|
||||
int dp_tx_delete_flow_pool(struct dp_soc *soc, struct dp_tx_desc_pool_s *pool,
|
||||
bool force)
|
||||
{
|
||||
struct dp_vdev *vdev;
|
||||
|
||||
if (!soc || !pool) {
|
||||
dp_err("pool or soc is NULL");
|
||||
QDF_ASSERT(0);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
dp_info("pool create_cnt=%d, avail_desc=%d, size=%d, status=%d",
|
||||
pool->pool_create_cnt, pool->avail_desc,
|
||||
pool->pool_size, pool->status);
|
||||
qdf_spin_lock_bh(&pool->flow_pool_lock);
|
||||
if (!pool->pool_create_cnt) {
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
dp_err("flow pool either not created or alread deleted");
|
||||
return -ENOENT;
|
||||
}
|
||||
pool->pool_create_cnt--;
|
||||
if (pool->pool_create_cnt) {
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
dp_err("pool is still attached, pending detach %d",
|
||||
pool->pool_create_cnt);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (pool->avail_desc < pool->pool_size) {
|
||||
pool->status = FLOW_POOL_INVALID;
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
/* Reset TX desc associated to this Vdev as NULL */
|
||||
vdev = dp_vdev_get_ref_by_id(soc, pool->flow_pool_id,
|
||||
DP_MOD_ID_MISC);
|
||||
if (vdev) {
|
||||
dp_tx_desc_flush(vdev->pdev, vdev, false);
|
||||
dp_vdev_unref_delete(soc, vdev,
|
||||
DP_MOD_ID_MISC);
|
||||
}
|
||||
dp_err("avail desc less than pool size");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* We have all the descriptors for the pool, we can delete the pool */
|
||||
dp_tx_desc_pool_deinit(soc, pool->flow_pool_id);
|
||||
dp_tx_desc_pool_free(soc, pool->flow_pool_id);
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_pool_vdev_map() - Map flow_pool with vdev
|
||||
* @pdev: Handle to struct dp_pdev
|
||||
* @pool: flow_pool
|
||||
* @vdev_id: flow_id /vdev_id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void dp_tx_flow_pool_vdev_map(struct dp_pdev *pdev,
|
||||
struct dp_tx_desc_pool_s *pool, uint8_t vdev_id)
|
||||
{
|
||||
struct dp_vdev *vdev;
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
|
||||
vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: invalid vdev_id %d",
|
||||
__func__, vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
vdev->pool = pool;
|
||||
qdf_spin_lock_bh(&pool->flow_pool_lock);
|
||||
pool->pool_owner_ctx = soc;
|
||||
pool->flow_pool_id = vdev_id;
|
||||
qdf_spin_unlock_bh(&pool->flow_pool_lock);
|
||||
dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_pool_vdev_unmap() - Unmap flow_pool from vdev
|
||||
* @pdev: Handle to struct dp_pdev
|
||||
* @pool: flow_pool
|
||||
* @vdev_id: flow_id /vdev_id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static void dp_tx_flow_pool_vdev_unmap(struct dp_pdev *pdev,
|
||||
struct dp_tx_desc_pool_s *pool, uint8_t vdev_id)
|
||||
{
|
||||
struct dp_vdev *vdev;
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
|
||||
vdev = dp_vdev_get_ref_by_id(soc, vdev_id, DP_MOD_ID_CDP);
|
||||
if (!vdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: invalid vdev_id %d",
|
||||
__func__, vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
vdev->pool = NULL;
|
||||
dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_pool_map_handler() - Map flow_id with pool of descriptors
|
||||
* @pdev: Handle to struct dp_pdev
|
||||
* @flow_id: flow id
|
||||
* @flow_type: flow type
|
||||
* @flow_pool_id: pool id
|
||||
* @flow_pool_size: pool size
|
||||
*
|
||||
* Process below target to host message
|
||||
* HTT_T2H_MSG_TYPE_FLOW_POOL_MAP
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_tx_flow_pool_map_handler(struct dp_pdev *pdev, uint8_t flow_id,
|
||||
uint8_t flow_type, uint8_t flow_pool_id, uint16_t flow_pool_size)
|
||||
{
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
struct dp_tx_desc_pool_s *pool;
|
||||
enum htt_flow_type type = flow_type;
|
||||
|
||||
|
||||
dp_info("flow_id %d flow_type %d flow_pool_id %d flow_pool_size %d",
|
||||
flow_id, flow_type, flow_pool_id, flow_pool_size);
|
||||
|
||||
if (qdf_unlikely(!soc)) {
|
||||
dp_err("soc is NULL");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
soc->pool_stats.pool_map_count++;
|
||||
|
||||
pool = dp_tx_create_flow_pool(soc, flow_pool_id,
|
||||
flow_pool_size);
|
||||
if (!pool) {
|
||||
dp_err("creation of flow_pool %d size %d failed",
|
||||
flow_pool_id, flow_pool_size);
|
||||
return QDF_STATUS_E_RESOURCES;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
||||
case FLOW_TYPE_VDEV:
|
||||
dp_tx_flow_pool_vdev_map(pdev, pool, flow_id);
|
||||
break;
|
||||
default:
|
||||
dp_err("flow type %d not supported", type);
|
||||
break;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_pool_unmap_handler() - Unmap flow_id from pool of descriptors
|
||||
* @pdev: Handle to struct dp_pdev
|
||||
* @flow_id: flow id
|
||||
* @flow_type: flow type
|
||||
* @flow_pool_id: pool id
|
||||
*
|
||||
* Process below target to host message
|
||||
* HTT_T2H_MSG_TYPE_FLOW_POOL_UNMAP
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_tx_flow_pool_unmap_handler(struct dp_pdev *pdev, uint8_t flow_id,
|
||||
uint8_t flow_type, uint8_t flow_pool_id)
|
||||
{
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
struct dp_tx_desc_pool_s *pool;
|
||||
enum htt_flow_type type = flow_type;
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||
"%s: flow_id %d flow_type %d flow_pool_id %d",
|
||||
__func__, flow_id, flow_type, flow_pool_id);
|
||||
|
||||
if (qdf_unlikely(!pdev)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: pdev is NULL", __func__);
|
||||
return;
|
||||
}
|
||||
soc->pool_stats.pool_unmap_count++;
|
||||
|
||||
pool = &soc->tx_desc[flow_pool_id];
|
||||
if (!pool) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: flow_pool not available flow_pool_id %d",
|
||||
__func__, type);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
||||
case FLOW_TYPE_VDEV:
|
||||
dp_tx_flow_pool_vdev_unmap(pdev, pool, flow_id);
|
||||
break;
|
||||
default:
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: flow type %d not supported !!!",
|
||||
__func__, type);
|
||||
return;
|
||||
}
|
||||
|
||||
/* only delete if all descriptors are available */
|
||||
dp_tx_delete_flow_pool(soc, pool, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_control_init() - Initialize tx flow control
|
||||
* @tx_desc_pool: Handle to flow_pool
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_tx_flow_control_init(struct dp_soc *soc)
|
||||
{
|
||||
qdf_spinlock_create(&soc->flow_pool_array_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_desc_pool_dealloc() - De-allocate tx desc pool
|
||||
* @tx_desc_pool: Handle to flow_pool
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void dp_tx_desc_pool_dealloc(struct dp_soc *soc)
|
||||
{
|
||||
struct dp_tx_desc_pool_s *tx_desc_pool;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_TXDESC_POOLS; i++) {
|
||||
tx_desc_pool = &((soc)->tx_desc[i]);
|
||||
if (!tx_desc_pool->desc_pages.num_pages)
|
||||
continue;
|
||||
|
||||
dp_tx_desc_pool_deinit(soc, i);
|
||||
dp_tx_desc_pool_free(soc, i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_flow_control_deinit() - Deregister fw based tx flow control
|
||||
* @tx_desc_pool: Handle to flow_pool
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_tx_flow_control_deinit(struct dp_soc *soc)
|
||||
{
|
||||
dp_tx_desc_pool_dealloc(soc);
|
||||
|
||||
qdf_spinlock_destroy(&soc->flow_pool_array_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_txrx_register_pause_cb() - Register pause callback
|
||||
* @ctx: Handle to struct dp_soc
|
||||
* @pause_cb: Tx pause_cb
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
QDF_STATUS dp_txrx_register_pause_cb(struct cdp_soc_t *handle,
|
||||
tx_pause_callback pause_cb)
|
||||
{
|
||||
struct dp_soc *soc = (struct dp_soc *)handle;
|
||||
|
||||
if (!soc || !pause_cb) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("soc or pause_cb is NULL"));
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
soc->pause_cb = pause_cb;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS dp_tx_flow_pool_map(struct cdp_soc_t *handle, uint8_t pdev_id,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(handle);
|
||||
struct dp_pdev *pdev =
|
||||
dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
|
||||
int tx_ring_size = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
|
||||
|
||||
if (!pdev) {
|
||||
dp_err("pdev is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
return dp_tx_flow_pool_map_handler(pdev, vdev_id, FLOW_TYPE_VDEV,
|
||||
vdev_id, tx_ring_size);
|
||||
}
|
||||
|
||||
void dp_tx_flow_pool_unmap(struct cdp_soc_t *handle, uint8_t pdev_id,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(handle);
|
||||
struct dp_pdev *pdev =
|
||||
dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
|
||||
|
||||
if (!pdev) {
|
||||
dp_err("pdev is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
return dp_tx_flow_pool_unmap_handler(pdev, vdev_id,
|
||||
FLOW_TYPE_VDEV, vdev_id);
|
||||
}
|
||||
3246
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_types.h
Normal file
3246
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_types.h
Normal file
File diff suppressed because it is too large
Load diff
330
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_wdi_event.c
Normal file
330
drivers/staging/qca-wifi-host-cmn/dp/wifi3.0/dp_wdi_event.c
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "dp_internal.h"
|
||||
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
||||
|
||||
#ifdef WDI_EVENT_ENABLE
|
||||
void *dp_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
|
||||
{
|
||||
struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
|
||||
struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
|
||||
|
||||
if (!pdev)
|
||||
return NULL;
|
||||
|
||||
return pdev->pl_dev;
|
||||
}
|
||||
/*
|
||||
* dp_wdi_event_next_sub() - Return handle for Next WDI event
|
||||
* @wdi_sub: WDI Event handle
|
||||
*
|
||||
* Return handle for next WDI event in list
|
||||
*
|
||||
* Return: Next WDI event to be subscribe
|
||||
*/
|
||||
static inline wdi_event_subscribe *
|
||||
dp_wdi_event_next_sub(wdi_event_subscribe *wdi_sub)
|
||||
{
|
||||
if (!wdi_sub) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid subscriber in %s", __func__);
|
||||
return NULL;
|
||||
}
|
||||
return wdi_sub->priv.next;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dp_wdi_event_del_subs() -Delete Event subscription
|
||||
* @wdi_sub: WDI Event handle
|
||||
* @event_index: Event index from list
|
||||
*
|
||||
* This API will delete subscribed event from list
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
dp_wdi_event_del_subs(wdi_event_subscribe *wdi_sub, int event_index)
|
||||
{
|
||||
/* Subscribers should take care of deletion */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dp_wdi_event_iter_sub() - Iterate through all WDI event in the list
|
||||
* and pass WDI event to callback function
|
||||
* @pdev: DP pdev handle
|
||||
* @event_index: Event index in list
|
||||
* @wdi_event: WDI event handle
|
||||
* @data: pointer to data
|
||||
* @peer_id: peer id number
|
||||
* @status: HTT rx status
|
||||
*
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void
|
||||
dp_wdi_event_iter_sub(
|
||||
struct dp_pdev *pdev,
|
||||
uint32_t event_index,
|
||||
wdi_event_subscribe *wdi_sub,
|
||||
void *data,
|
||||
uint16_t peer_id,
|
||||
int status)
|
||||
{
|
||||
enum WDI_EVENT event = event_index + WDI_EVENT_BASE;
|
||||
|
||||
if (wdi_sub) {
|
||||
do {
|
||||
wdi_sub->callback(wdi_sub->context, event, data,
|
||||
peer_id, status);
|
||||
} while ((wdi_sub = dp_wdi_event_next_sub(wdi_sub)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dp_wdi_event_handler() - Event handler for WDI event
|
||||
* @event: wdi event number
|
||||
* @soc: soc handle
|
||||
* @data: pointer to data
|
||||
* @peer_id: peer id number
|
||||
* @status: HTT rx status
|
||||
* @pdev_id: id of pdev
|
||||
*
|
||||
* It will be called to register WDI event
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void
|
||||
dp_wdi_event_handler(
|
||||
enum WDI_EVENT event,
|
||||
struct dp_soc *soc,
|
||||
void *data,
|
||||
uint16_t peer_id,
|
||||
int status, uint8_t pdev_id)
|
||||
{
|
||||
uint32_t event_index;
|
||||
wdi_event_subscribe *wdi_sub;
|
||||
struct dp_pdev *txrx_pdev;
|
||||
struct dp_soc *soc_t = (struct dp_soc *)soc;
|
||||
txrx_pdev = dp_get_pdev_for_mac_id(soc_t, pdev_id);
|
||||
|
||||
if (!event) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid WDI event in %s", __func__);
|
||||
return;
|
||||
}
|
||||
if (!txrx_pdev || txrx_pdev->pdev_deinit) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid pdev in WDI event handler");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* There can be NULL data, so no validation for the data
|
||||
* Subscribers must do the sanity based on the requirements
|
||||
*/
|
||||
event_index = event - WDI_EVENT_BASE;
|
||||
|
||||
DP_STATS_INC(txrx_pdev, wdi_event[event_index], 1);
|
||||
wdi_sub = txrx_pdev->wdi_event_list[event_index];
|
||||
|
||||
/* Find the subscriber */
|
||||
dp_wdi_event_iter_sub(txrx_pdev, event_index, wdi_sub, data,
|
||||
peer_id, status);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dp_wdi_event_sub() - Subscribe WDI event
|
||||
* @soc: soc handle
|
||||
* @pdev_id: id of pdev
|
||||
* @event_cb_sub_handle: subcribe evnet handle
|
||||
* @event: Event to be subscribe
|
||||
*
|
||||
* Return: 0 for success. nonzero for failure.
|
||||
*/
|
||||
int
|
||||
dp_wdi_event_sub(
|
||||
struct cdp_soc_t *soc, uint8_t pdev_id,
|
||||
wdi_event_subscribe *event_cb_sub_handle,
|
||||
uint32_t event)
|
||||
{
|
||||
uint32_t event_index;
|
||||
wdi_event_subscribe *wdi_sub;
|
||||
wdi_event_subscribe *wdi_sub_itr;
|
||||
struct dp_pdev *txrx_pdev =
|
||||
dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
|
||||
pdev_id);
|
||||
wdi_event_subscribe *event_cb_sub =
|
||||
(wdi_event_subscribe *) event_cb_sub_handle;
|
||||
|
||||
if (!txrx_pdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid txrx_pdev in %s", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!event_cb_sub) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid callback in %s", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((!event) || (event >= WDI_EVENT_LAST) || (event < WDI_EVENT_BASE)) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid event in %s", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
dp_set_pktlog_wifi3(txrx_pdev, event, true);
|
||||
event_index = event - WDI_EVENT_BASE;
|
||||
wdi_sub = txrx_pdev->wdi_event_list[event_index];
|
||||
|
||||
/*
|
||||
* Check if it is the first subscriber of the event
|
||||
*/
|
||||
if (!wdi_sub) {
|
||||
wdi_sub = event_cb_sub;
|
||||
wdi_sub->priv.next = NULL;
|
||||
wdi_sub->priv.prev = NULL;
|
||||
txrx_pdev->wdi_event_list[event_index] = wdi_sub;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if event is already subscribed */
|
||||
wdi_sub_itr = wdi_sub;
|
||||
do {
|
||||
if (wdi_sub_itr == event_cb_sub) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||
"Duplicate wdi subscribe event detected %s", __func__);
|
||||
return 0;
|
||||
}
|
||||
} while ((wdi_sub_itr = dp_wdi_event_next_sub(wdi_sub_itr)));
|
||||
|
||||
event_cb_sub->priv.next = wdi_sub;
|
||||
event_cb_sub->priv.prev = NULL;
|
||||
wdi_sub->priv.prev = event_cb_sub;
|
||||
txrx_pdev->wdi_event_list[event_index] = event_cb_sub;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_wdi_event_unsub() - WDI event unsubscribe
|
||||
* @soc: soc handle
|
||||
* @pdev_id: id of pdev
|
||||
* @event_cb_sub_handle: subscribed event handle
|
||||
* @event: Event to be unsubscribe
|
||||
*
|
||||
*
|
||||
* Return: 0 for success. nonzero for failure.
|
||||
*/
|
||||
int
|
||||
dp_wdi_event_unsub(
|
||||
struct cdp_soc_t *soc, uint8_t pdev_id,
|
||||
wdi_event_subscribe *event_cb_sub_handle,
|
||||
uint32_t event)
|
||||
{
|
||||
uint32_t event_index = event - WDI_EVENT_BASE;
|
||||
struct dp_pdev *txrx_pdev =
|
||||
dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
|
||||
pdev_id);
|
||||
wdi_event_subscribe *event_cb_sub =
|
||||
(wdi_event_subscribe *) event_cb_sub_handle;
|
||||
|
||||
if (!txrx_pdev || !event_cb_sub) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid callback or pdev in %s", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dp_set_pktlog_wifi3(txrx_pdev, event, false);
|
||||
|
||||
if (!event_cb_sub->priv.prev) {
|
||||
txrx_pdev->wdi_event_list[event_index] = event_cb_sub->priv.next;
|
||||
} else {
|
||||
event_cb_sub->priv.prev->priv.next = event_cb_sub->priv.next;
|
||||
}
|
||||
if (event_cb_sub->priv.next) {
|
||||
event_cb_sub->priv.next->priv.prev = event_cb_sub->priv.prev;
|
||||
}
|
||||
|
||||
/* Reset susbscribe event list elems */
|
||||
event_cb_sub->priv.next = NULL;
|
||||
event_cb_sub->priv.prev = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dp_wdi_event_attach() - Attach wdi event
|
||||
* @txrx_pdev: DP pdev handle
|
||||
*
|
||||
* Return: 0 for success. nonzero for failure.
|
||||
*/
|
||||
int
|
||||
dp_wdi_event_attach(struct dp_pdev *txrx_pdev)
|
||||
{
|
||||
if (!txrx_pdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid device in %s\nWDI event attach failed",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Separate subscriber list for each event */
|
||||
txrx_pdev->wdi_event_list = (wdi_event_subscribe **)
|
||||
qdf_mem_malloc(
|
||||
sizeof(wdi_event_subscribe *) * WDI_NUM_EVENTS);
|
||||
if (!txrx_pdev->wdi_event_list) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Insufficient memory for the WDI event lists");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dp_wdi_event_detach() - Detach WDI event
|
||||
* @txrx_pdev: DP pdev handle
|
||||
*
|
||||
* Return: 0 for success. nonzero for failure.
|
||||
*/
|
||||
int
|
||||
dp_wdi_event_detach(struct dp_pdev *txrx_pdev)
|
||||
{
|
||||
int i;
|
||||
wdi_event_subscribe *wdi_sub;
|
||||
if (!txrx_pdev) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
"Invalid device in %s\nWDI attach failed", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!txrx_pdev->wdi_event_list) {
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < WDI_NUM_EVENTS; i++) {
|
||||
wdi_sub = txrx_pdev->wdi_event_list[i];
|
||||
/* Delete all the subscribers */
|
||||
dp_wdi_event_del_subs(wdi_sub, i);
|
||||
}
|
||||
qdf_mem_free(txrx_pdev->wdi_event_list);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_WIN */
|
||||
182
drivers/staging/qca-wifi-host-cmn/ftm/core/src/wlan_ftm_svc.c
Normal file
182
drivers/staging/qca-wifi-host-cmn/ftm/core/src/wlan_ftm_svc.c
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: This implementation of init/deint functions for FTM services.
|
||||
*/
|
||||
|
||||
#include "wlan_ftm_svc_i.h"
|
||||
#include <wlan_lmac_if_def.h>
|
||||
#include <wlan_ftm_ucfg_api.h>
|
||||
|
||||
static inline struct wlan_lmac_if_ftm_tx_ops *
|
||||
wlan_psoc_get_ftm_txops(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct wlan_lmac_if_tx_ops *tx_ops;
|
||||
|
||||
tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
|
||||
if (!tx_ops) {
|
||||
ftm_err("tx_ops is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &tx_ops->ftm_tx_ops;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
ftm_pdev_obj_init(struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj)
|
||||
{
|
||||
ftm_pdev_obj->data = qdf_mem_malloc(FTM_CMD_MAX_BUF_LENGTH);
|
||||
if (!ftm_pdev_obj->data)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
ftm_pdev_obj->length = 0;
|
||||
|
||||
ftm_pdev_obj->cmd_type = WIFI_FTM_CMD_UNKNOWN;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_ftm_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
|
||||
void *arg_list)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
|
||||
|
||||
ftm_pdev_obj = qdf_mem_malloc(sizeof(*ftm_pdev_obj));
|
||||
|
||||
if (!ftm_pdev_obj)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
ftm_pdev_obj->pdev = pdev;
|
||||
status = ftm_pdev_obj_init(ftm_pdev_obj);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
ftm_err("ftm pdev obj init failed");
|
||||
qdf_mem_free(ftm_pdev_obj);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = wlan_objmgr_pdev_component_obj_attach(pdev,
|
||||
WLAN_UMAC_COMP_FTM,
|
||||
ftm_pdev_obj,
|
||||
QDF_STATUS_SUCCESS);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
ftm_err("ftm pdev obj attach failed");
|
||||
qdf_mem_free(ftm_pdev_obj);
|
||||
return status;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
ftm_pdev_obj_deinit(struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj)
|
||||
{
|
||||
if (ftm_pdev_obj->data) {
|
||||
qdf_mem_free(ftm_pdev_obj->data);
|
||||
|
||||
ftm_pdev_obj->data = NULL;
|
||||
ftm_pdev_obj->length = 0;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_ftm_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
|
||||
void *arg_list)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj =
|
||||
wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_FTM);
|
||||
|
||||
if (!ftm_pdev_obj) {
|
||||
ftm_err("invalid wifi ftm obj");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
status = wlan_objmgr_pdev_component_obj_detach(pdev, WLAN_UMAC_COMP_FTM,
|
||||
ftm_pdev_obj);
|
||||
|
||||
status = ftm_pdev_obj_deinit(ftm_pdev_obj);
|
||||
ftm_pdev_obj->pdev = NULL;
|
||||
|
||||
qdf_mem_free(ftm_pdev_obj);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_ftm_testmode_attach(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
|
||||
|
||||
ftm_tx_ops = wlan_psoc_get_ftm_txops(psoc);
|
||||
if (!ftm_tx_ops) {
|
||||
ftm_err("ftm_tx_ops is NULL");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
if (ftm_tx_ops->ftm_attach)
|
||||
return ftm_tx_ops->ftm_attach(psoc);
|
||||
else
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_ftm_testmode_detach(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
|
||||
|
||||
ftm_tx_ops = wlan_psoc_get_ftm_txops(psoc);
|
||||
if (!ftm_tx_ops) {
|
||||
ftm_err("ftm_tx_ops is NULL");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
if (ftm_tx_ops->ftm_detach)
|
||||
return ftm_tx_ops->ftm_detach(psoc);
|
||||
else
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_ftm_cmd_send(struct wlan_objmgr_pdev *pdev, uint8_t *buf,
|
||||
uint32_t len, uint8_t pdev_id)
|
||||
{
|
||||
struct wlan_lmac_if_ftm_tx_ops *ftm_tx_ops;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
|
||||
psoc = wlan_pdev_get_psoc(pdev);
|
||||
if (!psoc)
|
||||
return QDF_STATUS_E_NOENT;
|
||||
|
||||
ftm_tx_ops = wlan_psoc_get_ftm_txops(psoc);
|
||||
if (!ftm_tx_ops) {
|
||||
ftm_err("ftm_tx_ops is NULL");
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
if (ftm_tx_ops->ftm_cmd_send)
|
||||
return ftm_tx_ops->ftm_cmd_send(pdev, buf, len, pdev_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: declare the ftm service data structure and apis
|
||||
*/
|
||||
#ifndef _WLAN_FTM_SVC_H_
|
||||
#define _WLAN_FTM_SVC_H_
|
||||
|
||||
#include <qdf_types.h>
|
||||
#include <qdf_status.h>
|
||||
#include <wlan_objmgr_pdev_obj.h>
|
||||
|
||||
/**
|
||||
* struct ftm_seg_hdr_info - the segment header for the event from FW
|
||||
* @len: length of the segment header
|
||||
* @msgref: message reference
|
||||
* @segment_info: segment information
|
||||
* @pad: padding
|
||||
*
|
||||
*/
|
||||
struct ftm_seg_hdr_info {
|
||||
uint32_t len;
|
||||
uint32_t msgref;
|
||||
uint32_t segment_info;
|
||||
uint32_t pad;
|
||||
};
|
||||
|
||||
/**
|
||||
* wlan_ftm_pdev_obj_create_notification() - ftm pdev create handler
|
||||
* @pdev: pdev pointer
|
||||
* @arg_list: argument list
|
||||
*
|
||||
* return: QDF_STATUS_SUCCESS for success or error code
|
||||
*/
|
||||
QDF_STATUS wlan_ftm_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
|
||||
void *arg_list);
|
||||
|
||||
/**
|
||||
* wlan_ftm_pdev_obj_destroy_notification() - ftm pdev destroy handler
|
||||
* @pdev: pdev pointer
|
||||
* @arg_list: argument list
|
||||
*
|
||||
* return: QDF_STATUS_SUCCESS for success or error code
|
||||
*/
|
||||
QDF_STATUS wlan_ftm_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
|
||||
void *arg_list);
|
||||
|
||||
/**
|
||||
* wlan_ftm_cmd_send() - send ftm command to target_if layer
|
||||
* @pdev: pdev pointer
|
||||
* @buf: data buffer
|
||||
* @len: event length
|
||||
*
|
||||
* return: QDF_STATUS_SUCCESS for success or error code
|
||||
*/
|
||||
QDF_STATUS wlan_ftm_cmd_send(struct wlan_objmgr_pdev *pdev, uint8_t *buf,
|
||||
uint32_t len, uint8_t pdev_id);
|
||||
|
||||
/**
|
||||
* wlan_ftm_testmode_attach() - Attach FTM UTF handle
|
||||
* @psoc: psoc pointer
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS wlan_ftm_testmode_attach(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* wlan_ftm_testmode_detach() - Attach FTM UTF handle
|
||||
* @psoc: psoc pointer
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS wlan_ftm_testmode_detach(struct wlan_objmgr_psoc *psoc);
|
||||
#endif /* _WLAN_FTM_SVC_H_ */
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: declare the ftm service data structure and apis
|
||||
*/
|
||||
#ifndef _WLAN_FTM_UCFG_API_H_
|
||||
#define _WLAN_FTM_UCFG_API_H_
|
||||
|
||||
#include <qdf_types.h>
|
||||
#include <qdf_status.h>
|
||||
#include <wlan_objmgr_cmn.h>
|
||||
|
||||
#ifdef QCA_WIFI_FTM
|
||||
/**
|
||||
* dispatcher_ftm_init() - FTM testmode initialization API
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS dispatcher_ftm_init(void);
|
||||
|
||||
/**
|
||||
* dispatcher_ftm_deinit() - FTM testmode deinitialization API
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS dispatcher_ftm_deinit(void);
|
||||
|
||||
/**
|
||||
* dispatcher_ftm_psoc_open() - FTM module open API
|
||||
* @psoc: psoc object
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS dispatcher_ftm_psoc_open(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* dispatcher_ftm_psoc_close() - FTM module close API
|
||||
* @psoc: psoc object
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS dispatcher_ftm_psoc_close(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
#else
|
||||
static inline QDF_STATUS dispatcher_ftm_init(void)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS dispatcher_ftm_deinit(void)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
dispatcher_ftm_psoc_open(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
dispatcher_ftm_psoc_close(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
#endif /* _WLAN_FTM_UCFG_API_H_ */
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: declare the ftm service data structure and apis
|
||||
*/
|
||||
#ifndef _WLAN_FTM_UCFG_API_H_
|
||||
#define _WLAN_FTM_UCFG_API_H_
|
||||
|
||||
#include <qdf_types.h>
|
||||
#include <qdf_status.h>
|
||||
#include <wlan_objmgr_cmn.h>
|
||||
|
||||
#define FTM_DEBUG 0
|
||||
|
||||
#if FTM_DEBUG
|
||||
#define ftm_alert(params...) \
|
||||
QDF_TRACE_FATAL(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_err(params...) \
|
||||
QDF_TRACE_ERROR(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_warn(params...) \
|
||||
QDF_TRACE_WARN(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_notice(params...) \
|
||||
QDF_TRACE_INFO(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_debug(params...) \
|
||||
QDF_TRACE_DEBUG(QDF_MODULE_ID_FTM, params)
|
||||
|
||||
#define ftm_nofl_alert(params...) \
|
||||
QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_nofl_err(params...) \
|
||||
QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_nofl_warn(params...) \
|
||||
QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_nofl_notice(params...) \
|
||||
QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_FTM, params)
|
||||
#define ftm_nofl_debug(params...) \
|
||||
QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_FTM, params)
|
||||
|
||||
#else
|
||||
#define ftm_alert(params...)
|
||||
#define ftm_err(params...)
|
||||
#define ftm_warn(params...)
|
||||
#define ftm_notice(params...)
|
||||
#define ftm_debug(params...)
|
||||
|
||||
#define ftm_nofl_alert(params...)
|
||||
#define ftm_nofl_err(params...)
|
||||
#define ftm_nofl_warn(params...)
|
||||
#define ftm_nofl_notice(params...)
|
||||
#define ftm_nofl_debug(params...)
|
||||
#endif
|
||||
|
||||
#define FTM_IOCTL_UNIFIED_UTF_CMD 0x1000
|
||||
#define FTM_IOCTL_UNIFIED_UTF_RSP 0x1001
|
||||
#define FTM_CMD_MAX_BUF_LENGTH 2048
|
||||
|
||||
/**
|
||||
* enum wifi_ftm_cmd_type - the enumeration of the command source per pdev
|
||||
* @WIFI_FTM_CMD_IOCTL: command from ioctl on the pdev
|
||||
* @WIFI_FTM_CMD_NL80211: command from nl80211 on the pdev
|
||||
*
|
||||
*/
|
||||
enum wifi_ftm_pdev_cmd_type {
|
||||
WIFI_FTM_CMD_IOCTL = 1,
|
||||
WIFI_FTM_CMD_NL80211,
|
||||
|
||||
/* command should be added above */
|
||||
WIFI_FTM_CMD_UNKNOWN,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wifi_ftm_pdev_priv_obj - wifi ftm pdev utf event info
|
||||
* @pdev: pointer to pdev
|
||||
* @data: data ptr
|
||||
* @current_seq: curent squence
|
||||
* @expected_seq: expected sequence
|
||||
* @length: length
|
||||
* @offset: offset
|
||||
* @cmd_type: command type from either ioctl or nl80211
|
||||
*/
|
||||
struct wifi_ftm_pdev_priv_obj {
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
uint8_t *data;
|
||||
uint8_t current_seq;
|
||||
uint8_t expected_seq;
|
||||
qdf_size_t length;
|
||||
qdf_size_t offset;
|
||||
enum wifi_ftm_pdev_cmd_type cmd_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* wlan_ftm_testmode_cmd() - handle FTM testmode command
|
||||
* @pdev: pdev pointer
|
||||
* @data: data
|
||||
* @len: data length
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS ucfg_wlan_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t *data, uint32_t len);
|
||||
|
||||
/**
|
||||
* wlan_ftm_testmode_rsp() - handle FTM testmode command
|
||||
* @pdev: pdev pointer
|
||||
* @data: data
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
|
||||
*/
|
||||
QDF_STATUS ucfg_wlan_ftm_testmode_rsp(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t *data);
|
||||
|
||||
/**
|
||||
* wlan_ftm_process_utf_event() - process ftm UTF event
|
||||
* @scn_handle: scn handle
|
||||
* @event: event buffer
|
||||
* @len: event length
|
||||
*
|
||||
* return: QDF_STATUS_SUCCESS for success or error code
|
||||
*/
|
||||
QDF_STATUS wlan_ftm_process_utf_event(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t *event_buf, uint32_t len);
|
||||
#endif /* _WLAN_FTM_UCFG_API_H_ */
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: This implementation of init/deint functions for FTM services.
|
||||
*/
|
||||
|
||||
#include <wlan_ftm_init_deinit_api.h>
|
||||
#include <wlan_ftm_ucfg_api.h>
|
||||
#include <wlan_objmgr_global_obj.h>
|
||||
#include "../../core/src/wlan_ftm_svc_i.h"
|
||||
#include <wlan_cmn.h>
|
||||
#include <qdf_module.h>
|
||||
|
||||
QDF_STATUS dispatcher_ftm_init(void)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
status = wlan_objmgr_register_pdev_create_handler(WLAN_UMAC_COMP_FTM,
|
||||
wlan_ftm_pdev_obj_create_notification, NULL);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto err_pdev_create;
|
||||
|
||||
status = wlan_objmgr_register_pdev_destroy_handler(WLAN_UMAC_COMP_FTM,
|
||||
wlan_ftm_pdev_obj_destroy_notification, NULL);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto err_pdev_delete;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
err_pdev_delete:
|
||||
wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_FTM,
|
||||
wlan_ftm_pdev_obj_create_notification, NULL);
|
||||
err_pdev_create:
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS dispatcher_ftm_deinit(void)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
|
||||
status = wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_FTM,
|
||||
wlan_ftm_pdev_obj_create_notification, NULL);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
status = wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_FTM,
|
||||
wlan_ftm_pdev_obj_destroy_notification, NULL);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS dispatcher_ftm_psoc_open(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
/* calling the wmi event handler registration */
|
||||
return wlan_ftm_testmode_attach(psoc);
|
||||
}
|
||||
|
||||
QDF_STATUS dispatcher_ftm_psoc_close(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
/* calling the wmi event handler de-registration */
|
||||
return wlan_ftm_testmode_detach(psoc);
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: This implementation of init/deint functions for FTM services.
|
||||
*/
|
||||
|
||||
#include <wlan_ftm_ucfg_api.h>
|
||||
#include <wlan_cfg80211_ftm.h>
|
||||
#include "../../core/src/wlan_ftm_svc_i.h"
|
||||
#include <wlan_cmn.h>
|
||||
#include <qdf_module.h>
|
||||
|
||||
QDF_STATUS ucfg_wlan_ftm_testmode_cmd(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t *data, uint32_t len)
|
||||
{
|
||||
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
|
||||
uint8_t pdev_id;
|
||||
|
||||
ftm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
|
||||
WLAN_UMAC_COMP_FTM);
|
||||
if (!ftm_pdev_obj) {
|
||||
ftm_err("Failed to get ftm pdev component");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
ftm_pdev_obj->length = 0;
|
||||
pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
|
||||
|
||||
return wlan_ftm_cmd_send(pdev, data, len, pdev_id);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_ftm_process_utf_event(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t *event_buf, uint32_t len)
|
||||
{
|
||||
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
|
||||
uint32_t utf_datalen;
|
||||
uint8_t *utf_data;
|
||||
struct ftm_seg_hdr_info seghdr_info;
|
||||
u_int8_t total_segments, current_seq;
|
||||
|
||||
ftm_pdev_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
|
||||
WLAN_UMAC_COMP_FTM);
|
||||
if (!ftm_pdev_obj) {
|
||||
ftm_err("Failed to get ftm pdev component");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
utf_data = event_buf;
|
||||
seghdr_info = *(struct ftm_seg_hdr_info *)(event_buf);
|
||||
ftm_pdev_obj->current_seq = (seghdr_info.segment_info & 0xF);
|
||||
|
||||
current_seq = (seghdr_info.segment_info & 0xF);
|
||||
total_segments = (seghdr_info.segment_info >> 4) & 0xF;
|
||||
|
||||
utf_datalen = len - sizeof(seghdr_info);
|
||||
|
||||
if (current_seq == 0) {
|
||||
ftm_pdev_obj->expected_seq = 0;
|
||||
ftm_pdev_obj->offset = 0;
|
||||
} else {
|
||||
if (ftm_pdev_obj->expected_seq != current_seq) {
|
||||
ftm_debug("seq mismatch exp Seq %d got seq %d\n",
|
||||
ftm_pdev_obj->expected_seq, current_seq);
|
||||
}
|
||||
}
|
||||
|
||||
if ((len > FTM_CMD_MAX_BUF_LENGTH) ||
|
||||
(ftm_pdev_obj->offset > (FTM_CMD_MAX_BUF_LENGTH - utf_datalen))) {
|
||||
ftm_err("Invalid utf data len :%d", len);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
qdf_mem_copy(&ftm_pdev_obj->data[ftm_pdev_obj->offset],
|
||||
&utf_data[sizeof(seghdr_info)], utf_datalen);
|
||||
|
||||
ftm_pdev_obj->offset = ftm_pdev_obj->offset + utf_datalen;
|
||||
ftm_pdev_obj->expected_seq++;
|
||||
|
||||
if (ftm_pdev_obj->expected_seq == total_segments) {
|
||||
if (ftm_pdev_obj->offset != seghdr_info.len) {
|
||||
ftm_debug("len mismatch len %zu total len %d\n",
|
||||
ftm_pdev_obj->offset, seghdr_info.len);
|
||||
}
|
||||
|
||||
ftm_pdev_obj->length = ftm_pdev_obj->offset;
|
||||
|
||||
/**
|
||||
* If the repsonse is for a command from FTM daemon,
|
||||
* send this repsonse data to cfg80211
|
||||
*/
|
||||
if (ftm_pdev_obj->cmd_type == WIFI_FTM_CMD_NL80211) {
|
||||
if (wlan_cfg80211_ftm_rx_event(pdev, ftm_pdev_obj->data,
|
||||
ftm_pdev_obj->length) != QDF_STATUS_SUCCESS) {
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
ftm_pdev_obj->cmd_type = WIFI_FTM_CMD_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef QCA_WIFI_FTM_IOCTL
|
||||
QDF_STATUS ucfg_wlan_ftm_testmode_rsp(struct wlan_objmgr_pdev *pdev,
|
||||
uint8_t *data)
|
||||
{
|
||||
struct wifi_ftm_pdev_priv_obj *ftm_pdev_obj;
|
||||
uint32_t *len;
|
||||
|
||||
ftm_pdev_obj =
|
||||
wlan_objmgr_pdev_get_comp_private_obj(pdev,
|
||||
WLAN_UMAC_COMP_FTM);
|
||||
if (!ftm_pdev_obj) {
|
||||
ftm_err("Failed to get ftm pdev component");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (ftm_pdev_obj->length) {
|
||||
len = (uint32_t *)data;
|
||||
*len = ftm_pdev_obj->length;
|
||||
qdf_mem_copy((data + 4), ftm_pdev_obj->data,
|
||||
ftm_pdev_obj->length);
|
||||
|
||||
ftm_pdev_obj->length = 0;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _WLAN_GLOBAL_LMAC_IF_API_H_
|
||||
#define _WLAN_GLOBAL_LMAC_IF_API_H_
|
||||
|
||||
#include "wlan_objmgr_cmn.h"
|
||||
#include "wlan_objmgr_psoc_obj.h"
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_open() - global lmac_if open
|
||||
* @psoc: psoc context
|
||||
*
|
||||
* Opens up lmac_if southbound layer. This function calls OL,DA and UMAC
|
||||
* modules to register respective tx and rx callbacks.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_global_lmac_if_open(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_rx_ops_register() - UMAC rx handler register
|
||||
* @rx_ops: Pointer to rx_ops structure to be populated
|
||||
*
|
||||
* Register umac RX callabacks which will be called by DA/OL/WMA/WMI
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS wlan_global_lmac_if_rx_ops_register
|
||||
(struct wlan_lmac_if_rx_ops *rx_ops);
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_close() - Close global lmac_if
|
||||
* @psoc: psoc context
|
||||
*
|
||||
* Deregister global lmac_if TX and RX handlers
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS wlan_global_lmac_if_close(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_set_txops_registration_cb() -tx
|
||||
* registration callback assignment
|
||||
* @dev_type: Dev type can be either Direct attach or Offload
|
||||
* @handler: handler to be called for LMAC tx ops registration
|
||||
*
|
||||
* API to assign appropriate tx registration callback handler based on the
|
||||
* device type(Offload or Direct attach)
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_TYPE dev_type,
|
||||
QDF_STATUS (*handler)(struct wlan_lmac_if_tx_ops *));
|
||||
|
||||
#ifdef WLAN_CONV_SPECTRAL_ENABLE
|
||||
/**
|
||||
* wlan_lmac_if_sptrl_set_rx_ops_register_cb ()- Spectral LMAC Rx ops
|
||||
* registration callback assignment
|
||||
* @handler: Handler to be called for spectral LMAC rx ops registration
|
||||
*
|
||||
* API to assign appropriate Spectral LMAC rx ops registration callback handler
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS wlan_lmac_if_sptrl_set_rx_ops_register_cb(void (*handler)
|
||||
(struct wlan_lmac_if_rx_ops *));
|
||||
|
||||
#endif /* WLAN_CONV_SPECTRAL_ENABLE */
|
||||
|
||||
#ifdef WLAN_IOT_SIM_SUPPORT
|
||||
/**
|
||||
* wlan_lmac_if_iot_sim_set_rx_ops_register_cb ()- IOT_SIM LMAC Rx ops
|
||||
* registration callback assignment
|
||||
* @handler: Handler to be called for iot sim LMAC rx ops registration
|
||||
*
|
||||
* API to assign appropriate iot sim LMAC rx ops registration callback handler
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS wlan_lmac_if_iot_sim_set_rx_ops_register_cb(void (*handler)
|
||||
(struct wlan_lmac_if_rx_ops *));
|
||||
#endif
|
||||
#endif /* _WLAN_LMAC_IF_API_H */
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "qdf_mem.h"
|
||||
#include "qdf_module.h"
|
||||
#include "wlan_lmac_if_def.h"
|
||||
#include "wlan_lmac_if_api.h"
|
||||
#include "wlan_global_lmac_if_api.h"
|
||||
#ifdef WLAN_CONV_SPECTRAL_ENABLE
|
||||
#include <wlan_spectral_utils_api.h>
|
||||
#endif
|
||||
#include <target_if_psoc_wake_lock.h>
|
||||
|
||||
/* Function pointer to call DA/OL specific tx_ops registration function */
|
||||
QDF_STATUS (*wlan_global_lmac_if_tx_ops_register[MAX_DEV_TYPE])
|
||||
(struct wlan_lmac_if_tx_ops *tx_ops);
|
||||
|
||||
/*
|
||||
* spectral scan is built as separate .ko for WIN where
|
||||
* MCL it is part of wlan.ko so the registration of
|
||||
.* rx ops to global lmac if layer is different between WIN
|
||||
* and MCL
|
||||
*/
|
||||
#ifdef WLAN_CONV_SPECTRAL_ENABLE
|
||||
/**
|
||||
* wlan_spectral_register_rx_ops() - Register spectral component RX OPS
|
||||
* @rx_ops: lmac if receive ops
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
#ifdef SPECTRAL_MODULIZED_ENABLE
|
||||
/* Function pointer for spectral rx_ops registration function */
|
||||
void (*wlan_lmac_if_sptrl_rx_ops)(struct wlan_lmac_if_rx_ops *rx_ops);
|
||||
|
||||
QDF_STATUS wlan_lmac_if_sptrl_set_rx_ops_register_cb(void (*handler)
|
||||
(struct wlan_lmac_if_rx_ops *))
|
||||
{
|
||||
wlan_lmac_if_sptrl_rx_ops = handler;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
qdf_export_symbol(wlan_lmac_if_sptrl_set_rx_ops_register_cb);
|
||||
|
||||
static void wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
wlan_lmac_if_sptrl_rx_ops(rx_ops);
|
||||
}
|
||||
#else
|
||||
static void wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
wlan_lmac_if_sptrl_register_rx_ops(rx_ops);
|
||||
}
|
||||
#endif /* SPECTRAL_MODULIZED_ENABLE */
|
||||
#else
|
||||
/**
|
||||
* wlan_spectral_register_rx_ops() - Dummy api to register spectral RX OPS
|
||||
* @rx_ops: lmac if receive ops
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void wlan_spectral_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
}
|
||||
#endif /*WLAN_CONV_SPECTRAL_ENABLE*/
|
||||
|
||||
#ifdef WLAN_IOT_SIM_SUPPORT
|
||||
/* Function pointer for iot_sim rx_ops registration function */
|
||||
void (*wlan_lmac_if_iot_sim_rx_ops)(struct wlan_lmac_if_rx_ops *rx_ops);
|
||||
|
||||
QDF_STATUS wlan_lmac_if_iot_sim_set_rx_ops_register_cb(void (*handler)
|
||||
(struct wlan_lmac_if_rx_ops *))
|
||||
{
|
||||
wlan_lmac_if_iot_sim_rx_ops = handler;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
qdf_export_symbol(wlan_lmac_if_iot_sim_set_rx_ops_register_cb);
|
||||
|
||||
static void wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
if (wlan_lmac_if_iot_sim_rx_ops)
|
||||
wlan_lmac_if_iot_sim_rx_ops(rx_ops);
|
||||
else
|
||||
qdf_print("\n***** IOT SIM MODULE NOT LOADED *****\n");
|
||||
}
|
||||
|
||||
#else
|
||||
static void wlan_iot_sim_register_rx_ops(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_rx_ops_register() - Global lmac_if
|
||||
* rx handler register
|
||||
* @rx_ops: Pointer to rx_ops structure to be populated
|
||||
*
|
||||
* Register lmac_if RX callabacks which will be called by DA/OL/WMA/WMI
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS
|
||||
wlan_global_lmac_if_rx_ops_register(struct wlan_lmac_if_rx_ops *rx_ops)
|
||||
{
|
||||
/*
|
||||
* Component specific public api's to be called to register
|
||||
* respective callbacks
|
||||
* Ex: rx_ops->fp = function;
|
||||
*/
|
||||
if (!rx_ops) {
|
||||
qdf_err("lmac if rx ops pointer is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
/* Registeration for UMAC componets */
|
||||
wlan_lmac_if_umac_rx_ops_register(rx_ops);
|
||||
|
||||
/* spectral rx_ops registration*/
|
||||
wlan_spectral_register_rx_ops(rx_ops);
|
||||
|
||||
/* iot_sim rx_ops registration*/
|
||||
wlan_iot_sim_register_rx_ops(rx_ops);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_open() - global lmac_if open
|
||||
* @psoc: psoc context
|
||||
*
|
||||
* Opens up lmac_if southbound layer. This function calls OL,DA and UMAC
|
||||
* modules to register respective tx and rx callbacks.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_global_lmac_if_open(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
WLAN_DEV_TYPE dev_type;
|
||||
|
||||
struct wlan_lmac_if_tx_ops *tx_ops;
|
||||
struct wlan_lmac_if_rx_ops *rx_ops;
|
||||
|
||||
if (!psoc) {
|
||||
qdf_err("psoc is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
tx_ops = qdf_mem_malloc(sizeof(*tx_ops));
|
||||
if (!tx_ops) {
|
||||
qdf_err("tx_ops is NULL");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
rx_ops = qdf_mem_malloc(sizeof(*rx_ops));
|
||||
if (!rx_ops) {
|
||||
qdf_err("rx_ops is NULL");
|
||||
qdf_mem_free(tx_ops);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
wlan_psoc_set_lmac_if_txops(psoc, tx_ops);
|
||||
wlan_psoc_set_lmac_if_rxops(psoc, rx_ops);
|
||||
|
||||
dev_type = psoc->soc_nif.phy_type;
|
||||
|
||||
if (dev_type == WLAN_DEV_OL) {
|
||||
wlan_global_lmac_if_tx_ops_register[dev_type]
|
||||
(tx_ops);
|
||||
} else {
|
||||
/* Control should ideally not reach here */
|
||||
qdf_print("Invalid device type");
|
||||
qdf_mem_free(tx_ops);
|
||||
qdf_mem_free(rx_ops);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
/* Function call to register rx-ops handlers */
|
||||
wlan_global_lmac_if_rx_ops_register(rx_ops);
|
||||
|
||||
target_if_wake_lock_init(psoc);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
qdf_export_symbol(wlan_global_lmac_if_open);
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_close() - Close global lmac_if
|
||||
* @psoc: psoc context
|
||||
*
|
||||
* Deregister lmac_if TX and RX handlers
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS wlan_global_lmac_if_close(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct wlan_lmac_if_tx_ops *tx_ops;
|
||||
struct wlan_lmac_if_rx_ops *rx_ops;
|
||||
|
||||
if (!psoc) {
|
||||
qdf_err("psoc is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
target_if_wake_lock_deinit(psoc);
|
||||
tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
|
||||
rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
|
||||
|
||||
wlan_psoc_set_lmac_if_txops(psoc, NULL);
|
||||
wlan_psoc_set_lmac_if_rxops(psoc, NULL);
|
||||
|
||||
qdf_mem_free(tx_ops);
|
||||
qdf_mem_free(rx_ops);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
qdf_export_symbol(wlan_global_lmac_if_close);
|
||||
|
||||
/**
|
||||
* wlan_global_lmac_if_set_txops_registration_cb() - tx
|
||||
* registration callback assignment
|
||||
* @dev_type: Dev type can be either Direct attach or Offload
|
||||
* @handler: handler to be called for LMAC tx ops registration
|
||||
*
|
||||
* API to assign appropriate tx registration callback handler based on the
|
||||
* device type(Offload or Direct attach)
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS - in case of success
|
||||
*/
|
||||
QDF_STATUS wlan_global_lmac_if_set_txops_registration_cb(WLAN_DEV_TYPE dev_type,
|
||||
QDF_STATUS (*handler)(struct wlan_lmac_if_tx_ops *))
|
||||
{
|
||||
wlan_global_lmac_if_tx_ops_register[dev_type] = handler;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
qdf_export_symbol(wlan_global_lmac_if_set_txops_registration_cb);
|
||||
17
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/README
Normal file
17
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/README
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
The below qca6290 and qca8074 folder has c files defining functions
|
||||
and structures to hold target specific definitions to handle differences between
|
||||
chips with respect to hal.
|
||||
|
||||
Please ensure changes get applied to all platform specific files if the fixes
|
||||
are generic and applicable to all the folders.
|
||||
|
||||
qca6290
|
||||
hal_6290_rx.c - rx related target specific function
|
||||
hal_6290_srng_table.c - holds hw srng table and hal hw reg offsets array
|
||||
hal_6290_tx.c - tx related target specific function
|
||||
qca8074
|
||||
hal_8074_rx.c - rx related target specific function
|
||||
hal_8074_srng_table.c - holds hw srng table and hal hw reg offsets array
|
||||
hal_8074_tx.c - tx related target specific function
|
||||
|
||||
|
||||
2754
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api.h
Normal file
2754
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api.h
Normal file
File diff suppressed because it is too large
Load diff
752
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h
Normal file
752
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_api_mon.h
Normal file
|
|
@ -0,0 +1,752 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _HAL_API_MON_H_
|
||||
#define _HAL_API_MON_H_
|
||||
|
||||
#include "qdf_types.h"
|
||||
#include "hal_internal.h"
|
||||
#include <target_type.h>
|
||||
|
||||
#define HAL_RX_PHY_DATA_RADAR 0x01
|
||||
#define HAL_SU_MU_CODING_LDPC 0x01
|
||||
|
||||
#define HAL_RX_FCS_LEN (4)
|
||||
#define KEY_EXTIV 0x20
|
||||
|
||||
#define HAL_RX_USER_TLV32_TYPE_OFFSET 0x00000000
|
||||
#define HAL_RX_USER_TLV32_TYPE_LSB 1
|
||||
#define HAL_RX_USER_TLV32_TYPE_MASK 0x000003FE
|
||||
|
||||
#define HAL_RX_USER_TLV32_LEN_OFFSET 0x00000000
|
||||
#define HAL_RX_USER_TLV32_LEN_LSB 10
|
||||
#define HAL_RX_USER_TLV32_LEN_MASK 0x003FFC00
|
||||
|
||||
#define HAL_RX_USER_TLV32_USERID_OFFSET 0x00000000
|
||||
#define HAL_RX_USER_TLV32_USERID_LSB 26
|
||||
#define HAL_RX_USER_TLV32_USERID_MASK 0xFC000000
|
||||
|
||||
#define HAL_ALIGN(x, a) HAL_ALIGN_MASK(x, (a)-1)
|
||||
#define HAL_ALIGN_MASK(x, mask) (typeof(x))(((uint32)(x) + (mask)) & ~(mask))
|
||||
|
||||
#define HAL_RX_TLV32_HDR_SIZE 4
|
||||
|
||||
#define HAL_RX_GET_USER_TLV32_TYPE(rx_status_tlv_ptr) \
|
||||
((*((uint32_t *)(rx_status_tlv_ptr)) & \
|
||||
HAL_RX_USER_TLV32_TYPE_MASK) >> \
|
||||
HAL_RX_USER_TLV32_TYPE_LSB)
|
||||
|
||||
#define HAL_RX_GET_USER_TLV32_LEN(rx_status_tlv_ptr) \
|
||||
((*((uint32_t *)(rx_status_tlv_ptr)) & \
|
||||
HAL_RX_USER_TLV32_LEN_MASK) >> \
|
||||
HAL_RX_USER_TLV32_LEN_LSB)
|
||||
|
||||
#define HAL_RX_GET_USER_TLV32_USERID(rx_status_tlv_ptr) \
|
||||
((*((uint32_t *)(rx_status_tlv_ptr)) & \
|
||||
HAL_RX_USER_TLV32_USERID_MASK) >> \
|
||||
HAL_RX_USER_TLV32_USERID_LSB)
|
||||
|
||||
#define HAL_TLV_STATUS_PPDU_NOT_DONE 0
|
||||
#define HAL_TLV_STATUS_PPDU_DONE 1
|
||||
#define HAL_TLV_STATUS_BUF_DONE 2
|
||||
#define HAL_TLV_STATUS_PPDU_NON_STD_DONE 3
|
||||
#define HAL_TLV_STATUS_PPDU_START 4
|
||||
#define HAL_TLV_STATUS_HEADER 5
|
||||
#define HAL_TLV_STATUS_MPDU_END 6
|
||||
#define HAL_TLV_STATUS_MSDU_START 7
|
||||
#define HAL_TLV_STATUS_MSDU_END 8
|
||||
|
||||
#define HAL_MAX_UL_MU_USERS 37
|
||||
|
||||
#define HAL_RX_PKT_TYPE_11A 0
|
||||
#define HAL_RX_PKT_TYPE_11B 1
|
||||
#define HAL_RX_PKT_TYPE_11N 2
|
||||
#define HAL_RX_PKT_TYPE_11AC 3
|
||||
#define HAL_RX_PKT_TYPE_11AX 4
|
||||
|
||||
#define HAL_RX_RECEPTION_TYPE_SU 0
|
||||
#define HAL_RX_RECEPTION_TYPE_MU_MIMO 1
|
||||
#define HAL_RX_RECEPTION_TYPE_OFDMA 2
|
||||
#define HAL_RX_RECEPTION_TYPE_MU_OFDMA 3
|
||||
|
||||
/* Multiply rate by 2 to avoid float point
|
||||
* and get rate in units of 500kbps
|
||||
*/
|
||||
#define HAL_11B_RATE_0MCS 11*2
|
||||
#define HAL_11B_RATE_1MCS 5.5*2
|
||||
#define HAL_11B_RATE_2MCS 2*2
|
||||
#define HAL_11B_RATE_3MCS 1*2
|
||||
#define HAL_11B_RATE_4MCS 11*2
|
||||
#define HAL_11B_RATE_5MCS 5.5*2
|
||||
#define HAL_11B_RATE_6MCS 2*2
|
||||
|
||||
#define HAL_11A_RATE_0MCS 48*2
|
||||
#define HAL_11A_RATE_1MCS 24*2
|
||||
#define HAL_11A_RATE_2MCS 12*2
|
||||
#define HAL_11A_RATE_3MCS 6*2
|
||||
#define HAL_11A_RATE_4MCS 54*2
|
||||
#define HAL_11A_RATE_5MCS 36*2
|
||||
#define HAL_11A_RATE_6MCS 18*2
|
||||
#define HAL_11A_RATE_7MCS 9*2
|
||||
|
||||
#define HAL_LEGACY_MCS0 0
|
||||
#define HAL_LEGACY_MCS1 1
|
||||
#define HAL_LEGACY_MCS2 2
|
||||
#define HAL_LEGACY_MCS3 3
|
||||
#define HAL_LEGACY_MCS4 4
|
||||
#define HAL_LEGACY_MCS5 5
|
||||
#define HAL_LEGACY_MCS6 6
|
||||
#define HAL_LEGACY_MCS7 7
|
||||
|
||||
#define HE_GI_0_8 0
|
||||
#define HE_GI_0_4 1
|
||||
#define HE_GI_1_6 2
|
||||
#define HE_GI_3_2 3
|
||||
|
||||
#define HE_GI_RADIOTAP_0_8 0
|
||||
#define HE_GI_RADIOTAP_1_6 1
|
||||
#define HE_GI_RADIOTAP_3_2 2
|
||||
#define HE_GI_RADIOTAP_RESERVED 3
|
||||
|
||||
#define HE_LTF_RADIOTAP_UNKNOWN 0
|
||||
#define HE_LTF_RADIOTAP_1_X 1
|
||||
#define HE_LTF_RADIOTAP_2_X 2
|
||||
#define HE_LTF_RADIOTAP_4_X 3
|
||||
|
||||
#define HT_SGI_PRESENT 0x80
|
||||
|
||||
#define HE_LTF_1_X 0
|
||||
#define HE_LTF_2_X 1
|
||||
#define HE_LTF_4_X 2
|
||||
#define HE_LTF_UNKNOWN 3
|
||||
#define VHT_SIG_SU_NSS_MASK 0x7
|
||||
#define HT_SIG_SU_NSS_SHIFT 0x3
|
||||
|
||||
#define HAL_TID_INVALID 31
|
||||
#define HAL_AST_IDX_INVALID 0xFFFF
|
||||
|
||||
#ifdef GET_MSDU_AGGREGATION
|
||||
#define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs)\
|
||||
{\
|
||||
struct rx_msdu_end *rx_msdu_end;\
|
||||
bool first_msdu, last_msdu; \
|
||||
rx_msdu_end = &rx_desc->msdu_end_tlv.rx_msdu_end;\
|
||||
first_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_5, FIRST_MSDU);\
|
||||
last_msdu = HAL_RX_GET(rx_msdu_end, RX_MSDU_END_5, LAST_MSDU);\
|
||||
if (first_msdu && last_msdu)\
|
||||
rs->rs_flags &= (~IEEE80211_AMSDU_FLAG);\
|
||||
else\
|
||||
rs->rs_flags |= (IEEE80211_AMSDU_FLAG); \
|
||||
} \
|
||||
|
||||
#define HAL_RX_SET_MSDU_AGGREGATION((rs_mpdu), (rs_ppdu))\
|
||||
{\
|
||||
if (rs_mpdu->rs_flags & IEEE80211_AMSDU_FLAG)\
|
||||
rs_ppdu->rs_flags |= IEEE80211_AMSDU_FLAG;\
|
||||
} \
|
||||
|
||||
#else
|
||||
#define HAL_RX_GET_MSDU_AGGREGATION(rx_desc, rs)
|
||||
#define HAL_RX_SET_MSDU_AGGREGATION(rs_mpdu, rs_ppdu)
|
||||
#endif
|
||||
|
||||
/* Max MPDUs per status buffer */
|
||||
#define HAL_RX_MAX_MPDU 256
|
||||
#define HAL_RX_NUM_WORDS_PER_PPDU_BITMAP (HAL_RX_MAX_MPDU >> 5)
|
||||
#define HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER 16
|
||||
|
||||
/* Max pilot count */
|
||||
#define HAL_RX_MAX_SU_EVM_COUNT 32
|
||||
|
||||
/**
|
||||
* struct hal_rx_mon_desc_info () - HAL Rx Monitor descriptor info
|
||||
*
|
||||
* @ppdu_id: PHY ppdu id
|
||||
* @status_ppdu_id: status PHY ppdu id
|
||||
* @status_buf_count: number of status buffer count
|
||||
* @rxdma_push_reason: rxdma push reason
|
||||
* @rxdma_error_code: rxdma error code
|
||||
* @msdu_cnt: msdu count
|
||||
* @end_of_ppdu: end of ppdu
|
||||
* @link_desc: msdu link descriptor address
|
||||
* @status_buf: for a PPDU, status buffers can span acrosss
|
||||
* multiple buffers, status_buf points to first
|
||||
* status buffer address of PPDU
|
||||
* @drop_ppdu: flag to indicate current destination
|
||||
* ring ppdu drop
|
||||
*/
|
||||
struct hal_rx_mon_desc_info {
|
||||
uint16_t ppdu_id;
|
||||
uint16_t status_ppdu_id;
|
||||
uint8_t status_buf_count;
|
||||
uint8_t rxdma_push_reason;
|
||||
uint8_t rxdma_error_code;
|
||||
uint8_t msdu_count;
|
||||
uint8_t end_of_ppdu;
|
||||
struct hal_buf_info link_desc;
|
||||
struct hal_buf_info status_buf;
|
||||
bool drop_ppdu;
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct hal_rx_su_evm_info - SU evm info
|
||||
* @number_of_symbols: number of symbols
|
||||
* @nss_count: nss count
|
||||
* @pilot_count: pilot count
|
||||
* @pilot_evm: Array of pilot evm values
|
||||
*/
|
||||
struct hal_rx_su_evm_info {
|
||||
uint32_t number_of_symbols;
|
||||
uint8_t nss_count;
|
||||
uint8_t pilot_count;
|
||||
uint32_t pilot_evm[HAL_RX_MAX_SU_EVM_COUNT];
|
||||
};
|
||||
|
||||
enum {
|
||||
DP_PPDU_STATUS_START,
|
||||
DP_PPDU_STATUS_DONE,
|
||||
};
|
||||
|
||||
static inline
|
||||
uint8_t *HAL_RX_MON_DEST_GET_DESC(uint8_t *data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32_t HAL_RX_DESC_GET_MPDU_LENGTH_ERR(void *hw_desc_addr)
|
||||
{
|
||||
struct rx_attention *rx_attn;
|
||||
struct rx_mon_pkt_tlvs *rx_desc =
|
||||
(struct rx_mon_pkt_tlvs *)hw_desc_addr;
|
||||
|
||||
rx_attn = &rx_desc->attn_tlv.rx_attn;
|
||||
|
||||
return HAL_RX_GET(rx_attn, RX_ATTENTION_1, MPDU_LENGTH_ERR);
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32_t HAL_RX_DESC_GET_MPDU_FCS_ERR(void *hw_desc_addr)
|
||||
{
|
||||
struct rx_attention *rx_attn;
|
||||
struct rx_mon_pkt_tlvs *rx_desc =
|
||||
(struct rx_mon_pkt_tlvs *)hw_desc_addr;
|
||||
|
||||
rx_attn = &rx_desc->attn_tlv.rx_attn;
|
||||
|
||||
return HAL_RX_GET(rx_attn, RX_ATTENTION_1, FCS_ERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* HAL_RX_HW_DESC_MPDU_VALID() - check MPDU start TLV tag in MPDU
|
||||
* start TLV of Hardware TLV descriptor
|
||||
* @hw_desc_addr: Hardware desciptor address
|
||||
*
|
||||
* Return: bool: if TLV tag match
|
||||
*/
|
||||
static inline
|
||||
bool HAL_RX_HW_DESC_MPDU_VALID(void *hw_desc_addr)
|
||||
{
|
||||
struct rx_mon_pkt_tlvs *rx_desc =
|
||||
(struct rx_mon_pkt_tlvs *)hw_desc_addr;
|
||||
uint32_t tlv_tag;
|
||||
|
||||
tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(
|
||||
&rx_desc->mpdu_start_tlv);
|
||||
|
||||
return tlv_tag == WIFIRX_MPDU_START_E ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* HAL_RX_HW_DESC_MPDU_VALID() - check MPDU start TLV user id in MPDU
|
||||
* start TLV of Hardware TLV descriptor
|
||||
* @hw_desc_addr: Hardware desciptor address
|
||||
*
|
||||
* Return: unit32_t: user id
|
||||
*/
|
||||
static inline
|
||||
uint32_t HAL_RX_HW_DESC_MPDU_USER_ID(void *hw_desc_addr)
|
||||
{
|
||||
struct rx_mon_pkt_tlvs *rx_desc =
|
||||
(struct rx_mon_pkt_tlvs *)hw_desc_addr;
|
||||
uint32_t user_id;
|
||||
|
||||
user_id = HAL_RX_GET_USER_TLV32_USERID(
|
||||
&rx_desc->mpdu_start_tlv);
|
||||
|
||||
return user_id;
|
||||
}
|
||||
|
||||
/* TODO: Move all Rx descriptor functions to hal_rx.h to avoid duplication */
|
||||
|
||||
#define HAL_RX_BUFFER_ADDR_31_0_GET(buff_addr_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR(buff_addr_info, \
|
||||
BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_OFFSET)), \
|
||||
BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_MASK, \
|
||||
BUFFER_ADDR_INFO_0_BUFFER_ADDR_31_0_LSB))
|
||||
|
||||
#define HAL_RX_REO_ENT_BUFFER_ADDR_39_32_GET(reo_ent_desc) \
|
||||
(HAL_RX_BUFFER_ADDR_39_32_GET(& \
|
||||
(((struct reo_entrance_ring *)reo_ent_desc) \
|
||||
->reo_level_mpdu_frame_info.msdu_link_desc_addr_info)))
|
||||
|
||||
#define HAL_RX_REO_ENT_BUFFER_ADDR_31_0_GET(reo_ent_desc) \
|
||||
(HAL_RX_BUFFER_ADDR_31_0_GET(& \
|
||||
(((struct reo_entrance_ring *)reo_ent_desc) \
|
||||
->reo_level_mpdu_frame_info.msdu_link_desc_addr_info)))
|
||||
|
||||
#define HAL_RX_REO_ENT_BUF_COOKIE_GET(reo_ent_desc) \
|
||||
(HAL_RX_BUF_COOKIE_GET(& \
|
||||
(((struct reo_entrance_ring *)reo_ent_desc) \
|
||||
->reo_level_mpdu_frame_info.msdu_link_desc_addr_info)))
|
||||
|
||||
/**
|
||||
* hal_rx_reo_ent_buf_paddr_get: Gets the physical address and
|
||||
* cookie from the REO entrance ring element
|
||||
*
|
||||
* @ hal_rx_desc_cookie: Opaque cookie pointer used by HAL to get to
|
||||
* the current descriptor
|
||||
* @ buf_info: structure to return the buffer information
|
||||
* @ msdu_cnt: pointer to msdu count in MPDU
|
||||
* Return: void
|
||||
*/
|
||||
static inline
|
||||
void hal_rx_reo_ent_buf_paddr_get(hal_rxdma_desc_t rx_desc,
|
||||
struct hal_buf_info *buf_info,
|
||||
uint32_t *msdu_cnt
|
||||
)
|
||||
{
|
||||
struct reo_entrance_ring *reo_ent_ring =
|
||||
(struct reo_entrance_ring *)rx_desc;
|
||||
struct buffer_addr_info *buf_addr_info;
|
||||
struct rx_mpdu_desc_info *rx_mpdu_desc_info_details;
|
||||
uint32_t loop_cnt;
|
||||
|
||||
rx_mpdu_desc_info_details =
|
||||
&reo_ent_ring->reo_level_mpdu_frame_info.rx_mpdu_desc_info_details;
|
||||
|
||||
*msdu_cnt = HAL_RX_GET(rx_mpdu_desc_info_details,
|
||||
RX_MPDU_DESC_INFO_0, MSDU_COUNT);
|
||||
|
||||
loop_cnt = HAL_RX_GET(reo_ent_ring, REO_ENTRANCE_RING_7, LOOPING_COUNT);
|
||||
|
||||
buf_addr_info =
|
||||
&reo_ent_ring->reo_level_mpdu_frame_info.msdu_link_desc_addr_info;
|
||||
|
||||
buf_info->paddr =
|
||||
(HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) |
|
||||
((uint64_t)
|
||||
(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
|
||||
|
||||
buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info);
|
||||
buf_info->rbm = HAL_RX_BUF_RBM_GET(buf_addr_info);
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"[%s][%d] ReoAddr=%pK, addrInfo=%pK, paddr=0x%llx, loopcnt=%d",
|
||||
__func__, __LINE__, reo_ent_ring, buf_addr_info,
|
||||
(unsigned long long)buf_info->paddr, loop_cnt);
|
||||
}
|
||||
|
||||
static inline
|
||||
void hal_rx_mon_next_link_desc_get(void *rx_msdu_link_desc,
|
||||
struct hal_buf_info *buf_info)
|
||||
{
|
||||
struct rx_msdu_link *msdu_link =
|
||||
(struct rx_msdu_link *)rx_msdu_link_desc;
|
||||
struct buffer_addr_info *buf_addr_info;
|
||||
|
||||
buf_addr_info = &msdu_link->next_msdu_link_desc_addr_info;
|
||||
|
||||
buf_info->paddr =
|
||||
(HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) |
|
||||
((uint64_t)
|
||||
(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
|
||||
|
||||
buf_info->sw_cookie = HAL_RX_BUF_COOKIE_GET(buf_addr_info);
|
||||
buf_info->rbm = HAL_RX_BUF_RBM_GET(buf_addr_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_rx_msdu_link_desc_set: Retrieves MSDU Link Descriptor to WBM
|
||||
*
|
||||
* @ soc : HAL version of the SOC pointer
|
||||
* @ src_srng_desc : void pointer to the WBM Release Ring descriptor
|
||||
* @ buf_addr_info : void pointer to the buffer_addr_info
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
|
||||
static inline
|
||||
void hal_rx_mon_msdu_link_desc_set(hal_soc_handle_t hal_soc_hdl,
|
||||
void *src_srng_desc,
|
||||
hal_buff_addrinfo_t buf_addr_info)
|
||||
{
|
||||
struct buffer_addr_info *wbm_srng_buffer_addr_info =
|
||||
(struct buffer_addr_info *)src_srng_desc;
|
||||
uint64_t paddr;
|
||||
struct buffer_addr_info *p_buffer_addr_info =
|
||||
(struct buffer_addr_info *)buf_addr_info;
|
||||
|
||||
paddr =
|
||||
(HAL_RX_BUFFER_ADDR_31_0_GET(buf_addr_info) |
|
||||
((uint64_t)
|
||||
(HAL_RX_BUFFER_ADDR_39_32_GET(buf_addr_info)) << 32));
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
"[%s][%d] src_srng_desc=%pK, buf_addr=0x%llx, cookie=0x%llx",
|
||||
__func__, __LINE__, src_srng_desc, (unsigned long long)paddr,
|
||||
(unsigned long long)p_buffer_addr_info->sw_buffer_cookie);
|
||||
|
||||
/* Structure copy !!! */
|
||||
*wbm_srng_buffer_addr_info =
|
||||
*((struct buffer_addr_info *)buf_addr_info);
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32 hal_get_rx_msdu_link_desc_size(void)
|
||||
{
|
||||
return sizeof(struct rx_msdu_link);
|
||||
}
|
||||
|
||||
enum {
|
||||
HAL_PKT_TYPE_OFDM = 0,
|
||||
HAL_PKT_TYPE_CCK,
|
||||
HAL_PKT_TYPE_HT,
|
||||
HAL_PKT_TYPE_VHT,
|
||||
HAL_PKT_TYPE_HE,
|
||||
};
|
||||
|
||||
enum {
|
||||
HAL_SGI_0_8_US,
|
||||
HAL_SGI_0_4_US,
|
||||
HAL_SGI_1_6_US,
|
||||
HAL_SGI_3_2_US,
|
||||
};
|
||||
|
||||
enum {
|
||||
HAL_FULL_RX_BW_20,
|
||||
HAL_FULL_RX_BW_40,
|
||||
HAL_FULL_RX_BW_80,
|
||||
HAL_FULL_RX_BW_160,
|
||||
};
|
||||
|
||||
enum {
|
||||
HAL_RX_TYPE_SU,
|
||||
HAL_RX_TYPE_MU_MIMO,
|
||||
HAL_RX_TYPE_MU_OFDMA,
|
||||
HAL_RX_TYPE_MU_OFDMA_MIMO,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum
|
||||
* @HAL_RX_MON_PPDU_START: PPDU start TLV is decoded in HAL
|
||||
* @HAL_RX_MON_PPDU_END: PPDU end TLV is decoded in HAL
|
||||
* @HAL_RX_MON_PPDU_RESET: Not PPDU start and end TLV
|
||||
*/
|
||||
enum {
|
||||
HAL_RX_MON_PPDU_START = 0,
|
||||
HAL_RX_MON_PPDU_END,
|
||||
HAL_RX_MON_PPDU_RESET,
|
||||
};
|
||||
|
||||
/* struct hal_rx_ppdu_common_info - common ppdu info
|
||||
* @ppdu_id - ppdu id number
|
||||
* @ppdu_timestamp - timestamp at ppdu received
|
||||
* @mpdu_cnt_fcs_ok - mpdu count in ppdu with fcs ok
|
||||
* @mpdu_cnt_fcs_err - mpdu count in ppdu with fcs err
|
||||
* @mpdu_fcs_ok_bitmap - fcs ok mpdu count in ppdu bitmap
|
||||
* @last_ppdu_id - last received ppdu id
|
||||
* @mpdu_cnt - total mpdu count
|
||||
* @num_users - num users
|
||||
*/
|
||||
struct hal_rx_ppdu_common_info {
|
||||
uint32_t ppdu_id;
|
||||
uint32_t ppdu_timestamp;
|
||||
uint32_t mpdu_cnt_fcs_ok;
|
||||
uint32_t mpdu_cnt_fcs_err;
|
||||
uint32_t mpdu_fcs_ok_bitmap[HAL_RX_NUM_WORDS_PER_PPDU_BITMAP];
|
||||
uint32_t last_ppdu_id;
|
||||
uint32_t mpdu_cnt;
|
||||
uint8_t num_users;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_rx_msdu_payload_info - msdu payload info
|
||||
* @first_msdu_payload: pointer to first msdu payload
|
||||
* @payload_len: payload len
|
||||
*/
|
||||
struct hal_rx_msdu_payload_info {
|
||||
uint8_t *first_msdu_payload;
|
||||
uint32_t payload_len;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_rx_nac_info - struct for neighbour info
|
||||
* @fc_valid: flag indicate if it has valid frame control information
|
||||
* @frame_control: frame control from each MPDU
|
||||
* @to_ds_flag: flag indicate to_ds bit
|
||||
* @mac_addr2_valid: flag indicate if mac_addr2 is valid
|
||||
* @mac_addr2: mac address2 in wh
|
||||
* @mcast_bcast: multicast/broadcast
|
||||
*/
|
||||
struct hal_rx_nac_info {
|
||||
uint8_t fc_valid;
|
||||
uint16_t frame_control;
|
||||
uint8_t to_ds_flag;
|
||||
uint8_t mac_addr2_valid;
|
||||
uint8_t mac_addr2[QDF_MAC_ADDR_SIZE];
|
||||
uint8_t mcast_bcast;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_rx_ppdu_msdu_info - struct for msdu info from HW TLVs
|
||||
* @cce_metadata: cached CCE metadata value received in the MSDU_END TLV
|
||||
* @is_flow_idx_timeout: flag to indicate if flow search timeout occurred
|
||||
* @is_flow_idx_invalid: flag to indicate if flow idx is valid or not
|
||||
* @fse_metadata: cached FSE metadata value received in the MSDU END TLV
|
||||
* @flow_idx: flow idx matched in FSE received in the MSDU END TLV
|
||||
*/
|
||||
struct hal_rx_ppdu_msdu_info {
|
||||
uint16_t cce_metadata;
|
||||
bool is_flow_idx_timeout;
|
||||
bool is_flow_idx_invalid;
|
||||
uint32_t fse_metadata;
|
||||
uint32_t flow_idx;
|
||||
};
|
||||
|
||||
#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
|
||||
/**
|
||||
* struct hal_rx_ppdu_cfr_user_info - struct for storing peer info extracted
|
||||
* from HW TLVs, this will be used for correlating CFR data with multiple peers
|
||||
* in MU PPDUs
|
||||
*
|
||||
* @peer_macaddr: macaddr of the peer
|
||||
* @ast_index: AST index of the peer
|
||||
*/
|
||||
struct hal_rx_ppdu_cfr_user_info {
|
||||
uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE];
|
||||
uint32_t ast_index;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_rx_ppdu_cfr_info - struct for storing ppdu info extracted from HW
|
||||
* TLVs, this will be used for CFR correlation
|
||||
*
|
||||
* @bb_captured_channel : Set by RXPCU when MACRX_FREEZE_CAPTURE_CHANNEL TLV is
|
||||
* sent to PHY, SW checks it to correlate current PPDU TLVs with uploaded
|
||||
* channel information.
|
||||
*
|
||||
* @bb_captured_timeout : Set by RxPCU to indicate channel capture condition is
|
||||
* met, but MACRX_FREEZE_CAPTURE_CHANNEL is not sent to PHY due to AST delay,
|
||||
* which means the rx_frame_falling edge to FREEZE TLV ready time exceeds
|
||||
* the threshold time defined by RXPCU register FREEZE_TLV_DELAY_CNT_THRESH.
|
||||
* Bb_captured_reason is still valid in this case.
|
||||
*
|
||||
* @rx_location_info_valid: Indicates whether CFR DMA address in the PPDU TLV
|
||||
* is valid
|
||||
* <enum 0 rx_location_info_is_not_valid>
|
||||
* <enum 1 rx_location_info_is_valid>
|
||||
* <legal all>
|
||||
*
|
||||
* @bb_captured_reason : Copy capture_reason of MACRX_FREEZE_CAPTURE_CHANNEL
|
||||
* TLV to here for FW usage. Valid when bb_captured_channel or
|
||||
* bb_captured_timeout is set.
|
||||
* <enum 0 freeze_reason_TM>
|
||||
* <enum 1 freeze_reason_FTM>
|
||||
* <enum 2 freeze_reason_ACK_resp_to_TM_FTM>
|
||||
* <enum 3 freeze_reason_TA_RA_TYPE_FILTER>
|
||||
* <enum 4 freeze_reason_NDPA_NDP>
|
||||
* <enum 5 freeze_reason_ALL_PACKET>
|
||||
* <legal 0-5>
|
||||
*
|
||||
* @rtt_che_buffer_pointer_low32 : The low 32 bits of the 40 bits pointer to
|
||||
* external RTT channel information buffer
|
||||
*
|
||||
* @rtt_che_buffer_pointer_high8 : The high 8 bits of the 40 bits pointer to
|
||||
* external RTT channel information buffer
|
||||
*
|
||||
* @chan_capture_status : capture status reported by ucode
|
||||
* a. CAPTURE_IDLE: FW has disabled "REPETITIVE_CHE_CAPTURE_CTRL"
|
||||
* b. CAPTURE_BUSY: previous PPDU’s channel capture upload DMA ongoing. (Note
|
||||
* that this upload is triggered after receiving freeze_channel_capture TLV
|
||||
* after last PPDU is rx)
|
||||
* c. CAPTURE_ACTIVE: channel capture is enabled and no previous channel
|
||||
* capture ongoing
|
||||
* d. CAPTURE_NO_BUFFER: next buffer in IPC ring not available
|
||||
*
|
||||
* @cfr_user_info: Peer mac for upto 4 MU users
|
||||
*/
|
||||
|
||||
struct hal_rx_ppdu_cfr_info {
|
||||
bool bb_captured_channel;
|
||||
bool bb_captured_timeout;
|
||||
uint8_t bb_captured_reason;
|
||||
bool rx_location_info_valid;
|
||||
uint8_t chan_capture_status;
|
||||
uint8_t rtt_che_buffer_pointer_high8;
|
||||
uint32_t rtt_che_buffer_pointer_low32;
|
||||
struct hal_rx_ppdu_cfr_user_info cfr_user_info[HAL_MAX_UL_MU_USERS];
|
||||
};
|
||||
#else
|
||||
struct hal_rx_ppdu_cfr_info {};
|
||||
#endif
|
||||
|
||||
struct mon_rx_info {
|
||||
uint8_t qos_control_info_valid;
|
||||
uint16_t qos_control;
|
||||
uint8_t mac_addr1_valid;
|
||||
uint8_t mac_addr1[QDF_MAC_ADDR_SIZE];
|
||||
uint32_t user_id;
|
||||
};
|
||||
|
||||
struct mon_rx_user_info {
|
||||
uint16_t qos_control;
|
||||
uint8_t qos_control_info_valid;
|
||||
};
|
||||
|
||||
struct hal_rx_ppdu_info {
|
||||
struct hal_rx_ppdu_common_info com_info;
|
||||
struct mon_rx_status rx_status;
|
||||
struct mon_rx_user_status rx_user_status[HAL_MAX_UL_MU_USERS];
|
||||
struct mon_rx_info rx_info;
|
||||
struct mon_rx_user_info rx_user_info[HAL_MAX_UL_MU_USERS];
|
||||
struct hal_rx_msdu_payload_info msdu_info;
|
||||
struct hal_rx_msdu_payload_info fcs_ok_msdu_info;
|
||||
struct hal_rx_nac_info nac_info;
|
||||
/* status ring PPDU start and end state */
|
||||
uint32_t rx_state;
|
||||
/* MU user id for status ring TLV */
|
||||
uint32_t user_id;
|
||||
/* MPDU/MSDU truncated to 128 bytes header start addr in status skb */
|
||||
unsigned char *data;
|
||||
/* MPDU/MSDU truncated to 128 bytes header real length */
|
||||
uint32_t hdr_len;
|
||||
/* MPDU FCS error */
|
||||
bool fcs_err;
|
||||
/* Id to indicate how to process mpdu */
|
||||
uint8_t sw_frame_group_id;
|
||||
struct hal_rx_ppdu_msdu_info rx_msdu_info[HAL_MAX_UL_MU_USERS];
|
||||
/* fcs passed mpdu count in rx monitor status buffer */
|
||||
uint8_t fcs_ok_cnt;
|
||||
/* fcs error mpdu count in rx monitor status buffer */
|
||||
uint8_t fcs_err_cnt;
|
||||
/* MPDU FCS passed */
|
||||
bool is_fcs_passed;
|
||||
/* first msdu payload for all mpdus in rx monitor status buffer */
|
||||
struct hal_rx_msdu_payload_info ppdu_msdu_info[HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER];
|
||||
/* evm info */
|
||||
struct hal_rx_su_evm_info evm_info;
|
||||
/**
|
||||
* Will be used to store ppdu info extracted from HW TLVs,
|
||||
* and for CFR correlation as well
|
||||
*/
|
||||
struct hal_rx_ppdu_cfr_info cfr_info;
|
||||
};
|
||||
|
||||
static inline uint32_t
|
||||
hal_get_rx_status_buf_size(void) {
|
||||
/* RX status buffer size is hard coded for now */
|
||||
return 2048;
|
||||
}
|
||||
|
||||
static inline uint8_t*
|
||||
hal_rx_status_get_next_tlv(uint8_t *rx_tlv) {
|
||||
uint32_t tlv_len, tlv_tag;
|
||||
|
||||
tlv_len = HAL_RX_GET_USER_TLV32_LEN(rx_tlv);
|
||||
tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
|
||||
|
||||
/* The actual length of PPDU_END is the combined length of many PHY
|
||||
* TLVs that follow. Skip the TLV header and
|
||||
* rx_rxpcu_classification_overview that follows the header to get to
|
||||
* next TLV.
|
||||
*/
|
||||
if (tlv_tag == WIFIRX_PPDU_END_E)
|
||||
tlv_len = sizeof(struct rx_rxpcu_classification_overview);
|
||||
|
||||
return (uint8_t *)(((unsigned long)(rx_tlv + tlv_len +
|
||||
HAL_RX_TLV32_HDR_SIZE + 3)) & (~((unsigned long)3)));
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_rx_proc_phyrx_other_receive_info_tlv()
|
||||
* - process other receive info TLV
|
||||
* @rx_tlv_hdr: pointer to TLV header
|
||||
* @ppdu_info: pointer to ppdu_info
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static inline void hal_rx_proc_phyrx_other_receive_info_tlv(struct hal_soc *hal_soc,
|
||||
void *rx_tlv_hdr,
|
||||
struct hal_rx_ppdu_info
|
||||
*ppdu_info)
|
||||
{
|
||||
hal_soc->ops->hal_rx_proc_phyrx_other_receive_info_tlv(rx_tlv_hdr,
|
||||
(void *)ppdu_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_rx_status_get_tlv_info() - process receive info TLV
|
||||
* @rx_tlv_hdr: pointer to TLV header
|
||||
* @ppdu_info: pointer to ppdu_info
|
||||
* @hal_soc: HAL soc handle
|
||||
* @nbuf: PPDU status netowrk buffer
|
||||
*
|
||||
* Return: HAL_TLV_STATUS_PPDU_NOT_DONE or HAL_TLV_STATUS_PPDU_DONE from tlv
|
||||
*/
|
||||
static inline uint32_t
|
||||
hal_rx_status_get_tlv_info(void *rx_tlv_hdr, void *ppdu_info,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
return hal_soc->ops->hal_rx_status_get_tlv_info(
|
||||
rx_tlv_hdr,
|
||||
ppdu_info,
|
||||
hal_soc_hdl,
|
||||
nbuf);
|
||||
}
|
||||
|
||||
static inline
|
||||
uint32_t hal_get_rx_status_done_tlv_size(hal_soc_handle_t hal_soc_hdl)
|
||||
{
|
||||
return HAL_RX_TLV32_HDR_SIZE;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
hal_get_rx_status_done(uint8_t *rx_tlv)
|
||||
{
|
||||
uint32_t tlv_tag;
|
||||
|
||||
tlv_tag = HAL_RX_GET_USER_TLV32_TYPE(rx_tlv);
|
||||
|
||||
if (tlv_tag == WIFIRX_STATUS_BUFFER_DONE_E)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
else
|
||||
return QDF_STATUS_E_EMPTY;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS
|
||||
hal_clear_rx_status_done(uint8_t *rx_tlv)
|
||||
{
|
||||
*(uint32_t *)rx_tlv = 0;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
112
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_flow.h
Normal file
112
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_flow.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright (c) 2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __HAL_FLOW_H
|
||||
#define __HAL_FLOW_H
|
||||
|
||||
#define HAL_SET_FLD_SM(block, field, value) \
|
||||
(((value) << (block ## _ ## field ## _LSB)) & \
|
||||
(block ## _ ## field ## _MASK))
|
||||
|
||||
#define HAL_SET_FLD_MS(block, field, value) \
|
||||
(((value) & (block ## _ ## field ## _MASK)) >> \
|
||||
(block ## _ ## field ## _LSB))
|
||||
|
||||
#define HAL_CLR_FLD(desc, block, field) \
|
||||
do { \
|
||||
uint32_t val; \
|
||||
typeof(desc) desc_ = desc; \
|
||||
val = *((uint32_t *)((uint8_t *)(desc_) + \
|
||||
HAL_OFFSET(block, field))); \
|
||||
val &= ~(block ## _ ## field ## _MASK); \
|
||||
HAL_SET_FLD(desc_, block, field) = val; \
|
||||
} while (0)
|
||||
|
||||
#define HAL_GET_FLD(desc, block, field) \
|
||||
((*((uint32_t *)((uint8_t *)(desc) + HAL_OFFSET(block, field))) & \
|
||||
(block ## _ ## field ## _MASK)) >> (block ## _ ## field ## _LSB))
|
||||
|
||||
/**
|
||||
* struct hal_flow_tuple_info - Hal Flow 5-tuple
|
||||
* @dest_ip_127_96: Destination IP address bits 96-127
|
||||
* @dest_ip_95_64: Destination IP address bits 64-95
|
||||
* @dest_ip_63_32: Destination IP address bits 32-63
|
||||
* @dest_ip_31_0: Destination IP address bits 0-31
|
||||
* @src_ip_127_96: Source IP address bits 96-127
|
||||
* @src_ip_95_64: Source IP address bits 64-95
|
||||
* @src_ip_63_32: Source IP address bits 32-63
|
||||
* @src_ip_31_0: Source IP address bits 0-31
|
||||
* @dest_port: Destination Port
|
||||
* @src_port: Source Port
|
||||
* @l4_protocol: Layer-4 protocol type (TCP/UDP)
|
||||
*/
|
||||
struct hal_flow_tuple_info {
|
||||
uint32_t dest_ip_127_96;
|
||||
uint32_t dest_ip_95_64;
|
||||
uint32_t dest_ip_63_32;
|
||||
uint32_t dest_ip_31_0;
|
||||
uint32_t src_ip_127_96;
|
||||
uint32_t src_ip_95_64;
|
||||
uint32_t src_ip_63_32;
|
||||
uint32_t src_ip_31_0;
|
||||
uint16_t dest_port;
|
||||
uint16_t src_port;
|
||||
uint16_t l4_protocol;
|
||||
};
|
||||
|
||||
/**
|
||||
* key_bitwise_shift_left() - Bitwise left shift (in place) an array of bytes
|
||||
* @key: Pointer to array to key bytes
|
||||
* @len: size of array (number of key bytes)
|
||||
* @shift: number of shift operations to be performed
|
||||
*
|
||||
* Return:
|
||||
*/
|
||||
static inline void
|
||||
key_bitwise_shift_left(uint8_t *key, int len, int shift)
|
||||
{
|
||||
int i;
|
||||
int next;
|
||||
|
||||
while (shift--) {
|
||||
for (i = len - 1; i >= 0 ; i--) {
|
||||
if (i > 0)
|
||||
next = (key[i - 1] & 0x80 ? 1 : 0);
|
||||
else
|
||||
next = 0;
|
||||
key[i] = (key[i] << 1) | next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* key_reverse() - Reverse the key buffer from MSB to LSB
|
||||
* @dest: pointer to the destination key
|
||||
* @src: pointer to the source key which should be shifted
|
||||
* @len: size of key in bytes
|
||||
*
|
||||
* Return:
|
||||
*/
|
||||
static inline void
|
||||
key_reverse(uint8_t *dest, uint8_t *src, int len)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0, j = len - 1; i < len; i++, j--)
|
||||
dest[i] = src[j];
|
||||
}
|
||||
#endif /* HAL_FLOW_H */
|
||||
2518
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h
Normal file
2518
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_generic_api.h
Normal file
File diff suppressed because it is too large
Load diff
382
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_hw_headers.h
Normal file
382
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_hw_headers.h
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _HAL_HW_INTERNAL_H_
|
||||
#define _HAL_HW_INTERNAL_H_
|
||||
#include "qdf_types.h"
|
||||
#include "qdf_lock.h"
|
||||
#include "qdf_mem.h"
|
||||
#include "rx_msdu_link.h"
|
||||
#include "rx_reo_queue.h"
|
||||
#include "rx_reo_queue_ext.h"
|
||||
#include "wcss_seq_hwiobase.h"
|
||||
#include "tlv_hdr.h"
|
||||
#include "tlv_tag_def.h"
|
||||
#include "reo_destination_ring.h"
|
||||
#include "reo_reg_seq_hwioreg.h"
|
||||
#include "reo_entrance_ring.h"
|
||||
#include "reo_get_queue_stats.h"
|
||||
#include "reo_get_queue_stats_status.h"
|
||||
#include "tcl_data_cmd.h"
|
||||
#include "tcl_gse_cmd.h"
|
||||
#include "tcl_status_ring.h"
|
||||
#include "mac_tcl_reg_seq_hwioreg.h"
|
||||
#include "ce_src_desc.h"
|
||||
#include "ce_stat_desc.h"
|
||||
#ifdef QCA_WIFI_QCA6490
|
||||
#include "wfss_ce_channel_dst_reg_seq_hwioreg.h"
|
||||
#include "wfss_ce_channel_src_reg_seq_hwioreg.h"
|
||||
#else
|
||||
#include "wfss_ce_reg_seq_hwioreg.h"
|
||||
#endif /* QCA_WIFI_QCA6490 */
|
||||
#include "wbm_link_descriptor_ring.h"
|
||||
#include "wbm_reg_seq_hwioreg.h"
|
||||
#include "wbm_buffer_ring.h"
|
||||
#include "wbm_release_ring.h"
|
||||
#include "rx_msdu_desc_info.h"
|
||||
#include "rx_mpdu_start.h"
|
||||
#include "rx_mpdu_end.h"
|
||||
#include "rx_msdu_start.h"
|
||||
#include "rx_msdu_end.h"
|
||||
#include "rx_attention.h"
|
||||
#include "rx_ppdu_start.h"
|
||||
#include "rx_ppdu_start_user_info.h"
|
||||
#include "rx_ppdu_end_user_stats.h"
|
||||
#include "rx_ppdu_end_user_stats_ext.h"
|
||||
#include "rx_mpdu_desc_info.h"
|
||||
#include "rxpcu_ppdu_end_info.h"
|
||||
#include "phyrx_he_sig_a_su.h"
|
||||
#include "phyrx_he_sig_a_mu_dl.h"
|
||||
#if defined(QCA_WIFI_QCA6290_11AX_MU_UL) && defined(QCA_WIFI_QCA6290_11AX)
|
||||
#include "phyrx_he_sig_a_mu_ul.h"
|
||||
#endif
|
||||
#include "phyrx_he_sig_b1_mu.h"
|
||||
#include "phyrx_he_sig_b2_mu.h"
|
||||
#include "phyrx_he_sig_b2_ofdma.h"
|
||||
#include "phyrx_l_sig_a.h"
|
||||
#include "phyrx_l_sig_b.h"
|
||||
#include "phyrx_vht_sig_a.h"
|
||||
#include "phyrx_ht_sig.h"
|
||||
#include "tx_msdu_extension.h"
|
||||
#include "receive_rssi_info.h"
|
||||
#include "phyrx_pkt_end.h"
|
||||
#include "phyrx_rssi_legacy.h"
|
||||
#include "wcss_version.h"
|
||||
#include "rx_msdu_link.h"
|
||||
#include "hal_internal.h"
|
||||
|
||||
#define HAL_SRNG_REO_EXCEPTION HAL_SRNG_REO2SW1
|
||||
#define HAL_SRNG_REO_ALTERNATE_SELECT 0x7
|
||||
#define HAL_NON_QOS_TID 16
|
||||
|
||||
/* TODO: Check if the following can be provided directly by HW headers */
|
||||
#define SRNG_LOOP_CNT_MASK REO_DESTINATION_RING_15_LOOPING_COUNT_MASK
|
||||
#define SRNG_LOOP_CNT_LSB REO_DESTINATION_RING_15_LOOPING_COUNT_LSB
|
||||
|
||||
/* HAL Macro to get the buffer info size */
|
||||
#define HAL_RX_BUFFINFO_NUM_DWORDS NUM_OF_DWORDS_BUFFER_ADDR_INFO
|
||||
|
||||
#define HAL_DEFAULT_BE_BK_VI_REO_TIMEOUT_MS 100 /* milliseconds */
|
||||
#define HAL_DEFAULT_VO_REO_TIMEOUT_MS 40 /* milliseconds */
|
||||
|
||||
#define HAL_DESC_SET_FIELD(_desc, _word, _fld, _value) do { \
|
||||
((uint32_t *)(_desc))[(_word ## _ ## _fld ## _OFFSET) >> 2] &= \
|
||||
~(_word ## _ ## _fld ## _MASK); \
|
||||
((uint32_t *)(_desc))[(_word ## _ ## _fld ## _OFFSET) >> 2] |= \
|
||||
((_value) << _word ## _ ## _fld ## _LSB); \
|
||||
} while (0)
|
||||
|
||||
#define HAL_SM(_reg, _fld, _val) \
|
||||
(((_val) << (_reg ## _ ## _fld ## _SHFT)) & \
|
||||
(_reg ## _ ## _fld ## _BMSK))
|
||||
|
||||
#define HAL_MS(_reg, _fld, _val) \
|
||||
(((_val) & (_reg ## _ ## _fld ## _BMSK)) >> \
|
||||
(_reg ## _ ## _fld ## _SHFT))
|
||||
|
||||
#define HAL_REG_WRITE(_soc, _reg, _value) \
|
||||
hal_write32_mb(_soc, (_reg), (_value))
|
||||
|
||||
/* Check register writing result */
|
||||
#define HAL_REG_WRITE_CONFIRM(_soc, _reg, _value) \
|
||||
hal_write32_mb_confirm(_soc, (_reg), (_value))
|
||||
|
||||
#define HAL_REG_WRITE_CONFIRM_RETRY(_soc, _reg, _value, _recovery) \
|
||||
hal_write32_mb_confirm_retry(_soc, (_reg), (_value), (_recovery))
|
||||
|
||||
#define HAL_REG_READ(_soc, _offset) \
|
||||
hal_read32_mb(_soc, (_offset))
|
||||
|
||||
#define HAL_CMEM_WRITE(_soc, _reg, _value) \
|
||||
hal_write32_mb_cmem(_soc, (_reg), (_value))
|
||||
|
||||
#define HAL_CMEM_READ(_soc, _offset) \
|
||||
hal_read32_mb_cmem(_soc, (_offset))
|
||||
|
||||
#define WBM_IDLE_DESC_LIST 1
|
||||
|
||||
/**
|
||||
* Common SRNG register access macros:
|
||||
* The SRNG registers are distributed across various UMAC and LMAC HW blocks,
|
||||
* but the register group and format is exactly same for all rings, with some
|
||||
* difference between producer rings (these are 'producer rings' with respect
|
||||
* to HW and referred as 'destination rings' in SW) and consumer rings (these
|
||||
* are 'consumer rings' with respect to HW and
|
||||
* referred as 'source rings' in SW).
|
||||
* The following macros provide uniform access to all SRNG rings.
|
||||
*/
|
||||
|
||||
/* SRNG registers are split among two groups R0 and R2 and following
|
||||
* definitions identify the group to which each register belongs to
|
||||
*/
|
||||
#define R0_INDEX 0
|
||||
#define R2_INDEX 1
|
||||
|
||||
#define HWREG_INDEX(_reg_group) _reg_group ## _ ## INDEX
|
||||
|
||||
/* Registers in R0 group */
|
||||
#define BASE_LSB_GROUP R0
|
||||
#define BASE_MSB_GROUP R0
|
||||
#define ID_GROUP R0
|
||||
#define STATUS_GROUP R0
|
||||
#define MISC_GROUP R0
|
||||
#define HP_ADDR_LSB_GROUP R0
|
||||
#define HP_ADDR_MSB_GROUP R0
|
||||
#define PRODUCER_INT_SETUP_GROUP R0
|
||||
#define PRODUCER_INT_STATUS_GROUP R0
|
||||
#define PRODUCER_FULL_COUNTER_GROUP R0
|
||||
#define MSI1_BASE_LSB_GROUP R0
|
||||
#define MSI1_BASE_MSB_GROUP R0
|
||||
#define MSI1_DATA_GROUP R0
|
||||
#define HP_TP_SW_OFFSET_GROUP R0
|
||||
#define TP_ADDR_LSB_GROUP R0
|
||||
#define TP_ADDR_MSB_GROUP R0
|
||||
#define CONSUMER_INT_SETUP_IX0_GROUP R0
|
||||
#define CONSUMER_INT_SETUP_IX1_GROUP R0
|
||||
#define CONSUMER_INT_STATUS_GROUP R0
|
||||
#define CONSUMER_EMPTY_COUNTER_GROUP R0
|
||||
#define CONSUMER_PREFETCH_TIMER_GROUP R0
|
||||
#define CONSUMER_PREFETCH_STATUS_GROUP R0
|
||||
|
||||
/* Registers in R2 group */
|
||||
#define HP_GROUP R2
|
||||
#define TP_GROUP R2
|
||||
|
||||
/**
|
||||
* Register definitions for all SRNG based rings are same, except few
|
||||
* differences between source (HW consumer) and destination (HW producer)
|
||||
* registers. Following macros definitions provide generic access to all
|
||||
* SRNG based rings.
|
||||
* For source rings, we will use the register/field definitions of SW2TCL1
|
||||
* ring defined in the HW header file mac_tcl_reg_seq_hwioreg.h. To setup
|
||||
* individual fields, SRNG_SM macros should be used with fields specified
|
||||
* using SRNG_SRC_FLD(<register>, <field>), Register writes should be done
|
||||
* using SRNG_SRC_REG_WRITE(<hal_srng>, <register>, <value>).
|
||||
* Similarly for destination rings we will use definitions of REO2SW1 ring
|
||||
* defined in the register reo_destination_ring.h. To setup individual
|
||||
* fields SRNG_SM macros should be used with fields specified using
|
||||
* SRNG_DST_FLD(<register>, <field>). Register writes should be done using
|
||||
* SRNG_DST_REG_WRITE(<hal_srng>, <register>, <value>).
|
||||
*/
|
||||
|
||||
#define SRNG_DST_REG_OFFSET(_reg, _reg_group) \
|
||||
HWIO_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg##_ADDR(0)
|
||||
|
||||
#define SRNG_SRC_REG_OFFSET(_reg, _reg_group) \
|
||||
HWIO_TCL_ ## _reg_group ## _SW2TCL1_RING_ ## _reg ## _ADDR(0)
|
||||
|
||||
#define _SRNG_DST_FLD(_reg_group, _reg_fld) \
|
||||
HWIO_REO_ ## _reg_group ## _REO2SW1_RING_ ## _reg_fld
|
||||
#define _SRNG_SRC_FLD(_reg_group, _reg_fld) \
|
||||
HWIO_TCL_ ## _reg_group ## _SW2TCL1_RING_ ## _reg_fld
|
||||
|
||||
#define _SRNG_FLD(_reg_group, _reg_fld, _dir) \
|
||||
_SRNG_ ## _dir ## _FLD(_reg_group, _reg_fld)
|
||||
|
||||
#define SRNG_DST_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, DST)
|
||||
#define SRNG_SRC_FLD(_reg, _f) _SRNG_FLD(_reg ## _GROUP, _reg ## _ ## _f, SRC)
|
||||
|
||||
#define SRNG_SRC_R0_START_OFFSET SRNG_SRC_REG_OFFSET(BASE_LSB, R0)
|
||||
#define SRNG_DST_R0_START_OFFSET SRNG_DST_REG_OFFSET(BASE_LSB, R0)
|
||||
|
||||
#define SRNG_SRC_R2_START_OFFSET SRNG_SRC_REG_OFFSET(HP, R2)
|
||||
#define SRNG_DST_R2_START_OFFSET SRNG_DST_REG_OFFSET(HP, R2)
|
||||
|
||||
#define SRNG_SRC_START_OFFSET(_reg_group) \
|
||||
SRNG_SRC_ ## _reg_group ## _START_OFFSET
|
||||
#define SRNG_DST_START_OFFSET(_reg_group) \
|
||||
SRNG_DST_ ## _reg_group ## _START_OFFSET
|
||||
#define SRNG_REG_ADDR(_srng, _reg, _reg_group, _dir) \
|
||||
((_srng)->hwreg_base[HWREG_INDEX(_reg_group)] + \
|
||||
((_srng)->hal_soc->hal_hw_reg_offset[_dir ## _ ##_reg]))
|
||||
|
||||
#define CALCULATE_REG_OFFSET(_dir, _reg, _reg_group) \
|
||||
(SRNG_ ## _dir ## _REG_OFFSET(_reg, _reg_group) - \
|
||||
SRNG_ ## _dir ## _START_OFFSET(_reg_group))
|
||||
|
||||
#define REG_OFFSET(_dir, _reg) \
|
||||
CALCULATE_REG_OFFSET(_dir, _reg, _reg ## _GROUP)
|
||||
|
||||
#define SRNG_DST_ADDR(_srng, _reg) \
|
||||
SRNG_REG_ADDR(_srng, _reg, _reg ## _GROUP, DST)
|
||||
|
||||
#define SRNG_SRC_ADDR(_srng, _reg) \
|
||||
SRNG_REG_ADDR(_srng, _reg, _reg ## _GROUP, SRC)
|
||||
|
||||
#define SRNG_REG_WRITE(_srng, _reg, _value, _dir) \
|
||||
hal_write_address_32_mb(_srng->hal_soc,\
|
||||
SRNG_ ## _dir ## _ADDR(_srng, _reg), (_value), false)
|
||||
|
||||
#define SRNG_REG_WRITE_CONFIRM(_srng, _reg, _value, _dir) \
|
||||
hal_write_address_32_mb(_srng->hal_soc,\
|
||||
SRNG_ ## _dir ## _ADDR(_srng, _reg), (_value), true)
|
||||
|
||||
#define SRNG_REG_READ(_srng, _reg, _dir) \
|
||||
hal_read_address_32_mb(_srng->hal_soc, \
|
||||
SRNG_ ## _dir ## _ADDR(_srng, _reg))
|
||||
|
||||
#define SRNG_SRC_REG_WRITE(_srng, _reg, _value) \
|
||||
SRNG_REG_WRITE(_srng, _reg, _value, SRC)
|
||||
|
||||
#define SRNG_DST_REG_WRITE(_srng, _reg, _value) \
|
||||
SRNG_REG_WRITE(_srng, _reg, _value, DST)
|
||||
|
||||
#define SRNG_DST_REG_WRITE_CONFIRM(_srng, _reg, _value) \
|
||||
SRNG_REG_WRITE_CONFIRM(_srng, _reg, _value, DST)
|
||||
|
||||
#define SRNG_SRC_REG_READ(_srng, _reg) \
|
||||
SRNG_REG_READ(_srng, _reg, SRC)
|
||||
|
||||
#define SRNG_DST_REG_READ(_srng, _reg) \
|
||||
SRNG_REG_READ(_srng, _reg, DST)
|
||||
|
||||
#define _SRNG_FM(_reg_fld) _reg_fld ## _BMSK
|
||||
#define _SRNG_FS(_reg_fld) _reg_fld ## _SHFT
|
||||
|
||||
#define SRNG_SM(_reg_fld, _val) \
|
||||
(((_val) << _SRNG_FS(_reg_fld)) & _SRNG_FM(_reg_fld))
|
||||
|
||||
#define SRNG_MS(_reg_fld, _val) \
|
||||
(((_val) & _SRNG_FM(_reg_fld)) >> _SRNG_FS(_reg_fld))
|
||||
|
||||
#define SRNG_MAX_SIZE_DWORDS \
|
||||
(SRNG_MS(SRNG_SRC_FLD(BASE_MSB, RING_SIZE), 0xffffffff))
|
||||
|
||||
/**
|
||||
* HW ring configuration table to identify hardware ring attributes like
|
||||
* register addresses, number of rings, ring entry size etc., for each type
|
||||
* of SRNG ring.
|
||||
*
|
||||
* Currently there is just one HW ring table, but there could be multiple
|
||||
* configurations in future based on HW variants from the same wifi3.0 family
|
||||
* and hence need to be attached with hal_soc based on HW type
|
||||
*/
|
||||
#define HAL_SRNG_CONFIG(_hal_soc, _ring_type) \
|
||||
(&_hal_soc->hw_srng_table[_ring_type])
|
||||
|
||||
enum SRNG_REGISTERS {
|
||||
DST_HP = 0,
|
||||
DST_TP,
|
||||
DST_ID,
|
||||
DST_MISC,
|
||||
DST_HP_ADDR_LSB,
|
||||
DST_HP_ADDR_MSB,
|
||||
DST_MSI1_BASE_LSB,
|
||||
DST_MSI1_BASE_MSB,
|
||||
DST_MSI1_DATA,
|
||||
DST_BASE_LSB,
|
||||
DST_BASE_MSB,
|
||||
DST_PRODUCER_INT_SETUP,
|
||||
|
||||
SRC_HP,
|
||||
SRC_TP,
|
||||
SRC_ID,
|
||||
SRC_MISC,
|
||||
SRC_TP_ADDR_LSB,
|
||||
SRC_TP_ADDR_MSB,
|
||||
SRC_MSI1_BASE_LSB,
|
||||
SRC_MSI1_BASE_MSB,
|
||||
SRC_MSI1_DATA,
|
||||
SRC_BASE_LSB,
|
||||
SRC_BASE_MSB,
|
||||
SRC_CONSUMER_INT_SETUP_IX0,
|
||||
SRC_CONSUMER_INT_SETUP_IX1,
|
||||
};
|
||||
|
||||
/**
|
||||
* hal_set_link_desc_addr - Setup link descriptor in a buffer_addr_info
|
||||
* HW structure
|
||||
*
|
||||
* @desc: Descriptor entry (from WBM_IDLE_LINK ring)
|
||||
* @cookie: SW cookie for the buffer/descriptor
|
||||
* @link_desc_paddr: Physical address of link descriptor entry
|
||||
*
|
||||
*/
|
||||
static inline void hal_set_link_desc_addr(void *desc, uint32_t cookie,
|
||||
qdf_dma_addr_t link_desc_paddr)
|
||||
{
|
||||
uint32_t *buf_addr = (uint32_t *)desc;
|
||||
|
||||
HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_0, BUFFER_ADDR_31_0,
|
||||
link_desc_paddr & 0xffffffff);
|
||||
HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, BUFFER_ADDR_39_32,
|
||||
(uint64_t)link_desc_paddr >> 32);
|
||||
HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, RETURN_BUFFER_MANAGER,
|
||||
WBM_IDLE_DESC_LIST);
|
||||
HAL_DESC_SET_FIELD(buf_addr, BUFFER_ADDR_INFO_1, SW_BUFFER_COOKIE,
|
||||
cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_get_reo_qdesc_size - Get size of reo queue descriptor
|
||||
*
|
||||
* @hal_soc: Opaque HAL SOC handle
|
||||
* @ba_window_size: BlockAck window size
|
||||
* @tid: TID number
|
||||
*
|
||||
*/
|
||||
static inline
|
||||
uint32_t hal_get_reo_qdesc_size(hal_soc_handle_t hal_soc_hdl,
|
||||
uint32_t ba_window_size, int tid)
|
||||
{
|
||||
/* Return descriptor size corresponding to window size of 2 since
|
||||
* we set ba_window_size to 2 while setting up REO descriptors as
|
||||
* a WAR to get 2k jump exception aggregates are received without
|
||||
* a BA session.
|
||||
*/
|
||||
if (ba_window_size <= 1) {
|
||||
if (tid != HAL_NON_QOS_TID)
|
||||
return sizeof(struct rx_reo_queue) +
|
||||
sizeof(struct rx_reo_queue_ext);
|
||||
else
|
||||
return sizeof(struct rx_reo_queue);
|
||||
}
|
||||
|
||||
if (ba_window_size <= 105)
|
||||
return sizeof(struct rx_reo_queue) +
|
||||
sizeof(struct rx_reo_queue_ext);
|
||||
|
||||
if (ba_window_size <= 210)
|
||||
return sizeof(struct rx_reo_queue) +
|
||||
(2 * sizeof(struct rx_reo_queue_ext));
|
||||
|
||||
return sizeof(struct rx_reo_queue) +
|
||||
(3 * sizeof(struct rx_reo_queue_ext));
|
||||
}
|
||||
|
||||
#endif /* _HAL_HW_INTERNAL_H_ */
|
||||
920
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_internal.h
Normal file
920
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_internal.h
Normal file
|
|
@ -0,0 +1,920 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _HAL_INTERNAL_H_
|
||||
#define _HAL_INTERNAL_H_
|
||||
|
||||
#include "qdf_types.h"
|
||||
#include "qdf_atomic.h"
|
||||
#include "qdf_lock.h"
|
||||
#include "qdf_mem.h"
|
||||
#include "qdf_nbuf.h"
|
||||
#include "pld_common.h"
|
||||
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
|
||||
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
|
||||
#include "qdf_defer.h"
|
||||
#include "qdf_timer.h"
|
||||
#endif
|
||||
|
||||
#define hal_alert(params...) QDF_TRACE_FATAL(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_err(params...) QDF_TRACE_ERROR(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_info(params...) QDF_TRACE_INFO(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_HAL, params)
|
||||
|
||||
#define hal_alert_rl(params...) QDF_TRACE_FATAL_RL(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_err_rl(params...) QDF_TRACE_ERROR_RL(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_warn_rl(params...) QDF_TRACE_WARN_RL(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_info_rl(params...) QDF_TRACE_INFO_RL(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_debug_rl(params...) QDF_TRACE_DEBUG_RL(QDF_MODULE_ID_HAL, params)
|
||||
|
||||
#ifdef ENABLE_VERBOSE_DEBUG
|
||||
extern bool is_hal_verbose_debug_enabled;
|
||||
#define hal_verbose_debug(params...) \
|
||||
if (unlikely(is_hal_verbose_debug_enabled)) \
|
||||
do {\
|
||||
QDF_TRACE_DEBUG(QDF_MODULE_ID_HAL, params); \
|
||||
} while (0)
|
||||
#define hal_verbose_hex_dump(params...) \
|
||||
if (unlikely(is_hal_verbose_debug_enabled)) \
|
||||
do {\
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HAL, \
|
||||
QDF_TRACE_LEVEL_DEBUG, \
|
||||
params); \
|
||||
} while (0)
|
||||
#else
|
||||
#define hal_verbose_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_HAL, params)
|
||||
#define hal_verbose_hex_dump(params...) \
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HAL, QDF_TRACE_LEVEL_DEBUG, \
|
||||
params)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dp_hal_soc - opaque handle for DP HAL soc
|
||||
*/
|
||||
struct hal_soc_handle;
|
||||
typedef struct hal_soc_handle *hal_soc_handle_t;
|
||||
|
||||
/**
|
||||
* hal_ring_desc - opaque handle for DP ring descriptor
|
||||
*/
|
||||
struct hal_ring_desc;
|
||||
typedef struct hal_ring_desc *hal_ring_desc_t;
|
||||
|
||||
/**
|
||||
* hal_link_desc - opaque handle for DP link descriptor
|
||||
*/
|
||||
struct hal_link_desc;
|
||||
typedef struct hal_link_desc *hal_link_desc_t;
|
||||
|
||||
/**
|
||||
* hal_rxdma_desc - opaque handle for DP rxdma dst ring descriptor
|
||||
*/
|
||||
struct hal_rxdma_desc;
|
||||
typedef struct hal_rxdma_desc *hal_rxdma_desc_t;
|
||||
|
||||
/**
|
||||
* hal_buff_addrinfo - opaque handle for DP buffer address info
|
||||
*/
|
||||
struct hal_buff_addrinfo;
|
||||
typedef struct hal_buff_addrinfo *hal_buff_addrinfo_t;
|
||||
|
||||
/**
|
||||
* hal_rx_mon_desc_info - opaque handle for sw monitor ring desc info
|
||||
*/
|
||||
struct hal_rx_mon_desc_info;
|
||||
typedef struct hal_rx_mon_desc_info *hal_rx_mon_desc_info_t;
|
||||
|
||||
/* TBD: This should be movded to shared HW header file */
|
||||
enum hal_srng_ring_id {
|
||||
/* UMAC rings */
|
||||
HAL_SRNG_REO2SW1 = 0,
|
||||
HAL_SRNG_REO2SW2 = 1,
|
||||
HAL_SRNG_REO2SW3 = 2,
|
||||
HAL_SRNG_REO2SW4 = 3,
|
||||
HAL_SRNG_REO2TCL = 4,
|
||||
HAL_SRNG_SW2REO = 5,
|
||||
/* 6-7 unused */
|
||||
HAL_SRNG_REO_CMD = 8,
|
||||
HAL_SRNG_REO_STATUS = 9,
|
||||
/* 10-15 unused */
|
||||
HAL_SRNG_SW2TCL1 = 16,
|
||||
HAL_SRNG_SW2TCL2 = 17,
|
||||
HAL_SRNG_SW2TCL3 = 18,
|
||||
HAL_SRNG_SW2TCL4 = 19, /* FW2TCL ring */
|
||||
/* 20-23 unused */
|
||||
HAL_SRNG_SW2TCL_CMD = 24,
|
||||
HAL_SRNG_TCL_STATUS = 25,
|
||||
/* 26-31 unused */
|
||||
HAL_SRNG_CE_0_SRC = 32,
|
||||
HAL_SRNG_CE_1_SRC = 33,
|
||||
HAL_SRNG_CE_2_SRC = 34,
|
||||
HAL_SRNG_CE_3_SRC = 35,
|
||||
HAL_SRNG_CE_4_SRC = 36,
|
||||
HAL_SRNG_CE_5_SRC = 37,
|
||||
HAL_SRNG_CE_6_SRC = 38,
|
||||
HAL_SRNG_CE_7_SRC = 39,
|
||||
HAL_SRNG_CE_8_SRC = 40,
|
||||
HAL_SRNG_CE_9_SRC = 41,
|
||||
HAL_SRNG_CE_10_SRC = 42,
|
||||
HAL_SRNG_CE_11_SRC = 43,
|
||||
/* 44-55 unused */
|
||||
HAL_SRNG_CE_0_DST = 56,
|
||||
HAL_SRNG_CE_1_DST = 57,
|
||||
HAL_SRNG_CE_2_DST = 58,
|
||||
HAL_SRNG_CE_3_DST = 59,
|
||||
HAL_SRNG_CE_4_DST = 60,
|
||||
HAL_SRNG_CE_5_DST = 61,
|
||||
HAL_SRNG_CE_6_DST = 62,
|
||||
HAL_SRNG_CE_7_DST = 63,
|
||||
HAL_SRNG_CE_8_DST = 64,
|
||||
HAL_SRNG_CE_9_DST = 65,
|
||||
HAL_SRNG_CE_10_DST = 66,
|
||||
HAL_SRNG_CE_11_DST = 67,
|
||||
/* 68-79 unused */
|
||||
HAL_SRNG_CE_0_DST_STATUS = 80,
|
||||
HAL_SRNG_CE_1_DST_STATUS = 81,
|
||||
HAL_SRNG_CE_2_DST_STATUS = 82,
|
||||
HAL_SRNG_CE_3_DST_STATUS = 83,
|
||||
HAL_SRNG_CE_4_DST_STATUS = 84,
|
||||
HAL_SRNG_CE_5_DST_STATUS = 85,
|
||||
HAL_SRNG_CE_6_DST_STATUS = 86,
|
||||
HAL_SRNG_CE_7_DST_STATUS = 87,
|
||||
HAL_SRNG_CE_8_DST_STATUS = 88,
|
||||
HAL_SRNG_CE_9_DST_STATUS = 89,
|
||||
HAL_SRNG_CE_10_DST_STATUS = 90,
|
||||
HAL_SRNG_CE_11_DST_STATUS = 91,
|
||||
/* 92-103 unused */
|
||||
HAL_SRNG_WBM_IDLE_LINK = 104,
|
||||
HAL_SRNG_WBM_SW_RELEASE = 105,
|
||||
HAL_SRNG_WBM2SW0_RELEASE = 106,
|
||||
HAL_SRNG_WBM2SW1_RELEASE = 107,
|
||||
HAL_SRNG_WBM2SW2_RELEASE = 108,
|
||||
HAL_SRNG_WBM2SW3_RELEASE = 109,
|
||||
/* 110-127 unused */
|
||||
HAL_SRNG_UMAC_ID_END = 127,
|
||||
/* LMAC rings - The following set will be replicated for each LMAC */
|
||||
HAL_SRNG_LMAC1_ID_START = 128,
|
||||
HAL_SRNG_WMAC1_SW2RXDMA0_BUF0 = HAL_SRNG_LMAC1_ID_START,
|
||||
#ifdef IPA_OFFLOAD
|
||||
HAL_SRNG_WMAC1_SW2RXDMA0_BUF1 = (HAL_SRNG_LMAC1_ID_START + 1),
|
||||
HAL_SRNG_WMAC1_SW2RXDMA0_BUF2 = (HAL_SRNG_LMAC1_ID_START + 2),
|
||||
HAL_SRNG_WMAC1_SW2RXDMA1_BUF = (HAL_SRNG_WMAC1_SW2RXDMA0_BUF2 + 1),
|
||||
#else
|
||||
HAL_SRNG_WMAC1_SW2RXDMA1_BUF = (HAL_SRNG_WMAC1_SW2RXDMA0_BUF0 + 1),
|
||||
#endif
|
||||
HAL_SRNG_WMAC1_SW2RXDMA2_BUF = (HAL_SRNG_WMAC1_SW2RXDMA1_BUF + 1),
|
||||
HAL_SRNG_WMAC1_SW2RXDMA0_STATBUF = (HAL_SRNG_WMAC1_SW2RXDMA2_BUF + 1),
|
||||
HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF =
|
||||
(HAL_SRNG_WMAC1_SW2RXDMA0_STATBUF + 1),
|
||||
HAL_SRNG_WMAC1_RXDMA2SW0 = (HAL_SRNG_WMAC1_SW2RXDMA1_STATBUF + 1),
|
||||
HAL_SRNG_WMAC1_RXDMA2SW1 = (HAL_SRNG_WMAC1_RXDMA2SW0 + 1),
|
||||
HAL_SRNG_WMAC1_SW2RXDMA1_DESC = (HAL_SRNG_WMAC1_RXDMA2SW1 + 1),
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
HAL_SRNG_WIFI_POS_SRC_DMA_RING = (HAL_SRNG_WMAC1_SW2RXDMA1_DESC + 1),
|
||||
HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING = (HAL_SRNG_WIFI_POS_SRC_DMA_RING + 1),
|
||||
#else
|
||||
HAL_SRNG_DIR_BUF_RX_SRC_DMA_RING = (HAL_SRNG_WMAC1_SW2RXDMA1_DESC + 1),
|
||||
#endif
|
||||
/* -142 unused */
|
||||
HAL_SRNG_LMAC1_ID_END = 143
|
||||
};
|
||||
|
||||
/* SRNG type to be passed in APIs hal_srng_get_entrysize and hal_srng_setup */
|
||||
enum hal_ring_type {
|
||||
REO_DST = 0,
|
||||
REO_EXCEPTION = 1,
|
||||
REO_REINJECT = 2,
|
||||
REO_CMD = 3,
|
||||
REO_STATUS = 4,
|
||||
TCL_DATA = 5,
|
||||
TCL_CMD_CREDIT = 6,
|
||||
TCL_STATUS = 7,
|
||||
CE_SRC = 8,
|
||||
CE_DST = 9,
|
||||
CE_DST_STATUS = 10,
|
||||
WBM_IDLE_LINK = 11,
|
||||
SW2WBM_RELEASE = 12,
|
||||
WBM2SW_RELEASE = 13,
|
||||
RXDMA_BUF = 14,
|
||||
RXDMA_DST = 15,
|
||||
RXDMA_MONITOR_BUF = 16,
|
||||
RXDMA_MONITOR_STATUS = 17,
|
||||
RXDMA_MONITOR_DST = 18,
|
||||
RXDMA_MONITOR_DESC = 19,
|
||||
DIR_BUF_RX_DMA_SRC = 20,
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
WIFI_POS_SRC,
|
||||
#endif
|
||||
MAX_RING_TYPES
|
||||
};
|
||||
|
||||
#define HAL_RXDMA_MAX_RING_SIZE 0xFFFF
|
||||
#define HAL_MAX_LMACS 3
|
||||
#define HAL_MAX_RINGS_PER_LMAC (HAL_SRNG_LMAC1_ID_END - HAL_SRNG_LMAC1_ID_START)
|
||||
#define HAL_MAX_LMAC_RINGS (HAL_MAX_LMACS * HAL_MAX_RINGS_PER_LMAC)
|
||||
|
||||
#define HAL_SRNG_ID_MAX (HAL_SRNG_UMAC_ID_END + HAL_MAX_LMAC_RINGS)
|
||||
|
||||
enum hal_srng_dir {
|
||||
HAL_SRNG_SRC_RING,
|
||||
HAL_SRNG_DST_RING
|
||||
};
|
||||
|
||||
/* Lock wrappers for SRNG */
|
||||
#define hal_srng_lock_t qdf_spinlock_t
|
||||
#define SRNG_LOCK_INIT(_lock) qdf_spinlock_create(_lock)
|
||||
#define SRNG_LOCK(_lock) qdf_spin_lock_bh(_lock)
|
||||
#define SRNG_TRY_LOCK(_lock) qdf_spin_trylock_bh(_lock)
|
||||
#define SRNG_UNLOCK(_lock) qdf_spin_unlock_bh(_lock)
|
||||
#define SRNG_LOCK_DESTROY(_lock) qdf_spinlock_destroy(_lock)
|
||||
|
||||
struct hal_soc;
|
||||
|
||||
/**
|
||||
* dp_hal_ring - opaque handle for DP HAL SRNG
|
||||
*/
|
||||
struct hal_ring_handle;
|
||||
typedef struct hal_ring_handle *hal_ring_handle_t;
|
||||
|
||||
#define MAX_SRNG_REG_GROUPS 2
|
||||
|
||||
/* Hal Srng bit mask
|
||||
* HAL_SRNG_FLUSH_EVENT: SRNG HP TP flush in case of link down
|
||||
*/
|
||||
#define HAL_SRNG_FLUSH_EVENT BIT(0)
|
||||
|
||||
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
|
||||
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
|
||||
|
||||
/**
|
||||
* struct hal_reg_write_q_elem - delayed register write queue element
|
||||
* @srng: hal_srng queued for a delayed write
|
||||
* @addr: iomem address of the register
|
||||
* @enqueue_val: register value at the time of delayed write enqueue
|
||||
* @dequeue_val: register value at the time of delayed write dequeue
|
||||
* @valid: whether this entry is valid or not
|
||||
* @enqueue_time: enqueue time (qdf_log_timestamp)
|
||||
* @work_scheduled_time: work scheduled time (qdf_log_timestamp)
|
||||
* @dequeue_time: dequeue time (qdf_log_timestamp)
|
||||
*/
|
||||
struct hal_reg_write_q_elem {
|
||||
struct hal_srng *srng;
|
||||
void __iomem *addr;
|
||||
uint32_t enqueue_val;
|
||||
uint32_t dequeue_val;
|
||||
uint8_t valid;
|
||||
qdf_time_t enqueue_time;
|
||||
qdf_time_t work_scheduled_time;
|
||||
qdf_time_t dequeue_time;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reg_write_srng_stats - srng stats to keep track of register writes
|
||||
* @enqueues: writes enqueued to delayed work
|
||||
* @dequeues: writes dequeued from delayed work (not written yet)
|
||||
* @coalesces: writes not enqueued since srng is already queued up
|
||||
* @direct: writes not enqueued and written to register directly
|
||||
* @dequeue_delay: dequeue operation be delayed
|
||||
*/
|
||||
struct hal_reg_write_srng_stats {
|
||||
uint32_t enqueues;
|
||||
uint32_t dequeues;
|
||||
uint32_t coalesces;
|
||||
uint32_t direct;
|
||||
uint32_t dequeue_delay;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum hal_reg_sched_delay - ENUM for write sched delay histogram
|
||||
* @REG_WRITE_SCHED_DELAY_SUB_100us: index for delay < 100us
|
||||
* @REG_WRITE_SCHED_DELAY_SUB_1000us: index for delay < 1000us
|
||||
* @REG_WRITE_SCHED_DELAY_SUB_5000us: index for delay < 5000us
|
||||
* @REG_WRITE_SCHED_DELAY_GT_5000us: index for delay >= 5000us
|
||||
* @REG_WRITE_SCHED_DELAY_HIST_MAX: Max value (nnsize of histogram array)
|
||||
*/
|
||||
enum hal_reg_sched_delay {
|
||||
REG_WRITE_SCHED_DELAY_SUB_100us,
|
||||
REG_WRITE_SCHED_DELAY_SUB_1000us,
|
||||
REG_WRITE_SCHED_DELAY_SUB_5000us,
|
||||
REG_WRITE_SCHED_DELAY_GT_5000us,
|
||||
REG_WRITE_SCHED_DELAY_HIST_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reg_write_soc_stats - soc stats to keep track of register writes
|
||||
* @enqueues: writes enqueued to delayed work
|
||||
* @dequeues: writes dequeued from delayed work (not written yet)
|
||||
* @coalesces: writes not enqueued since srng is already queued up
|
||||
* @direct: writes not enqueud and writted to register directly
|
||||
* @prevent_l1_fails: prevent l1 API failed
|
||||
* @q_depth: current queue depth in delayed register write queue
|
||||
* @max_q_depth: maximum queue for delayed register write queue
|
||||
* @sched_delay: = kernel work sched delay + bus wakeup delay, histogram
|
||||
* @dequeue_delay: dequeue operation be delayed
|
||||
*/
|
||||
struct hal_reg_write_soc_stats {
|
||||
qdf_atomic_t enqueues;
|
||||
uint32_t dequeues;
|
||||
qdf_atomic_t coalesces;
|
||||
qdf_atomic_t direct;
|
||||
uint32_t prevent_l1_fails;
|
||||
qdf_atomic_t q_depth;
|
||||
uint32_t max_q_depth;
|
||||
uint32_t sched_delay[REG_WRITE_SCHED_DELAY_HIST_MAX];
|
||||
uint32_t dequeue_delay;
|
||||
};
|
||||
|
||||
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
|
||||
struct hal_reg_write_tcl_stats {
|
||||
uint32_t wq_delayed;
|
||||
uint32_t wq_direct;
|
||||
uint32_t timer_enq;
|
||||
uint32_t timer_direct;
|
||||
uint32_t enq_timer_set;
|
||||
uint32_t direct_timer_set;
|
||||
uint32_t timer_reset;
|
||||
qdf_time_t enq_time;
|
||||
qdf_time_t deq_time;
|
||||
uint32_t sched_delay[REG_WRITE_SCHED_DELAY_HIST_MAX];
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Common SRNG ring structure for source and destination rings */
|
||||
struct hal_srng {
|
||||
/* Unique SRNG ring ID */
|
||||
uint8_t ring_id;
|
||||
|
||||
/* Ring initialization done */
|
||||
uint8_t initialized;
|
||||
|
||||
/* Interrupt/MSI value assigned to this ring */
|
||||
int irq;
|
||||
|
||||
/* Physical base address of the ring */
|
||||
qdf_dma_addr_t ring_base_paddr;
|
||||
|
||||
/* Virtual base address of the ring */
|
||||
uint32_t *ring_base_vaddr;
|
||||
|
||||
/* Number of entries in ring */
|
||||
uint32_t num_entries;
|
||||
|
||||
/* Ring size */
|
||||
uint32_t ring_size;
|
||||
|
||||
/* Ring size mask */
|
||||
uint32_t ring_size_mask;
|
||||
|
||||
/* Size of ring entry */
|
||||
uint32_t entry_size;
|
||||
|
||||
/* Interrupt timer threshold – in micro seconds */
|
||||
uint32_t intr_timer_thres_us;
|
||||
|
||||
/* Interrupt batch counter threshold – in number of ring entries */
|
||||
uint32_t intr_batch_cntr_thres_entries;
|
||||
|
||||
/* Applicable only for CE dest ring */
|
||||
uint32_t prefetch_timer;
|
||||
|
||||
/* MSI Address */
|
||||
qdf_dma_addr_t msi_addr;
|
||||
|
||||
/* MSI data */
|
||||
uint32_t msi_data;
|
||||
|
||||
/* Misc flags */
|
||||
uint32_t flags;
|
||||
|
||||
/* Lock for serializing ring index updates */
|
||||
hal_srng_lock_t lock;
|
||||
|
||||
/* Start offset of SRNG register groups for this ring
|
||||
* TBD: See if this is required - register address can be derived
|
||||
* from ring ID
|
||||
*/
|
||||
void *hwreg_base[MAX_SRNG_REG_GROUPS];
|
||||
|
||||
/* Ring type/name */
|
||||
enum hal_ring_type ring_type;
|
||||
|
||||
/* Source or Destination ring */
|
||||
enum hal_srng_dir ring_dir;
|
||||
|
||||
union {
|
||||
struct {
|
||||
/* SW tail pointer */
|
||||
uint32_t tp;
|
||||
|
||||
/* Shadow head pointer location to be updated by HW */
|
||||
uint32_t *hp_addr;
|
||||
|
||||
/* Cached head pointer */
|
||||
uint32_t cached_hp;
|
||||
|
||||
/* Tail pointer location to be updated by SW – This
|
||||
* will be a register address and need not be
|
||||
* accessed through SW structure */
|
||||
uint32_t *tp_addr;
|
||||
|
||||
/* Current SW loop cnt */
|
||||
uint32_t loop_cnt;
|
||||
|
||||
/* max transfer size */
|
||||
uint16_t max_buffer_length;
|
||||
} dst_ring;
|
||||
|
||||
struct {
|
||||
/* SW head pointer */
|
||||
uint32_t hp;
|
||||
|
||||
/* SW reap head pointer */
|
||||
uint32_t reap_hp;
|
||||
|
||||
/* Shadow tail pointer location to be updated by HW */
|
||||
uint32_t *tp_addr;
|
||||
|
||||
/* Cached tail pointer */
|
||||
uint32_t cached_tp;
|
||||
|
||||
/* Head pointer location to be updated by SW – This
|
||||
* will be a register address and need not be accessed
|
||||
* through SW structure */
|
||||
uint32_t *hp_addr;
|
||||
|
||||
/* Low threshold – in number of ring entries */
|
||||
uint32_t low_threshold;
|
||||
} src_ring;
|
||||
} u;
|
||||
|
||||
struct hal_soc *hal_soc;
|
||||
|
||||
/* Number of times hp/tp updated in runtime resume */
|
||||
uint32_t flush_count;
|
||||
/* hal srng event flag*/
|
||||
unsigned long srng_event;
|
||||
/* last flushed time stamp */
|
||||
uint64_t last_flush_ts;
|
||||
#if defined(CLEAR_SW2TCL_CONSUMED_DESC)
|
||||
/* last ring desc entry cleared */
|
||||
uint32_t last_desc_cleared;
|
||||
#endif
|
||||
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
|
||||
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
|
||||
/* Previous hp/tp (based on ring dir) value written to the reg */
|
||||
uint32_t last_reg_wr_val;
|
||||
/* flag to indicate whether srng is already queued for delayed write */
|
||||
uint8_t reg_write_in_progress;
|
||||
/* last dequeue elem time stamp */
|
||||
qdf_time_t last_dequeue_time;
|
||||
|
||||
/* srng specific delayed write stats */
|
||||
struct hal_reg_write_srng_stats wstats;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* HW SRNG configuration table */
|
||||
struct hal_hw_srng_config {
|
||||
int start_ring_id;
|
||||
uint16_t max_rings;
|
||||
uint16_t entry_size;
|
||||
uint32_t reg_start[MAX_SRNG_REG_GROUPS];
|
||||
uint16_t reg_size[MAX_SRNG_REG_GROUPS];
|
||||
uint8_t lmac_ring;
|
||||
enum hal_srng_dir ring_dir;
|
||||
uint32_t max_size;
|
||||
};
|
||||
|
||||
#define MAX_SHADOW_REGISTERS 36
|
||||
#define MAX_GENERIC_SHADOW_REG 5
|
||||
|
||||
/**
|
||||
* struct shadow_reg_config - Hal soc structure that contains
|
||||
* the list of generic shadow registers
|
||||
* @target_register: target reg offset
|
||||
* @shadow_config_index: shadow config index in shadow config
|
||||
* list sent to FW
|
||||
* @va: virtual addr of shadow reg
|
||||
*
|
||||
* This structure holds the generic registers that are mapped to
|
||||
* the shadow region and holds the mapping of the target
|
||||
* register offset to shadow config index provided to FW during
|
||||
* init
|
||||
*/
|
||||
struct shadow_reg_config {
|
||||
uint32_t target_register;
|
||||
int shadow_config_index;
|
||||
uint64_t va;
|
||||
};
|
||||
|
||||
/* REO parameters to be passed to hal_reo_setup */
|
||||
struct hal_reo_params {
|
||||
/** rx hash steering enabled or disabled */
|
||||
bool rx_hash_enabled;
|
||||
/** reo remap 1 register */
|
||||
uint32_t remap1;
|
||||
/** reo remap 2 register */
|
||||
uint32_t remap2;
|
||||
/** fragment destination ring */
|
||||
uint8_t frag_dst_ring;
|
||||
/** padding */
|
||||
uint8_t padding[3];
|
||||
};
|
||||
|
||||
struct hal_hw_txrx_ops {
|
||||
|
||||
/* init and setup */
|
||||
void (*hal_srng_dst_hw_init)(struct hal_soc *hal,
|
||||
struct hal_srng *srng);
|
||||
void (*hal_srng_src_hw_init)(struct hal_soc *hal,
|
||||
struct hal_srng *srng);
|
||||
void (*hal_get_hw_hptp)(struct hal_soc *hal,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
uint32_t *headp, uint32_t *tailp,
|
||||
uint8_t ring_type);
|
||||
void (*hal_reo_setup)(struct hal_soc *hal_soc, void *reoparams);
|
||||
void (*hal_setup_link_idle_list)(
|
||||
struct hal_soc *hal_soc,
|
||||
qdf_dma_addr_t scatter_bufs_base_paddr[],
|
||||
void *scatter_bufs_base_vaddr[],
|
||||
uint32_t num_scatter_bufs,
|
||||
uint32_t scatter_buf_size,
|
||||
uint32_t last_buf_end_offset,
|
||||
uint32_t num_entries);
|
||||
qdf_iomem_t (*hal_get_window_address)(struct hal_soc *hal_soc,
|
||||
qdf_iomem_t addr);
|
||||
void (*hal_reo_set_err_dst_remap)(void *hal_soc);
|
||||
|
||||
/* tx */
|
||||
void (*hal_tx_desc_set_dscp_tid_table_id)(void *desc, uint8_t id);
|
||||
void (*hal_tx_set_dscp_tid_map)(struct hal_soc *hal_soc, uint8_t *map,
|
||||
uint8_t id);
|
||||
void (*hal_tx_update_dscp_tid)(struct hal_soc *hal_soc, uint8_t tid,
|
||||
uint8_t id,
|
||||
uint8_t dscp);
|
||||
void (*hal_tx_desc_set_lmac_id)(void *desc, uint8_t lmac_id);
|
||||
void (*hal_tx_desc_set_buf_addr)(void *desc, dma_addr_t paddr,
|
||||
uint8_t pool_id, uint32_t desc_id, uint8_t type);
|
||||
void (*hal_tx_desc_set_search_type)(void *desc, uint8_t search_type);
|
||||
void (*hal_tx_desc_set_search_index)(void *desc, uint32_t search_index);
|
||||
void (*hal_tx_desc_set_cache_set_num)(void *desc, uint8_t search_index);
|
||||
void (*hal_tx_comp_get_status)(void *desc, void *ts,
|
||||
struct hal_soc *hal);
|
||||
uint8_t (*hal_tx_comp_get_release_reason)(void *hal_desc);
|
||||
uint8_t (*hal_get_wbm_internal_error)(void *hal_desc);
|
||||
void (*hal_tx_desc_set_mesh_en)(void *desc, uint8_t en);
|
||||
void (*hal_tx_init_cmd_credit_ring)(hal_soc_handle_t hal_soc_hdl,
|
||||
hal_ring_handle_t hal_ring_hdl);
|
||||
|
||||
/* rx */
|
||||
uint32_t (*hal_rx_msdu_start_nss_get)(uint8_t *);
|
||||
void (*hal_rx_mon_hw_desc_get_mpdu_status)(void *hw_desc_addr,
|
||||
struct mon_rx_status *rs);
|
||||
uint8_t (*hal_rx_get_tlv)(void *rx_tlv);
|
||||
void (*hal_rx_proc_phyrx_other_receive_info_tlv)(void *rx_tlv_hdr,
|
||||
void *ppdu_info_handle);
|
||||
void (*hal_rx_dump_msdu_start_tlv)(void *msdu_start, uint8_t dbg_level);
|
||||
void (*hal_rx_dump_msdu_end_tlv)(void *msdu_end,
|
||||
uint8_t dbg_level);
|
||||
uint32_t (*hal_get_link_desc_size)(void);
|
||||
uint32_t (*hal_rx_mpdu_start_tid_get)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_msdu_start_reception_type_get)(uint8_t *buf);
|
||||
uint16_t (*hal_rx_msdu_end_da_idx_get)(uint8_t *buf);
|
||||
void* (*hal_rx_msdu_desc_info_get_ptr)(void *msdu_details_ptr);
|
||||
void* (*hal_rx_link_desc_msdu0_ptr)(void *msdu_link_ptr);
|
||||
void (*hal_reo_status_get_header)(uint32_t *d, int b, void *h);
|
||||
uint32_t (*hal_rx_status_get_tlv_info)(void *rx_tlv_hdr,
|
||||
void *ppdu_info,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
qdf_nbuf_t nbuf);
|
||||
void (*hal_rx_wbm_err_info_get)(void *wbm_desc,
|
||||
void *wbm_er_info);
|
||||
void (*hal_rx_dump_mpdu_start_tlv)(void *mpdustart,
|
||||
uint8_t dbg_level);
|
||||
|
||||
void (*hal_tx_set_pcp_tid_map)(struct hal_soc *hal_soc, uint8_t *map);
|
||||
void (*hal_tx_update_pcp_tid_map)(struct hal_soc *hal_soc, uint8_t pcp,
|
||||
uint8_t id);
|
||||
void (*hal_tx_set_tidmap_prty)(struct hal_soc *hal_soc, uint8_t prio);
|
||||
uint8_t (*hal_rx_get_rx_fragment_number)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_msdu_end_da_is_mcbc_get)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_msdu_end_sa_is_valid_get)(uint8_t *buf);
|
||||
uint16_t (*hal_rx_msdu_end_sa_idx_get)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_desc_is_first_msdu)(void *hw_desc_addr);
|
||||
uint32_t (*hal_rx_msdu_end_l3_hdr_padding_get)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_encryption_info_valid)(uint8_t *buf);
|
||||
void (*hal_rx_print_pn)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_msdu_end_first_msdu_get)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_msdu_end_da_is_valid_get)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_msdu_end_last_msdu_get)(uint8_t *buf);
|
||||
bool (*hal_rx_get_mpdu_mac_ad4_valid)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_mpdu_start_sw_peer_id_get)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_mpdu_get_to_ds)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_mpdu_get_fr_ds)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_get_mpdu_frame_control_valid)(uint8_t *buf);
|
||||
QDF_STATUS
|
||||
(*hal_rx_mpdu_get_addr1)(uint8_t *buf, uint8_t *mac_addr);
|
||||
QDF_STATUS
|
||||
(*hal_rx_mpdu_get_addr2)(uint8_t *buf, uint8_t *mac_addr);
|
||||
QDF_STATUS
|
||||
(*hal_rx_mpdu_get_addr3)(uint8_t *buf, uint8_t *mac_addr);
|
||||
QDF_STATUS
|
||||
(*hal_rx_mpdu_get_addr4)(uint8_t *buf, uint8_t *mac_addr);
|
||||
uint8_t (*hal_rx_get_mpdu_sequence_control_valid)(uint8_t *buf);
|
||||
bool (*hal_rx_is_unicast)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_tid_get)(hal_soc_handle_t hal_soc_hdl, uint8_t *buf);
|
||||
uint32_t (*hal_rx_hw_desc_get_ppduid_get)(void *rx_tlv_hdr,
|
||||
void *rxdma_dst_ring_desc);
|
||||
uint32_t (*hal_rx_mpdu_start_mpdu_qos_control_valid_get)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_msdu_end_sa_sw_peer_id_get)(uint8_t *buf);
|
||||
void * (*hal_rx_msdu0_buffer_addr_lsb)(void *link_desc_addr);
|
||||
void * (*hal_rx_msdu_desc_info_ptr_get)(void *msdu0);
|
||||
void * (*hal_ent_mpdu_desc_info)(void *hw_addr);
|
||||
void * (*hal_dst_mpdu_desc_info)(void *hw_addr);
|
||||
uint8_t (*hal_rx_get_fc_valid)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_get_to_ds_flag)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_get_mac_addr2_valid)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_get_filter_category)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_get_ppdu_id)(uint8_t *buf);
|
||||
void (*hal_reo_config)(struct hal_soc *soc,
|
||||
uint32_t reg_val,
|
||||
struct hal_reo_params *reo_params);
|
||||
uint32_t (*hal_rx_msdu_flow_idx_get)(uint8_t *buf);
|
||||
bool (*hal_rx_msdu_flow_idx_invalid)(uint8_t *buf);
|
||||
bool (*hal_rx_msdu_flow_idx_timeout)(uint8_t *buf);
|
||||
uint32_t (*hal_rx_msdu_fse_metadata_get)(uint8_t *buf);
|
||||
uint16_t (*hal_rx_msdu_cce_metadata_get)(uint8_t *buf);
|
||||
void
|
||||
(*hal_rx_msdu_get_flow_params)(
|
||||
uint8_t *buf,
|
||||
bool *flow_invalid,
|
||||
bool *flow_timeout,
|
||||
uint32_t *flow_index);
|
||||
uint16_t (*hal_rx_tlv_get_tcp_chksum)(uint8_t *buf);
|
||||
uint16_t (*hal_rx_get_rx_sequence)(uint8_t *buf);
|
||||
void (*hal_rx_get_bb_info)(void *rx_tlv, void *ppdu_info_handle);
|
||||
void (*hal_rx_get_rtt_info)(void *rx_tlv, void *ppdu_info_handle);
|
||||
void (*hal_rx_msdu_packet_metadata_get)(uint8_t *buf,
|
||||
void *msdu_pkt_metadata);
|
||||
uint16_t (*hal_rx_get_fisa_cumulative_l4_checksum)(uint8_t *buf);
|
||||
uint16_t (*hal_rx_get_fisa_cumulative_ip_length)(uint8_t *buf);
|
||||
bool (*hal_rx_get_udp_proto)(uint8_t *buf);
|
||||
bool (*hal_rx_get_fisa_flow_agg_continuation)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_get_fisa_flow_agg_count)(uint8_t *buf);
|
||||
bool (*hal_rx_get_fisa_timeout)(uint8_t *buf);
|
||||
uint8_t (*hal_rx_mpdu_start_tlv_tag_valid)(void *rx_tlv_hdr);
|
||||
void (*hal_rx_sw_mon_desc_info_get)(hal_ring_desc_t rxdma_dst_ring_desc,
|
||||
hal_rx_mon_desc_info_t mon_desc_info);
|
||||
uint8_t (*hal_rx_wbm_err_msdu_continuation_get)(void *ring_desc);
|
||||
uint32_t (*hal_rx_msdu_end_offset_get)(void);
|
||||
uint32_t (*hal_rx_attn_offset_get)(void);
|
||||
uint32_t (*hal_rx_msdu_start_offset_get)(void);
|
||||
uint32_t (*hal_rx_mpdu_start_offset_get)(void);
|
||||
uint32_t (*hal_rx_mpdu_end_offset_get)(void);
|
||||
void * (*hal_rx_flow_setup_fse)(uint8_t *rx_fst,
|
||||
uint32_t table_offset,
|
||||
uint8_t *rx_flow);
|
||||
void (*hal_compute_reo_remap_ix2_ix3)(uint32_t *ring,
|
||||
uint32_t num_rings,
|
||||
uint32_t *remap1,
|
||||
uint32_t *remap2);
|
||||
uint32_t (*hal_rx_flow_setup_cmem_fse)(
|
||||
struct hal_soc *soc, uint32_t cmem_ba,
|
||||
uint32_t table_offset, uint8_t *rx_flow);
|
||||
uint32_t (*hal_rx_flow_get_cmem_fse_ts)(struct hal_soc *soc,
|
||||
uint32_t fse_offset);
|
||||
void (*hal_rx_flow_get_cmem_fse)(struct hal_soc *soc,
|
||||
uint32_t fse_offset,
|
||||
uint32_t *fse, qdf_size_t len);
|
||||
void (*hal_rx_msdu_get_reo_destination_indication)(uint8_t *buf,
|
||||
uint32_t *reo_destination_indication);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_soc_stats - Hal layer stats
|
||||
* @reg_write_fail: number of failed register writes
|
||||
* @wstats: delayed register write stats
|
||||
* @shadow_reg_write_fail: shadow reg write failure stats
|
||||
* @shadow_reg_write_succ: shadow reg write success stats
|
||||
*
|
||||
* This structure holds all the statistics at HAL layer.
|
||||
*/
|
||||
struct hal_soc_stats {
|
||||
uint32_t reg_write_fail;
|
||||
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
|
||||
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
|
||||
struct hal_reg_write_soc_stats wstats;
|
||||
#endif
|
||||
#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
|
||||
uint32_t shadow_reg_write_fail;
|
||||
uint32_t shadow_reg_write_succ;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef ENABLE_HAL_REG_WR_HISTORY
|
||||
/* The history size should always be a power of 2 */
|
||||
#define HAL_REG_WRITE_HIST_SIZE 8
|
||||
|
||||
/**
|
||||
* struct hal_reg_write_fail_entry - Record of
|
||||
* register write which failed.
|
||||
* @timestamp: timestamp of reg write failure
|
||||
* @reg_offset: offset of register where the write failed
|
||||
* @write_val: the value which was to be written
|
||||
* @read_val: the value read back from the register after write
|
||||
*/
|
||||
struct hal_reg_write_fail_entry {
|
||||
uint64_t timestamp;
|
||||
uint32_t reg_offset;
|
||||
uint32_t write_val;
|
||||
uint32_t read_val;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reg_write_fail_history - Hal layer history
|
||||
* of all the register write failures.
|
||||
* @index: index to add the new record
|
||||
* @record: array of all the records in history
|
||||
*
|
||||
* This structure holds the history of register write
|
||||
* failures at HAL layer.
|
||||
*/
|
||||
struct hal_reg_write_fail_history {
|
||||
qdf_atomic_t index;
|
||||
struct hal_reg_write_fail_entry record[HAL_REG_WRITE_HIST_SIZE];
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct hal_soc - HAL context to be used to access SRNG APIs
|
||||
* (currently used by data path and
|
||||
* transport (CE) modules)
|
||||
* @list_shadow_reg_config: array of generic regs mapped to
|
||||
* shadow regs
|
||||
* @num_generic_shadow_regs_configured: number of generic regs
|
||||
* mapped to shadow regs
|
||||
*/
|
||||
struct hal_soc {
|
||||
/* HIF handle to access HW registers */
|
||||
struct hif_opaque_softc *hif_handle;
|
||||
|
||||
/* QDF device handle */
|
||||
qdf_device_t qdf_dev;
|
||||
|
||||
/* Device base address */
|
||||
void *dev_base_addr;
|
||||
/* Device base address for ce - qca5018 target */
|
||||
void *dev_base_addr_ce;
|
||||
|
||||
/* HAL internal state for all SRNG rings.
|
||||
* TODO: See if this is required
|
||||
*/
|
||||
struct hal_srng srng_list[HAL_SRNG_ID_MAX];
|
||||
|
||||
/* Remote pointer memory for HW/FW updates */
|
||||
uint32_t *shadow_rdptr_mem_vaddr;
|
||||
qdf_dma_addr_t shadow_rdptr_mem_paddr;
|
||||
|
||||
/* Shared memory for ring pointer updates from host to FW */
|
||||
uint32_t *shadow_wrptr_mem_vaddr;
|
||||
qdf_dma_addr_t shadow_wrptr_mem_paddr;
|
||||
|
||||
/* REO blocking resource index */
|
||||
uint8_t reo_res_bitmap;
|
||||
uint8_t index;
|
||||
uint32_t target_type;
|
||||
|
||||
/* shadow register configuration */
|
||||
struct pld_shadow_reg_v2_cfg shadow_config[MAX_SHADOW_REGISTERS];
|
||||
int num_shadow_registers_configured;
|
||||
bool use_register_windowing;
|
||||
uint32_t register_window;
|
||||
qdf_spinlock_t register_access_lock;
|
||||
|
||||
/* Static window map configuration for multiple window write*/
|
||||
bool static_window_map;
|
||||
|
||||
/* srng table */
|
||||
struct hal_hw_srng_config *hw_srng_table;
|
||||
int32_t *hal_hw_reg_offset;
|
||||
struct hal_hw_txrx_ops *ops;
|
||||
|
||||
/* Indicate srngs initialization */
|
||||
bool init_phase;
|
||||
/* Hal level stats */
|
||||
struct hal_soc_stats stats;
|
||||
#ifdef ENABLE_HAL_REG_WR_HISTORY
|
||||
struct hal_reg_write_fail_history *reg_wr_fail_hist;
|
||||
#endif
|
||||
#ifdef FEATURE_HAL_DELAYED_REG_WRITE
|
||||
/* queue(array) to hold register writes */
|
||||
struct hal_reg_write_q_elem *reg_write_queue;
|
||||
/* delayed work to be queued into workqueue */
|
||||
qdf_work_t reg_write_work;
|
||||
/* workqueue for delayed register writes */
|
||||
qdf_workqueue_t *reg_write_wq;
|
||||
/* write index used by caller to enqueue delayed work */
|
||||
qdf_atomic_t write_idx;
|
||||
/* read index used by worker thread to dequeue/write registers */
|
||||
uint32_t read_idx;
|
||||
#endif /*FEATURE_HAL_DELAYED_REG_WRITE */
|
||||
#ifdef FEATURE_HAL_DELAYED_REG_WRITE_V2
|
||||
/* delayed work for TCL reg write to be queued into workqueue */
|
||||
qdf_work_t tcl_reg_write_work;
|
||||
/* workqueue for TCL delayed register writes */
|
||||
qdf_workqueue_t *tcl_reg_write_wq;
|
||||
/* flag denotes whether TCL delayed write work is active */
|
||||
qdf_atomic_t tcl_work_active;
|
||||
/* flag indiactes TCL write happening from direct context */
|
||||
bool tcl_direct;
|
||||
/* timer to handle the pending TCL reg writes */
|
||||
qdf_timer_t tcl_reg_write_timer;
|
||||
/* stats related to TCL reg write */
|
||||
struct hal_reg_write_tcl_stats tcl_stats;
|
||||
#endif /* FEATURE_HAL_DELAYED_REG_WRITE_V2 */
|
||||
qdf_atomic_t active_work_cnt;
|
||||
#ifdef GENERIC_SHADOW_REGISTER_ACCESS_ENABLE
|
||||
struct shadow_reg_config
|
||||
list_shadow_reg_config[MAX_GENERIC_SHADOW_REG];
|
||||
int num_generic_shadow_regs_configured;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(FEATURE_HAL_DELAYED_REG_WRITE) || \
|
||||
defined(FEATURE_HAL_DELAYED_REG_WRITE_V2)
|
||||
/**
|
||||
* hal_delayed_reg_write() - delayed regiter write
|
||||
* @hal_soc: HAL soc handle
|
||||
* @srng: hal srng
|
||||
* @addr: iomem address
|
||||
* @value: value to be written
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void hal_delayed_reg_write(struct hal_soc *hal_soc,
|
||||
struct hal_srng *srng,
|
||||
void __iomem *addr,
|
||||
uint32_t value);
|
||||
#endif
|
||||
|
||||
void hal_qca6750_attach(struct hal_soc *hal_soc);
|
||||
void hal_qca6490_attach(struct hal_soc *hal_soc);
|
||||
void hal_qca6390_attach(struct hal_soc *hal_soc);
|
||||
void hal_qca6290_attach(struct hal_soc *hal_soc);
|
||||
void hal_qca8074_attach(struct hal_soc *hal_soc);
|
||||
|
||||
/*
|
||||
* hal_soc_to_dp_hal_roc - API to convert hal_soc to opaque
|
||||
* dp_hal_soc handle type
|
||||
* @hal_soc - hal_soc type
|
||||
*
|
||||
* Return: hal_soc_handle_t type
|
||||
*/
|
||||
static inline
|
||||
hal_soc_handle_t hal_soc_to_hal_soc_handle(struct hal_soc *hal_soc)
|
||||
{
|
||||
return (hal_soc_handle_t)hal_soc;
|
||||
}
|
||||
|
||||
/*
|
||||
* hal_srng_to_hal_ring_handle - API to convert hal_srng to opaque
|
||||
* dp_hal_ring handle type
|
||||
* @hal_srng - hal_srng type
|
||||
*
|
||||
* Return: hal_ring_handle_t type
|
||||
*/
|
||||
static inline
|
||||
hal_ring_handle_t hal_srng_to_hal_ring_handle(struct hal_srng *hal_srng)
|
||||
{
|
||||
return (hal_ring_handle_t)hal_srng;
|
||||
}
|
||||
|
||||
/*
|
||||
* hal_ring_handle_to_hal_srng - API to convert dp_hal_ring to hal_srng handle
|
||||
* @hal_ring - hal_ring_handle_t type
|
||||
*
|
||||
* Return: hal_srng pointer type
|
||||
*/
|
||||
static inline
|
||||
struct hal_srng *hal_ring_handle_to_hal_srng(hal_ring_handle_t hal_ring)
|
||||
{
|
||||
return (struct hal_srng *)hal_ring;
|
||||
}
|
||||
#endif /* _HAL_INTERNAL_H_ */
|
||||
1409
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.c
Normal file
1409
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.c
Normal file
File diff suppressed because it is too large
Load diff
546
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.h
Normal file
546
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_reo.h
Normal file
|
|
@ -0,0 +1,546 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _HAL_REO_H_
|
||||
#define _HAL_REO_H_
|
||||
|
||||
#include <qdf_types.h>
|
||||
/* HW headers */
|
||||
#include <reo_descriptor_threshold_reached_status.h>
|
||||
#include <reo_flush_queue.h>
|
||||
#include <reo_flush_timeout_list_status.h>
|
||||
#include <reo_unblock_cache.h>
|
||||
#include <reo_flush_cache.h>
|
||||
#include <reo_flush_queue_status.h>
|
||||
#include <reo_get_queue_stats.h>
|
||||
#include <reo_unblock_cache_status.h>
|
||||
#include <reo_flush_cache_status.h>
|
||||
#include <reo_flush_timeout_list.h>
|
||||
#include <reo_get_queue_stats_status.h>
|
||||
#include <reo_update_rx_reo_queue.h>
|
||||
#include <reo_update_rx_reo_queue_status.h>
|
||||
#include <tlv_tag_def.h>
|
||||
|
||||
/* SW headers */
|
||||
#include "hal_api.h"
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Preprocessor definitions and constants
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* TLV values */
|
||||
#define HAL_REO_GET_QUEUE_STATS_TLV WIFIREO_GET_QUEUE_STATS_E
|
||||
#define HAL_REO_FLUSH_QUEUE_TLV WIFIREO_FLUSH_QUEUE_E
|
||||
#define HAL_REO_FLUSH_CACHE_TLV WIFIREO_FLUSH_CACHE_E
|
||||
#define HAL_REO_UNBLOCK_CACHE_TLV WIFIREO_UNBLOCK_CACHE_E
|
||||
#define HAL_REO_FLUSH_TIMEOUT_LIST_TLV WIFIREO_FLUSH_TIMEOUT_LIST_E
|
||||
#define HAL_REO_RX_UPDATE_QUEUE_TLV WIFIREO_UPDATE_RX_REO_QUEUE_E
|
||||
|
||||
#define HAL_REO_QUEUE_STATS_STATUS_TLV WIFIREO_GET_QUEUE_STATS_STATUS_E
|
||||
#define HAL_REO_FLUSH_QUEUE_STATUS_TLV WIFIREO_FLUSH_QUEUE_STATUS_E
|
||||
#define HAL_REO_FLUSH_CACHE_STATUS_TLV WIFIREO_FLUSH_CACHE_STATUS_E
|
||||
#define HAL_REO_UNBLK_CACHE_STATUS_TLV WIFIREO_UNBLOCK_CACHE_STATUS_E
|
||||
#define HAL_REO_TIMOUT_LIST_STATUS_TLV WIFIREO_FLUSH_TIMEOUT_LIST_STATUS_E
|
||||
#define HAL_REO_DESC_THRES_STATUS_TLV \
|
||||
WIFIREO_DESCRIPTOR_THRESHOLD_REACHED_STATUS_E
|
||||
#define HAL_REO_UPDATE_RX_QUEUE_STATUS_TLV WIFIREO_UPDATE_RX_REO_QUEUE_STATUS_E
|
||||
|
||||
#define HAL_SET_FIELD(block, field, value) \
|
||||
((value << (block ## _ ## field ## _LSB)) & \
|
||||
(block ## _ ## field ## _MASK))
|
||||
|
||||
#define HAL_GET_FIELD(block, field, value) \
|
||||
((value & (block ## _ ## field ## _MASK)) >> \
|
||||
(block ## _ ## field ## _LSB))
|
||||
|
||||
#define HAL_SET_TLV_HDR(desc, tag, len) \
|
||||
do { \
|
||||
((struct tlv_32_hdr *) desc)->tlv_tag = tag; \
|
||||
((struct tlv_32_hdr *) desc)->tlv_len = len; \
|
||||
} while (0)
|
||||
|
||||
#define HAL_GET_TLV(desc) (((struct tlv_32_hdr *) desc)->tlv_tag)
|
||||
|
||||
#define HAL_OFFSET_DW(_block, _field) (HAL_OFFSET(_block, _field) >> 2)
|
||||
/* dword offsets in REO cmd TLV */
|
||||
#define CMD_HEADER_DW_OFFSET 0
|
||||
|
||||
/**
|
||||
* enum reo_unblock_cache_type: Enum for unblock type in REO unblock command
|
||||
* @UNBLOCK_RES_INDEX: Unblock a block resource
|
||||
* @UNBLOCK_CACHE: Unblock cache
|
||||
*/
|
||||
enum reo_unblock_cache_type {
|
||||
UNBLOCK_RES_INDEX = 0,
|
||||
UNBLOCK_CACHE = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* enum reo_thres_index_reg: Enum for reo descriptor usage counter for
|
||||
* which threshold status is being indicated.
|
||||
* @reo_desc_counter0_threshold: counter0 reached threshold
|
||||
* @reo_desc_counter1_threshold: counter1 reached threshold
|
||||
* @reo_desc_counter2_threshold: counter2 reached threshold
|
||||
* @reo_desc_counter_sum_threshold: Total count reached threshold
|
||||
*/
|
||||
enum reo_thres_index_reg {
|
||||
reo_desc_counter0_threshold = 0,
|
||||
reo_desc_counter1_threshold = 1,
|
||||
reo_desc_counter2_threshold = 2,
|
||||
reo_desc_counter_sum_threshold = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* enum reo_cmd_exec_status: Enum for execution status of REO command
|
||||
*
|
||||
* @HAL_REO_CMD_SUCCESS: Command has successfully be executed
|
||||
* @HAL_REO_CMD_BLOCKED: Command could not be executed as the queue or cache
|
||||
* was blocked
|
||||
* @HAL_REO_CMD_FAILED: Command has encountered problems when executing, like
|
||||
* the queue descriptor not being valid
|
||||
*/
|
||||
enum reo_cmd_exec_status {
|
||||
HAL_REO_CMD_SUCCESS = 0,
|
||||
HAL_REO_CMD_BLOCKED = 1,
|
||||
HAL_REO_CMD_FAILED = 2,
|
||||
HAL_REO_CMD_RESOURCE_BLOCKED = 3,
|
||||
HAL_REO_CMD_DRAIN = 0xff
|
||||
};
|
||||
|
||||
/**
|
||||
* enum hal_reo_cmd_type: Enum for REO command type
|
||||
* @CMD_GET_QUEUE_STATS: Get REO queue status/stats
|
||||
* @CMD_FLUSH_QUEUE: Flush all frames in REO queue
|
||||
* @CMD_FLUSH_CACHE: Flush descriptor entries in the cache
|
||||
* @CMD_UNBLOCK_CACHE: Unblock a descriptor’s address that was blocked
|
||||
* earlier with a ‘REO_FLUSH_CACHE’ command
|
||||
* @CMD_FLUSH_TIMEOUT_LIST: Flush buffers/descriptors from timeout list
|
||||
* @CMD_UPDATE_RX_REO_QUEUE: Update REO queue settings
|
||||
*/
|
||||
enum hal_reo_cmd_type {
|
||||
CMD_GET_QUEUE_STATS = 0,
|
||||
CMD_FLUSH_QUEUE = 1,
|
||||
CMD_FLUSH_CACHE = 2,
|
||||
CMD_UNBLOCK_CACHE = 3,
|
||||
CMD_FLUSH_TIMEOUT_LIST = 4,
|
||||
CMD_UPDATE_RX_REO_QUEUE = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_params_std: Standard REO command parameters
|
||||
* @need_status: Status required for the command
|
||||
* @addr_lo: Lower 32 bits of REO queue descriptor address
|
||||
* @addr_hi: Upper 8 bits of REO queue descriptor address
|
||||
*/
|
||||
struct hal_reo_cmd_params_std {
|
||||
bool need_status;
|
||||
uint32_t addr_lo;
|
||||
uint8_t addr_hi;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_get_queue_stats_params: Parameters to
|
||||
* CMD_GET_QUEUE_STATScommand
|
||||
* @clear: Clear stats after retreiving
|
||||
*/
|
||||
struct hal_reo_cmd_get_queue_stats_params {
|
||||
bool clear;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_flush_queue_params: Parameters to CMD_FLUSH_QUEUE
|
||||
* @use_after_flush: Block usage after flush till unblock command
|
||||
* @index: Blocking resource to be used
|
||||
*/
|
||||
struct hal_reo_cmd_flush_queue_params {
|
||||
bool block_use_after_flush;
|
||||
uint8_t index;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_flush_cache_params: Parameters to CMD_FLUSH_CACHE
|
||||
* @fwd_mpdus_in_queue: Forward MPDUs before flushing descriptor
|
||||
* @rel_block_index: Release blocking resource used earlier
|
||||
* @cache_block_res_index: Blocking resource to be used
|
||||
* @flush_no_inval: Flush without invalidatig descriptor
|
||||
* @use_after_flush: Block usage after flush till unblock command
|
||||
* @flush_entire_cache: Flush entire REO cache
|
||||
*/
|
||||
struct hal_reo_cmd_flush_cache_params {
|
||||
bool fwd_mpdus_in_queue;
|
||||
bool rel_block_index;
|
||||
uint8_t cache_block_res_index;
|
||||
bool flush_no_inval;
|
||||
bool block_use_after_flush;
|
||||
bool flush_entire_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_unblock_cache_params: Parameters to CMD_UNBLOCK_CACHE
|
||||
* @type: Unblock type (enum reo_unblock_cache_type)
|
||||
* @index: Blocking index to be released
|
||||
*/
|
||||
struct hal_reo_cmd_unblock_cache_params {
|
||||
enum reo_unblock_cache_type type;
|
||||
uint8_t index;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_flush_timeout_list_params: Parameters to
|
||||
* CMD_FLUSH_TIMEOUT_LIST
|
||||
* @ac_list: AC timeout list to be flushed
|
||||
* @min_rel_desc: Min. number of link descriptors to be release
|
||||
* @min_fwd_buf: Min. number of buffers to be forwarded
|
||||
*/
|
||||
struct hal_reo_cmd_flush_timeout_list_params {
|
||||
uint8_t ac_list;
|
||||
uint16_t min_rel_desc;
|
||||
uint16_t min_fwd_buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_update_queue_params: Parameters to CMD_UPDATE_RX_REO_QUEUE
|
||||
* @update_rx_queue_num: Update receive queue number
|
||||
* @update_vld: Update valid bit
|
||||
* @update_assoc_link_desc: Update associated link descriptor
|
||||
* @update_disable_dup_detect: Update duplicate detection
|
||||
* @update_soft_reorder_enab: Update soft reorder enable
|
||||
* @update_ac: Update access category
|
||||
* @update_bar: Update BAR received bit
|
||||
* @update_rty: Update retry bit
|
||||
* @update_chk_2k_mode: Update chk_2k_mode setting
|
||||
* @update_oor_mode: Update OOR mode setting
|
||||
* @update_ba_window_size: Update BA window size
|
||||
* @update_pn_check_needed: Update pn_check_needed
|
||||
* @update_pn_even: Update pn_even
|
||||
* @update_pn_uneven: Update pn_uneven
|
||||
* @update_pn_hand_enab: Update pn_handling_enable
|
||||
* @update_pn_size: Update pn_size
|
||||
* @update_ignore_ampdu: Update ignore_ampdu
|
||||
* @update_svld: update svld
|
||||
* @update_ssn: Update SSN
|
||||
* @update_seq_2k_err_detect: Update seq_2k_err_detected flag
|
||||
* @update_pn_err_detect: Update pn_err_detected flag
|
||||
* @update_pn_valid: Update pn_valid
|
||||
* @update_pn: Update PN
|
||||
* @rx_queue_num: rx_queue_num to be updated
|
||||
* @vld: valid bit to be updated
|
||||
* @assoc_link_desc: assoc_link_desc counter
|
||||
* @disable_dup_detect: disable_dup_detect to be updated
|
||||
* @soft_reorder_enab: soft_reorder_enab to be updated
|
||||
* @ac: AC to be updated
|
||||
* @bar: BAR flag to be updated
|
||||
* @rty: RTY flag to be updated
|
||||
* @chk_2k_mode: check_2k_mode setting to be updated
|
||||
* @oor_mode: oor_mode to be updated
|
||||
* @pn_check_needed: pn_check_needed to be updated
|
||||
* @pn_even: pn_even to be updated
|
||||
* @pn_uneven: pn_uneven to be updated
|
||||
* @pn_hand_enab: pn_handling_enable to be updated
|
||||
* @ignore_ampdu: ignore_ampdu to be updated
|
||||
* @ba_window_size: BA window size to be updated
|
||||
* @pn_size: pn_size to be updated
|
||||
* @svld: svld flag to be updated
|
||||
* @ssn: SSN to be updated
|
||||
* @seq_2k_err_detect: seq_2k_err_detected flag to be updated
|
||||
* @pn_err_detect: pn_err_detected flag to be updated
|
||||
* @pn_31_0: PN bits 31-0
|
||||
* @pn_63_32: PN bits 63-32
|
||||
* @pn_95_64: PN bits 95-64
|
||||
* @pn_127_96: PN bits 127-96
|
||||
*/
|
||||
struct hal_reo_cmd_update_queue_params {
|
||||
uint32_t update_rx_queue_num:1,
|
||||
update_vld:1,
|
||||
update_assoc_link_desc:1,
|
||||
update_disable_dup_detect:1,
|
||||
update_soft_reorder_enab:1,
|
||||
update_ac:1,
|
||||
update_bar:1,
|
||||
update_rty:1,
|
||||
update_chk_2k_mode:1,
|
||||
update_oor_mode:1,
|
||||
update_ba_window_size:1,
|
||||
update_pn_check_needed:1,
|
||||
update_pn_even:1,
|
||||
update_pn_uneven:1,
|
||||
update_pn_hand_enab:1,
|
||||
update_pn_size:1,
|
||||
update_ignore_ampdu:1,
|
||||
update_svld:1,
|
||||
update_ssn:1,
|
||||
update_seq_2k_err_detect:1,
|
||||
update_pn_err_detect:1,
|
||||
update_pn_valid:1,
|
||||
update_pn:1;
|
||||
uint32_t rx_queue_num:16,
|
||||
vld:1,
|
||||
assoc_link_desc:2,
|
||||
disable_dup_detect:1,
|
||||
soft_reorder_enab:1,
|
||||
ac:2,
|
||||
bar:1,
|
||||
rty:1,
|
||||
chk_2k_mode:1,
|
||||
oor_mode:1,
|
||||
pn_check_needed:1,
|
||||
pn_even:1,
|
||||
pn_uneven:1,
|
||||
pn_hand_enab:1,
|
||||
ignore_ampdu:1;
|
||||
uint32_t ba_window_size:9,
|
||||
pn_size:8,
|
||||
svld:1,
|
||||
ssn:12,
|
||||
seq_2k_err_detect:1,
|
||||
pn_err_detect:1;
|
||||
uint32_t pn_31_0:32;
|
||||
uint32_t pn_63_32:32;
|
||||
uint32_t pn_95_64:32;
|
||||
uint32_t pn_127_96:32;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_cmd_params: Common structure to pass REO command parameters
|
||||
* @hal_reo_cmd_params_std: Standard parameters
|
||||
* @u: Union of various REO command parameters
|
||||
*/
|
||||
struct hal_reo_cmd_params {
|
||||
struct hal_reo_cmd_params_std std;
|
||||
union {
|
||||
struct hal_reo_cmd_get_queue_stats_params stats_params;
|
||||
struct hal_reo_cmd_flush_queue_params fl_queue_params;
|
||||
struct hal_reo_cmd_flush_cache_params fl_cache_params;
|
||||
struct hal_reo_cmd_unblock_cache_params unblk_cache_params;
|
||||
struct hal_reo_cmd_flush_timeout_list_params fl_tim_list_params;
|
||||
struct hal_reo_cmd_update_queue_params upd_queue_params;
|
||||
} u;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_status_header: Common REO status header
|
||||
* @cmd_num: Command number
|
||||
* @exec_time: execution time
|
||||
* @status: command execution status
|
||||
* @tstamp: Timestamp of status updated
|
||||
*/
|
||||
struct hal_reo_status_header {
|
||||
uint16_t cmd_num;
|
||||
uint16_t exec_time;
|
||||
enum reo_cmd_exec_status status;
|
||||
uint32_t tstamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_queue_status: REO queue status structure
|
||||
* @header: Common REO status header
|
||||
* @ssn: SSN of current BA window
|
||||
* @curr_idx: last forwarded pkt
|
||||
* @pn_31_0, pn_63_32, pn_95_64, pn_127_96:
|
||||
* PN number bits extracted from IV field
|
||||
* @last_rx_enq_tstamp: Last enqueue timestamp
|
||||
* @last_rx_deq_tstamp: Last dequeue timestamp
|
||||
* @rx_bitmap_31_0, rx_bitmap_63_32, rx_bitmap_95_64
|
||||
* @rx_bitmap_127_96, rx_bitmap_159_128, rx_bitmap_191_160
|
||||
* @rx_bitmap_223_192, rx_bitmap_255_224: Each bit corresonds to a frame
|
||||
* held in re-order queue
|
||||
* @curr_mpdu_cnt, curr_msdu_cnt: Number of MPDUs and MSDUs in the queue
|
||||
* @fwd_timeout_cnt: Frames forwarded due to timeout
|
||||
* @fwd_bar_cnt: Frames forwarded BAR frame
|
||||
* @dup_cnt: duplicate frames detected
|
||||
* @frms_in_order_cnt: Frames received in order
|
||||
* @bar_rcvd_cnt: BAR frame count
|
||||
* @mpdu_frms_cnt, msdu_frms_cnt, total_cnt: MPDU, MSDU, total frames
|
||||
processed by REO
|
||||
* @late_recv_mpdu_cnt; received after window had moved on
|
||||
* @win_jump_2k: 2K jump count
|
||||
* @hole_cnt: sequence hole count
|
||||
*/
|
||||
struct hal_reo_queue_status {
|
||||
struct hal_reo_status_header header;
|
||||
uint16_t ssn;
|
||||
uint8_t curr_idx;
|
||||
uint32_t pn_31_0, pn_63_32, pn_95_64, pn_127_96;
|
||||
uint32_t last_rx_enq_tstamp, last_rx_deq_tstamp;
|
||||
uint32_t rx_bitmap_31_0, rx_bitmap_63_32, rx_bitmap_95_64;
|
||||
uint32_t rx_bitmap_127_96, rx_bitmap_159_128, rx_bitmap_191_160;
|
||||
uint32_t rx_bitmap_223_192, rx_bitmap_255_224;
|
||||
uint8_t curr_mpdu_cnt, curr_msdu_cnt;
|
||||
uint8_t fwd_timeout_cnt, fwd_bar_cnt;
|
||||
uint16_t dup_cnt;
|
||||
uint32_t frms_in_order_cnt;
|
||||
uint8_t bar_rcvd_cnt;
|
||||
uint32_t mpdu_frms_cnt, msdu_frms_cnt, total_cnt;
|
||||
uint16_t late_recv_mpdu_cnt;
|
||||
uint8_t win_jump_2k;
|
||||
uint16_t hole_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_flush_queue_status: FLUSH_QUEUE status structure
|
||||
* @header: Common REO status header
|
||||
* @error: Error detected
|
||||
*/
|
||||
struct hal_reo_flush_queue_status {
|
||||
struct hal_reo_status_header header;
|
||||
bool error;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_flush_cache_status: FLUSH_CACHE status structure
|
||||
* @header: Common REO status header
|
||||
* @error: Error detected
|
||||
* @block_error: Blocking related error
|
||||
* @cache_flush_status: Cache hit/miss
|
||||
* @cache_flush_status_desc_type: type of descriptor flushed
|
||||
* @cache_flush_cnt: number of lines actually flushed
|
||||
*/
|
||||
struct hal_reo_flush_cache_status {
|
||||
struct hal_reo_status_header header;
|
||||
bool error;
|
||||
uint8_t block_error;
|
||||
bool cache_flush_status;
|
||||
uint8_t cache_flush_status_desc_type;
|
||||
uint8_t cache_flush_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_unblk_cache_status: UNBLOCK_CACHE status structure
|
||||
* @header: Common REO status header
|
||||
* @error: error detected
|
||||
* unblock_type: resoure or cache
|
||||
*/
|
||||
struct hal_reo_unblk_cache_status {
|
||||
struct hal_reo_status_header header;
|
||||
bool error;
|
||||
enum reo_unblock_cache_type unblock_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_flush_timeout_list_status: FLUSH_TIMEOUT_LIST status structure
|
||||
* @header: Common REO status header
|
||||
* @error: error detected
|
||||
* @list_empty: timeout list empty
|
||||
* @rel_desc_cnt: number of link descriptors released
|
||||
* @fwd_buf_cnt: number of buffers forwarded to REO destination ring
|
||||
*/
|
||||
struct hal_reo_flush_timeout_list_status {
|
||||
struct hal_reo_status_header header;
|
||||
bool error;
|
||||
bool list_empty;
|
||||
uint16_t rel_desc_cnt;
|
||||
uint16_t fwd_buf_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_desc_thres_reached_status: desc_thres_reached status structure
|
||||
* @header: Common REO status header
|
||||
* @thres_index: Index of descriptor threshold counter
|
||||
* @link_desc_counter0, link_desc_counter1, link_desc_counter2: descriptor
|
||||
* counter values
|
||||
* @link_desc_counter_sum: overall descriptor count
|
||||
*/
|
||||
struct hal_reo_desc_thres_reached_status {
|
||||
struct hal_reo_status_header header;
|
||||
enum reo_thres_index_reg thres_index;
|
||||
uint32_t link_desc_counter0, link_desc_counter1, link_desc_counter2;
|
||||
uint32_t link_desc_counter_sum;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_reo_update_rx_queue_status: UPDATE_RX_QUEUE status structure
|
||||
* @header: Common REO status header
|
||||
*/
|
||||
struct hal_reo_update_rx_queue_status {
|
||||
struct hal_reo_status_header header;
|
||||
};
|
||||
|
||||
/**
|
||||
* union hal_reo_status: Union to pass REO status to callbacks
|
||||
* @queue_status: Refer to struct hal_reo_queue_status
|
||||
* @fl_cache_status: Refer to struct hal_reo_flush_cache_status
|
||||
* @fl_queue_status: Refer to struct hal_reo_flush_queue_status
|
||||
* @fl_timeout_status: Refer to struct hal_reo_flush_timeout_list_status
|
||||
* @unblk_cache_status: Refer to struct hal_reo_unblk_cache_status
|
||||
* @thres_status: struct hal_reo_desc_thres_reached_status
|
||||
* @rx_queue_status: struct hal_reo_update_rx_queue_status
|
||||
*/
|
||||
union hal_reo_status {
|
||||
struct hal_reo_queue_status queue_status;
|
||||
struct hal_reo_flush_cache_status fl_cache_status;
|
||||
struct hal_reo_flush_queue_status fl_queue_status;
|
||||
struct hal_reo_flush_timeout_list_status fl_timeout_status;
|
||||
struct hal_reo_unblk_cache_status unblk_cache_status;
|
||||
struct hal_reo_desc_thres_reached_status thres_status;
|
||||
struct hal_reo_update_rx_queue_status rx_queue_status;
|
||||
};
|
||||
|
||||
/* Prototypes */
|
||||
/* REO command ring routines */
|
||||
void hal_reo_cmd_set_descr_addr(uint32_t *reo_desc,
|
||||
enum hal_reo_cmd_type type,
|
||||
uint32_t paddr_lo,
|
||||
uint8_t paddr_hi);
|
||||
int hal_reo_cmd_queue_stats(hal_ring_handle_t hal_ring_hdl,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_reo_cmd_params *cmd);
|
||||
int hal_reo_cmd_flush_queue(hal_ring_handle_t hal_ring_hdl,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_reo_cmd_params *cmd);
|
||||
int hal_reo_cmd_flush_cache(hal_ring_handle_t hal_ring_hdl,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_reo_cmd_params *cmd);
|
||||
int hal_reo_cmd_unblock_cache(hal_ring_handle_t hal_ring_hdl,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_reo_cmd_params *cmd);
|
||||
int hal_reo_cmd_flush_timeout_list(hal_ring_handle_t hal_ring_hdl,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_reo_cmd_params *cmd);
|
||||
int hal_reo_cmd_update_rx_queue(hal_ring_handle_t hal_ring_hdl,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_reo_cmd_params *cmd);
|
||||
|
||||
/* REO status ring routines */
|
||||
void hal_reo_queue_stats_status(uint32_t *reo_desc,
|
||||
struct hal_reo_queue_status *st,
|
||||
hal_soc_handle_t hal_soc_hdl);
|
||||
void hal_reo_flush_queue_status(uint32_t *reo_desc,
|
||||
struct hal_reo_flush_queue_status *st,
|
||||
hal_soc_handle_t hal_soc_hdl);
|
||||
void hal_reo_flush_cache_status(uint32_t *reo_desc,
|
||||
struct hal_reo_flush_cache_status *st,
|
||||
hal_soc_handle_t hal_soc_hdl);
|
||||
void hal_reo_unblock_cache_status(uint32_t *reo_desc,
|
||||
hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_reo_unblk_cache_status *st);
|
||||
void hal_reo_flush_timeout_list_status(
|
||||
uint32_t *reo_desc,
|
||||
struct hal_reo_flush_timeout_list_status *st,
|
||||
hal_soc_handle_t hal_soc_hdl);
|
||||
void hal_reo_desc_thres_reached_status(
|
||||
uint32_t *reo_desc,
|
||||
struct hal_reo_desc_thres_reached_status *st,
|
||||
hal_soc_handle_t hal_soc_hdl);
|
||||
void hal_reo_rx_update_queue_status(uint32_t *reo_desc,
|
||||
struct hal_reo_update_rx_queue_status *st,
|
||||
hal_soc_handle_t hal_soc_hdl);
|
||||
|
||||
void hal_reo_init_cmd_ring(hal_soc_handle_t hal_soc_hdl,
|
||||
hal_ring_handle_t hal_ring_hdl);
|
||||
|
||||
#endif /* _HAL_REO_H */
|
||||
4060
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx.h
Normal file
4060
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx.h
Normal file
File diff suppressed because it is too large
Load diff
663
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.c
Normal file
663
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.c
Normal file
|
|
@ -0,0 +1,663 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "qdf_module.h"
|
||||
#include "dp_types.h"
|
||||
#include "hal_rx_flow.h"
|
||||
|
||||
/**
|
||||
* hal_rx_flow_get_cmem_fse() - Get FSE from CMEM
|
||||
* @hal_soc_hdl: HAL SOC handle
|
||||
* @fse_offset: CMEM FSE offset
|
||||
* @fse: referece where FSE will be copied
|
||||
* @len: length of FSE
|
||||
*
|
||||
* Return: If read is succesfull or not
|
||||
*/
|
||||
static void
|
||||
hal_rx_flow_get_cmem_fse(hal_soc_handle_t hal_soc_hdl, uint32_t fse_offset,
|
||||
uint32_t *fse, qdf_size_t len)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
if (hal_soc->ops->hal_rx_flow_get_cmem_fse) {
|
||||
return hal_soc->ops->hal_rx_flow_get_cmem_fse(
|
||||
hal_soc, fse_offset, fse, len);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WLAN_SUPPORT_RX_FISA)
|
||||
static inline void hal_rx_dump_fse(struct rx_flow_search_entry *fse, int index)
|
||||
{
|
||||
dp_info("index %d:"
|
||||
" src_ip_127_96 0x%x"
|
||||
" src_ip_95_640 0x%x"
|
||||
" src_ip_63_32 0x%x"
|
||||
" src_ip_31_0 0x%x"
|
||||
" dest_ip_127_96 0x%x"
|
||||
" dest_ip_95_64 0x%x"
|
||||
" dest_ip_63_32 0x%x"
|
||||
" dest_ip_31_0 0x%x"
|
||||
" src_port 0x%x"
|
||||
" dest_port 0x%x"
|
||||
" l4_protocol 0x%x"
|
||||
" valid 0x%x"
|
||||
" reo_destination_indication 0x%x"
|
||||
" msdu_drop 0x%x"
|
||||
" reo_destination_handler 0x%x"
|
||||
" metadata 0x%x"
|
||||
" aggregation_count0x%x"
|
||||
" lro_eligible 0x%x"
|
||||
" msdu_count 0x%x"
|
||||
" msdu_byte_count 0x%x"
|
||||
" timestamp 0x%x"
|
||||
" cumulative_l4_checksum 0x%x"
|
||||
" cumulative_ip_length 0x%x"
|
||||
" tcp_sequence_number 0x%x",
|
||||
index,
|
||||
fse->src_ip_127_96,
|
||||
fse->src_ip_95_64,
|
||||
fse->src_ip_63_32,
|
||||
fse->src_ip_31_0,
|
||||
fse->dest_ip_127_96,
|
||||
fse->dest_ip_95_64,
|
||||
fse->dest_ip_63_32,
|
||||
fse->dest_ip_31_0,
|
||||
fse->src_port,
|
||||
fse->dest_port,
|
||||
fse->l4_protocol,
|
||||
fse->valid,
|
||||
fse->reo_destination_indication,
|
||||
fse->msdu_drop,
|
||||
fse->reo_destination_handler,
|
||||
fse->metadata,
|
||||
fse->aggregation_count,
|
||||
fse->lro_eligible,
|
||||
fse->msdu_count,
|
||||
fse->msdu_byte_count,
|
||||
fse->timestamp,
|
||||
fse->cumulative_l4_checksum,
|
||||
fse->cumulative_ip_length,
|
||||
fse->tcp_sequence_number);
|
||||
}
|
||||
|
||||
void hal_rx_dump_fse_table(struct hal_rx_fst *fst)
|
||||
{
|
||||
int i = 0;
|
||||
struct rx_flow_search_entry *fse =
|
||||
(struct rx_flow_search_entry *)fst->base_vaddr;
|
||||
|
||||
dp_info("Number flow table entries %d", fst->add_flow_count);
|
||||
for (i = 0; i < fst->max_entries; i++) {
|
||||
if (fse[i].valid)
|
||||
hal_rx_dump_fse(&fse[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
void hal_rx_dump_cmem_fse(hal_soc_handle_t hal_soc_hdl, uint32_t fse_offset,
|
||||
int index)
|
||||
{
|
||||
struct rx_flow_search_entry fse = {0};
|
||||
|
||||
if (!fse_offset)
|
||||
return;
|
||||
|
||||
hal_rx_flow_get_cmem_fse(hal_soc_hdl, fse_offset, (uint32_t *)&fse,
|
||||
sizeof(struct rx_flow_search_entry));
|
||||
if (fse.valid)
|
||||
hal_rx_dump_fse(&fse, index);
|
||||
}
|
||||
#else
|
||||
void hal_rx_dump_fse_table(struct hal_rx_fst *fst)
|
||||
{
|
||||
}
|
||||
|
||||
void hal_rx_dump_cmem_fse(hal_soc_handle_t hal_soc_hdl, uint32_t fse_offset,
|
||||
int index)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal_rx_flow_setup_fse() - Setup a flow search entry in HW FST
|
||||
* @fst: Pointer to the Rx Flow Search Table
|
||||
* @table_offset: offset into the table where the flow is to be setup
|
||||
* @flow: Flow Parameters
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
void *
|
||||
hal_rx_flow_setup_fse(hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_rx_fst *fst, uint32_t table_offset,
|
||||
struct hal_rx_flow *flow)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
if (hal_soc->ops->hal_rx_flow_setup_fse) {
|
||||
return hal_soc->ops->hal_rx_flow_setup_fse((uint8_t *)fst,
|
||||
table_offset,
|
||||
(uint8_t *)flow);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_flow_setup_fse);
|
||||
|
||||
/**
|
||||
* hal_rx_flow_setup_cmem_fse() - Setup a flow search entry in HW CMEM FST
|
||||
* @hal_soc_hdl: HAL SOC handle
|
||||
* @cmem_ba: CMEM base address
|
||||
* @table_offset: offset into the table where the flow is to be setup
|
||||
* @flow: Flow Parameters
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
uint32_t
|
||||
hal_rx_flow_setup_cmem_fse(hal_soc_handle_t hal_soc_hdl, uint32_t cmem_ba,
|
||||
uint32_t table_offset, struct hal_rx_flow *flow)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
if (hal_soc->ops->hal_rx_flow_setup_cmem_fse) {
|
||||
return hal_soc->ops->hal_rx_flow_setup_cmem_fse(
|
||||
hal_soc, cmem_ba,
|
||||
table_offset, (uint8_t *)flow);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_flow_setup_cmem_fse);
|
||||
|
||||
/**
|
||||
* hal_rx_flow_get_cmem_fse_timestamp() - Get timestamp field from CMEM FSE
|
||||
* @hal_soc_hdl: HAL SOC handle
|
||||
* @fse_offset: CMEM FSE offset
|
||||
*
|
||||
* Return: Timestamp
|
||||
*/
|
||||
uint32_t hal_rx_flow_get_cmem_fse_timestamp(hal_soc_handle_t hal_soc_hdl,
|
||||
uint32_t fse_offset)
|
||||
{
|
||||
struct hal_soc *hal_soc = (struct hal_soc *)hal_soc_hdl;
|
||||
|
||||
if (hal_soc->ops->hal_rx_flow_get_cmem_fse_ts) {
|
||||
return hal_soc->ops->hal_rx_flow_get_cmem_fse_ts(hal_soc,
|
||||
fse_offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_flow_get_cmem_fse_timestamp);
|
||||
|
||||
/**
|
||||
* hal_rx_flow_delete_entry() - Delete a flow from the Rx Flow Search Table
|
||||
* @fst: Pointer to the Rx Flow Search Table
|
||||
* @hal_rx_fse: Pointer to the Rx Flow that is to be deleted from the FST
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
inline QDF_STATUS
|
||||
hal_rx_flow_delete_entry(struct hal_rx_fst *fst, void *hal_rx_fse)
|
||||
{
|
||||
uint8_t *fse = (uint8_t *)hal_rx_fse;
|
||||
|
||||
if (!HAL_GET_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID))
|
||||
return QDF_STATUS_E_NOENT;
|
||||
|
||||
HAL_CLR_FLD(fse, RX_FLOW_SEARCH_ENTRY_9, VALID);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_flow_delete_entry);
|
||||
|
||||
#ifndef WLAN_SUPPORT_RX_FISA
|
||||
/**
|
||||
* hal_rx_fst_key_configure() - Configure the Toeplitz key in the FST
|
||||
* @fst: Pointer to the Rx Flow Search Table
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
static void hal_rx_fst_key_configure(struct hal_rx_fst *fst)
|
||||
{
|
||||
uint8_t key_bytes[HAL_FST_HASH_KEY_SIZE_BYTES];
|
||||
|
||||
qdf_mem_copy(key_bytes, fst->key, HAL_FST_HASH_KEY_SIZE_BYTES);
|
||||
|
||||
/**
|
||||
* The Toeplitz algorithm as per the Microsoft spec works in a
|
||||
* “big-endian” manner, using the MSBs of the key to hash the
|
||||
* initial bytes of the input going on to use up the lower order bits
|
||||
* of the key to hash further bytes of the input until the LSBs of the
|
||||
* key are used finally.
|
||||
*
|
||||
* So first, rightshift 320-bit input key 5 times to get 315 MS bits
|
||||
*/
|
||||
key_bitwise_shift_left(key_bytes, HAL_FST_HASH_KEY_SIZE_BYTES, 5);
|
||||
key_reverse(fst->shifted_key, key_bytes, HAL_FST_HASH_KEY_SIZE_BYTES);
|
||||
}
|
||||
#else
|
||||
static void hal_rx_fst_key_configure(struct hal_rx_fst *fst)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal_rx_fst_get_base() - Retrieve the virtual base address of the Rx FST
|
||||
* @fst: Pointer to the Rx Flow Search Table
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
static inline void *hal_rx_fst_get_base(struct hal_rx_fst *fst)
|
||||
{
|
||||
return fst->base_vaddr;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_rx_fst_get_fse_size() - Retrieve the size of each entry(flow) in Rx FST
|
||||
*
|
||||
* Return: size of each entry/flow in Rx FST
|
||||
*/
|
||||
static inline uint32_t hal_rx_fst_get_fse_size(void)
|
||||
{
|
||||
return HAL_RX_FST_ENTRY_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal_rx_flow_get_tuple_info() - Retrieve the 5-tuple flow info for an entry
|
||||
* @hal_fse: Pointer to the Flow in Rx FST
|
||||
* @tuple_info: 5-tuple info of the flow returned to the caller
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
QDF_STATUS hal_rx_flow_get_tuple_info(void *hal_fse,
|
||||
struct hal_flow_tuple_info *tuple_info)
|
||||
{
|
||||
if (!hal_fse || !tuple_info)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
if (!HAL_GET_FLD(hal_fse, RX_FLOW_SEARCH_ENTRY_9, VALID))
|
||||
return QDF_STATUS_E_NOENT;
|
||||
|
||||
tuple_info->src_ip_127_96 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_0,
|
||||
SRC_IP_127_96));
|
||||
tuple_info->src_ip_95_64 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_1,
|
||||
SRC_IP_95_64));
|
||||
tuple_info->src_ip_63_32 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_2,
|
||||
SRC_IP_63_32));
|
||||
tuple_info->src_ip_31_0 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_3,
|
||||
SRC_IP_31_0));
|
||||
tuple_info->dest_ip_127_96 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_4,
|
||||
DEST_IP_127_96));
|
||||
tuple_info->dest_ip_95_64 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_5,
|
||||
DEST_IP_95_64));
|
||||
tuple_info->dest_ip_63_32 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_6,
|
||||
DEST_IP_63_32));
|
||||
tuple_info->dest_ip_31_0 =
|
||||
qdf_ntohl(HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_7,
|
||||
DEST_IP_31_0));
|
||||
tuple_info->dest_port = HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_8,
|
||||
DEST_PORT);
|
||||
tuple_info->src_port = HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_8,
|
||||
SRC_PORT);
|
||||
tuple_info->l4_protocol = HAL_GET_FLD(hal_fse,
|
||||
RX_FLOW_SEARCH_ENTRY_9,
|
||||
L4_PROTOCOL);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#ifndef WLAN_SUPPORT_RX_FISA
|
||||
/**
|
||||
* hal_flow_toeplitz_create_cache() - Calculate hashes for each possible
|
||||
* byte value with the key taken as is
|
||||
*
|
||||
* @fst: FST Handle
|
||||
* @key: Hash Key
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
static void hal_flow_toeplitz_create_cache(struct hal_rx_fst *fst)
|
||||
{
|
||||
int bit;
|
||||
int val;
|
||||
int i;
|
||||
uint8_t *key = fst->shifted_key;
|
||||
|
||||
/*
|
||||
* Initialise to first 32 bits of the key; shift in further key material
|
||||
* through the loop
|
||||
*/
|
||||
uint32_t cur_key = (key[0] << 24) | (key[1] << 16) | (key[2] << 8) |
|
||||
key[3];
|
||||
|
||||
for (i = 0; i < HAL_FST_HASH_KEY_SIZE_BYTES; i++) {
|
||||
uint8_t new_key_byte;
|
||||
uint32_t shifted_key[8];
|
||||
|
||||
if (i + 4 < HAL_FST_HASH_KEY_SIZE_BYTES)
|
||||
new_key_byte = key[i + 4];
|
||||
else
|
||||
new_key_byte = 0;
|
||||
|
||||
shifted_key[0] = cur_key;
|
||||
|
||||
for (bit = 1; bit < 8; bit++) {
|
||||
/*
|
||||
* For each iteration, shift out one more bit of the
|
||||
* current key and shift in one more bit of the new key
|
||||
* material
|
||||
*/
|
||||
shifted_key[bit] = cur_key << bit |
|
||||
new_key_byte >> (8 - bit);
|
||||
}
|
||||
|
||||
for (val = 0; val < (1 << 8); val++) {
|
||||
uint32_t hash = 0;
|
||||
int mask;
|
||||
|
||||
/*
|
||||
* For each bit set in the input, XOR in
|
||||
* the appropriately shifted key
|
||||
*/
|
||||
for (bit = 0, mask = 1 << 7; bit < 8; bit++, mask >>= 1)
|
||||
if ((val & mask))
|
||||
hash ^= shifted_key[bit];
|
||||
|
||||
fst->key_cache[i][val] = hash;
|
||||
}
|
||||
|
||||
cur_key = cur_key << 8 | new_key_byte;
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void hal_flow_toeplitz_create_cache(struct hal_rx_fst *fst)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal_rx_fst_attach() - Initialize Rx flow search table in HW FST
|
||||
*
|
||||
* @qdf_dev: QDF device handle
|
||||
* @hal_fst_base_paddr: Pointer to the physical base address of the Rx FST
|
||||
* @max_entries: Max number of flows allowed in the FST
|
||||
* @max_search: Number of collisions allowed in the hash-based FST
|
||||
* @hash_key: Toeplitz key used for the hash FST
|
||||
*
|
||||
* Return:
|
||||
*/
|
||||
struct hal_rx_fst *
|
||||
hal_rx_fst_attach(qdf_device_t qdf_dev,
|
||||
uint64_t *hal_fst_base_paddr, uint16_t max_entries,
|
||||
uint16_t max_search, uint8_t *hash_key)
|
||||
{
|
||||
struct hal_rx_fst *fst = qdf_mem_malloc(sizeof(struct hal_rx_fst));
|
||||
|
||||
if (!fst) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("hal fst allocation failed,"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qdf_mem_set(fst, sizeof(struct hal_rx_fst), 0);
|
||||
|
||||
fst->key = hash_key;
|
||||
fst->max_skid_length = max_search;
|
||||
fst->max_entries = max_entries;
|
||||
fst->hash_mask = max_entries - 1;
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
||||
"HAL FST allocation %pK %d * %d\n", fst,
|
||||
fst->max_entries, HAL_RX_FST_ENTRY_SIZE);
|
||||
|
||||
fst->base_vaddr = (uint8_t *)qdf_mem_alloc_consistent(qdf_dev,
|
||||
qdf_dev->dev,
|
||||
(fst->max_entries * HAL_RX_FST_ENTRY_SIZE),
|
||||
&fst->base_paddr);
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
|
||||
"hal_rx_fst base address 0x%pK", (void *)fst->base_paddr);
|
||||
if (!fst->base_vaddr) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("hal fst->base_vaddr allocation failed"));
|
||||
qdf_mem_free(fst);
|
||||
return NULL;
|
||||
}
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG,
|
||||
(void *)fst->key, HAL_FST_HASH_KEY_SIZE_BYTES);
|
||||
|
||||
qdf_mem_set((uint8_t *)fst->base_vaddr,
|
||||
(fst->max_entries * HAL_RX_FST_ENTRY_SIZE), 0);
|
||||
|
||||
hal_rx_fst_key_configure(fst);
|
||||
hal_flow_toeplitz_create_cache(fst);
|
||||
*hal_fst_base_paddr = (uint64_t)fst->base_paddr;
|
||||
return fst;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_fst_attach);
|
||||
|
||||
/**
|
||||
* hal_rx_fst_detach() - De-init the Rx flow search table from HW
|
||||
*
|
||||
* @rx_fst: Pointer to the Rx FST
|
||||
* @qdf_dev: QDF device handle
|
||||
*
|
||||
* Return:
|
||||
*/
|
||||
void hal_rx_fst_detach(struct hal_rx_fst *rx_fst,
|
||||
qdf_device_t qdf_dev)
|
||||
{
|
||||
if (!rx_fst || !qdf_dev)
|
||||
return;
|
||||
|
||||
qdf_mem_free_consistent(qdf_dev, qdf_dev->dev,
|
||||
rx_fst->max_entries * HAL_RX_FST_ENTRY_SIZE,
|
||||
rx_fst->base_vaddr, rx_fst->base_paddr, 0);
|
||||
|
||||
qdf_mem_free(rx_fst);
|
||||
}
|
||||
qdf_export_symbol(hal_rx_fst_detach);
|
||||
|
||||
#ifndef WLAN_SUPPORT_RX_FISA
|
||||
/**
|
||||
* hal_flow_toeplitz_hash() - Calculate Toeplitz hash by using the cached key
|
||||
*
|
||||
* @hal_fst: FST Handle
|
||||
* @flow: Flow Parameters
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
uint32_t
|
||||
hal_flow_toeplitz_hash(void *hal_fst, struct hal_rx_flow *flow)
|
||||
{
|
||||
int i, j;
|
||||
uint32_t hash = 0;
|
||||
struct hal_rx_fst *fst = (struct hal_rx_fst *)hal_fst;
|
||||
uint32_t input[HAL_FST_HASH_KEY_SIZE_WORDS];
|
||||
uint8_t *tuple;
|
||||
|
||||
qdf_mem_zero(input, HAL_FST_HASH_KEY_SIZE_BYTES);
|
||||
*(uint32_t *)&input[0] = qdf_htonl(flow->tuple_info.src_ip_127_96);
|
||||
*(uint32_t *)&input[1] = qdf_htonl(flow->tuple_info.src_ip_95_64);
|
||||
*(uint32_t *)&input[2] = qdf_htonl(flow->tuple_info.src_ip_63_32);
|
||||
*(uint32_t *)&input[3] = qdf_htonl(flow->tuple_info.src_ip_31_0);
|
||||
*(uint32_t *)&input[4] = qdf_htonl(flow->tuple_info.dest_ip_127_96);
|
||||
*(uint32_t *)&input[5] = qdf_htonl(flow->tuple_info.dest_ip_95_64);
|
||||
*(uint32_t *)&input[6] = qdf_htonl(flow->tuple_info.dest_ip_63_32);
|
||||
*(uint32_t *)&input[7] = qdf_htonl(flow->tuple_info.dest_ip_31_0);
|
||||
*(uint32_t *)&input[8] = (flow->tuple_info.dest_port << 16) |
|
||||
(flow->tuple_info.src_port);
|
||||
*(uint32_t *)&input[9] = flow->tuple_info.l4_protocol;
|
||||
|
||||
tuple = (uint8_t *)input;
|
||||
QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
|
||||
tuple, sizeof(input));
|
||||
for (i = 0, j = HAL_FST_HASH_DATA_SIZE - 1;
|
||||
i < HAL_FST_HASH_KEY_SIZE_BYTES && j >= 0; i++, j--) {
|
||||
hash ^= fst->key_cache[i][tuple[j]];
|
||||
}
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_LOW,
|
||||
"Hash value %u %u truncated hash %u\n", hash,
|
||||
(hash >> 12), (hash >> 12) % (fst->max_entries));
|
||||
|
||||
hash >>= 12;
|
||||
hash &= (fst->max_entries - 1);
|
||||
|
||||
return hash;
|
||||
}
|
||||
#else
|
||||
uint32_t
|
||||
hal_flow_toeplitz_hash(void *hal_fst, struct hal_rx_flow *flow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
qdf_export_symbol(hal_flow_toeplitz_hash);
|
||||
|
||||
/**
|
||||
* hal_rx_get_hal_hash() - Retrieve hash index of a flow in the FST table
|
||||
*
|
||||
* @hal_fst: HAL Rx FST Handle
|
||||
* @flow_hash: Flow hash computed from flow tuple
|
||||
*
|
||||
* Return: hash index truncated to the size of the hash table
|
||||
*/
|
||||
uint32_t hal_rx_get_hal_hash(struct hal_rx_fst *hal_fst, uint32_t flow_hash)
|
||||
{
|
||||
uint32_t trunc_hash = flow_hash;
|
||||
|
||||
/* Take care of hash wrap around scenario */
|
||||
if (flow_hash >= hal_fst->max_entries)
|
||||
trunc_hash &= hal_fst->hash_mask;
|
||||
return trunc_hash;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_get_hal_hash);
|
||||
|
||||
/**
|
||||
* hal_rx_insert_flow_entry() - Add a flow into the FST table
|
||||
*
|
||||
* @hal_fst: HAL Rx FST Handle
|
||||
* @flow_hash: Flow hash computed from flow tuple
|
||||
* @flow_tuple_info: Flow tuple used to compute the hash
|
||||
* @flow_index: Hash index of the flow in the table when inserted successfully
|
||||
*
|
||||
* Return: Success if flow is inserted into the table, error otherwise
|
||||
*/
|
||||
QDF_STATUS
|
||||
hal_rx_insert_flow_entry(struct hal_rx_fst *fst, uint32_t flow_hash,
|
||||
void *flow_tuple_info, uint32_t *flow_idx)
|
||||
{
|
||||
int i;
|
||||
void *hal_fse = NULL;
|
||||
uint32_t hal_hash = 0;
|
||||
struct hal_flow_tuple_info hal_tuple_info = { 0 };
|
||||
QDF_STATUS status;
|
||||
|
||||
for (i = 0; i < fst->max_skid_length; i++) {
|
||||
hal_hash = hal_rx_get_hal_hash(fst, (flow_hash + i));
|
||||
hal_fse = (uint8_t *)fst->base_vaddr +
|
||||
(hal_hash * HAL_RX_FST_ENTRY_SIZE);
|
||||
status = hal_rx_flow_get_tuple_info(hal_fse, &hal_tuple_info);
|
||||
if (status == QDF_STATUS_E_NOENT)
|
||||
break;
|
||||
|
||||
/* Find the matching flow entry in HW FST */
|
||||
if (!qdf_mem_cmp(&hal_tuple_info,
|
||||
flow_tuple_info,
|
||||
sizeof(struct hal_flow_tuple_info))) {
|
||||
dp_err("Duplicate flow entry in FST %u at skid %u ",
|
||||
hal_hash, i);
|
||||
return QDF_STATUS_E_EXISTS;
|
||||
}
|
||||
}
|
||||
if (i == fst->max_skid_length) {
|
||||
dp_err("Max skid length reached for hash %u", flow_hash);
|
||||
return QDF_STATUS_E_RANGE;
|
||||
}
|
||||
*flow_idx = hal_hash;
|
||||
dp_info("flow_hash = %u, skid_entry = %d, flow_addr = %pK flow_idx = %d",
|
||||
flow_hash, i, hal_fse, *flow_idx);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_insert_flow_entry);
|
||||
|
||||
/**
|
||||
* hal_rx_find_flow_from_tuple() - Find a flow in the FST table
|
||||
*
|
||||
* @fst: HAL Rx FST Handle
|
||||
* @flow_hash: Flow hash computed from flow tuple
|
||||
* @flow_tuple_info: Flow tuple used to compute the hash
|
||||
* @flow_index: Hash index of the flow in the table when found
|
||||
*
|
||||
* Return: Success if matching flow is found in the table, error otherwise
|
||||
*/
|
||||
QDF_STATUS
|
||||
hal_rx_find_flow_from_tuple(struct hal_rx_fst *fst, uint32_t flow_hash,
|
||||
void *flow_tuple_info, uint32_t *flow_idx)
|
||||
{
|
||||
int i;
|
||||
void *hal_fse = NULL;
|
||||
uint32_t hal_hash = 0;
|
||||
struct hal_flow_tuple_info hal_tuple_info = { 0 };
|
||||
QDF_STATUS status;
|
||||
|
||||
for (i = 0; i < fst->max_skid_length; i++) {
|
||||
hal_hash = hal_rx_get_hal_hash(fst, (flow_hash + i));
|
||||
hal_fse = (uint8_t *)fst->base_vaddr +
|
||||
(hal_hash * HAL_RX_FST_ENTRY_SIZE);
|
||||
status = hal_rx_flow_get_tuple_info(hal_fse, &hal_tuple_info);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
continue;
|
||||
|
||||
/* Find the matching flow entry in HW FST */
|
||||
if (!qdf_mem_cmp(&hal_tuple_info,
|
||||
flow_tuple_info,
|
||||
sizeof(struct hal_flow_tuple_info))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == fst->max_skid_length) {
|
||||
dp_err("Max skid length reached for hash %u", flow_hash);
|
||||
return QDF_STATUS_E_RANGE;
|
||||
}
|
||||
|
||||
*flow_idx = hal_hash;
|
||||
dp_info("flow_hash = %u, skid_entry = %d, flow_addr = %pK flow_idx = %d",
|
||||
flow_hash, i, hal_fse, *flow_idx);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
qdf_export_symbol(hal_rx_find_flow_from_tuple);
|
||||
211
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.h
Normal file
211
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_rx_flow.h
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __HAL_RX_FLOW_H
|
||||
#define __HAL_RX_FLOW_H
|
||||
|
||||
#include "hal_flow.h"
|
||||
#include "wlan_cfg.h"
|
||||
#include "hal_api.h"
|
||||
#include "qdf_mem.h"
|
||||
#include "rx_flow_search_entry.h"
|
||||
#include "hal_rx_flow_info.h"
|
||||
|
||||
#define HAL_FST_HASH_KEY_SIZE_BITS 315
|
||||
#define HAL_FST_HASH_KEY_SIZE_WORDS 10
|
||||
#define HAL_FST_HASH_DATA_SIZE 37
|
||||
#define HAL_FST_HASH_MASK 0x7ffff
|
||||
#define HAL_RX_FST_ENTRY_SIZE (NUM_OF_DWORDS_RX_FLOW_SEARCH_ENTRY * 4)
|
||||
|
||||
/**
|
||||
* Four possible options for IP SA/DA prefix, currently use 0x0 which
|
||||
* maps to type 2 in HW spec
|
||||
*/
|
||||
#define HAL_FST_IP_DA_SA_PFX_TYPE_IPV4_COMPATIBLE_IPV6 2
|
||||
|
||||
#define HAL_IP_DA_SA_PREFIX_IPV4_COMPATIBLE_IPV6 0x0
|
||||
|
||||
/**
|
||||
* REO destination indication is a lower 4-bits of hash value
|
||||
* This should match the REO destination used in Rx hash based routing.
|
||||
*/
|
||||
#define HAL_REO_DEST_IND_HASH_MASK 0xF
|
||||
|
||||
/**
|
||||
* REO destinations are valid from 16-31 for Hawkeye
|
||||
* and 0-15 are not setup for SW
|
||||
*/
|
||||
#define HAL_REO_DEST_IND_START_OFFSET 0x10
|
||||
|
||||
/**
|
||||
* enum hal_rx_fse_reo_destination_handler
|
||||
* @HAL_RX_FSE_REO_DEST_FT: Use this entry's destination indication
|
||||
* @HAL_RX_FSE_REO_DEST_ASPT: Use Address Search + Peer Table's entry
|
||||
* @HAL_RX_FSE_REO_DEST_FT2: Use FT2's destination indication
|
||||
* @HAL_RX_FSE_REO_DEST_CCE: Use CCE's destination indication for this entry
|
||||
*/
|
||||
enum hal_rx_fse_reo_destination_handler {
|
||||
HAL_RX_FSE_REO_DEST_FT = 0,
|
||||
HAL_RX_FSE_REO_DEST_ASPT = 1,
|
||||
HAL_RX_FSE_REO_DEST_FT2 = 2,
|
||||
HAL_RX_FSE_REO_DEST_CCE = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* hal_rx_flow_setup_fse() - Setup a flow search entry in HW FST
|
||||
* @fst: Pointer to the Rx Flow Search Table
|
||||
* @table_offset: offset into the table where the flow is to be setup
|
||||
* @flow: Flow Parameters
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
void *
|
||||
hal_rx_flow_setup_fse(hal_soc_handle_t hal_soc_hdl,
|
||||
struct hal_rx_fst *fst, uint32_t table_offset,
|
||||
struct hal_rx_flow *flow);
|
||||
|
||||
/**
|
||||
* hal_rx_flow_setup_cmem_fse() - Setup a flow search entry in HW CMEM FST
|
||||
* @hal_soc_hdl: HAL SOC handle
|
||||
* @cmem_ba: CMEM base address
|
||||
* @table_offset: offset into the table where the flow is to be setup
|
||||
* @flow: Flow Parameters
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
uint32_t
|
||||
hal_rx_flow_setup_cmem_fse(hal_soc_handle_t hal_soc_hdl, uint32_t cmem_ba,
|
||||
uint32_t table_offset, struct hal_rx_flow *flow);
|
||||
|
||||
/**
|
||||
* hal_rx_flow_get_cmem_fse_timestamp() - Get timestamp field from CMEM FSE
|
||||
* @hal_soc_hdl: HAL SOC handle
|
||||
* @fse_offset: CMEM FSE offset
|
||||
*
|
||||
* Return: Timestamp
|
||||
*/
|
||||
uint32_t hal_rx_flow_get_cmem_fse_timestamp(hal_soc_handle_t hal_soc_hdl,
|
||||
uint32_t fse_offset);
|
||||
|
||||
/**
|
||||
* hal_rx_flow_delete_entry() - Delete a flow from the Rx Flow Search Table
|
||||
* @fst: Pointer to the Rx Flow Search Table
|
||||
* @hal_rx_fse: Pointer to the Rx Flow that is to be deleted from the FST
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
QDF_STATUS
|
||||
hal_rx_flow_delete_entry(struct hal_rx_fst *fst, void *hal_rx_fse);
|
||||
|
||||
/**
|
||||
* hal_rx_flow_get_tuple_info() - Retrieve the 5-tuple flow info for an entry
|
||||
* @hal_fse: Pointer to the Flow in Rx FST
|
||||
* @tuple_info: 5-tuple info of the flow returned to the caller
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
QDF_STATUS hal_rx_flow_get_tuple_info(void *hal_fse,
|
||||
struct hal_flow_tuple_info *tuple_info);
|
||||
|
||||
/**
|
||||
* hal_rx_fst_attach() - Initialize Rx flow search table in HW FST
|
||||
*
|
||||
* @qdf_dev: QDF device handle
|
||||
* @hal_fst_base_paddr: Pointer to the physical base address of the Rx FST
|
||||
* @max_entries: Max number of flows allowed in the FST
|
||||
* @max_search: Number of collisions allowed in the hash-based FST
|
||||
* @hash_key: Toeplitz key used for the hash FST
|
||||
*
|
||||
* Return:
|
||||
*/
|
||||
struct hal_rx_fst *
|
||||
hal_rx_fst_attach(qdf_device_t qdf_dev,
|
||||
uint64_t *hal_fst_base_paddr, uint16_t max_entries,
|
||||
uint16_t max_search, uint8_t *hash_key);
|
||||
|
||||
/**
|
||||
* hal_rx_fst_detach() - De-init the Rx flow search table from HW
|
||||
*
|
||||
* @rx_fst: Pointer to the Rx FST
|
||||
* @qdf_dev: QDF device handle
|
||||
*
|
||||
* Return:
|
||||
*/
|
||||
void hal_rx_fst_detach(struct hal_rx_fst *rx_fst, qdf_device_t qdf_dev);
|
||||
|
||||
/**
|
||||
* hal_rx_insert_flow_entry() - Add a flow into the FST table
|
||||
*
|
||||
* @hal_fst: HAL Rx FST Handle
|
||||
* @flow_hash: Flow hash computed from flow tuple
|
||||
* @flow_tuple_info: Flow tuple used to compute the hash
|
||||
* @flow_index: Hash index of the flow in the table when inserted successfully
|
||||
*
|
||||
* Return: Success if flow is inserted into the table, error otherwise
|
||||
*/
|
||||
QDF_STATUS
|
||||
hal_rx_insert_flow_entry(struct hal_rx_fst *fst, uint32_t flow_hash,
|
||||
void *flow_tuple_info, uint32_t *flow_idx);
|
||||
|
||||
/**
|
||||
* hal_rx_find_flow_from_tuple() - Find a flow in the FST table
|
||||
*
|
||||
* @fst: HAL Rx FST Handle
|
||||
* @flow_hash: Flow hash computed from flow tuple
|
||||
* @flow_tuple_info: Flow tuple used to compute the hash
|
||||
* @flow_index: Hash index of the flow in the table when found
|
||||
*
|
||||
* Return: Success if matching flow is found in the table, error otherwise
|
||||
*/
|
||||
QDF_STATUS
|
||||
hal_rx_find_flow_from_tuple(struct hal_rx_fst *fst, uint32_t flow_hash,
|
||||
void *flow_tuple_info, uint32_t *flow_idx);
|
||||
|
||||
/**
|
||||
* hal_rx_get_hal_hash() - Retrieve hash index of a flow in the FST table
|
||||
*
|
||||
* @hal_fst: HAL Rx FST Handle
|
||||
* @flow_hash: Flow hash computed from flow tuple
|
||||
*
|
||||
* Return: hash index truncated to the size of the hash table
|
||||
*/
|
||||
uint32_t hal_rx_get_hal_hash(struct hal_rx_fst *hal_fst, uint32_t flow_hash);
|
||||
|
||||
/**
|
||||
* hal_flow_toeplitz_hash() - Calculate Toeplitz hash by using the cached key
|
||||
*
|
||||
* @hal_fst: FST Handle
|
||||
* @flow: Flow Parameters
|
||||
*
|
||||
* Return: Success/Failure
|
||||
*/
|
||||
uint32_t
|
||||
hal_flow_toeplitz_hash(void *hal_fst, struct hal_rx_flow *flow);
|
||||
|
||||
void hal_rx_dump_fse_table(struct hal_rx_fst *fst);
|
||||
|
||||
/**
|
||||
* hal_rx_dump_cmem_fse() - Dump flow search table entry which is in CMEM
|
||||
* @hal_soc_hdl: HAL SOC handle
|
||||
* @fse_offset: Offset in to the CMEM where FSE is located
|
||||
* @index: FSE index
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void hal_rx_dump_cmem_fse(hal_soc_handle_t hal_soc_hdl, uint32_t fse_offset,
|
||||
int index);
|
||||
#endif /* HAL_RX_FLOW_H */
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __HAL_RX_FLOW_DEFINES_H
|
||||
#define __HAL_RX_FLOW_DEFINES_H
|
||||
|
||||
#define HAL_FST_HASH_KEY_SIZE_BYTES 40
|
||||
#define HAL_OFFSET(block, field) block ## _ ## field ## _OFFSET
|
||||
|
||||
#define HAL_RX_FST_ENTRY_SIZE (NUM_OF_DWORDS_RX_FLOW_SEARCH_ENTRY * 4)
|
||||
|
||||
/**
|
||||
* struct hal_rx_flow - Rx Flow parameters to be sent to HW
|
||||
* @tuple_info: Rx Flow 5-tuple (src & dest IP, src & dest ports, L4 protocol)
|
||||
* @reo_destination_handler: REO destination for this flow
|
||||
* @reo_destination_indication: REO indication for this flow
|
||||
* @fse_metadata: Flow metadata or tag passed to HW for marking packets
|
||||
*/
|
||||
struct hal_rx_flow {
|
||||
struct hal_flow_tuple_info tuple_info;
|
||||
uint8_t reo_destination_handler;
|
||||
uint8_t reo_destination_indication;
|
||||
uint32_t fse_metadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hal_rx_fst - HAL RX Flow search table context
|
||||
* @base_vaddr: Virtual Base address of HW FST
|
||||
* @base_paddr: Physical Base address of HW FST
|
||||
* @key: Pointer to 320-bit Key read from cfg
|
||||
* @shifted_key: Pointer to left-shifted 320-bit Key used for Toeplitz Hash
|
||||
* @max_entries : Max number of entries in flow searchh table
|
||||
* @max_skid_length : Max search length if there is hash collision
|
||||
* @hash_mask: Hash mask to apply to index into FST
|
||||
* @key_cache: Toepliz Key Cache configured key
|
||||
* @add_flow_count: Add flow count
|
||||
* @del_flow_count: Delete flow count
|
||||
*/
|
||||
struct hal_rx_fst {
|
||||
uint8_t *base_vaddr;
|
||||
qdf_dma_addr_t base_paddr;
|
||||
uint8_t *key;
|
||||
#ifndef WLAN_SUPPORT_RX_FISA
|
||||
uint8_t shifted_key[HAL_FST_HASH_KEY_SIZE_BYTES];
|
||||
uint32_t key_cache[HAL_FST_HASH_KEY_SIZE_BYTES][1 << 8];
|
||||
#endif
|
||||
uint16_t max_entries;
|
||||
uint16_t max_skid_length;
|
||||
uint16_t hash_mask;
|
||||
uint32_t add_flow_count;
|
||||
uint32_t del_flow_count;
|
||||
};
|
||||
|
||||
#endif /* HAL_RX_FLOW_DEFINES_H */
|
||||
2041
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_srng.c
Normal file
2041
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_srng.c
Normal file
File diff suppressed because it is too large
Load diff
1184
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_tx.h
Normal file
1184
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_tx.h
Normal file
File diff suppressed because it is too large
Load diff
165
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_wbm.h
Normal file
165
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/hal_wbm.h
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* hal_setup_link_idle_list - Setup scattered idle list using the
|
||||
* buffer list provided
|
||||
*
|
||||
* @hal_soc: Opaque HAL SOC handle
|
||||
* @scatter_bufs_base_paddr: Array of physical base addresses
|
||||
* @scatter_bufs_base_vaddr: Array of virtual base addresses
|
||||
* @num_scatter_bufs: Number of scatter buffers in the above lists
|
||||
* @scatter_buf_size: Size of each scatter buffer
|
||||
* @last_buf_end_offset: Offset to the last entry
|
||||
* @num_entries: Total entries of all scatter bufs
|
||||
*
|
||||
*/
|
||||
static void
|
||||
hal_setup_link_idle_list_generic(struct hal_soc *soc,
|
||||
qdf_dma_addr_t scatter_bufs_base_paddr[],
|
||||
void *scatter_bufs_base_vaddr[],
|
||||
uint32_t num_scatter_bufs,
|
||||
uint32_t scatter_buf_size,
|
||||
uint32_t last_buf_end_offset,
|
||||
uint32_t num_entries)
|
||||
{
|
||||
int i;
|
||||
uint32_t *prev_buf_link_ptr = NULL;
|
||||
uint32_t reg_scatter_buf_size, reg_tot_scatter_buf_size;
|
||||
uint32_t val;
|
||||
|
||||
/* Link the scatter buffers */
|
||||
for (i = 0; i < num_scatter_bufs; i++) {
|
||||
if (i > 0) {
|
||||
prev_buf_link_ptr[0] =
|
||||
scatter_bufs_base_paddr[i] & 0xffffffff;
|
||||
prev_buf_link_ptr[1] = HAL_SM(
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
|
||||
BASE_ADDRESS_39_32,
|
||||
((uint64_t)(scatter_bufs_base_paddr[i])
|
||||
>> 32)) | HAL_SM(
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
|
||||
ADDRESS_MATCH_TAG,
|
||||
ADDRESS_MATCH_TAG_VAL);
|
||||
}
|
||||
prev_buf_link_ptr = (uint32_t *)(scatter_bufs_base_vaddr[i] +
|
||||
scatter_buf_size - WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE);
|
||||
}
|
||||
|
||||
/* TBD: Register programming partly based on MLD & the rest based on
|
||||
* inputs from HW team. Not complete yet.
|
||||
*/
|
||||
|
||||
reg_scatter_buf_size = (scatter_buf_size -
|
||||
WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE)/64;
|
||||
reg_tot_scatter_buf_size = ((scatter_buf_size -
|
||||
WBM_IDLE_SCATTER_BUF_NEXT_PTR_SIZE) * num_scatter_bufs)/64;
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_IDLE_LIST_CONTROL_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
HAL_SM(HWIO_WBM_R0_IDLE_LIST_CONTROL, SCATTER_BUFFER_SIZE,
|
||||
reg_scatter_buf_size) |
|
||||
HAL_SM(HWIO_WBM_R0_IDLE_LIST_CONTROL, LINK_DESC_IDLE_LIST_MODE,
|
||||
0x1));
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_IDLE_LIST_SIZE_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
HAL_SM(HWIO_WBM_R0_IDLE_LIST_SIZE,
|
||||
SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST,
|
||||
reg_tot_scatter_buf_size));
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_LSB_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
scatter_bufs_base_paddr[0] & 0xffffffff);
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
((uint64_t)(scatter_bufs_base_paddr[0]) >> 32) &
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_BASE_ADDRESS_39_32_BMSK);
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
|
||||
BASE_ADDRESS_39_32, ((uint64_t)(scatter_bufs_base_paddr[0])
|
||||
>> 32)) |
|
||||
HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_LIST_BASE_MSB,
|
||||
ADDRESS_MATCH_TAG, ADDRESS_MATCH_TAG_VAL));
|
||||
|
||||
/* ADDRESS_MATCH_TAG field in the above register is expected to match
|
||||
* with the upper bits of link pointer. The above write sets this field
|
||||
* to zero and we are also setting the upper bits of link pointers to
|
||||
* zero while setting up the link list of scatter buffers above
|
||||
*/
|
||||
|
||||
/* Setup head and tail pointers for the idle list */
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX0_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
scatter_bufs_base_paddr[num_scatter_bufs-1] & 0xffffffff);
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1,
|
||||
BUFFER_ADDRESS_39_32,
|
||||
((uint64_t)(scatter_bufs_base_paddr[num_scatter_bufs-1])
|
||||
>> 32)) |
|
||||
HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX1,
|
||||
HEAD_POINTER_OFFSET, last_buf_end_offset >> 2));
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HEAD_INFO_IX0_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
scatter_bufs_base_paddr[0] & 0xffffffff);
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX0_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
scatter_bufs_base_paddr[0] & 0xffffffff);
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1,
|
||||
BUFFER_ADDRESS_39_32,
|
||||
((uint64_t)(scatter_bufs_base_paddr[0]) >>
|
||||
32)) | HAL_SM(HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_TAIL_INFO_IX1,
|
||||
TAIL_POINTER_OFFSET, 0));
|
||||
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_SCATTERED_LINK_DESC_PTR_HP_ADDR(
|
||||
SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
2*num_entries);
|
||||
|
||||
/* Set RING_ID_DISABLE */
|
||||
val = HAL_SM(HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC, RING_ID_DISABLE, 1);
|
||||
|
||||
/*
|
||||
* SRNG_ENABLE bit is not available in HWK v1 (QCA8074v1). Hence
|
||||
* check the presence of the bit before toggling it.
|
||||
*/
|
||||
#ifdef HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE_BMSK
|
||||
val |= HAL_SM(HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC, SRNG_ENABLE, 1);
|
||||
#endif
|
||||
HAL_REG_WRITE(soc,
|
||||
HWIO_WBM_R0_WBM_IDLE_LINK_RING_MISC_ADDR(SEQ_WCSS_UMAC_WBM_REG_OFFSET),
|
||||
val);
|
||||
}
|
||||
2230
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca5018/hal_5018.c
Normal file
2230
drivers/staging/qca-wifi-host-cmn/hal/wifi3.0/qca5018/hal_5018.c
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue