Merge 02194073f2 on remote branch

Change-Id: Ife68585f7979d8a9db574c95d5c1db7c765e1967
This commit is contained in:
Linux Build Service Account 2024-07-13 05:52:08 -07:00
commit 07b7842e81
19 changed files with 375 additions and 216 deletions

View file

@ -347,6 +347,7 @@ CONFIG_SERIAL_MSM=y
CONFIG_QCOM_EUD=y
CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE=y
CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_DEFAULT=y
CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_NODUMP=y
CONFIG_POWER_RESET_QCOM_REBOOT_REASON=y
CONFIG_POWER_RESET_MSM=y
CONFIG_QCOM_MINIDUMP=y

View file

@ -207,6 +207,25 @@ void qcom_scm_set_download_mode(enum qcom_download_mode mode,
}
EXPORT_SYMBOL(qcom_scm_set_download_mode);
int qcom_scm_get_download_mode(unsigned int *mode, phys_addr_t tcsr_boot_misc)
{
int ret = -EINVAL;
struct device *dev = __scm ? __scm->dev : NULL;
if (tcsr_boot_misc || (__scm && __scm->dload_mode_addr)) {
ret = qcom_scm_io_readl(tcsr_boot_misc ? : __scm->dload_mode_addr, mode);
} else {
dev_err(dev,
"No available mechanism for getting download mode\n");
}
if (ret)
dev_err(dev, "failed to get download mode: %d\n", ret);
return ret;
}
EXPORT_SYMBOL_GPL(qcom_scm_get_download_mode);
int qcom_scm_config_cpu_errata(void)
{
return __qcom_scm_config_cpu_errata(__scm->dev);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/debugfs.h>
@ -601,8 +602,6 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
if (drawctxt != NULL && kgsl_context_detached(&drawctxt->base))
return -ENOENT;
trace_adreno_drawctxt_switch(rb, drawctxt);
/* Get a refcount to the new instance */
if (drawctxt) {
if (!_kgsl_context_get(&drawctxt->base))
@ -616,7 +615,7 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
ret = adreno_iommu_set_pt_ctx(rb, new_pt, drawctxt);
if (ret)
return ret;
goto err;
if (rb->drawctxt_active) {
/* Wait for the timestamp to expire */
@ -626,7 +625,12 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
kgsl_context_put(&rb->drawctxt_active->base);
}
}
trace_adreno_drawctxt_switch(rb, drawctxt);
rb->drawctxt_active = drawctxt;
return 0;
err:
if (drawctxt)
kgsl_context_put(&drawctxt->base);
return ret;
}

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/slab.h>
@ -353,63 +353,6 @@ static unsigned int __add_curr_ctxt_cmds(struct adreno_ringbuffer *rb,
return cmds - cmds_orig;
}
/**
* _set_ctxt_gpu() - Add commands to set the current context in memstore
* @rb: The ringbuffer in which commands to set memstore are added
* @drawctxt: The context whose id is being set in memstore
*/
static int _set_ctxt_gpu(struct adreno_ringbuffer *rb,
struct adreno_context *drawctxt)
{
unsigned int link[15], *cmds;
int result;
cmds = &link[0];
cmds += __add_curr_ctxt_cmds(rb, cmds, drawctxt);
result = adreno_ringbuffer_issue_internal_cmds(rb, 0, link,
(unsigned int)(cmds - link));
return result;
}
/**
* _set_pagetable_gpu() - Use GPU to switch the pagetable
* @rb: The rb in which commands to switch pagetable are to be
* submitted
* @new_pt: The pagetable to switch to
*/
static int _set_pagetable_gpu(struct adreno_ringbuffer *rb,
struct kgsl_pagetable *new_pt)
{
struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb);
unsigned int *link = NULL, count;
int result;
link = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (link == NULL)
return -ENOMEM;
/* If we are in a fault the MMU will be reset soon */
if (test_bit(ADRENO_DEVICE_FAULT, &adreno_dev->priv)) {
kfree(link);
return 0;
}
count = adreno_iommu_set_pt_generate_cmds(rb, link, new_pt);
WARN(count > (PAGE_SIZE / sizeof(unsigned int)),
"Temp command buffer overflow\n");
/*
* This returns the per context timestamp but we need to
* use the global timestamp for iommu clock disablement
*/
result = adreno_ringbuffer_issue_internal_cmds(rb,
KGSL_CMD_FLAGS_PMODE, link, count);
kfree(link);
return result;
}
/**
* adreno_iommu_init() - Adreno iommu init
* @adreno_dev: Adreno device
@ -443,7 +386,6 @@ void adreno_iommu_init(struct adreno_device *adreno_dev)
/**
* adreno_iommu_set_pt_ctx() - Change the pagetable of the current RB
* @device: Pointer to device to which the rb belongs
* @rb: The RB pointer on which pagetable is to be changed
* @new_pt: The new pt the device will change to
* @drawctxt: The context whose pagetable the ringbuffer is switching to,
@ -458,21 +400,34 @@ int adreno_iommu_set_pt_ctx(struct adreno_ringbuffer *rb,
struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb);
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct kgsl_pagetable *cur_pt = device->mmu.defaultpagetable;
unsigned int *cmds = NULL, count = 0;
int result = 0;
cmds = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (cmds == NULL)
return -ENOMEM;
/* Switch the page table if a MMU is attached */
if (kgsl_mmu_get_mmutype(device) != KGSL_MMU_TYPE_NONE) {
if (rb->drawctxt_active)
cur_pt = rb->drawctxt_active->base.proc_priv->pagetable;
/* Pagetable switch */
/* Add commands for pagetable switch */
if (new_pt != cur_pt)
result = _set_pagetable_gpu(rb, new_pt);
count += adreno_iommu_set_pt_generate_cmds(rb, cmds, new_pt);
if (result)
return result;
}
/* Context switch */
return _set_ctxt_gpu(rb, drawctxt);
/* Add commands to set the current context in memstore */
count += __add_curr_ctxt_cmds(rb, cmds + count, drawctxt);
WARN(count > (PAGE_SIZE / sizeof(unsigned int)),
"Temp command buffer overflow\n");
result = adreno_ringbuffer_issue_internal_cmds(rb, KGSL_CMD_FLAGS_PMODE,
cmds, count);
kfree(cmds);
return result;
}

View file

@ -2334,6 +2334,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s);
/*
* QPS615 PCIe-PCI bridge devices cause AER timeout errors on the upstream
* PCIe root port when L0s is enabled in CPE platform with SDX65.
* Disable L0s for both QPS615 and SDX65 when QPS615 switch is
* present.
*/
static void quirk_disable_aspm_qps615_l0s(struct pci_dev *dev)
{
struct pci_dev *p;
pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
p = pci_get_device(PCI_VENDOR_ID_QCOM, 0x0308, NULL);
pci_disable_link_state(p, PCIE_LINK_STATE_L0S);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA, 0x0623, quirk_disable_aspm_qps615_l0s);
static void quirk_disable_aspm_l0s_l1(struct pci_dev *dev)
{
pci_info(dev, "Disabling ASPM L0s/L1\n");

View file

@ -132,6 +132,16 @@ config POWER_RESET_QCOM_DOWNLOAD_MODE_DEFAULT
Say Y here to enable "download mode" by default.
config POWER_RESET_QCOM_DOWNLOAD_MODE_NODUMP
bool "MSM download mode as nodump"
depends on POWER_RESET_QCOM_DOWNLOAD_MODE
help
Support MSM boards to be able to set nodump as download mode,
when unexpected warm-restart is called, so that device will
not go into ramdump path.
Say N if not sure.
config POWER_RESET_QCOM_PON
tristate "Qualcomm power-on driver"
depends on ARCH_QCOM

View file

@ -203,6 +203,11 @@ static ssize_t dload_mode_show(struct kobject *kobj,
case QCOM_DOWNLOAD_BOTHDUMP:
mode = "both";
break;
#ifdef CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_NODUMP
case QCOM_DOWNLOAD_NODUMP:
mode = "nodump";
break;
#endif
default:
mode = "unknown";
break;
@ -214,6 +219,17 @@ static ssize_t dload_mode_store(struct kobject *kobj,
const char *buf, size_t count)
{
enum qcom_download_mode mode;
#ifdef CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_NODUMP
int temp;
dump_mode = qcom_scm_get_download_mode(&temp, 0) ? dump_mode : temp;
if (dump_mode == QCOM_DOWNLOAD_NODUMP) {
pr_err("%s: Current dump mode already set: nodump\n", __func__);
pr_err("%s: Changing dump mode now is not allowed, reboot the device\n", __func__);
return -EINVAL;
}
#endif
if (sysfs_streq(buf, "full"))
mode = QCOM_DOWNLOAD_FULLDUMP;
@ -221,9 +237,19 @@ static ssize_t dload_mode_store(struct kobject *kobj,
mode = QCOM_DOWNLOAD_MINIDUMP;
else if (sysfs_streq(buf, "both"))
mode = QCOM_DOWNLOAD_BOTHDUMP;
#ifdef CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_NODUMP
else if (sysfs_streq(buf, "nodump")) {
mode = QCOM_DOWNLOAD_NODUMP;
qcom_scm_disable_sdi();
}
#endif
else {
pr_err("Invalid dump mode request...\n");
#ifdef CONFIG_POWER_RESET_QCOM_DOWNLOAD_MODE_NODUMP
pr_err("Supported dumps: 'full', 'mini', 'both' or 'nodump'\n");
#else
pr_err("Supported dumps: 'full', 'mini', or 'both'\n");
#endif
return -EINVAL;
}

View file

@ -2,6 +2,7 @@
/*
* Copyright (c) 2016-2017, Linaro Ltd
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/idr.h>
@ -354,6 +355,38 @@ static void qcom_glink_channel_release(struct kref *ref)
kfree(channel);
}
static struct glink_channel *qcom_glink_channel_ref_get(
struct qcom_glink *glink,
bool remote_channel, int cid)
{
struct glink_channel *channel = NULL;
unsigned long flags;
if (!glink)
return NULL;
spin_lock_irqsave(&glink->idr_lock, flags);
if (remote_channel)
channel = idr_find(&glink->rcids, cid);
else
channel = idr_find(&glink->lcids, cid);
if (channel)
kref_get(&channel->refcount);
spin_unlock_irqrestore(&glink->idr_lock, flags);
return channel;
}
static void qcom_glink_channel_ref_put(struct glink_channel *channel)
{
if (!channel)
return;
kref_put(&channel->refcount, qcom_glink_channel_release);
}
static size_t qcom_glink_rx_avail(struct qcom_glink *glink)
{
return glink->rx_pipe->avail(glink->rx_pipe);
@ -505,11 +538,8 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
unsigned int cid, bool granted)
{
struct glink_channel *channel;
unsigned long flags;
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
channel = qcom_glink_channel_ref_get(glink, true, cid);
if (!channel) {
dev_err(glink->dev, "unable to find channel\n");
return;
@ -519,6 +549,7 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink,
atomic_inc(&channel->intent_req_acked);
wake_up(&channel->intent_req_ack);
CH_INFO(channel, "\n");
qcom_glink_channel_ref_put(channel);
}
/**
@ -867,9 +898,7 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
struct glink_channel *channel;
unsigned long flags;
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
channel = qcom_glink_channel_ref_get(glink, true, cid);
if (!channel) {
dev_err(glink->dev, "invalid channel id received\n");
return;
@ -881,6 +910,7 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
if (!intent) {
spin_unlock_irqrestore(&channel->intent_lock, flags);
dev_err(glink->dev, "invalid intent id received\n");
qcom_glink_channel_ref_put(channel);
return;
}
@ -892,6 +922,7 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink,
kfree(intent);
}
spin_unlock_irqrestore(&channel->intent_lock, flags);
qcom_glink_channel_ref_put(channel);
}
/**
@ -914,9 +945,7 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
unsigned long flags;
int iid;
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
channel = qcom_glink_channel_ref_get(glink, true, cid);
if (!channel) {
pr_err("%s channel not found for cid %d\n", __func__, cid);
@ -933,6 +962,7 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
spin_unlock_irqrestore(&channel->intent_lock, flags);
if (intent) {
qcom_glink_send_intent_req_ack(glink, channel, !!intent);
qcom_glink_channel_ref_put(channel);
return;
}
@ -942,6 +972,7 @@ static void qcom_glink_handle_intent_req(struct qcom_glink *glink,
qcom_glink_advertise_intent(glink, channel, intent);
qcom_glink_send_intent_req_ack(glink, channel, !!intent);
qcom_glink_channel_ref_put(channel);
}
static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra)
@ -976,7 +1007,7 @@ static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra)
static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
{
struct glink_core_rx_intent *intent;
struct glink_channel *channel;
struct glink_channel *channel = NULL;
struct {
struct glink_msg msg;
__le32 chunk_size;
@ -1004,9 +1035,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
}
rcid = le16_to_cpu(hdr.msg.param1);
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, rcid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
channel = qcom_glink_channel_ref_get(glink, true, rcid);
if (!channel) {
dev_dbg(glink->dev, "Data on non-existing channel\n");
@ -1019,13 +1048,16 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
/* Might have an ongoing, fragmented, message to append */
if (!channel->buf) {
intent = kzalloc(sizeof(*intent), GFP_ATOMIC);
if (!intent)
if (!intent) {
qcom_glink_channel_ref_put(channel);
return -ENOMEM;
}
intent->data = kmalloc(chunk_size + left_size,
GFP_ATOMIC);
if (!intent->data) {
kfree(intent);
qcom_glink_channel_ref_put(channel);
return -ENOMEM;
}
@ -1092,7 +1124,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail)
advance_rx:
qcom_glink_rx_advance(glink, ALIGN(sizeof(hdr) + chunk_size, 8));
qcom_glink_channel_ref_put(channel);
return ret;
}
@ -1123,9 +1155,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
return;
}
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, cid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
channel = qcom_glink_channel_ref_get(glink, true, cid);
if (!channel) {
dev_err(glink->dev, "intents for non-existing channel\n");
qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
@ -1133,8 +1163,10 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
}
msg = kmalloc(msglen, GFP_ATOMIC);
if (!msg)
if (!msg) {
qcom_glink_channel_ref_put(channel);
return;
}
qcom_glink_rx_peak(glink, msg, 0, msglen);
@ -1163,15 +1195,14 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink,
kfree(msg);
qcom_glink_rx_advance(glink, ALIGN(msglen, 8));
qcom_glink_channel_ref_put(channel);
}
static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
{
struct glink_channel *channel;
spin_lock(&glink->idr_lock);
channel = idr_find(&glink->lcids, lcid);
spin_unlock(&glink->idr_lock);
channel = qcom_glink_channel_ref_get(glink, false, lcid);
if (!channel) {
dev_err(glink->dev, "Invalid open ack packet\n");
return -EINVAL;
@ -1179,7 +1210,7 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
CH_INFO(channel, "\n");
complete_all(&channel->open_ack);
qcom_glink_channel_ref_put(channel);
return 0;
}
@ -1220,12 +1251,9 @@ static int qcom_glink_handle_signals(struct qcom_glink *glink,
unsigned int rcid, unsigned int signals)
{
struct glink_channel *channel;
unsigned long flags;
u32 old;
spin_lock_irqsave(&glink->idr_lock, flags);
channel = idr_find(&glink->rcids, rcid);
spin_unlock_irqrestore(&glink->idr_lock, flags);
channel = qcom_glink_channel_ref_get(glink, true, rcid);
if (!channel) {
dev_err(glink->dev, "signal for non-existing channel\n");
return -EINVAL;
@ -1252,6 +1280,7 @@ static int qcom_glink_handle_signals(struct qcom_glink *glink,
old, channel->rsigs);
}
qcom_glink_channel_ref_put(channel);
return 0;
}

View file

@ -92,10 +92,16 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len)
size_t ehdr_size;
void *data;
if (fw->size < sizeof(struct elf32_hdr)) {
dev_err(dev, "Image is too small\n");
return ERR_PTR(-EINVAL);
}
ehdr = (struct elf32_hdr *)fw->data;
phdrs = (struct elf32_phdr *)(ehdr + 1);
if (ehdr->e_phnum < 2 || ehdr->e_phnum > PN_XNUM)
if (ehdr->e_phnum < 2 || ehdr->e_phoff > fw->size ||
(sizeof(phdrs) * ehdr->e_phnum > fw->size - ehdr->e_phoff))
return ERR_PTR(-EINVAL);
if (phdrs[0].p_type == PT_LOAD)

View file

@ -100,7 +100,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
* Wait until device controller is ready. Only applies to 1.94a and
* later RTL.
*/
if (dwc->revision >= DWC3_REVISION_194A) {
if (dwc3_is_usb3(dwc) && dwc->revision >= DWC3_REVISION_194A) {
while (--retries) {
reg = dwc3_readl(dwc->regs, DWC3_DSTS);
if (reg & DWC3_DSTS_DCNRD)
@ -124,7 +124,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
* The following code is racy when called from dwc3_gadget_wakeup,
* and is not needed, at least on newer versions
*/
if (dwc->revision >= DWC3_REVISION_194A)
if (dwc3_is_usb3(dwc) && dwc->revision >= DWC3_REVISION_194A)
return 0;
/* wait for a change in DSTS */
@ -2116,13 +2116,10 @@ static int dwc3_gadget_remote_wakeup(struct dwc3 *dwc)
goto out;
}
/* Recent versions do this automatically */
if (dwc->revision < DWC3_REVISION_194A) {
/* write zeroes to Link Change Request */
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
}
/* write zeroes to Link Change Request */
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK;
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
spin_unlock_irqrestore(&dwc->lock, flags);
enable_irq(dwc->irq);

View file

@ -732,13 +732,26 @@ static int usb_cser_notify(struct f_cdev *port, u8 type, u16 value,
static int port_notify_serial_state(struct cserial *cser)
{
struct f_cdev *port = cser_to_port(cser);
int status;
int status, ret;
unsigned long flags;
struct usb_composite_dev *cdev = port->port_usb.func.config->cdev;
struct usb_function *func = &cser->func;
struct usb_gadget *gadget;
if (port->is_suspended) {
gadget = cser->func.config->cdev->gadget;
port->pending_state_notify = true;
pr_debug("%s: port is suspended\n", __func__);
if (usb_cser_get_remote_wakeup_capable(func, gadget)) {
if (gadget->speed >= USB_SPEED_SUPER && port->func_is_suspended) {
ret = usb_func_wakeup(func);
port->func_wakeup_pending = (ret == -EAGAIN) ? true : false;
} else {
ret = usb_gadget_wakeup(gadget);
}
} else {
pr_debug("%s remote-wakeup not capable\n", __func__);
}
return 0;
}

View file

@ -619,6 +619,7 @@ static void xhci_port_set_test_mode(struct xhci_hcd *xhci,
static int xhci_enter_test_mode(struct xhci_hcd *xhci,
u16 test_mode, u16 wIndex, unsigned long *flags)
{
struct usb_hcd *usb3_hcd = xhci_get_usb3_hcd(xhci);
int i, retval;
/* Disable all Device Slots */
@ -639,7 +640,7 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci,
xhci_dbg(xhci, "Disable all port (PP = 0)\n");
/* Power off USB3 ports*/
for (i = 0; i < xhci->usb3_rhub.num_ports; i++)
xhci_set_port_power(xhci, xhci->shared_hcd, i, false, flags);
xhci_set_port_power(xhci, usb3_hcd, i, false, flags);
/* Power off USB2 ports*/
for (i = 0; i < xhci->usb2_rhub.num_ports; i++)
xhci_set_port_power(xhci, xhci->main_hcd, i, false, flags);
@ -1743,7 +1744,8 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
status = 1;
}
if (!status && !reset_change) {
xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
xhci_dbg(xhci, "%s: stopping usb%d port polling\n",
__func__, hcd->self.busnum);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
}
spin_unlock_irqrestore(&xhci->lock, flags);
@ -1775,7 +1777,8 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
if (bus_state->resuming_ports || /* USB2 */
bus_state->port_remote_wakeup) { /* USB3 */
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg(xhci, "suspend failed because a port is resuming\n");
xhci_dbg(xhci, "usb%d bus suspend to fail because a port is resuming\n",
hcd->self.busnum);
return -EBUSY;
}
}

View file

@ -1086,7 +1086,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd *xhci,
struct usb_hcd *hcd;
if (udev->speed >= USB_SPEED_SUPER)
hcd = xhci->shared_hcd;
hcd = xhci_get_usb3_hcd(xhci);
else
hcd = xhci->main_hcd;
@ -2494,10 +2494,11 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
xhci->usb2_rhub.num_ports = USB_MAXCHILDREN;
}
/*
* Note we could have all USB 3.0 ports, or all USB 2.0 ports.
* Not sure how the USB core will handle a hub with no ports...
*/
if (!xhci->usb2_rhub.num_ports)
xhci_info(xhci, "USB2 root hub has no ports\n");
if (!xhci->usb3_rhub.num_ports)
xhci_info(xhci, "USB3 root hub has no ports\n");
xhci_create_rhub_port_array(xhci, &xhci->usb2_rhub, flags);
xhci_create_rhub_port_array(xhci, &xhci->usb3_rhub, flags);

View file

@ -171,7 +171,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
struct device *sysdev, *tmpdev;
struct xhci_hcd *xhci;
struct resource *res;
struct usb_hcd *hcd;
struct usb_hcd *hcd, *usb3_hcd;
int ret;
int irq;
struct xhci_plat_priv *priv = NULL;
@ -246,6 +246,8 @@ static int xhci_plat_probe(struct platform_device *pdev)
xhci = hcd_to_xhci(hcd);
xhci->allow_single_roothub = 1;
/*
* Not all platforms have clks so it is not an error if the
* clock do not exist.
@ -291,12 +293,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
device_init_wakeup(hcd->self.controller, 1);
xhci->main_hcd = hcd;
xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
dev_name(&pdev->dev), hcd);
if (!xhci->shared_hcd) {
ret = -ENOMEM;
goto disable_clk;
}
/* imod_interval is the interrupt moderation value in nanoseconds. */
xhci->imod_interval = 40000;
@ -321,16 +317,15 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (IS_ERR(hcd->usb_phy)) {
ret = PTR_ERR(hcd->usb_phy);
if (ret == -EPROBE_DEFER)
goto put_usb3_hcd;
goto disable_clk;
hcd->usb_phy = NULL;
} else {
ret = usb_phy_init(hcd->usb_phy);
if (ret)
goto put_usb3_hcd;
goto disable_clk;
}
hcd->tpl_support = of_usb_host_tpl_support(sysdev->of_node);
xhci->shared_hcd->tpl_support = hcd->tpl_support;
if (priv) {
ret = xhci_priv_plat_setup(hcd);
@ -345,16 +340,31 @@ static int xhci_plat_probe(struct platform_device *pdev)
if (ret)
goto disable_usb_phy;
if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
xhci->shared_hcd->can_do_streams = 1;
if (!xhci_has_one_roothub(xhci)) {
xhci->shared_hcd = __usb_create_hcd(driver, sysdev, &pdev->dev,
dev_name(&pdev->dev), hcd);
if (!xhci->shared_hcd) {
ret = -ENOMEM;
goto dealloc_usb2_hcd;
}
ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
if (ret)
goto dealloc_usb2_hcd;
xhci->shared_hcd->tpl_support = hcd->tpl_support;
}
usb3_hcd = xhci_get_usb3_hcd(xhci);
if (usb3_hcd && HCC_MAX_PSA(xhci->hcc_params) >= 4)
usb3_hcd->can_do_streams = 1;
if (xhci->shared_hcd) {
ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);
if (ret)
goto put_usb3_hcd;
}
device_enable_async_suspend(&pdev->dev);
if (device_may_wakeup(sysdev)) {
device_wakeup_enable(&xhci->shared_hcd->self.root_hub->dev);
if (xhci->shared_hcd)
device_wakeup_enable(&xhci->shared_hcd->self.root_hub->dev);
device_wakeup_enable(&hcd->self.root_hub->dev);
}
@ -364,15 +374,15 @@ static int xhci_plat_probe(struct platform_device *pdev)
return 0;
put_usb3_hcd:
usb_put_hcd(xhci->shared_hcd);
dealloc_usb2_hcd:
usb_remove_hcd(hcd);
disable_usb_phy:
usb_phy_shutdown(hcd->usb_phy);
put_usb3_hcd:
usb_put_hcd(xhci->shared_hcd);
disable_clk:
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
@ -398,12 +408,17 @@ static int xhci_plat_remove(struct platform_device *dev)
pm_runtime_get_sync(&dev->dev);
xhci->xhc_state |= XHCI_STATE_REMOVING;
usb_remove_hcd(shared_hcd);
if (shared_hcd)
usb_remove_hcd(shared_hcd);
usb_phy_shutdown(hcd->usb_phy);
usb_remove_hcd(hcd);
xhci->shared_hcd = NULL;
usb_put_hcd(shared_hcd);
if (shared_hcd) {
xhci->shared_hcd = NULL;
usb_put_hcd(shared_hcd);
}
clk_disable_unprepare(clk);
clk_disable_unprepare(reg_clk);

View file

@ -1808,7 +1808,8 @@ cleanup:
* bits are still set. When an event occurs, switch over to
* polling to avoid losing status changes.
*/
xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
xhci_dbg(xhci, "%s: starting usb%d port polling.\n",
__func__, hcd->self.busnum);
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
spin_unlock(&xhci->lock);
/* Pass this up to the core */

View file

@ -520,6 +520,10 @@ static void compliance_mode_recovery(struct timer_list *t)
xhci = from_timer(xhci, t, comp_mode_recovery_timer);
rhub = &xhci->usb3_rhub;
hcd = rhub->hcd;
if (!hcd)
return;
for (i = 0; i < rhub->num_ports; i++) {
temp = readl(rhub->ports[i]->addr);
@ -533,7 +537,6 @@ static void compliance_mode_recovery(struct timer_list *t)
i + 1);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Attempting compliance mode recovery");
hcd = xhci->shared_hcd;
if (hcd->state == HC_STATE_SUSPENDED)
usb_hcd_resume_root_hub(hcd);
@ -646,14 +649,11 @@ static int xhci_run_finished(struct xhci_hcd *xhci)
xhci_halt(xhci);
return -ENODEV;
}
xhci->shared_hcd->state = HC_STATE_RUNNING;
xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
if (xhci->quirks & XHCI_NEC_HOST)
xhci_ring_cmd_db(xhci);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Finished xhci_run for USB3 roothub");
return 0;
}
@ -727,14 +727,19 @@ int xhci_run(struct usb_hcd *hcd)
if (ret)
xhci_free_command(xhci, command);
}
set_bit(HCD_FLAG_DEFER_RH_REGISTER, &hcd->flags);
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Finished xhci_run for USB2 roothub");
"Finished %s for main hcd", __func__);
xhci_dbc_init(xhci);
xhci_debugfs_init(xhci);
if (xhci_has_one_roothub(xhci))
return xhci_run_finished(xhci);
/* Defer primary roothub registration if we have 2 root hubs only */
set_bit(HCD_FLAG_DEFER_RH_REGISTER, &hcd->flags);
return 0;
}
EXPORT_SYMBOL_GPL(xhci_run);
@ -1027,7 +1032,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
return 0;
if (hcd->state != HC_STATE_SUSPENDED ||
xhci->shared_hcd->state != HC_STATE_SUSPENDED)
(xhci->shared_hcd &&
xhci->shared_hcd->state != HC_STATE_SUSPENDED))
return -EINVAL;
if (!HCD_HW_ACCESSIBLE(hcd))
@ -1040,18 +1046,22 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
xhci_dbc_suspend(xhci);
/* Don't poll the roothubs on bus suspend. */
xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
xhci_dbg(xhci, "%s: stopping usb%d port polling.\n",
__func__, hcd->self.busnum);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
del_timer_sync(&hcd->rh_timer);
clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
del_timer_sync(&xhci->shared_hcd->rh_timer);
if (xhci->shared_hcd) {
clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
del_timer_sync(&xhci->shared_hcd->rh_timer);
}
if (xhci->quirks & XHCI_SUSPEND_DELAY)
usleep_range(1000, 1500);
spin_lock_irq(&xhci->lock);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
if (xhci->shared_hcd)
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
/* step 1: stop endpoint */
/* skipped assuming that port suspend has done */
@ -1070,7 +1080,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
* served.
*/
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
if (xhci->shared_hcd)
set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
xhci_hc_died(xhci);
spin_unlock_irq(&xhci->lock);
return -ETIMEDOUT;
@ -1157,7 +1168,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
msleep(100);
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
if (xhci->shared_hcd)
set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
spin_lock_irq(&xhci->lock);
@ -1218,7 +1230,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
/* Let the USB core know _both_ roothubs lost power. */
usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
if (xhci->shared_hcd)
usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
xhci_dbg(xhci, "Stop HCD\n");
xhci_halt(xhci);
@ -1258,12 +1271,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
xhci_dbg(xhci, "Start the primary HCD\n");
retval = xhci_run(hcd->primary_hcd);
if (!retval) {
if (!retval && secondary_hcd) {
xhci_dbg(xhci, "Start the secondary HCD\n");
retval = xhci_run(secondary_hcd);
}
hcd->state = HC_STATE_SUSPENDED;
xhci->shared_hcd->state = HC_STATE_SUSPENDED;
if (xhci->shared_hcd)
xhci->shared_hcd->state = HC_STATE_SUSPENDED;
goto done;
}
@ -1301,7 +1315,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
}
if (pending_portevent) {
usb_hcd_resume_root_hub(xhci->shared_hcd);
if (xhci->shared_hcd)
usb_hcd_resume_root_hub(xhci->shared_hcd);
usb_hcd_resume_root_hub(hcd);
}
}
@ -1318,9 +1333,12 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
usb_asmedia_modifyflowcontrol(to_pci_dev(hcd->self.controller));
/* Re-enable port polling. */
xhci_dbg(xhci, "%s: starting port polling.\n", __func__);
set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
usb_hcd_poll_rh_status(xhci->shared_hcd);
xhci_dbg(xhci, "%s: starting usb%d port polling.\n",
__func__, hcd->self.busnum);
if (xhci->shared_hcd) {
set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
usb_hcd_poll_rh_status(xhci->shared_hcd);
}
set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
usb_hcd_poll_rh_status(hcd);
@ -5229,6 +5247,55 @@ static int xhci_get_frame(struct usb_hcd *hcd)
return readl(&xhci->run_regs->microframe_index) >> 3;
}
static void xhci_hcd_init_usb2_data(struct xhci_hcd *xhci, struct usb_hcd *hcd)
{
xhci->usb2_rhub.hcd = hcd;
hcd->speed = HCD_USB2;
hcd->self.root_hub->speed = USB_SPEED_HIGH;
/*
* USB 2.0 roothub under xHCI has an integrated TT,
* (rate matching hub) as opposed to having an OHCI/UHCI
* companion controller.
*/
hcd->has_tt = 1;
}
static void xhci_hcd_init_usb3_data(struct xhci_hcd *xhci, struct usb_hcd *hcd)
{
unsigned int minor_rev;
/*
* Early xHCI 1.1 spec did not mention USB 3.1 capable hosts
* should return 0x31 for sbrn, or that the minor revision
* is a two digit BCD containig minor and sub-minor numbers.
* This was later clarified in xHCI 1.2.
*
* Some USB 3.1 capable hosts therefore have sbrn 0x30, and
* minor revision set to 0x1 instead of 0x10.
*/
if (xhci->usb3_rhub.min_rev == 0x1)
minor_rev = 1;
else
minor_rev = xhci->usb3_rhub.min_rev / 0x10;
switch (minor_rev) {
case 2:
hcd->speed = HCD_USB32;
hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
hcd->self.root_hub->rx_lanes = 2;
hcd->self.root_hub->tx_lanes = 2;
break;
case 1:
hcd->speed = HCD_USB31;
hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
break;
}
xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n",
minor_rev, minor_rev ? "Enhanced " : "");
xhci->usb3_rhub.hcd = hcd;
}
int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
{
struct xhci_hcd *xhci;
@ -5237,7 +5304,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
* quirks
*/
struct device *dev = hcd->self.sysdev;
unsigned int minor_rev;
int retval;
/* Accept arbitrarily long scatter-gather lists */
@ -5251,59 +5317,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
xhci = hcd_to_xhci(hcd);
if (usb_hcd_is_primary_hcd(hcd)) {
xhci->main_hcd = hcd;
xhci->usb2_rhub.hcd = hcd;
/* Mark the first roothub as being USB 2.0.
* The xHCI driver will register the USB 3.0 roothub.
*/
hcd->speed = HCD_USB2;
hcd->self.root_hub->speed = USB_SPEED_HIGH;
/*
* USB 2.0 roothub under xHCI has an integrated TT,
* (rate matching hub) as opposed to having an OHCI/UHCI
* companion controller.
*/
hcd->has_tt = 1;
} else {
/*
* Early xHCI 1.1 spec did not mention USB 3.1 capable hosts
* should return 0x31 for sbrn, or that the minor revision
* is a two digit BCD containig minor and sub-minor numbers.
* This was later clarified in xHCI 1.2.
*
* Some USB 3.1 capable hosts therefore have sbrn 0x30, and
* minor revision set to 0x1 instead of 0x10.
*/
if (xhci->usb3_rhub.min_rev == 0x1)
minor_rev = 1;
else
minor_rev = xhci->usb3_rhub.min_rev / 0x10;
switch (minor_rev) {
case 2:
hcd->speed = HCD_USB32;
hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
hcd->self.root_hub->rx_lanes = 2;
hcd->self.root_hub->tx_lanes = 2;
break;
case 1:
hcd->speed = HCD_USB31;
hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
break;
}
xhci_info(xhci, "Host supports USB 3.%x %sSuperSpeed\n",
minor_rev,
minor_rev ? "Enhanced " : "");
xhci->usb3_rhub.hcd = hcd;
/* xHCI private pointer was set in xhci_pci_probe for the second
* registered roothub.
*/
if (!usb_hcd_is_primary_hcd(hcd)) {
xhci_hcd_init_usb3_data(xhci, hcd);
return 0;
}
mutex_init(&xhci->mutex);
xhci->main_hcd = hcd;
xhci->cap_regs = hcd->regs;
xhci->op_regs = hcd->regs +
HC_LENGTH(readl(&xhci->cap_regs->hc_capbase));
@ -5379,6 +5399,11 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
return retval;
xhci_dbg(xhci, "Called HCD init\n");
if (xhci_hcd_is_usb3(hcd))
xhci_hcd_init_usb3_data(xhci, hcd);
else
xhci_hcd_init_usb2_data(xhci, hcd);
xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%016llx\n",
xhci->hcc_params, xhci->hci_version, xhci->quirks);

View file

@ -1902,6 +1902,8 @@ struct xhci_hcd {
unsigned hw_lpm_support:1;
/* Broken Suspend flag for SNPS Suspend resume issue */
unsigned broken_suspend:1;
/* Indicates that omitting hcd is supported if root hub has no ports */
unsigned allow_single_roothub:1;
/* cached usb2 extened protocol capabilites */
u32 *ext_caps;
unsigned int num_ext_caps;
@ -1955,6 +1957,30 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
return xhci->main_hcd;
}
static inline struct usb_hcd *xhci_get_usb3_hcd(struct xhci_hcd *xhci)
{
if (xhci->shared_hcd)
return xhci->shared_hcd;
if (!xhci->usb2_rhub.num_ports)
return xhci->main_hcd;
return NULL;
}
static inline bool xhci_hcd_is_usb3(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
return hcd == xhci_get_usb3_hcd(xhci);
}
static inline bool xhci_has_one_roothub(struct xhci_hcd *xhci)
{
return xhci->allow_single_roothub &&
(!xhci->usb2_rhub.num_ports || !xhci->usb3_rhub.num_ports);
}
#define xhci_dbg(xhci, fmt, args...) \
dev_dbg(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
#define xhci_err(xhci, fmt, args...) \

View file

@ -95,6 +95,7 @@ extern int qcom_scm_set_remote_state(u32 state, u32 id);
extern int qcom_scm_spin_cpu(void);
extern void qcom_scm_set_download_mode(enum qcom_download_mode mode,
phys_addr_t tcsr_boot_misc);
extern int qcom_scm_get_download_mode(unsigned int *mode, phys_addr_t tcsr_boot_misc);
extern int qcom_scm_config_cpu_errata(void);
extern void qcom_scm_phy_update_scm_level_shifter(u32 val);
extern bool qcom_scm_pas_supported(u32 peripheral);
@ -244,6 +245,8 @@ static inline u32 qcom_scm_set_remote_state(u32 state, u32 id)
static inline int qcom_scm_spin_cpu(void) { return -ENODEV; }
static inline void qcom_scm_set_download_mode(enum qcom_download_mode mode,
phys_addr_t tcsr_boot_misc) {}
static inline int qcom_scm_get_download_mode(unsigned int *mode,
phys_addr_t tcsr_boot_misc) {}
static inline int qcom_scm_config_cpu_errata(void)
{ return -ENODEV; }
static inline void qcom_scm_phy_update_scm_level_shifter(u32 val) {}

View file

@ -1731,7 +1731,7 @@ struct IpaDscpVlanPcpMap_t {
uint8_t num_vlan; /* indicate how many vlans valid vlan above */
uint8_t num_s_vlan; /* indicate how many vlans valid in s_vlan below */
uint8_t dscp_opt; /* indicates if dscp is required or optional */
uint8_t pad1; /* for alignment */
uint8_t tunnel_id; /* tunnel id */
/*
* The same lookup scheme, using vlan[] above, is used for
* generating the first index of mpls below; and in addition,
@ -1750,8 +1750,8 @@ struct IpaDscpVlanPcpMap_t {
* mpls_val_sorted is in ascending order, by mpls label values in mpls array
* vlan_c and vlan_s are vlan id values that are corresponding to the mpls label
*/
uint16_t pad2; /* for alignment */
uint8_t pad3; /* for alignment */
uint16_t del_add_vlan_id; /* vlan id to add or del */
uint8_t is_vlan_to_del_add; /* whether to add or del vlan? */
uint8_t num_mpls_val_sorted; /* num of elements in mpls_val_sorted */
uint32_t mpls_val_sorted[IPA_EoGRE_MAX_VLAN * IPA_GRE_MAX_S_VLAN];
uint16_t vlan_c[IPA_EoGRE_MAX_VLAN * IPA_GRE_MAX_S_VLAN];
@ -1825,7 +1825,7 @@ struct singletag_mux_mapping_table_t {
uint8_t mux_id;
/* flag if 1=>pkt_with_option_hdr 0=>pkt_without_option_hdr */
uint8_t is_v6_options_hdr_present;
uint16_t pad0; /*for alignment*/
uint16_t tunnel_id;/* tunnel_id */
uint32_t *tunnel_template_addr;
} __packed;
@ -1850,13 +1850,22 @@ struct doubletag_mux_mapping_table_t {
/* max number of tunnel to support ie: per PDN two tunnel (2*8)*/
#define MAX_TUNNEL_SUPPORT 16
/* configuration table */
/* @tunnel_protocols_config_table_t: Config tbl for uC
* @untagged_mapping_table : Store the untag tunnel info.
* @num_of_single_tag_configs : no of active tunnel in single tag config.
* @feature_mode: which tunnel feature is enabled.
* @tunnel_id: Which tunnel info receive from ipacm.
* @is_tunnel_id_to_del: whether tunnel to delete.
* @singletag_mux_mapping_table: Store tunnel info for active tunnels.
* @num_of_double_tag_configs: no of active tunnel in double tag config.
* @doubletag_mux_mapping_table: Store double tag tunnel info.
*/
struct tunnel_protocols_config_table_t {
struct untag_pkt_config_t untagged_mapping_table;
uint8_t num_of_single_tag_configs;
uint8_t pad0; /*for alignment*/
uint16_t pad1; /*for alignment*/
uint32_t pad2; /*for alignment*/
uint8_t feature_mode;
uint16_t tunnel_id;
uint32_t is_tunnel_id_to_del;
/* table for single tag pkt */
struct singletag_mux_mapping_table_t singletag_mux_mapping_table[MAX_TUNNEL_SUPPORT];
uint8_t num_of_double_tag_configs;