Merge b23ae7f5e4
on remote branch
Change-Id: If08b53e6188781fb8fac42ce0929da5a064a1330
This commit is contained in:
@@ -59,10 +59,7 @@
|
||||
* No. of filters reserving at wlan for IPA-XR usecase.
|
||||
*/
|
||||
#define NO_OF_FILTERS 2
|
||||
|
||||
static void ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler(struct work_struct *work);
|
||||
static struct workqueue_struct *wlan_flt_rsrv_wq = NULL;
|
||||
static DECLARE_DELAYED_WORK(wlan_flt_rsrv_handle, ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler);
|
||||
#define IPA_WDI_FLT_RSRV_TIMEOUT_MS 200
|
||||
|
||||
struct ipa_wdi_intf_info {
|
||||
char netdev_name[IPA_RESOURCE_NAME_MAX];
|
||||
@@ -107,7 +104,7 @@ struct ipa_wdi_opt_dpath_add_flt_handle {
|
||||
uint64_t filter_handle;
|
||||
};
|
||||
|
||||
struct ipa_wdi_opt_dpath_add_flt_handle add_flt_hndl[4];
|
||||
struct ipa_wdi_opt_dpath_add_flt_handle add_flt_hndl[MAX_STREAMS];
|
||||
|
||||
/**
|
||||
* opt_dpath_info contains fn callbacks which are set by WLAN context and
|
||||
@@ -874,23 +871,6 @@ int ipa_wdi_enable_pipes_per_inst(ipa_wdi_hdl_t hdl)
|
||||
}
|
||||
}
|
||||
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) {
|
||||
if (wlan_flt_rsrv_wq == NULL) {
|
||||
wlan_flt_rsrv_wq = create_singlethread_workqueue("wlan_flt_rsrv_wq");
|
||||
if (!wlan_flt_rsrv_wq) {
|
||||
IPA_WDI_ERR("failed to create wq\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = queue_delayed_work(wlan_flt_rsrv_wq, &wlan_flt_rsrv_handle,
|
||||
msecs_to_jiffies(QUEUE_DELAY_TIME));
|
||||
if (!ret) {
|
||||
IPA_WDI_ERR("failed to queue delayed wq\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_wdi_enable_pipes_per_inst);
|
||||
@@ -1123,6 +1103,7 @@ int ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst
|
||||
(ipa_wdi_hdl_t hdl, bool is_success)
|
||||
{
|
||||
int ret = 0;
|
||||
int flt_rsv_status = 0;
|
||||
struct ipa_wlan_opt_dp_rsrv_filter_complt_ind_msg_v01 ind;
|
||||
|
||||
if (hdl < 0 || hdl >= IPA_WDI_INST_MAX) {
|
||||
@@ -1144,7 +1125,10 @@ int ipa_wdi_opt_dpath_notify_flt_rsvd_per_inst
|
||||
}
|
||||
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) {
|
||||
ipa3_ctx->ipa_xr_wdi_flt_rsv_status = is_success;
|
||||
IPA_WDI_DBG("Received wlan flt rsv status %d\n", is_success);
|
||||
flt_rsv_status = is_success ? 1 : 0;
|
||||
atomic_set(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status, flt_rsv_status);
|
||||
complete(&ipa3_ctx->ipa_xr_wdi_flt_rsrv_success);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1169,6 +1153,7 @@ int ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst
|
||||
(ipa_wdi_hdl_t hdl, bool is_success)
|
||||
{
|
||||
int ret = 0;
|
||||
int flt_rsv_status = 0;
|
||||
struct ipa_wlan_opt_dp_remove_all_filter_complt_ind_msg_v01 ind;
|
||||
|
||||
if (hdl < 0 || hdl >= IPA_WDI_INST_MAX) {
|
||||
@@ -1182,8 +1167,13 @@ int ipa_wdi_opt_dpath_notify_flt_rlsd_per_inst
|
||||
}
|
||||
|
||||
ret = ipa_pm_deferred_deactivate(ipa_wdi_ctx_list[0]->ipa_pm_hdl);
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR)
|
||||
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR) {
|
||||
IPA_WDI_DBG("Received wlan flt rlsd status %d\n", is_success);
|
||||
flt_rsv_status = is_success ? 0 : 1;
|
||||
atomic_set(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status, flt_rsv_status);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(&ind, 0, sizeof(ind));
|
||||
ind.filter_removal_all_status.result =
|
||||
@@ -1476,6 +1466,7 @@ int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ipa_wdi_opt_dpath_flt_rsrv_cb_params rsrv_filter_req;
|
||||
int rsrv_completed;
|
||||
|
||||
memset(&rsrv_filter_req, 0, sizeof(struct ipa_wdi_opt_dpath_flt_rsrv_cb_params));
|
||||
if (!atomic_read(&opt_dpath_info[0].is_xr_opt_dp_cb_registered)) {
|
||||
@@ -1494,6 +1485,7 @@ int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
init_completion(&ipa3_ctx->ipa_xr_wdi_flt_rsrv_success);
|
||||
rsrv_filter_req.num_filters = NO_OF_FILTERS;
|
||||
ret = opt_dpath_info[0].flt_rsrv_cb(
|
||||
opt_dpath_info[0].priv, &rsrv_filter_req);
|
||||
@@ -1505,6 +1497,12 @@ int ipa_xr_wdi_opt_dpath_rsrv_filter_req(void)
|
||||
}
|
||||
|
||||
IPA_WDI_DBG("reserved filter callbacks called.\n");
|
||||
rsrv_completed = wait_for_completion_timeout(&ipa3_ctx->ipa_xr_wdi_flt_rsrv_success,
|
||||
msecs_to_jiffies(IPA_WDI_FLT_RSRV_TIMEOUT_MS));
|
||||
if (!rsrv_completed) {
|
||||
IPADBG("Timed out waiting for filter reservation notification from WLAN\n");
|
||||
return -EPERM;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_rsrv_filter_req);
|
||||
@@ -1532,8 +1530,9 @@ int ipa_xr_wdi_opt_dpath_add_filter_req(struct ipa_wdi_opt_dpath_flt_add_cb_para
|
||||
ret =
|
||||
opt_dpath_info[0].flt_add_cb
|
||||
(opt_dpath_info[0].priv, req);
|
||||
add_flt_hndl[stream_id].filter_handle = req->flt_info[0].out_hdl;
|
||||
IPA_WDI_DBG("add filter callbacks called, stream id %d\n", stream_id);
|
||||
IPA_WDI_DBG("Add filter callbacks called for stream id %d\n", stream_id);
|
||||
if (!ret)
|
||||
add_flt_hndl[stream_id].filter_handle = req->flt_info[0].out_hdl;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_add_filter_req);
|
||||
@@ -1563,7 +1562,9 @@ int ipa_xr_wdi_opt_dpath_remove_filter_req(u32 stream_id)
|
||||
|
||||
ret = opt_dpath_info[0].flt_rem_cb
|
||||
(opt_dpath_info[0].priv, &flt_rem_req);
|
||||
IPA_WDI_DBG("remove filter callbacks called, stream id %d\n", stream_id);
|
||||
IPA_WDI_DBG("Remove filter callbacks called for stream id %d\n", stream_id);
|
||||
if (!ret)
|
||||
add_flt_hndl[stream_id].filter_handle = 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_remove_filter_req);
|
||||
@@ -1606,16 +1607,6 @@ int ipa_xr_wdi_opt_dpath_remove_all_filter_req(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ipa_xr_wdi_opt_dpath_remove_all_filter_req);
|
||||
|
||||
|
||||
static void ipa_xr_wdi_opt_dpath_rsrv_filter_wq_handler(struct work_struct *work)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
res = ipa_xr_wdi_opt_dpath_rsrv_filter_req();
|
||||
if (res)
|
||||
IPAERR("Failed to reserve the filters in wlan\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up WDI IPA offload data path
|
||||
*
|
||||
@@ -1773,11 +1764,6 @@ int ipa_wdi_disconn_pipes_per_inst(ipa_wdi_hdl_t hdl)
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (wlan_flt_rsrv_wq) {
|
||||
destroy_workqueue(wlan_flt_rsrv_wq);
|
||||
wlan_flt_rsrv_wq = NULL;
|
||||
}
|
||||
|
||||
if (ipa_wdi_ctx_list[hdl]->wdi_version >= IPA_WDI_1 &&
|
||||
ipa_wdi_ctx_list[hdl]->wdi_version < IPA_WDI_3 &&
|
||||
hdl > 0) {
|
||||
@@ -1919,6 +1905,8 @@ int ipa_wdi_disable_pipes_per_inst(ipa_wdi_hdl_t hdl)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (ipa3_ctx->platform_type == IPA_PLAT_TYPE_XR)
|
||||
atomic_set(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status, 0);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ipa_wdi_disable_pipes_per_inst);
|
||||
|
@@ -131,6 +131,7 @@
|
||||
ipa3_dec_client_disable_clks_no_block(&log_info); \
|
||||
} while (0)
|
||||
|
||||
#ifdef IPA_DEBUG
|
||||
/*
|
||||
* Printing one warning message in 5 seconds if multiple warning messages
|
||||
* are coming back to back.
|
||||
@@ -146,6 +147,9 @@
|
||||
if (unlikely(rtn && __ratelimit(&_rs))) \
|
||||
WARN_ON(rtn); \
|
||||
})
|
||||
#else
|
||||
#define WARN_ON_RATELIMIT_IPA(condition) ((void)0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Printing one error message in 5 seconds if multiple error messages
|
||||
|
@@ -6789,7 +6789,7 @@ void ipa3_disable_clks(void)
|
||||
* issue on GSI FW side. We need to capture before
|
||||
* turn off the ipa clock.
|
||||
*/
|
||||
if (!ipa3_ctx->ipa_config_is_mhi) {
|
||||
if (!ipa3_ctx->ipa_config_is_mhi || (ipa3_ctx->platform_type != IPA_PLAT_TYPE_XR)) {
|
||||
type = gsi_pending_irq_type();
|
||||
if (type != -EPERM && type) {
|
||||
IPAERR("unexpected gsi irq type: %d\n", type);
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#define IPA_DBG_MAX_RULE_IN_TBL 128
|
||||
#define IPA_DBG_ACTIVE_CLIENT_BUF_SIZE ((IPA3_ACTIVE_CLIENTS_LOG_LINE_LEN \
|
||||
* IPA3_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES) + IPA_MAX_MSG_LEN)
|
||||
#define MAX_UC_BUFF_SIZE (1 * 1024UL * 1024UL)
|
||||
|
||||
#define IPA_DUMP_STATUS_FIELD(f) \
|
||||
pr_err(#f "=0x%x\n", status->f)
|
||||
@@ -144,6 +145,8 @@ static char *active_clients_buf;
|
||||
|
||||
static s8 ep_reg_idx;
|
||||
static void *ipa_ipc_low_buff;
|
||||
static u8 active_streams[MAX_STREAMS];
|
||||
static u8 active_flt_cnt;
|
||||
|
||||
|
||||
static ssize_t ipa3_read_gen_reg(struct file *file, char __user *ubuf,
|
||||
@@ -3542,6 +3545,492 @@ free_rt:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 ip_to_int(u8 a, u8 b, u8 c, u8 d)
|
||||
{
|
||||
// IP to int is first octet * 256^3 + second octet * 256^2 + third octet * 256 + fourth oct
|
||||
// Bit shifting is quicker than multiplication
|
||||
// 2^24 = 256^3, 2^16 = 256^2, 256 = 2^8
|
||||
return (a << 24) + (b << 16) + (c << 8) + d;
|
||||
}
|
||||
|
||||
static u32 string_ip_to_integer_ip(char *str_ip)
|
||||
{
|
||||
u8 a = 0, b = 0, c = 0, d = 0;
|
||||
char *found = NULL;
|
||||
u32 ip = 0;
|
||||
|
||||
if (!str_ip)
|
||||
return ip;
|
||||
|
||||
found = strsep(&str_ip, ".");
|
||||
if (!found || kstrtou8(found, 0, &a))
|
||||
goto err;
|
||||
|
||||
found = strsep(&str_ip, ".");
|
||||
if (!found || kstrtou8(found, 0, &b))
|
||||
goto err;
|
||||
|
||||
found = strsep(&str_ip, ".");
|
||||
if (!found || kstrtou8(found, 0, &c))
|
||||
goto err;
|
||||
|
||||
found = strsep(&str_ip, ".");
|
||||
if (!found || kstrtou8(found, 0, &d))
|
||||
goto err;
|
||||
|
||||
pr_info("IP ADDR -> %d.%d.%d.%d\n", a, b, c, d);
|
||||
ip = ip_to_int(a, b, c, d);
|
||||
|
||||
err:
|
||||
return ip;
|
||||
}
|
||||
|
||||
static ssize_t ipa_xr_add_flt_to_wlan(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
u32 src_ip[MAX_STREAMS] = {0};
|
||||
u32 dst_ip[MAX_STREAMS] = {0};
|
||||
u16 src_port[MAX_STREAMS] = {0};
|
||||
u16 dst_port[MAX_STREAMS] = {0};
|
||||
u8 prot[MAX_STREAMS] = {0};
|
||||
u8 num_filters = 0;
|
||||
ssize_t missing = 0;
|
||||
char *sptr = NULL;
|
||||
char *token = NULL;
|
||||
struct ipa_wdi_opt_dpath_flt_add_cb_params flt_add_req;
|
||||
int result = 0;
|
||||
u8 i = 0, j = 0, stream_id = 0;
|
||||
|
||||
if (count >= sizeof(dbg_buff))
|
||||
return -EFAULT;
|
||||
|
||||
memset(dbg_buff, 0, sizeof(dbg_buff));
|
||||
missing = copy_from_user(dbg_buff, buf, count);
|
||||
if (missing)
|
||||
return -EFAULT;
|
||||
|
||||
dbg_buff[count] = '\0';
|
||||
sptr = dbg_buff;
|
||||
|
||||
/* Getting the number of filters configured by user */
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou8(token, 0, &num_filters))
|
||||
return -EINVAL;
|
||||
|
||||
IPADBG("Number of filters %d\n", num_filters);
|
||||
|
||||
if (num_filters > MAX_STREAMS || num_filters == 0) {
|
||||
IPAERR("Number of filters is zero or more than max_streams, so it is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) {
|
||||
memset(active_streams, 0, sizeof(active_streams));
|
||||
active_flt_cnt = 0;
|
||||
}
|
||||
|
||||
if (active_flt_cnt + num_filters > MAX_STREAMS) {
|
||||
IPAERR("Active filter count of %u exceeded maximum streams of %u\n",
|
||||
active_flt_cnt, MAX_STREAMS);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_filters; i++) {
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
src_ip[i] = string_ip_to_integer_ip(token);
|
||||
if (!src_ip[i])
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
dst_ip[i] = string_ip_to_integer_ip(token);
|
||||
if (!dst_ip[i])
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
/* Range detection will be done by this API */
|
||||
if (kstrtou16(token, 0, &src_port[i]) || src_port[i] == 0)
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
/* Range detection will be done by this API */
|
||||
if (kstrtou16(token, 0, &dst_port[i]) || dst_port[i] == 0)
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou8(token, 0, &prot[i]) ||
|
||||
!(prot[i] == IPPROTO_UDP || prot[i] == IPPROTO_TCP))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) {
|
||||
result = ipa_xr_wdi_opt_dpath_rsrv_filter_req();
|
||||
if (result) {
|
||||
IPAERR("Filter reservation failed at WLAN %d\n", result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_filters; i++) {
|
||||
for (j = 0; j < MAX_STREAMS; j++) {
|
||||
if (active_streams[j] == 0) {
|
||||
stream_id = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IPADBG("Available stream id %u\n", stream_id);
|
||||
memset(&flt_add_req, 0, sizeof(struct ipa_wdi_opt_dpath_flt_add_cb_params));
|
||||
flt_add_req.num_tuples = 1;
|
||||
flt_add_req.flt_info[0].version = 0;
|
||||
flt_add_req.flt_info[0].ipv4_addr.ipv4_saddr = src_ip[i];
|
||||
flt_add_req.flt_info[0].ipv4_addr.ipv4_daddr = dst_ip[i];
|
||||
flt_add_req.flt_info[0].sport = src_port[i];
|
||||
flt_add_req.flt_info[0].dport = dst_port[i];
|
||||
flt_add_req.flt_info[0].protocol = prot[i];
|
||||
|
||||
IPADBG("IPv4 saddr:%lu, daddr:%lu IPv4 sport:%u, dport:%u protocol:%u\n",
|
||||
flt_add_req.flt_info[0].ipv4_addr.ipv4_saddr,
|
||||
flt_add_req.flt_info[0].ipv4_addr.ipv4_daddr,
|
||||
flt_add_req.flt_info[0].sport,
|
||||
flt_add_req.flt_info[0].dport,
|
||||
flt_add_req.flt_info[0].protocol);
|
||||
|
||||
result = ipa_xr_wdi_opt_dpath_add_filter_req(&flt_add_req, stream_id);
|
||||
if (result) {
|
||||
IPAERR("Failed to add filters at wlan\n");
|
||||
return -EPERM;
|
||||
}
|
||||
active_streams[stream_id] = 1;
|
||||
active_flt_cnt++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ipa_xr_remove_flt_to_wlan(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
char *sptr = NULL, *token = NULL;
|
||||
u8 flt_opt = 0;
|
||||
int result = 0;
|
||||
ssize_t missing = 0;
|
||||
|
||||
if (active_flt_cnt == 0) {
|
||||
IPAERR("No active filters to delete\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (count >= sizeof(dbg_buff))
|
||||
return -EFAULT;
|
||||
|
||||
memset(dbg_buff, 0, sizeof(dbg_buff));
|
||||
missing = copy_from_user(dbg_buff, buf, count);
|
||||
if (missing)
|
||||
return -EFAULT;
|
||||
|
||||
dbg_buff[count] = '\0';
|
||||
sptr = dbg_buff;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou8(token, 0, &flt_opt))
|
||||
return -EINVAL;
|
||||
|
||||
if (flt_opt > MAX_STREAMS) {
|
||||
IPAERR("Flt_opt is more than max_streams, so it is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) {
|
||||
IPAERR("No existing filters at wlan\n");
|
||||
memset(active_streams, 0, sizeof(active_streams));
|
||||
active_flt_cnt = 0;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* flt_opt == 0, will remove all streams filters from wlan */
|
||||
if (!flt_opt) {
|
||||
result = ipa_xr_wdi_opt_dpath_remove_all_filter_req();
|
||||
if (result) {
|
||||
IPAERR("Failed to remove all streams filters from wlan\n");
|
||||
return -EPERM;
|
||||
}
|
||||
active_flt_cnt = 0;
|
||||
memset(active_streams, 0, sizeof(active_streams));
|
||||
IPADBG("Removed all streams existing filters\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
if (active_streams[flt_opt-1] == 0) {
|
||||
IPADBG("Stream_ID: %d filter is already deleted at WLAN\n", flt_opt);
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* Based on stream ID removing filters from wlan */
|
||||
result = ipa_xr_wdi_opt_dpath_remove_filter_req(flt_opt - 1);
|
||||
if (result) {
|
||||
IPAERR("Failed to remove stream-id: %d filter from wlan\n", flt_opt);
|
||||
return -EPERM;
|
||||
}
|
||||
IPADBG("Removed stream-id: %d filter from wlan\n", flt_opt);
|
||||
active_flt_cnt--;
|
||||
active_streams[flt_opt - 1] = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPA_RTP
|
||||
static ssize_t ipa_xr_add_flt_to_ipa_wlan(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct traffic_tuple_info tuple_info;
|
||||
u32 src_ip = 0;
|
||||
u32 dst_ip = 0;
|
||||
u16 src_port = 0;
|
||||
u16 dst_port = 0;
|
||||
u8 prot = 0;
|
||||
ssize_t missing = 0;
|
||||
char *sptr = NULL, *token = NULL;
|
||||
int result = 0;
|
||||
u32 bs_buff_size = 0;
|
||||
u8 stream_id = 0;
|
||||
|
||||
struct bitstream_buffers_to_uc data;
|
||||
dma_addr_t bs_phys_base[MAX_BUFF], mb_phys_base[MAX_BUFF];
|
||||
void *bs_va[MAX_BUFF] = {NULL}, *mb_va[MAX_BUFF] = {NULL};
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) {
|
||||
memset(active_streams, 0, sizeof(active_streams));
|
||||
active_flt_cnt = 0;
|
||||
}
|
||||
|
||||
if (active_flt_cnt >= MAX_STREAMS) {
|
||||
IPAERR("Maximum filters already installed: %u\n", active_flt_cnt);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (count >= sizeof(dbg_buff))
|
||||
return -EFAULT;
|
||||
|
||||
memset(dbg_buff, 0, sizeof(dbg_buff));
|
||||
missing = copy_from_user(dbg_buff, buf, count);
|
||||
if (missing)
|
||||
return -EFAULT;
|
||||
|
||||
dbg_buff[count] = '\0';
|
||||
sptr = dbg_buff;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
src_ip = string_ip_to_integer_ip(token);
|
||||
if (!src_ip)
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
dst_ip = string_ip_to_integer_ip(token);
|
||||
if (!dst_ip)
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou16(token, 0, &src_port) || src_port == 0)
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou16(token, 0, &dst_port) || dst_port == 0)
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou8(token, 0, &prot) || prot != IPPROTO_UDP)
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou32(token, 0, &bs_buff_size) || bs_buff_size > MAX_UC_BUFF_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
for (j = 0; j < MAX_STREAMS; j++) {
|
||||
if (active_streams[j] == 0) {
|
||||
stream_id = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IPADBG("Available stream id %u\n", stream_id);
|
||||
IPADBG("Framing bitstream & Metadata buffer of size :%lu\n", bs_buff_size);
|
||||
|
||||
data.buff_cnt = MAX_BUFF;
|
||||
data.cookie = 0x1234;
|
||||
for (i = 0; i < data.buff_cnt; i++) {
|
||||
data.bs_info[i].stream_id = stream_id;
|
||||
data.bs_info[i].fence_id = i;
|
||||
bs_va[i] = dma_alloc_coherent(ipa3_ctx->rtp_pdev, bs_buff_size,
|
||||
&bs_phys_base[i], GFP_KERNEL);
|
||||
if (!bs_va[i]) {
|
||||
IPADBG("Failed to allocate bitstream buffers of size: %u\n",
|
||||
bs_buff_size);
|
||||
goto free_bs_mb_buff;
|
||||
}
|
||||
|
||||
IPADBG("Bit stream buffer va is 0x%x\n", bs_va[i]);
|
||||
IPADBG("Bit stream buffer iova is 0x%x\n", bs_phys_base[i]);
|
||||
data.bs_info[i].buff_addr = bs_phys_base[i];
|
||||
data.bs_info[i].buff_fd = 0;
|
||||
data.bs_info[i].buff_size = bs_buff_size;
|
||||
mb_va[i] = dma_alloc_coherent(ipa3_ctx->rtp_pdev, IPA_MAX_MSG_LEN,
|
||||
&mb_phys_base[i], GFP_KERNEL);
|
||||
if (!mb_va[i]) {
|
||||
IPADBG("Failed to allocate metadata buffers of size: %u\n",
|
||||
IPA_MAX_MSG_LEN);
|
||||
dma_free_coherent(ipa3_ctx->rtp_pdev, bs_buff_size,
|
||||
bs_va[i], bs_phys_base[i]);
|
||||
goto free_bs_mb_buff;
|
||||
}
|
||||
|
||||
IPADBG("Metadata buffer va is 0x%x\n", mb_va[i]);
|
||||
IPADBG("Metadata buffer iova is 0x%x\n", mb_phys_base[i]);
|
||||
data.bs_info[i].meta_buff_addr = mb_phys_base[i];
|
||||
data.bs_info[i].meta_buff_fd = 0;
|
||||
data.bs_info[i].meta_buff_size = IPA_MAX_MSG_LEN;
|
||||
}
|
||||
|
||||
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
|
||||
|
||||
result = ipa3_uc_send_add_bitstream_buffers_cmd(&data);
|
||||
if (result) {
|
||||
IPAERR("Failed to send bitstream buffers to uC\n");
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
goto free_bs_mb_buff;
|
||||
}
|
||||
|
||||
tuple_info.ts_info.no_of_openframe = 3;
|
||||
tuple_info.ts_info.max_pkt_frame = 256;
|
||||
tuple_info.ts_info.stream_type = 0;
|
||||
tuple_info.ts_info.reorder_timeout = 100;
|
||||
tuple_info.ts_info.num_slices_per_frame = 0;
|
||||
|
||||
tuple_info.ip_type = 0;
|
||||
tuple_info.ip_info.ipv4.src_port_number = src_port;
|
||||
tuple_info.ip_info.ipv4.dst_port_number = dst_port;
|
||||
tuple_info.ip_info.ipv4.src_ip = src_ip;
|
||||
tuple_info.ip_info.ipv4.dst_ip = dst_ip;
|
||||
tuple_info.ip_info.ipv4.protocol = prot;
|
||||
|
||||
IPADBG("IPv4 saddr:0x%x, daddr:0x%x\n",
|
||||
tuple_info.ip_info.ipv4.src_ip,
|
||||
tuple_info.ip_info.ipv4.dst_ip);
|
||||
IPADBG("IPv4 sport:%u, dport:%u\n",
|
||||
tuple_info.ip_info.ipv4.src_port_number,
|
||||
tuple_info.ip_info.ipv4.dst_port_number);
|
||||
|
||||
if (ipa3_install_rtp_hdr_proc_rt_flt_rules(&tuple_info, stream_id) ||
|
||||
ipa3_tuple_info_cmd_to_wlan_uc(&tuple_info, stream_id)) {
|
||||
IPAERR("Failed to install rtp hdr proc and flt rules or filters at WLAN\n");
|
||||
ipa3_delete_rtp_hdr_proc_rt_flt_rules(stream_id);
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
goto free_bs_mb_buff;
|
||||
}
|
||||
active_flt_cnt++;
|
||||
active_streams[stream_id] = 1;
|
||||
IPADBG("Sent bitstream and metadata buffer, filter info to uC or WLAN\n");
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
|
||||
return count;
|
||||
|
||||
free_bs_mb_buff:
|
||||
/* ith bs_buff is already freed above */
|
||||
for (j = i-1; j >= 0; j--) {
|
||||
if (bs_va[j])
|
||||
dma_free_coherent(ipa3_ctx->rtp_pdev, bs_buff_size,
|
||||
bs_va[j], bs_phys_base[j]);
|
||||
if (mb_va[j])
|
||||
dma_free_coherent(ipa3_ctx->rtp_pdev, IPA_MAX_MSG_LEN,
|
||||
mb_va[j], mb_phys_base[j]);
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static ssize_t ipa_xr_remove_flt_to_ipa_wlan(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
char *sptr = NULL, *token = NULL;
|
||||
u8 stream_id = 0;
|
||||
ssize_t missing = 0;
|
||||
struct remove_bitstream_buffers rmv_sid_req;
|
||||
|
||||
if (active_flt_cnt == 0) {
|
||||
IPAERR("No active filters to delete\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) {
|
||||
IPAERR("No existing filters at wlan\n");
|
||||
memset(active_streams, 0, sizeof(active_streams));
|
||||
active_flt_cnt = 0;
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (count >= sizeof(dbg_buff))
|
||||
return -EFAULT;
|
||||
|
||||
memset(dbg_buff, 0, sizeof(dbg_buff));
|
||||
missing = copy_from_user(dbg_buff, buf, count);
|
||||
if (missing)
|
||||
return -EFAULT;
|
||||
|
||||
dbg_buff[count] = '\0';
|
||||
sptr = dbg_buff;
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou8(token, 0, &stream_id))
|
||||
return -EINVAL;
|
||||
|
||||
if (stream_id > MAX_STREAMS || stream_id == 0) {
|
||||
IPAERR("Stream_id is zero or more than %u. Exit\n", MAX_STREAMS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
|
||||
|
||||
rmv_sid_req.stream_id = stream_id;
|
||||
if (ipa3_uc_send_remove_stream_cmd(&rmv_sid_req) ||
|
||||
ipa3_delete_rtp_hdr_proc_rt_flt_rules(stream_id - 1)) {
|
||||
IPADBG("Failed to remove stream id: %d filters from IPA and WLAN\n", stream_id);
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
active_streams[stream_id - 1] = 0;
|
||||
active_flt_cnt--;
|
||||
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
|
||||
IPADBG("Removed stream id: %d filters from IPA and WLAN\n", stream_id);
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct ipa3_debugfs_file debugfs_files[] = {
|
||||
{
|
||||
"gen_reg", IPA_READ_ONLY_MODE, NULL, {
|
||||
@@ -3777,6 +4266,24 @@ static const struct ipa3_debugfs_file debugfs_files[] = {
|
||||
"ipa_loopback_on_ipa", IPA_READ_ONLY_MODE, NULL, {
|
||||
.read = ipa3_perform_loopback,
|
||||
}
|
||||
}, {
|
||||
"xr_wlan_add_flt", IPA_WRITE_ONLY_MODE, NULL, {
|
||||
.write = ipa_xr_add_flt_to_wlan
|
||||
}
|
||||
}, {
|
||||
"xr_wlan_rmv_flt", IPA_WRITE_ONLY_MODE, NULL, {
|
||||
.write = ipa_xr_remove_flt_to_wlan,
|
||||
}
|
||||
#if defined(CONFIG_IPA_RTP)
|
||||
}, {
|
||||
"xr_ipa_wlan_add_flt", IPA_WRITE_ONLY_MODE, NULL, {
|
||||
.write = ipa_xr_add_flt_to_ipa_wlan,
|
||||
}
|
||||
}, {
|
||||
"xr_ipa_wlan_rmv_flt", IPA_WRITE_ONLY_MODE, NULL, {
|
||||
.write = ipa_xr_remove_flt_to_ipa_wlan,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -579,7 +579,7 @@ enum {
|
||||
/* XR-IPA uC no. of temp buffers */
|
||||
#define NO_OF_BUFFS 0x04
|
||||
/* Max number of RTP streams supported */
|
||||
#define MAX_STREAMS 4
|
||||
#define MAX_STREAMS 2
|
||||
|
||||
/* miscellaneous for rmnet_ipa and qmi_service */
|
||||
enum ipa_type_mode {
|
||||
@@ -2439,7 +2439,8 @@ struct ipa3_context {
|
||||
bool ipa_wdi2_over_gsi;
|
||||
bool ipa_wdi3_over_gsi;
|
||||
bool ipa_wdi_opt_dpath;
|
||||
bool ipa_xr_wdi_flt_rsv_status;
|
||||
atomic_t ipa_xr_wdi_flt_rsv_status;
|
||||
struct completion ipa_xr_wdi_flt_rsrv_success;
|
||||
u8 rtp_stream_id_cnt;
|
||||
u32 rtp_proc_hdls[MAX_STREAMS];
|
||||
u32 rtp_rt4_tbl_hdls[MAX_STREAMS];
|
||||
@@ -3862,5 +3863,6 @@ int ipa3_create_hfi_send_uc(void);
|
||||
int ipa3_allocate_uc_pipes_er_tr_send_to_uc(void);
|
||||
void ipa3_free_uc_temp_buffs(unsigned int no_of_buffs);
|
||||
void ipa3_free_uc_pipes_er_tr(void);
|
||||
int ipa3_uc_send_add_bitstream_buffers_cmd(struct bitstream_buffers_to_uc *data);
|
||||
#endif
|
||||
#endif /* _IPA3_I_H_ */
|
||||
|
@@ -24,7 +24,7 @@
|
||||
.flags = 0, \
|
||||
}
|
||||
|
||||
static u8 si[MAX_STREAMS];
|
||||
static u8 ipa_rtp_active_streams[MAX_STREAMS];
|
||||
|
||||
static struct nla_policy ipa_rtp_genl_attr_policy[IPA_RTP_GENL_ATTR_MAX + 1] = {
|
||||
[IPA_RTP_GENL_ATTR_STR] = { .type = NLA_NUL_STRING, .len = IPA_RTP_GENL_MAX_STR_LEN },
|
||||
@@ -119,7 +119,6 @@ static int ipa3_rtp_del_flt_rule(u32 stream_id)
|
||||
struct ipa3_ep_context *ep;
|
||||
struct ipa_ioc_del_flt_rule *rtp_del_flt_rule = NULL;
|
||||
|
||||
IPADBG("Deleting rtp filter rules of stream_id: %u\n", stream_id);
|
||||
rtp_del_flt_rule = kzalloc(sizeof(*rtp_del_flt_rule) +
|
||||
1 * sizeof(struct ipa_flt_rule_del), GFP_KERNEL);
|
||||
if (!rtp_del_flt_rule) {
|
||||
@@ -130,7 +129,10 @@ static int ipa3_rtp_del_flt_rule(u32 stream_id)
|
||||
|
||||
ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_WLAN2_PROD);
|
||||
ep = &ipa3_ctx->ep[ipa_ep_idx];
|
||||
if (ep->rtp_flt4_rule_hdls[stream_id]) {
|
||||
|
||||
/* check whether filter rule hdl is deleted or not */
|
||||
if (ep->rtp_flt4_rule_hdls[stream_id] != -1) {
|
||||
IPADBG("Deleting rtp filter rules of stream_id: %u\n", stream_id);
|
||||
rtp_del_flt_rule->commit = 1;
|
||||
rtp_del_flt_rule->ip = 0;
|
||||
rtp_del_flt_rule->num_hdls = 1;
|
||||
@@ -141,7 +143,7 @@ static int ipa3_rtp_del_flt_rule(u32 stream_id)
|
||||
rc = -EPERM;
|
||||
return rc;
|
||||
}
|
||||
ep->rtp_flt4_rule_hdls[stream_id] = 0;
|
||||
ep->rtp_flt4_rule_hdls[stream_id] = -1;
|
||||
}
|
||||
|
||||
kfree(rtp_del_flt_rule);
|
||||
@@ -153,7 +155,6 @@ static int ipa3_rtp_del_rt_rule(u32 stream_id)
|
||||
int rc = 0;
|
||||
struct ipa_ioc_del_rt_rule *rtp_del_rt_rule = NULL;
|
||||
|
||||
IPADBG("Deleting rtp route rules of stream_id: %u\n", stream_id);
|
||||
rtp_del_rt_rule = kzalloc(sizeof(*rtp_del_rt_rule) +
|
||||
1 * sizeof(struct ipa_rt_rule_del), GFP_KERNEL);
|
||||
if (!rtp_del_rt_rule) {
|
||||
@@ -162,7 +163,9 @@ static int ipa3_rtp_del_rt_rule(u32 stream_id)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ipa3_ctx->rtp_rt4_rule_hdls[stream_id]) {
|
||||
/* check whether route rule hdl is deleted or not */
|
||||
if (ipa3_ctx->rtp_rt4_rule_hdls[stream_id] != -1) {
|
||||
IPADBG("Deleting rtp route rules of stream_id: %u\n", stream_id);
|
||||
rtp_del_rt_rule->commit = 1;
|
||||
rtp_del_rt_rule->ip = 0;
|
||||
rtp_del_rt_rule->num_hdls = 1;
|
||||
@@ -187,7 +190,6 @@ static int ipa3_rtp_del_hdr_proc_ctx(u32 stream_id)
|
||||
struct ipa_ioc_del_hdr_proc_ctx *rtp_del_proc_ctx = NULL;
|
||||
struct ipa_hdr_proc_ctx_del *rtp_del_proc_ctx_entry = NULL;
|
||||
|
||||
IPADBG("Deleting rtp hdr proc ctx of stream_id: %u\n", stream_id);
|
||||
buf_size = (sizeof(struct ipa_ioc_del_hdr_proc_ctx) +
|
||||
(sizeof(struct ipa_hdr_proc_ctx_del)));
|
||||
rtp_del_proc_ctx = kzalloc(buf_size, GFP_KERNEL);
|
||||
@@ -197,7 +199,9 @@ static int ipa3_rtp_del_hdr_proc_ctx(u32 stream_id)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ipa3_ctx->rtp_proc_hdls[stream_id]) {
|
||||
/* check whether hdr proc ctx hdl is deleted or not */
|
||||
if (ipa3_ctx->rtp_proc_hdls[stream_id] != -1) {
|
||||
IPADBG("Deleting rtp hdr proc ctx of stream_id: %u\n", stream_id);
|
||||
rtp_del_proc_ctx_entry = &(rtp_del_proc_ctx->hdl[0]);
|
||||
rtp_del_proc_ctx->commit = 1;
|
||||
rtp_del_proc_ctx->num_hdls = 1;
|
||||
@@ -526,16 +530,15 @@ int ipa_rtp_tuple_info_req_hdlr(struct sk_buff *skb_2,
|
||||
memset(&tuple_info_resp, 0, sizeof(tuple_info_resp));
|
||||
|
||||
for (i = 0; i < MAX_STREAMS; i++) {
|
||||
if (si[i] == 0) {
|
||||
if (ipa_rtp_active_streams[i] == 0) {
|
||||
tuple_info_resp.stream_id = i;
|
||||
si[i] = 1;
|
||||
stream_id_available = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stream_id_available) {
|
||||
IPAERR("max stream-ids supported are four only\n");
|
||||
IPAERR("max stream-ids supported are %u only\n", MAX_STREAMS);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -543,17 +546,20 @@ int ipa_rtp_tuple_info_req_hdlr(struct sk_buff *skb_2,
|
||||
if (ipa3_install_rtp_hdr_proc_rt_flt_rules(&tuple_info_req, tuple_info_resp.stream_id) ||
|
||||
ipa3_tuple_info_cmd_to_wlan_uc(&tuple_info_req, tuple_info_resp.stream_id)) {
|
||||
IPAERR("failed to install hdr proc and flt rules or filters at WLAN\n");
|
||||
ipa3_delete_rtp_hdr_proc_rt_flt_rules(tuple_info_resp.stream_id);
|
||||
return rc;
|
||||
}
|
||||
|
||||
ipa_rtp_active_streams[tuple_info_resp.stream_id] = 1;
|
||||
|
||||
if (is_req_valid &&
|
||||
ipa_rtp_send_tuple_info_resp(info, &tuple_info_resp)) {
|
||||
ipa_rtp_send_tuple_info_resp(info, &tuple_info_resp)) {
|
||||
IPAERR("failed in sending stream_id response\n");
|
||||
memset(&rmv_sid_req, 0, sizeof(rmv_sid_req));
|
||||
rmv_sid_req.stream_id = tuple_info_resp.stream_id;
|
||||
ipa3_uc_send_remove_stream_cmd(&rmv_sid_req);
|
||||
ipa3_delete_rtp_hdr_proc_rt_flt_rules(rmv_sid_req.stream_id);
|
||||
si[tuple_info_resp.stream_id] = 0;
|
||||
ipa_rtp_active_streams[tuple_info_resp.stream_id] = 0;
|
||||
} else
|
||||
rc = 0;
|
||||
|
||||
@@ -865,7 +871,7 @@ int ipa_rtp_rmv_stream_id_req_hdlr(struct sk_buff *skb_2,
|
||||
return rc;
|
||||
}
|
||||
|
||||
si[rmv_sid_req.stream_id] = 0;
|
||||
ipa_rtp_active_streams[rmv_sid_req.stream_id] = 0;
|
||||
ipa3_ctx->rtp_stream_id_cnt--;
|
||||
|
||||
IPADBG("Exit\n");
|
||||
|
@@ -69,6 +69,24 @@ struct remove_bitstream_buffers {
|
||||
uint32_t stream_id;
|
||||
};
|
||||
|
||||
struct bitstream_buffer_info_to_uc {
|
||||
uint8_t stream_id;
|
||||
uint16_t fence_id;
|
||||
uint8_t reserved;
|
||||
u64 buff_addr;
|
||||
u32 buff_fd;
|
||||
u32 buff_size;
|
||||
u64 meta_buff_addr;
|
||||
u32 meta_buff_fd;
|
||||
u32 meta_buff_size;
|
||||
} __packed;
|
||||
|
||||
struct bitstream_buffers_to_uc {
|
||||
uint16_t buff_cnt;
|
||||
uint16_t cookie;
|
||||
struct bitstream_buffer_info_to_uc bs_info[MAX_BUFF];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct traffic_selector_info - traffic selector information.
|
||||
* @no_of_openframe: no. of openframes in a stream.
|
||||
|
@@ -25,8 +25,6 @@
|
||||
#define MAX_UC_PROD_PIPES_ER_INDEX (MAX_UC_PROD_PIPES_TR_INDEX + MAX_UC_PROD_PIPES)
|
||||
#define MAX_UC_CONS_PIPES_TR_INDEX (MAX_UC_PROD_PIPES_ER_INDEX + MAX_UC_CONS_PIPES)
|
||||
|
||||
#define ER_TR_UC_BUFFS (MAX_UC_PROD_PIPES + MAX_UC_PROD_PIPES + MAX_UC_CONS_PIPES)
|
||||
|
||||
#define MAX_SYNX_FENCE_SESSION_NAME 64
|
||||
#define DMA_DIR DMA_BIDIRECTIONAL
|
||||
|
||||
@@ -60,24 +58,6 @@ enum ipa3_cpu_2_hw_rtp_commands {
|
||||
FEATURE_ENUM_VAL(IPA_HW_FEATURE_RTP, 11),
|
||||
};
|
||||
|
||||
struct bitstream_buffer_info_to_uc {
|
||||
uint8_t stream_id;
|
||||
uint16_t fence_id;
|
||||
uint8_t reserved;
|
||||
u64 buff_addr;
|
||||
u32 buff_fd;
|
||||
u32 buff_size;
|
||||
u64 meta_buff_addr;
|
||||
u32 meta_buff_fd;
|
||||
u32 meta_buff_size;
|
||||
} __packed;
|
||||
|
||||
struct bitstream_buffers_to_uc {
|
||||
uint16_t buff_cnt;
|
||||
uint16_t cookie;
|
||||
struct bitstream_buffer_info_to_uc bs_info[MAX_BUFF];
|
||||
} __packed;
|
||||
|
||||
struct dma_address_map_table {
|
||||
struct dma_buf *dma_buf_list[2];
|
||||
struct dma_buf_attachment *attachment[2];
|
||||
@@ -105,17 +85,15 @@ struct prod_pipe_tre {
|
||||
} __packed;
|
||||
|
||||
struct con_pipe_tre {
|
||||
uint64_t buffer_ptr;
|
||||
uint16_t buf_len;
|
||||
uint16_t resvd1;
|
||||
uint16_t chain:1;
|
||||
uint16_t resvd4:7;
|
||||
uint16_t ieob:1;
|
||||
uint16_t ieot:1;
|
||||
uint16_t bei:1;
|
||||
uint16_t resvd3:5;
|
||||
uint8_t re_type;
|
||||
uint8_t resvd2;
|
||||
uint16_t bufferIndex;
|
||||
uint16_t offset2Payload;
|
||||
uint16_t payloadSize:16;
|
||||
uint8_t valid:1;
|
||||
uint8_t ieot:1;
|
||||
uint8_t tre_type:2;
|
||||
uint8_t reserved0:4;
|
||||
uint8_t last_tre:1;
|
||||
uint8_t reserved1:7;
|
||||
} __packed;
|
||||
|
||||
struct temp_buff_info {
|
||||
@@ -131,7 +109,7 @@ struct rtp_pipe_setup_cmd_data {
|
||||
|
||||
struct hfi_queue_info {
|
||||
u64 hfi_queue_addr;
|
||||
u32 hfi_queue_size;
|
||||
u32 hfi_queue_payload_size;
|
||||
u64 queue_header_start_addr;
|
||||
u64 queue_payload_start_addr;
|
||||
} __packed;
|
||||
@@ -147,9 +125,13 @@ struct uc_temp_buffer_info {
|
||||
} __packed;
|
||||
|
||||
struct er_tr_to_free {
|
||||
void *cpu_address[ER_TR_UC_BUFFS];
|
||||
void *cpu_address_prod_tr[MAX_UC_PROD_PIPES];
|
||||
void *cpu_address_prod_er[MAX_UC_PROD_PIPES];
|
||||
void *cpu_address_cons_tr[MAX_UC_CONS_PIPES];
|
||||
struct rtp_pipe_setup_cmd_data rtp_tr_er;
|
||||
uint16_t no_buffs;
|
||||
uint8_t prod_tr_no_buffs;
|
||||
uint8_t prod_er_no_buffs;
|
||||
uint8_t cons_tr_no_buffs;
|
||||
} __packed;
|
||||
|
||||
struct er_tr_to_free er_tr_cpu_addresses;
|
||||
@@ -222,9 +204,8 @@ int ipa3_tuple_info_cmd_to_wlan_uc(struct traffic_tuple_info *req, u32 stream_id
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ipa3_ctx->ipa_xr_wdi_flt_rsv_status) {
|
||||
if (!atomic_read(&ipa3_ctx->ipa_xr_wdi_flt_rsv_status)) {
|
||||
result = ipa_xr_wdi_opt_dpath_rsrv_filter_req();
|
||||
ipa3_ctx->ipa_xr_wdi_flt_rsv_status = !result;
|
||||
if (result) {
|
||||
IPAERR("filter reservation failed at WLAN %d\n", result);
|
||||
return result;
|
||||
@@ -264,18 +245,20 @@ int ipa3_tuple_info_cmd_to_wlan_uc(struct traffic_tuple_info *req, u32 stream_id
|
||||
flt_add_req.flt_info[0].ipv6_addr.ipv6_daddr[3]);
|
||||
}
|
||||
|
||||
result = ipa3_uc_send_tuple_info_cmd(req);
|
||||
if (result) {
|
||||
IPAERR("Fail to send tuple info cmd to uc\n");
|
||||
return -EPERM;
|
||||
}
|
||||
else
|
||||
IPADBG("send tuple info cmd to uc succeeded\n");
|
||||
|
||||
result = ipa_xr_wdi_opt_dpath_add_filter_req(&flt_add_req, stream_id);
|
||||
if (result) {
|
||||
IPAERR("Fail to send tuple info cmd to wlan\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
result = ipa3_uc_send_tuple_info_cmd(req);
|
||||
if (result)
|
||||
IPAERR("Fail to send tuple info cmd to uc\n");
|
||||
else
|
||||
IPADBG("send tuple info cmd to uc succeeded\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -291,8 +274,10 @@ int ipa3_uc_send_remove_stream_cmd(struct remove_bitstream_buffers *data)
|
||||
}
|
||||
|
||||
result = ipa_xr_wdi_opt_dpath_remove_filter_req(data->stream_id);
|
||||
if (result)
|
||||
if (result) {
|
||||
IPAERR("Failed to remove wlan filter of stream ID %d\n", data->stream_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
cmd.size = sizeof(*cmd_data);
|
||||
cmd.base = dma_alloc_coherent(ipa3_ctx->uc_pdev, cmd.size,
|
||||
@@ -513,8 +498,8 @@ static int ipa3_uc_setup_prod_pipe_transfer_ring(
|
||||
|
||||
rtp_cmd_data->uc_prod_tr[idx].temp_buff_pa = ring.phys_base;
|
||||
rtp_cmd_data->uc_prod_tr[idx].temp_buff_size = ring.size;
|
||||
er_tr_cpu_addresses.cpu_address[er_tr_cpu_addresses.no_buffs] = ring.base;
|
||||
er_tr_cpu_addresses.no_buffs += 1;
|
||||
er_tr_cpu_addresses.cpu_address_prod_tr[idx] = ring.base;
|
||||
er_tr_cpu_addresses.prod_tr_no_buffs += 1;
|
||||
IPADBG("prod pipe transfer ring setup done\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -539,8 +524,8 @@ static int ipa3_uc_setup_prod_pipe_event_ring(
|
||||
|
||||
rtp_cmd_data->uc_prod_er[index].temp_buff_pa = ring.phys_base;
|
||||
rtp_cmd_data->uc_prod_er[index].temp_buff_size = ring.size;
|
||||
er_tr_cpu_addresses.cpu_address[er_tr_cpu_addresses.no_buffs] = ring.base;
|
||||
er_tr_cpu_addresses.no_buffs += 1;
|
||||
er_tr_cpu_addresses.cpu_address_prod_er[index] = ring.base;
|
||||
er_tr_cpu_addresses.prod_er_no_buffs += 1;
|
||||
IPADBG("prod pipe event ring setup done\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -565,45 +550,35 @@ static int ipa3_uc_setup_con_pipe_transfer_ring(
|
||||
|
||||
rtp_cmd_data->uc_cons_tr[index].temp_buff_pa = ring.phys_base;
|
||||
rtp_cmd_data->uc_cons_tr[index].temp_buff_size = ring.size;
|
||||
er_tr_cpu_addresses.cpu_address[er_tr_cpu_addresses.no_buffs] = ring.base;
|
||||
er_tr_cpu_addresses.no_buffs += 1;
|
||||
er_tr_cpu_addresses.cpu_address_cons_tr[index] = ring.base;
|
||||
er_tr_cpu_addresses.cons_tr_no_buffs += 1;
|
||||
IPADBG("con pipe transfer ring setup done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ipa3_free_uc_pipes_er_tr(void)
|
||||
{
|
||||
uint16_t index = 0;
|
||||
uint8_t index = 0;
|
||||
|
||||
for (index = 0; index < er_tr_cpu_addresses.no_buffs; index++) {
|
||||
if (index < MAX_UC_PROD_PIPES_TR_INDEX) {
|
||||
dma_free_coherent(ipa3_ctx->uc_pdev,
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_size,
|
||||
er_tr_cpu_addresses.cpu_address[index],
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_pa);
|
||||
} else if (index >= MAX_UC_PROD_PIPES_TR_INDEX &&
|
||||
index < MAX_UC_PROD_PIPES_ER_INDEX) {
|
||||
/* subtracting MAX_UC_PROD_TR_INDEX here because,
|
||||
* uc_prod_er[] is of size MAX_UC_PROD_PIPES only
|
||||
*/
|
||||
dma_free_coherent(ipa3_ctx->uc_pdev,
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index
|
||||
-MAX_UC_PROD_PIPES_TR_INDEX].temp_buff_size,
|
||||
er_tr_cpu_addresses.cpu_address[index],
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index
|
||||
-MAX_UC_PROD_PIPES_TR_INDEX].temp_buff_pa);
|
||||
} else if (index >= MAX_UC_PROD_PIPES_ER_INDEX &&
|
||||
index < MAX_UC_CONS_PIPES_TR_INDEX) {
|
||||
/* subtracting MAX_UC_PROD_TR_INDEX here because,
|
||||
* uc_cons_tr[] is of size MAX_UC_CONS_PIPES only
|
||||
*/
|
||||
dma_free_coherent(ipa3_ctx->uc_pdev,
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index
|
||||
-MAX_UC_PROD_PIPES_ER_INDEX].temp_buff_size,
|
||||
er_tr_cpu_addresses.cpu_address[index],
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index
|
||||
-MAX_UC_PROD_PIPES_ER_INDEX].temp_buff_pa);
|
||||
}
|
||||
for (index = 0; index < er_tr_cpu_addresses.prod_tr_no_buffs; index++) {
|
||||
dma_free_coherent(ipa3_ctx->uc_pdev,
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_size,
|
||||
er_tr_cpu_addresses.cpu_address_prod_tr[index],
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_tr[index].temp_buff_pa);
|
||||
}
|
||||
|
||||
for (index = 0; index < er_tr_cpu_addresses.prod_er_no_buffs; index++) {
|
||||
dma_free_coherent(ipa3_ctx->uc_pdev,
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index].temp_buff_size,
|
||||
er_tr_cpu_addresses.cpu_address_prod_er[index],
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_prod_er[index].temp_buff_pa);
|
||||
}
|
||||
|
||||
for (index = 0; index < er_tr_cpu_addresses.cons_tr_no_buffs; index++) {
|
||||
dma_free_coherent(ipa3_ctx->uc_pdev,
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index].temp_buff_size,
|
||||
er_tr_cpu_addresses.cpu_address_cons_tr[index],
|
||||
er_tr_cpu_addresses.rtp_tr_er.uc_cons_tr[index].temp_buff_pa);
|
||||
}
|
||||
|
||||
IPADBG("freed uc pipes er and tr memory\n");
|
||||
@@ -1053,6 +1028,7 @@ int ipa3_create_hfi_send_uc(void)
|
||||
struct hfi_queue_info data;
|
||||
dma_addr_t hfi_queue_addr = 0;
|
||||
struct ipa_smmu_cb_ctx *cb = NULL;
|
||||
struct synx_hw_fence_hfi_queue_header *hfi_queue_payload_vptr = NULL;
|
||||
|
||||
snprintf(synx_session_name, MAX_SYNX_FENCE_SESSION_NAME, "ipa synx fence");
|
||||
queue_desc.vaddr = NULL;
|
||||
@@ -1086,11 +1062,15 @@ int ipa3_create_hfi_send_uc(void)
|
||||
|
||||
hfi_queue_addr = queue_desc.dev_addr;
|
||||
data.hfi_queue_addr = hfi_queue_addr;
|
||||
data.hfi_queue_size = queue_desc.size;
|
||||
data.queue_header_start_addr = hfi_queue_addr +
|
||||
sizeof(struct synx_hw_fence_hfi_queue_table_header);
|
||||
data.queue_payload_start_addr = data.queue_header_start_addr +
|
||||
sizeof(struct synx_hw_fence_hfi_queue_header);
|
||||
hfi_queue_payload_vptr = (struct synx_hw_fence_hfi_queue_header *)(queue_desc.vaddr +
|
||||
sizeof(struct synx_hw_fence_hfi_queue_table_header));
|
||||
data.hfi_queue_payload_size = hfi_queue_payload_vptr->queue_size;
|
||||
IPADBG("hfi queue payload vptr is 0x%x\n", hfi_queue_payload_vptr);
|
||||
IPADBG("hfi queue payload size is 0x%x\n", data.hfi_queue_payload_size);
|
||||
res = ipa3_uc_send_hfi_cmd(&data);
|
||||
return res;
|
||||
}
|
||||
|
@@ -3959,9 +3959,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this,
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP)
|
||||
case SUBSYS_BEFORE_DS_ENTRY:
|
||||
#endif
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0))
|
||||
case QCOM_SSR_BEFORE_SHUTDOWN:
|
||||
#else
|
||||
@@ -3990,17 +3987,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this,
|
||||
ipa3_odl_pipe_cleanup_from_ssr();
|
||||
IPAWANINFO("IPA BEFORE_SHUTDOWN handling is complete\n");
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP)
|
||||
case SUBSYS_AFTER_DS_ENTRY:
|
||||
IPAWANINFO("IPA Received AFTER DEEPSLEEP ENTRY\n");
|
||||
if (atomic_read(&rmnet_ipa3_ctx->is_ssr) &&
|
||||
ipa3_ctx_get_type(IPA_HW_TYPE) < IPA_HW_v4_0)
|
||||
ipa3_q6_post_shutdown_cleanup();
|
||||
|
||||
IPAWANINFO("AFTER DEEPSLEEP ENTRY handling is complete\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0))
|
||||
case QCOM_SSR_AFTER_SHUTDOWN:
|
||||
#else
|
||||
@@ -4027,21 +4013,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this,
|
||||
ipa3_client_prod_post_shutdown_cleanup();
|
||||
IPAWANINFO("IPA AFTER_SHUTDOWN handling is complete\n");
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP)
|
||||
case SUBSYS_BEFORE_DS_EXIT:
|
||||
IPAWANINFO("IPA received BEFORE DEEPSLEEP EXIT\n");
|
||||
if (atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
|
||||
/* clean up cached QMI msg/handlers */
|
||||
ipa3_qmi_service_exit();
|
||||
ipa3_q6_pre_powerup_cleanup();
|
||||
}
|
||||
/* hold a proxy vote for the modem. */
|
||||
ipa3_proxy_clk_vote(atomic_read(&rmnet_ipa3_ctx->is_ssr));
|
||||
ipa3_reset_freeze_vote();
|
||||
IPAWANINFO("BEFORE DEEPSLEEP EXIT handling is complete\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0))
|
||||
case QCOM_SSR_BEFORE_POWERUP:
|
||||
#else
|
||||
@@ -4058,9 +4029,6 @@ static int ipa3_lcl_mdm_ssr_notifier_cb(struct notifier_block *this,
|
||||
ipa3_reset_freeze_vote();
|
||||
IPAWANINFO("IPA BEFORE_POWERUP handling is complete\n");
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_DEEPSLEEP)
|
||||
case SUBSYS_AFTER_DS_EXIT:
|
||||
#endif
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0))
|
||||
case QCOM_SSR_AFTER_POWERUP:
|
||||
#else
|
||||
|
Reference in New Issue
Block a user