msm: ipa: Dual NIC IPA offload support & ipa_eth client APIs refactor

Dual NIC IPA offload feature support including vlan.
APIs refactor:
1. move the ipa_eth_conn/disconn_evt API inside ipa_eth_reg/unreg_intf.
2. deprecate the ipa_eth_conn/disconn_evt APIs.
3. add multiple eth vlan support

Change-Id: Icb769df9a3f8a650bc47914e86150d75abfb479d
Acked-by: Eliad Ben Yishay <ebenyish@qti.qualcomm.com>
Signed-off-by: Ilia Lin <ilialin@codeaurora.org>
Tento commit je obsažen v:
Ilia Lin
2021-09-02 13:23:49 +03:00
odevzdal Gerrit - the friendly Code Review server
rodič 3b0bfb100b
revize a06ad613b2
7 změnil soubory, kde provedl 364 přidání a 69 odebrání

Zobrazit soubor

@@ -38,7 +38,7 @@
OFFLOAD_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPA_ETH_PIPES_NO 6
#define IPA_ETH_PIPES_NO 8
struct ipa_eth_ready_cb_wrapper {
struct list_head link;
@@ -108,6 +108,12 @@ static u8 client_to_pipe_index(enum ipa_client_type client_type)
case IPA_CLIENT_AQC_ETHERNET_PROD:
return 5;
break;
case IPA_CLIENT_ETHERNET2_CONS:
return 6;
break;
case IPA_CLIENT_ETHERNET2_PROD:
return 7;
break;
default:
IPAERR("invalid eth client_type\n");
ipa_assert();
@@ -397,6 +403,25 @@ static enum ipa_client_type
}
}
break;
#if IPA_ETH_API_VER >= 2
case IPA_ETH_CLIENT_NTN3:
if (client->traffic_type == IPA_ETH_PIPE_BEST_EFFORT) {
if (client->inst_id == 0) {
if (pipe->dir == IPA_ETH_PIPE_DIR_TX) {
ipa_client_type = IPA_CLIENT_ETHERNET_CONS;
} else {
ipa_client_type = IPA_CLIENT_ETHERNET_PROD;
}
} else if (client->inst_id == 1) {
if (pipe->dir == IPA_ETH_PIPE_DIR_TX) {
ipa_client_type = IPA_CLIENT_ETHERNET2_CONS;
} else {
ipa_client_type = IPA_CLIENT_ETHERNET2_PROD;
}
}
}
break;
#endif
default:
IPA_ETH_ERR("invalid client type%d\n",
client->client_type);
@@ -714,7 +739,8 @@ static int ipa_eth_client_disconn_pipes_internal(struct ipa_eth_client *client)
pipe->dir);
holb.en = 1;
holb.tmr_val = 0;
ipa3_cfg_ep_holb(ipa_get_ep_mapping(ipa_eth_get_ipa_client_type_from_pipe(pipe)), &holb);
ipa3_cfg_ep_holb(ipa_get_ep_mapping(
ipa_eth_get_ipa_client_type_from_pipe(pipe)), &holb);
}
}
@@ -735,6 +761,59 @@ static int ipa_eth_client_disconn_pipes_internal(struct ipa_eth_client *client)
return 0;
}
static void ipa_eth_msg_free_cb(void *buff, u32 len, u32 type)
{
kfree(buff);
}
static int ipa_eth_client_conn_evt_internal(struct ipa_ecm_msg *msg)
{
struct ipa_msg_meta msg_meta;
struct ipa_ecm_msg *eth_msg;
int ret;
IPA_ETH_DBG("enter\n");
eth_msg = kzalloc(sizeof(*eth_msg), GFP_KERNEL);
if (eth_msg == NULL)
return -ENOMEM;
memcpy(eth_msg, msg, sizeof(struct ipa_ecm_msg));
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
msg_meta.msg_type = IPA_PERIPHERAL_CONNECT;
IPA_ETH_DBG("send IPA_PERIPHERAL_CONNECT, len:%d, buff %pK", msg_meta.msg_len, eth_msg);
ret = ipa_send_msg(&msg_meta, eth_msg, ipa_eth_msg_free_cb);
IPA_ETH_DBG("exit\n");
return ret;
}
static int ipa_eth_client_disconn_evt_internal(struct ipa_ecm_msg *msg)
{
struct ipa_msg_meta msg_meta;
struct ipa_ecm_msg *eth_msg;
int ret;
IPA_ETH_DBG("enter\n");
eth_msg = kzalloc(sizeof(*eth_msg), GFP_KERNEL);
if (eth_msg == NULL)
return -ENOMEM;
memcpy(eth_msg, msg, sizeof(struct ipa_ecm_msg));
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
msg_meta.msg_type = IPA_PERIPHERAL_DISCONNECT;
IPA_ETH_DBG("send PERIPHERAL_DISCONNECT, len:%d, buff %pK", msg_meta.msg_len, eth_msg);
ret = ipa_send_msg(&msg_meta, eth_msg, ipa_eth_msg_free_cb);
IPA_ETH_DBG("exit\n");
return ret;
}
static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
{
struct ipa_eth_intf *new_intf;
@@ -749,6 +828,13 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
struct ipa_eth_client_pipe_info *pipe;
u32 len;
int ret = 0, i;
#if IPA_ETH_API_VER >= 2
struct ipa_ecm_msg msg;
bool vlan_mode = false;
struct ipa_eth_hdr_info intf_hdr[IPA_IP_MAX];
struct ethhdr l_ethhdr[IPA_IP_MAX] = { 0 };
struct vlan_ethhdr l_vlan_ethhdr[IPA_IP_MAX] = { 0 };
#endif
if (intf == NULL) {
IPA_ETH_ERR("invalid params intf=%pK\n", intf);
@@ -758,15 +844,92 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
IPA_ETH_ERR("disconn called before register readiness\n");
return -EFAULT;
}
#if IPA_ETH_API_VER >= 2
if (!intf->client) {
IPA_ETH_ERR("invalid intf->client\n");
return -EFAULT;
}
if (!intf->client->net_dev) {
IPA_ETH_ERR("invalid netdev\n");
return -EFAULT;
}
if (!intf->net_dev)
intf->net_dev = intf->client->net_dev;
IPA_ETH_DBG("register interface for netdev %s\n", intf->net_dev->name);
/* multiple attach support */
if (strnstr(intf->net_dev->name, "eth0", strlen(intf->net_dev->name))) {
ret = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH0, &vlan_mode);
if (ret) {
IPA_ETH_ERR("Could not determine IPA VLAN mode\n");
return ret;
}
} else if (strnstr(intf->net_dev->name, "eth1", strlen(intf->net_dev->name))) {
ret = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH1, &vlan_mode);
if (ret) {
IPA_ETH_ERR("Could not determine IPA VLAN mode\n");
return ret;
}
} else {
ret = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH, &vlan_mode);
if (ret) {
IPA_ETH_ERR("Could not determine IPA VLAN mode\n");
return ret;
}
}
#else
IPA_ETH_DBG("register interface for netdev %s\n",
intf->netdev_name);
#endif
mutex_lock(&ipa_eth_ctx->lock);
list_for_each_entry(entry, &ipa_eth_ctx->head_intf_list, link)
#if IPA_ETH_API_VER >= 2
if (strcmp(entry->netdev_name, intf->net_dev->name) == 0) {
#else
if (strcmp(entry->netdev_name, intf->netdev_name) == 0) {
#endif
IPA_ETH_DBG("intf was added before.\n");
mutex_unlock(&ipa_eth_ctx->lock);
return 0;
}
#if IPA_ETH_API_VER >= 2
memset(intf_hdr, 0, sizeof(intf_hdr));
if (!vlan_mode) {
struct ethhdr *eth_h;
intf_hdr[0].hdr = (u8 *)&l_ethhdr[0];
eth_h = (struct ethhdr *) intf_hdr[0].hdr;
memcpy(&eth_h->h_source, intf->net_dev->dev_addr, ETH_ALEN);
eth_h->h_proto = htons(ETH_P_IP);
intf_hdr[0].hdr_len = ETH_HLEN;
intf_hdr[0].hdr_type = IPA_HDR_L2_ETHERNET_II;
intf_hdr[1].hdr = (u8 *)&l_ethhdr[1];
eth_h = (struct ethhdr *) intf_hdr[1].hdr;
memcpy(&eth_h->h_source, intf->net_dev->dev_addr, ETH_ALEN);
eth_h->h_proto = htons(ETH_P_IPV6);
intf_hdr[1].hdr_len = ETH_HLEN;
intf_hdr[1].hdr_type = IPA_HDR_L2_ETHERNET_II;
} else {
struct vlan_ethhdr *vlan_eth_h;
intf_hdr[0].hdr = (u8 *)&l_vlan_ethhdr[0];
vlan_eth_h = (struct vlan_ethhdr *) intf_hdr[0].hdr;
memcpy(&vlan_eth_h->h_source, intf->net_dev->dev_addr, ETH_ALEN);
vlan_eth_h->h_vlan_proto = htons(ETH_P_8021Q);
vlan_eth_h->h_vlan_encapsulated_proto = htons(ETH_P_IP);
intf_hdr[0].hdr_len = VLAN_ETH_HLEN;
intf_hdr[0].hdr_type = IPA_HDR_L2_802_1Q;
intf_hdr[1].hdr = (u8 *)&l_vlan_ethhdr[1];
vlan_eth_h = (struct vlan_ethhdr *) intf_hdr[1].hdr;
memcpy(&vlan_eth_h->h_source, intf->net_dev->dev_addr, ETH_ALEN);
vlan_eth_h->h_vlan_proto = htons(ETH_P_8021Q);
vlan_eth_h->h_vlan_encapsulated_proto = htons(ETH_P_IPV6);
intf_hdr[1].hdr_len = VLAN_ETH_HLEN;
intf_hdr[1].hdr_type = IPA_HDR_L2_802_1Q;;
}
#endif
new_intf = kzalloc(sizeof(*new_intf), GFP_KERNEL);
if (new_intf == NULL) {
IPA_ETH_ERR("fail to alloc new intf\n");
@@ -774,9 +937,14 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
return -ENOMEM;
}
INIT_LIST_HEAD(&new_intf->link);
#if IPA_ETH_API_VER >= 2
strlcpy(new_intf->netdev_name, intf->net_dev->name, sizeof(new_intf->netdev_name));
new_intf->hdr_len = intf_hdr[0].hdr_len;
#else
strlcpy(new_intf->netdev_name, intf->netdev_name,
sizeof(new_intf->netdev_name));
new_intf->hdr_len = intf->hdr[0].hdr_len;
#endif
/* add partial header */
len = sizeof(struct ipa_ioc_add_hdr) + 2 * sizeof(struct ipa_hdr_add);
hdr = kzalloc(len, GFP_KERNEL);
@@ -785,9 +953,12 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
ret = -EFAULT;
goto fail_alloc_hdr;
}
#if IPA_ETH_API_VER >= 2
if (ipa_eth_commit_partial_hdr(hdr, intf->net_dev->name, (struct ipa_eth_hdr_info *)intf_hdr)) {
#else
if (ipa_eth_commit_partial_hdr(hdr,
intf->netdev_name, intf->hdr)) {
#endif
IPA_ETH_ERR("fail to commit partial headers\n");
ret = -EFAULT;
goto fail_commit_hdr;
@@ -800,8 +971,12 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
memset(&tx, 0, sizeof(struct ipa_tx_intf));
memset(&rx, 0, sizeof(struct ipa_rx_intf));
#if IPA_ETH_API_VER >= 2
list_for_each_entry(pipe, &intf->client->pipe_list, link) {
#else
for (i = 0; i < intf->pipe_hdl_list_size; i++) {
pipe = ipa_eth_get_pipe_from_hdl(intf->pipe_hdl_list[i]);
#endif
if (pipe->dir == IPA_ETH_PIPE_DIR_TX) {
tx_client[tx.num_props] =
ipa_eth_get_ipa_client_type_from_pipe(pipe);
@@ -828,13 +1003,21 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
for (i = 0; i < tx.num_props; i++) {
tx_prop[i].ip = IPA_IP_v4;
tx_prop[i].dst_pipe = tx_client[i];
#if IPA_ETH_API_VER >= 2
tx_prop[i].hdr_l2_type = intf_hdr[0].hdr_type;
#else
tx_prop[i].hdr_l2_type = intf->hdr[0].hdr_type;
#endif
strlcpy(tx_prop[i].hdr_name, hdr->hdr[IPA_IP_v4].name,
sizeof(tx_prop[i].hdr_name));
tx_prop[i+1].ip = IPA_IP_v6;
tx_prop[i+1].dst_pipe = tx_client[i];
#if IPA_ETH_API_VER >= 2
tx_prop[i+1].hdr_l2_type = intf_hdr[1].hdr_type;
#else
tx_prop[i+1].hdr_l2_type = intf->hdr[1].hdr_type;
#endif
strlcpy(tx_prop[i+1].hdr_name, hdr->hdr[IPA_IP_v6].name,
sizeof(tx_prop[i+1].hdr_name));
}
@@ -855,16 +1038,27 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
for (i = 0; i < rx.num_props; i++) {
rx_prop[i].ip = IPA_IP_v4;
rx_prop[i].src_pipe = rx_client[i];
#if IPA_ETH_API_VER >= 2
rx_prop[i].hdr_l2_type = intf_hdr[0].hdr_type;
#else
rx_prop[i].hdr_l2_type = intf->hdr[0].hdr_type;
#endif
rx_prop[i+1].ip = IPA_IP_v6;
rx_prop[i+1].src_pipe = rx_client[i];
#if IPA_ETH_API_VER >= 2
rx_prop[i+1].hdr_l2_type = intf_hdr[1].hdr_type;
#else
rx_prop[i+1].hdr_l2_type = intf->hdr[1].hdr_type;
#endif
}
tx.num_props *= IPA_IP_MAX;
rx.num_props *= IPA_IP_MAX;
}
#if IPA_ETH_API_VER >= 2
if (ipa_register_intf(intf->net_dev->name, &tx, &rx)) {
#else
if (ipa_register_intf(intf->netdev_name, &tx, &rx)) {
#endif
IPA_ETH_ERR("fail to add interface prop\n");
ret = -EFAULT;
goto fail_commit_hdr;
@@ -876,6 +1070,14 @@ static int ipa_eth_client_reg_intf_internal(struct ipa_eth_intf_info *intf)
kfree(tx_prop);
kfree(rx_prop);
mutex_unlock(&ipa_eth_ctx->lock);
#if IPA_ETH_API_VER >= 2
if (intf->is_conn_evt) {
strlcpy(msg.name, intf->net_dev->name, sizeof(msg.name));
msg.ifindex = intf->net_dev->ifindex;
ipa_eth_client_conn_evt_internal(&msg);
}
#endif
return 0;
fail_commit_hdr:
kfree(hdr);
@@ -893,6 +1095,9 @@ static int ipa_eth_client_unreg_intf_internal(struct ipa_eth_intf_info *intf)
struct ipa_ioc_del_hdr *hdr = NULL;
struct ipa_eth_intf *entry;
struct ipa_eth_intf *next;
#if IPA_ETH_API_VER >= 2
struct ipa_ecm_msg msg;
#endif
if (intf == NULL) {
IPA_ETH_ERR("invalid params intf=%pK\n", intf);
@@ -902,12 +1107,24 @@ static int ipa_eth_client_unreg_intf_internal(struct ipa_eth_intf_info *intf)
IPA_ETH_ERR("disconn called before register readiness\n");
return -EFAULT;
}
#if IPA_ETH_API_VER >= 2
if (!intf->net_dev) {
IPA_ETH_ERR("invalid netdev\n");
return -EFAULT;
}
IPA_ETH_DBG("unregister interface for netdev %s\n", intf->net_dev->name);
#else
IPA_ETH_DBG("unregister interface for netdev %s\n",
intf->netdev_name);
#endif
mutex_lock(&ipa_eth_ctx->lock);
list_for_each_entry_safe(entry, next, &ipa_eth_ctx->head_intf_list,
link)
#if IPA_ETH_API_VER >= 2
if (strcmp(entry->netdev_name, intf->net_dev->name) == 0) {
#else
if (strcmp(entry->netdev_name, intf->netdev_name) == 0) {
#endif
len = sizeof(struct ipa_ioc_del_hdr) +
IPA_IP_MAX * sizeof(struct ipa_hdr_del);
hdr = kzalloc(len, GFP_KERNEL);
@@ -944,6 +1161,13 @@ static int ipa_eth_client_unreg_intf_internal(struct ipa_eth_intf_info *intf)
fail:
kfree(hdr);
mutex_unlock(&ipa_eth_ctx->lock);
#if IPA_ETH_API_VER >= 2
if (intf->is_conn_evt) {
strlcpy(msg.name, intf->net_dev->name, sizeof(msg.name));
msg.ifindex = intf->net_dev->ifindex;
ipa_eth_client_disconn_evt_internal(&msg);
}
#endif
return ret;
}
@@ -971,61 +1195,6 @@ static int ipa_eth_client_set_perf_profile_internal(struct ipa_eth_client *clien
return 0;
}
static void ipa_eth_msg_free_cb(void *buff, u32 len, u32 type)
{
kfree(buff);
}
static int ipa_eth_client_conn_evt_internal(struct ipa_ecm_msg *msg)
{
struct ipa_msg_meta msg_meta;
struct ipa_ecm_msg *eth_msg;
int ret;
IPADBG("enter\n");
eth_msg = kzalloc(sizeof(*eth_msg), GFP_KERNEL);
if (eth_msg == NULL)
return -ENOMEM;
memcpy(eth_msg, msg, sizeof(struct ipa_ecm_msg));
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
msg_meta.msg_type = IPA_PERIPHERAL_CONNECT;
IPADBG("send IPA_PERIPHERAL_CONNECT, len:%d, buff %pK",
msg_meta.msg_len, eth_msg);
ret = ipa_send_msg(&msg_meta, eth_msg, ipa_eth_msg_free_cb);
IPADBG("exit\n");
return ret;
}
static int ipa_eth_client_disconn_evt_internal(struct ipa_ecm_msg *msg)
{
struct ipa_msg_meta msg_meta;
struct ipa_ecm_msg *eth_msg;
int ret;
IPADBG("enter\n");
eth_msg = kzalloc(sizeof(*eth_msg), GFP_KERNEL);
if (eth_msg == NULL)
return -ENOMEM;
memcpy(eth_msg, msg, sizeof(struct ipa_ecm_msg));
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
msg_meta.msg_type = IPA_PERIPHERAL_DISCONNECT;
IPADBG("send PERIPHERAL_DISCONNECT, len:%d, buff %pK",
msg_meta.msg_len, eth_msg);
ret = ipa_send_msg(&msg_meta, eth_msg, ipa_eth_msg_free_cb);
IPADBG("exit\n");
return ret;
}
enum ipa_client_type ipa_eth_get_ipa_client_type_from_eth_type_internal(
enum ipa_eth_client_type eth_client_type, enum ipa_eth_pipe_direction dir)
{
@@ -1090,8 +1259,10 @@ void ipa_eth_register(void)
funcs.ipa_eth_client_unreg_intf = ipa_eth_client_unreg_intf_internal;
funcs.ipa_eth_client_set_perf_profile =
ipa_eth_client_set_perf_profile_internal;
#if IPA_ETH_API_VER < 2
funcs.ipa_eth_client_conn_evt = ipa_eth_client_conn_evt_internal;
funcs.ipa_eth_client_disconn_evt = ipa_eth_client_disconn_evt_internal;
#endif
funcs.ipa_eth_get_ipa_client_type_from_eth_type =
ipa_eth_get_ipa_client_type_from_eth_type_internal;
funcs.ipa_eth_client_exist = ipa_eth_client_exist_internal;

Zobrazit soubor

@@ -19,6 +19,10 @@
#include "ipa_stats.h"
#include "gsi.h"
#ifndef IPA_ETH_API_VER
#define IPA_ETH_API_VER 1
#endif
#define WARNON_RATELIMIT_BURST 1
#define IPA_RATELIMIT_BURST 1
#define IPA_EP_ARR_SIZE 2
@@ -882,10 +886,13 @@ int ipa_eth_emac_disconnect(
struct ipa_eth_client_pipe_info *pipe,
enum ipa_client_type client_type);
#if IPA_ETH_API_VER < 2
int ipa_eth_client_conn_evt(struct ipa_ecm_msg *msg);
int ipa_eth_client_disconn_evt(struct ipa_ecm_msg *msg);
#endif
/* ULSO mode Query */
bool ipa3_is_ulso_supported(void);

Zobrazit soubor

@@ -8017,6 +8017,18 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf,
if (strnstr(dbg_buff, "eth", strlen(dbg_buff)))
ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_EMAC] =
true;
#if IPA_ETH_API_VER >= 2
/* In Dual NIC mode we get "vlan: eth [eth0|eth1] [eth0|eth1]?" while device name is
"eth0" in legacy so, we set it to false to diffrentiate Dual NIC from legacy */
if (strnstr(dbg_buff, "eth0", strlen(dbg_buff))) {
ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_ETH0] = true;
ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_EMAC] = false;
}
if (strnstr(dbg_buff, "eth1", strlen(dbg_buff))){
ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_ETH1] = true;
ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_EMAC] = false;
}
#endif
if (strnstr(dbg_buff, "rndis", strlen(dbg_buff)))
ipa3_ctx->vlan_mode_iface[IPA_VLAN_IF_RNDIS] =
true;

Zobrazit soubor

@@ -880,6 +880,9 @@ static int ipa3_eth_get_prot(struct ipa_eth_client_pipe_info *pipe,
*prot = IPA_HW_PROTOCOL_RTK;
break;
case IPA_ETH_CLIENT_NTN:
#if IPA_ETH_API_VER >= 2
case IPA_ETH_CLIENT_NTN3:
#endif
*prot = IPA_HW_PROTOCOL_NTN3;
break;
case IPA_ETH_CLIENT_EMAC:
@@ -910,6 +913,9 @@ int ipa3_eth_connect(
int ch;
u64 bar_addr;
enum ipa4_hw_protocol prot;
#if IPA_ETH_API_VER >= 2
struct net_device *net_dev;
#endif
ep_idx = ipa_get_ep_mapping(client_type);
if (ep_idx == -1 || ep_idx >= IPA3_MAX_NUM_PIPES) {
@@ -931,12 +937,36 @@ int ipa3_eth_connect(
}
}
/* need enhancement for vlan support on multiple attach */
#if IPA_ETH_API_VER >= 2
net_dev = pipe->client_info->net_dev;
/* multiple attach support */
if (strnstr(net_dev->name, "eth0", strlen(net_dev->name))) {
result = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH0, &vlan_mode);
if (result) {
IPAERR("Could not determine IPA VLAN mode\n");
return result;
}
} else if (strnstr(net_dev->name, "eth1", strlen(net_dev->name))) {
result = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH1, &vlan_mode);
if (result) {
IPAERR("Could not determine IPA VLAN mode\n");
return result;
}
} else {
result = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH, &vlan_mode);
if (result) {
IPAERR("Could not determine IPA VLAN mode\n");
return result;
}
}
#else
result = ipa3_is_vlan_mode(IPA_VLAN_IF_ETH, &vlan_mode);
if (result) {
IPAERR("Could not determine IPA VLAN mode\n");
return result;
}
#endif
result = ipa3_eth_get_prot(pipe, &prot);
if (result) {

Zobrazit soubor

@@ -3438,8 +3438,10 @@ int ipa3_eth_connect(
int ipa3_eth_disconnect(
struct ipa_eth_client_pipe_info *pipe,
enum ipa_client_type client_type);
#if IPA_ETH_API_VER < 2
int ipa3_eth_client_conn_evt(struct ipa_ecm_msg *msg);
int ipa3_eth_client_disconn_evt(struct ipa_ecm_msg *msg);
#endif
void ipa3_eth_get_status(u32 client, int scratch_id,
struct ipa3_eth_error_stats *stats);
int ipa3_get_gsi_chan_info(struct gsi_chan_info *gsi_chan_info,

Zobrazit soubor

@@ -4092,7 +4092,7 @@ static const struct ipa_ep_configuration ipa3_ep_mapping
true,
IPA_DPS_HPS_SEQ_TYPE_2ND_PKT_PROCESS_PASS_NO_DEC_UCP,
QMB_MASTER_SELECT_DDR,
{ 3 , 15, 8 , 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3},
{ 3 , 7, 8 , 16, IPA_EE_AP, GSI_SMART_PRE_FETCH, 3},
IPA_TX_INSTANCE_NA },
[IPA_5_0][IPA_CLIENT_APPS_LAN_PROD] = {
true, IPA_v5_0_GROUP_DL,

Zobrazit soubor

@@ -47,6 +47,9 @@ struct ipa_test_ntn_context {
int tx_db_local;
int rx_idx;
int tx_idx;
enum ipa_client_type cons_client_type;
enum ipa_client_type prod_client_type;
int eth_client_inst_id;
};
static struct ipa_test_ntn_context *test_ntn_ctx;
@@ -101,6 +104,14 @@ struct rx_event_ring_ele
uint32_t own : 1;
}__packed;
static inline void ipa_test_ntn_set_client_params(enum ipa_client_type cons_type,
enum ipa_client_type prod_type, int inst_id)
{
test_ntn_ctx->cons_client_type = cons_type;
test_ntn_ctx->prod_client_type = prod_type;
test_ntn_ctx->eth_client_inst_id = inst_id;
}
static void ipa_test_ntn_free_dma_buff(struct ipa_mem_buffer *mem)
{
struct ipa_smmu_cb_ctx *cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
@@ -397,6 +408,8 @@ static int ipa_test_ntn_suite_setup(void **priv)
return -ENOMEM;
}
ipa_test_ntn_set_client_params(IPA_CLIENT_ETHERNET_CONS, IPA_CLIENT_ETHERNET_PROD, 0);
init_completion(&test_ntn_ctx->init_completion_obj);
/*
@@ -468,8 +481,8 @@ static void ipa_ntn_test_print_stats()
stats.u.ring[0].RingUtilCount);
/* now get gsi stats */
tx_ep = IPA_CLIENT_ETHERNET_CONS;
rx_ep = IPA_CLIENT_ETHERNET_PROD;
tx_ep = test_ntn_ctx->cons_client_type;
rx_ep = test_ntn_ctx->prod_client_type;
ipa3_eth_get_status(tx_ep, 6, &tx_stats);
ipa3_eth_get_status(rx_ep, 6, &rx_stats);
@@ -532,10 +545,23 @@ static int ipa_ntn_test_setup_pipes(void)
{
struct ipa_eth_client *client;
int ret, i;
#if IPA_ETH_API_VER >= 2
struct net_device dummy_net_dev;
unsigned char dummy_dev_addr = 1;
memset(dummy_net_dev.name, 0, sizeof(dummy_net_dev.name));
dummy_net_dev.dev_addr = &dummy_dev_addr;
test_ntn_ctx->client.client_type = IPA_ETH_CLIENT_NTN3;
test_ntn_ctx->client.inst_id = test_ntn_ctx->eth_client_inst_id;
#else
test_ntn_ctx->client.client_type = IPA_ETH_CLIENT_NTN;
test_ntn_ctx->client.inst_id = 0;
#endif
test_ntn_ctx->client.traffic_type = IPA_ETH_PIPE_BEST_EFFORT;
#if IPA_ETH_API_VER >= 2
test_ntn_ctx->client.net_dev = &dummy_net_dev;
#endif
/* RX pipe */
/* ring */
@@ -675,11 +701,26 @@ conn_failed:
static int ipa_ntn_test_reg_intf(void)
{
struct ipa_eth_intf_info intf;
#if IPA_ETH_API_VER >= 2
struct net_device dummy_net_dev;
unsigned char dummy_dev_addr[ETH_ALEN] = { 0 };
#else
char netdev_name[IPA_RESOURCE_NAME_MAX] = { 0 };
int ret = 0;
u8 hdr_content = 1;
#endif
int ret = 0;
memset(&intf, 0, sizeof(intf));
#if IPA_ETH_API_VER >= 2
memset(dummy_net_dev.name, 0, sizeof(dummy_net_dev.name));
intf.net_dev = &dummy_net_dev;
intf.net_dev->dev_addr = (unsigned char *)dummy_dev_addr;
intf.is_conn_evt = true;
snprintf(intf.net_dev->name, sizeof(intf.net_dev->name), "ntn_test");
IPA_UT_INFO("netdev name: %s strlen: %lu\n", intf.net_dev->name, strlen(intf.net_dev->name));
#else
snprintf(netdev_name, sizeof(netdev_name), "ntn_test");
intf.netdev_name = netdev_name;
IPA_UT_INFO("netdev name: %s strlen: %lu\n", intf.netdev_name,
@@ -707,13 +748,17 @@ static int ipa_ntn_test_reg_intf(void)
intf.pipe_hdl_list[0] = test_ntn_ctx->rx_pipe_info.pipe_hdl;
intf.pipe_hdl_list[1] = test_ntn_ctx->tx_pipe_info.pipe_hdl;
intf.pipe_hdl_list_size = IPA_TEST_NTN_NUM_PIPES;
#endif
ret = ipa_eth_client_reg_intf(&intf);
if (ret) {
IPA_UT_ERR("Failed to register IPA interface");
}
#if IPA_ETH_API_VER >= 2
#else
kfree(intf.pipe_hdl_list);
#endif
return ret;
}
@@ -721,13 +766,26 @@ static int ipa_ntn_test_reg_intf(void)
static int ipa_ntn_test_unreg_intf(void)
{
struct ipa_eth_intf_info intf;
#if IPA_ETH_API_VER >= 2
struct net_device dummy_net_dev;
#else
char netdev_name[IPA_RESOURCE_NAME_MAX] = { 0 };
#endif
memset(&intf, 0, sizeof(intf));
#if IPA_ETH_API_VER >= 2
memset(dummy_net_dev.name, 0, sizeof(dummy_net_dev.name));
intf.net_dev = &dummy_net_dev;
snprintf(intf.net_dev->name, sizeof(intf.net_dev->name), "ntn_test");
IPA_UT_INFO("netdev name: %s strlen: %lu\n", intf.net_dev->name, strlen(intf.net_dev->name));
#else
snprintf(netdev_name, sizeof(netdev_name), "ntn_test");
intf.netdev_name = netdev_name;
IPA_UT_INFO("netdev name: %s strlen: %lu\n", intf.netdev_name,
strlen(intf.netdev_name));
#endif
return (ipa_eth_client_unreg_intf(&intf));
}
@@ -810,7 +868,6 @@ static int ipa_ntn_send_one_packet(void)
while ((orig_rx_tail == *rx_ring_tail) ||
(orig_tx_tail == *tx_ring_tail)) {
loop_cnt++;
if (loop_cnt == 1000) {
IPA_UT_ERR("transfer timeout!\n");
IPA_UT_ERR("orig_tx_tail: %X tx_ring_db: %X\n",
@@ -957,11 +1014,11 @@ static int ipa_ntn_test_prepare_test(void)
/* configure NTN RX EP in DMA mode */
ep_cfg.mode.mode = IPA_DMA;
ep_cfg.mode.dst = IPA_CLIENT_ETHERNET_CONS;
ep_cfg.mode.dst = test_ntn_ctx->cons_client_type;
ep_cfg.seq.set_dynamic = true;
if (ipa3_cfg_ep(ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_PROD),
if (ipa3_cfg_ep(ipa_get_ep_mapping(test_ntn_ctx->prod_client_type),
&ep_cfg)) {
IPA_UT_ERR("fail to configure DMA mode.\n");
ret = -EFAULT;
@@ -1184,7 +1241,7 @@ static int ipa_ntn_send_packet_burst(void)
*/
ep_cfg_ctrl.ipa_ep_delay = true;
ret = ipa3_cfg_ep_ctrl(
ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_PROD),
ipa_get_ep_mapping(test_ntn_ctx->prod_client_type),
&ep_cfg_ctrl);
if (ret) {
IPA_UT_ERR("couldn't set delay to ETHERNET_PROD\n");
@@ -1219,7 +1276,7 @@ static int ipa_ntn_send_packet_burst(void)
msleep(20);
ep_cfg_ctrl.ipa_ep_delay = false;
ret = ipa3_cfg_ep_ctrl(
ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_PROD),
ipa_get_ep_mapping(test_ntn_ctx->prod_client_type),
&ep_cfg_ctrl);
if (ret) {
IPA_UT_ERR("couldn't unset delay to ETHERNET_PROD\n");
@@ -1374,6 +1431,17 @@ fail:
return ret;
}
static int ipa_ntn_test_clients2_multi_transfer_burst(void *priv)
{
int ret;
ipa_test_ntn_set_client_params(IPA_CLIENT_ETHERNET2_CONS, IPA_CLIENT_ETHERNET2_PROD, 1);
ret = ipa_ntn_test_multi_transfer_burst(priv);
ipa_test_ntn_set_client_params(IPA_CLIENT_ETHERNET_CONS, IPA_CLIENT_ETHERNET_PROD, 0);
return ret;
}
/* Suite definition block */
IPA_UT_DEFINE_SUITE_START(ntn, "NTN3 tests",
ipa_test_ntn_suite_setup, ipa_test_ntn_suite_teardown)
@@ -1402,6 +1470,11 @@ IPA_UT_DEFINE_SUITE_START(ntn, "NTN3 tests",
"send entire ring in one shot",
ipa_ntn_test_multi_transfer_burst,
true, IPA_HW_v5_0, IPA_HW_MAX),
IPA_UT_ADD_TEST(clients2_multi_transfer_burst,
"Clients pair 2 send entire ring in one shot",
ipa_ntn_test_clients2_multi_transfer_burst,
true, IPA_HW_v5_0, IPA_HW_MAX),
} IPA_UT_DEFINE_SUITE_END(ntn);