fix
This commit is contained in:
parent
cce722cf5f
commit
e8394c927d
@ -8,7 +8,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=pcie_mhi
|
PKG_NAME:=pcie_mhi
|
||||||
PKG_VERSION:=3.6
|
PKG_VERSION:=3.2
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/kernel.mk
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
@ -1,20 +1,4 @@
|
|||||||
Release Notes
|
Release Notes
|
||||||
[V1.3.6]
|
|
||||||
Date: 01/08/2023
|
|
||||||
enhancement:
|
|
||||||
1. support Linux Kernel V6.4
|
|
||||||
2. support change mtu
|
|
||||||
fix:
|
|
||||||
1. fix compile error on ipq's spf12.x
|
|
||||||
|
|
||||||
Release Notes
|
|
||||||
[V1.3.5]
|
|
||||||
Date: 25/02/2023
|
|
||||||
enhancement:
|
|
||||||
1. support efuse SDX sleep
|
|
||||||
2. support IPQ9574 SFE
|
|
||||||
fix:
|
|
||||||
1. fix cannot find the node when dialing. Nodes in the /sys/bus/mhi_q/devices directory named hex
|
|
||||||
|
|
||||||
[V1.3.4]
|
[V1.3.4]
|
||||||
Date: 12/8/2022
|
Date: 12/8/2022
|
||||||
|
@ -15,36 +15,10 @@
|
|||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/msi.h>
|
#include <linux/msi.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#define MAX_MHI 8
|
|
||||||
#ifdef CONFIG_PCI_MSM
|
|
||||||
#define QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/msm_pcie.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
//#define QCOM_AP_SDM845_IOMMU_MAP
|
|
||||||
#ifdef QCOM_AP_SDM845_IOMMU_MAP
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
#include <asm/dma-iommu.h>
|
|
||||||
#include <linux/iommu.h>
|
|
||||||
#endif
|
|
||||||
#include "../core/mhi.h"
|
#include "../core/mhi.h"
|
||||||
#include "../core/mhi_internal.h"
|
#include "../core/mhi_internal.h"
|
||||||
#include "mhi_qti.h"
|
#include "mhi_qti.h"
|
||||||
|
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
extern int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val);
|
|
||||||
struct arch_info {
|
|
||||||
struct mhi_dev *mhi_dev;
|
|
||||||
struct msm_bus_scale_pdata *msm_bus_pdata;
|
|
||||||
u32 bus_client;
|
|
||||||
struct pci_saved_state *pcie_state;
|
|
||||||
struct pci_saved_state *ref_pcie_state;
|
|
||||||
struct dma_iommu_mapping *mapping;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,10,65 ))
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,10,65 ))
|
||||||
static inline int dma_set_mask_and_coherent(struct device *dev, u64 mask)
|
static inline int dma_set_mask_and_coherent(struct device *dev, u64 mask)
|
||||||
@ -203,12 +177,9 @@ static int mhi_init_pci_dev(struct mhi_controller *mhi_cntrl)
|
|||||||
|
|
||||||
#if 1 //some SOC like rpi_4b need next codes
|
#if 1 //some SOC like rpi_4b need next codes
|
||||||
ret = -EIO;
|
ret = -EIO;
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0))
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||||
if (!dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64))) {
|
if((ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64))))
|
||||||
ret = dma_set_coherent_mask(&pci_dev->dev, DMA_BIT_MASK(64));
|
ret = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
|
||||||
} else if (!dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
|
|
||||||
ret = dma_set_coherent_mask(&pci_dev->dev, DMA_BIT_MASK(32));
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) {
|
if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) {
|
||||||
ret = pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(64));
|
ret = pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(64));
|
||||||
@ -618,28 +589,6 @@ static void mhi_runtime_mark_last_busy(struct mhi_controller *mhi_cntrl, void *p
|
|||||||
pm_runtime_mark_last_busy(dev);
|
pm_runtime_mark_last_busy(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
static void mhi_pci_event_cb(struct msm_pcie_notify *notify)
|
|
||||||
{
|
|
||||||
struct pci_dev *pci_dev = notify->user;
|
|
||||||
struct device *dev = &pci_dev->dev;
|
|
||||||
|
|
||||||
dev_info(&pci_dev->dev, "Received PCIe event %d", notify->event);
|
|
||||||
switch (notify->event) {
|
|
||||||
case MSM_PCIE_EVENT_WAKEUP:
|
|
||||||
if (dev && pm_runtime_status_suspended(dev)) {
|
|
||||||
pm_request_resume(dev);
|
|
||||||
pm_runtime_mark_last_busy(dev);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct msm_pcie_register_event mhi_pcie_events[MAX_MHI];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void mhi_status_cb(struct mhi_controller *mhi_cntrl,
|
static void mhi_status_cb(struct mhi_controller *mhi_cntrl,
|
||||||
void *priv,
|
void *priv,
|
||||||
enum MHI_CB reason)
|
enum MHI_CB reason)
|
||||||
@ -910,11 +859,6 @@ int mhi_pci_probe(struct pci_dev *pci_dev,
|
|||||||
pr_info("%s pci_dev->name = %s, domain=%d, bus=%d, slot=%d, vendor=%04X, device=%04X\n",
|
pr_info("%s pci_dev->name = %s, domain=%d, bus=%d, slot=%d, vendor=%04X, device=%04X\n",
|
||||||
__func__, dev_name(&pci_dev->dev), domain, bus, slot, pci_dev->vendor, pci_dev->device);
|
__func__, dev_name(&pci_dev->dev), domain, bus, slot, pci_dev->vendor, pci_dev->device);
|
||||||
|
|
||||||
#if !defined(CONFIG_PCI_MSI)
|
|
||||||
/* MT7621 RTL8198D EcoNet-EN7565 */
|
|
||||||
#error "pcie msi is not support by this soc! and i donot support INTx (SW1SDX55-2688)"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!mhi_pci_is_alive(pci_dev)) {
|
if (!mhi_pci_is_alive(pci_dev)) {
|
||||||
/*
|
/*
|
||||||
root@OpenWrt:~# hexdump /sys/bus/pci/devices/0000:01:00.0/config
|
root@OpenWrt:~# hexdump /sys/bus/pci/devices/0000:01:00.0/config
|
||||||
@ -938,11 +882,9 @@ int mhi_pci_probe(struct pci_dev *pci_dev,
|
|||||||
mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
||||||
mhi_dev->powered_on = true;
|
mhi_dev->powered_on = true;
|
||||||
|
|
||||||
mhi_arch_iommu_init(mhi_cntrl);
|
|
||||||
|
|
||||||
ret = mhi_arch_pcie_init(mhi_cntrl);
|
ret = mhi_arch_pcie_init(mhi_cntrl);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_init_pci_arch;
|
return ret;
|
||||||
|
|
||||||
mhi_cntrl->dev = &pci_dev->dev;
|
mhi_cntrl->dev = &pci_dev->dev;
|
||||||
ret = mhi_init_pci_dev(mhi_cntrl);
|
ret = mhi_init_pci_dev(mhi_cntrl);
|
||||||
@ -960,28 +902,6 @@ int mhi_pci_probe(struct pci_dev *pci_dev,
|
|||||||
|
|
||||||
mhi_pci_show_link(mhi_cntrl, pci_dev);
|
mhi_pci_show_link(mhi_cntrl, pci_dev);
|
||||||
|
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
{
|
|
||||||
struct msm_pcie_register_event *pcie_event = &mhi_pcie_events[mhi_cntrl->cntrl_idx];
|
|
||||||
|
|
||||||
pcie_event->events = MSM_PCIE_EVENT_WAKEUP;
|
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 4,14,117 ))
|
|
||||||
pcie_event->pcie_event.user = pci_dev;
|
|
||||||
pcie_event->pcie_event.mode = MSM_PCIE_TRIGGER_CALLBACK;
|
|
||||||
pcie_event->pcie_event.callback = mhi_pci_event_cb;
|
|
||||||
#else
|
|
||||||
pcie_event->user = pci_dev;
|
|
||||||
pcie_event->mode = MSM_PCIE_TRIGGER_CALLBACK;
|
|
||||||
pcie_event->callback = mhi_pci_event_cb;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = msm_pcie_register_event(pcie_event);
|
|
||||||
if (ret) {
|
|
||||||
MHI_LOG("Failed to register for PCIe event");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MHI_LOG("Return successful\n");
|
MHI_LOG("Return successful\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -992,8 +912,6 @@ error_power_up:
|
|||||||
|
|
||||||
error_init_pci:
|
error_init_pci:
|
||||||
mhi_arch_pcie_deinit(mhi_cntrl);
|
mhi_arch_pcie_deinit(mhi_cntrl);
|
||||||
error_init_pci_arch:
|
|
||||||
mhi_arch_iommu_deinit(mhi_cntrl);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1012,14 +930,6 @@ void mhi_pci_device_removed(struct pci_dev *pci_dev)
|
|||||||
|
|
||||||
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
||||||
|
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
{
|
|
||||||
struct msm_pcie_register_event *pcie_event = &mhi_pcie_events[mhi_cntrl->cntrl_idx];
|
|
||||||
|
|
||||||
msm_pcie_deregister_event(pcie_event);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pm_stay_awake(&mhi_cntrl->mhi_dev->dev);
|
pm_stay_awake(&mhi_cntrl->mhi_dev->dev);
|
||||||
|
|
||||||
/* if link is in drv suspend, wake it up */
|
/* if link is in drv suspend, wake it up */
|
||||||
@ -1045,7 +955,6 @@ void mhi_pci_device_removed(struct pci_dev *pci_dev)
|
|||||||
mhi_arch_link_off(mhi_cntrl, false);
|
mhi_arch_link_off(mhi_cntrl, false);
|
||||||
|
|
||||||
mhi_arch_pcie_deinit(mhi_cntrl);
|
mhi_arch_pcie_deinit(mhi_cntrl);
|
||||||
mhi_arch_iommu_deinit(mhi_cntrl);
|
|
||||||
|
|
||||||
pm_relax(&mhi_cntrl->mhi_dev->dev);
|
pm_relax(&mhi_cntrl->mhi_dev->dev);
|
||||||
|
|
||||||
@ -1100,108 +1009,26 @@ void mhi_controller_qcom_exit(void)
|
|||||||
pr_info("%s exit\n", __func__);
|
pr_info("%s exit\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QCOM_AP_SDM845_IOMMU_MAP
|
|
||||||
struct dma_iommu_mapping *mhi_smmu_mapping[MAX_MHI];
|
|
||||||
|
|
||||||
#define SMMU_BASE 0x10000000
|
|
||||||
#define SMMU_SIZE 0x40000000
|
|
||||||
static struct dma_iommu_mapping * sdm845_smmu_init(struct pci_dev *pdev) {
|
|
||||||
int ret = 0;
|
|
||||||
int atomic_ctx = 1;
|
|
||||||
int s1_bypass = 1;
|
|
||||||
struct dma_iommu_mapping *mapping;
|
|
||||||
|
|
||||||
mapping = arm_iommu_create_mapping(&platform_bus_type, SMMU_BASE, SMMU_SIZE);
|
|
||||||
if (IS_ERR(mapping)) {
|
|
||||||
ret = PTR_ERR(mapping);
|
|
||||||
dev_err(&pdev->dev, "Create mapping failed, err = %d\n", ret);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_ATOMIC, &atomic_ctx);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(&pdev->dev, "Set atomic_ctx attribute failed, err = %d\n", ret);
|
|
||||||
goto set_attr_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = iommu_domain_set_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS, &s1_bypass);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(&pdev->dev, "Set s1_bypass attribute failed, err = %d\n", ret);
|
|
||||||
arm_iommu_release_mapping(mapping);
|
|
||||||
goto set_attr_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = arm_iommu_attach_device(&pdev->dev, mapping);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(&pdev->dev, "Attach device failed, err = %d\n", ret);
|
|
||||||
goto attach_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mapping;
|
|
||||||
|
|
||||||
attach_fail:
|
|
||||||
set_attr_fail:
|
|
||||||
arm_iommu_release_mapping(mapping);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int mhi_arch_iommu_init(struct mhi_controller *mhi_cntrl)
|
int mhi_arch_iommu_init(struct mhi_controller *mhi_cntrl)
|
||||||
{
|
{
|
||||||
#ifdef QCOM_AP_SDM845_IOMMU_MAP
|
|
||||||
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
||||||
|
|
||||||
mhi_smmu_mapping[mhi_cntrl->cntrl_idx] = sdm845_smmu_init(mhi_dev->pci_dev);
|
mhi_cntrl->dev = &mhi_dev->pci_dev->dev;
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return dma_set_mask_and_coherent(mhi_cntrl->dev, DMA_BIT_MASK(64));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mhi_arch_iommu_deinit(struct mhi_controller *mhi_cntrl)
|
void mhi_arch_iommu_deinit(struct mhi_controller *mhi_cntrl)
|
||||||
{
|
{
|
||||||
#ifdef QCOM_AP_SDM845_IOMMU_MAP
|
|
||||||
if (mhi_smmu_mapping[mhi_cntrl->cntrl_idx]) {
|
|
||||||
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
|
||||||
|
|
||||||
arm_iommu_detach_device(&mhi_dev->pci_dev->dev);
|
|
||||||
arm_iommu_release_mapping(mhi_smmu_mapping[mhi_cntrl->cntrl_idx]);
|
|
||||||
mhi_smmu_mapping[mhi_cntrl->cntrl_idx] = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mhi_arch_set_bus_request(struct mhi_controller *mhi_cntrl, int index)
|
|
||||||
{
|
|
||||||
MHI_LOG("Setting bus request to index %d\n", index);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl)
|
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl)
|
||||||
{
|
{
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
return 0;
|
||||||
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
|
||||||
struct arch_info *arch_info = mhi_dev->arch_info;
|
|
||||||
|
|
||||||
if (!arch_info) {
|
|
||||||
arch_info = devm_kzalloc(&mhi_dev->pci_dev->dev,
|
|
||||||
sizeof(*arch_info), GFP_KERNEL);
|
|
||||||
if (!arch_info)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
mhi_dev->arch_info = arch_info;
|
|
||||||
|
|
||||||
/* save reference state for pcie config space */
|
|
||||||
arch_info->ref_pcie_state = pci_store_saved_state(
|
|
||||||
mhi_dev->pci_dev);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return mhi_arch_set_bus_request(mhi_cntrl, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl)
|
void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl)
|
||||||
{
|
{
|
||||||
mhi_arch_set_bus_request(mhi_cntrl, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mhi_arch_platform_init(struct mhi_dev *mhi_dev)
|
int mhi_arch_platform_init(struct mhi_dev *mhi_dev)
|
||||||
@ -1216,91 +1043,11 @@ void mhi_arch_platform_deinit(struct mhi_dev *mhi_dev)
|
|||||||
int mhi_arch_link_off(struct mhi_controller *mhi_cntrl,
|
int mhi_arch_link_off(struct mhi_controller *mhi_cntrl,
|
||||||
bool graceful)
|
bool graceful)
|
||||||
{
|
{
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
|
||||||
struct arch_info *arch_info = mhi_dev->arch_info;
|
|
||||||
struct pci_dev *pci_dev = mhi_dev->pci_dev;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
MHI_LOG("Entered\n");
|
|
||||||
|
|
||||||
if (graceful) {
|
|
||||||
pci_clear_master(pci_dev);
|
|
||||||
ret = pci_save_state(mhi_dev->pci_dev);
|
|
||||||
if (ret) {
|
|
||||||
MHI_ERR("Failed with pci_save_state, ret:%d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
arch_info->pcie_state = pci_store_saved_state(pci_dev);
|
|
||||||
pci_disable_device(pci_dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We will always attempt to put link into D3hot, however
|
|
||||||
* link down may have happened due to error fatal, so
|
|
||||||
* ignoring the return code
|
|
||||||
*/
|
|
||||||
pci_set_power_state(pci_dev, PCI_D3hot);
|
|
||||||
|
|
||||||
ret = msm_pcie_pm_control(MSM_PCIE_SUSPEND, mhi_cntrl->bus, pci_dev,
|
|
||||||
NULL, 0);
|
|
||||||
MHI_ERR("msm_pcie_pm_control(MSM_PCIE_SUSPEND), ret:%d\n", ret);
|
|
||||||
|
|
||||||
/* release the resources */
|
|
||||||
mhi_arch_set_bus_request(mhi_cntrl, 0);
|
|
||||||
|
|
||||||
MHI_LOG("Exited\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mhi_arch_link_on(struct mhi_controller *mhi_cntrl)
|
int mhi_arch_link_on(struct mhi_controller *mhi_cntrl)
|
||||||
{
|
{
|
||||||
#ifdef QCOM_AP_AND_EFUSE_PCIE_SLEEP
|
|
||||||
struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
|
|
||||||
struct arch_info *arch_info = mhi_dev->arch_info;
|
|
||||||
struct pci_dev *pci_dev = mhi_dev->pci_dev;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
MHI_LOG("Entered\n");
|
|
||||||
|
|
||||||
/* request resources and establish link trainning */
|
|
||||||
ret = mhi_arch_set_bus_request(mhi_cntrl, 1);
|
|
||||||
if (ret)
|
|
||||||
MHI_LOG("Could not set bus frequency, ret:%d\n", ret);
|
|
||||||
|
|
||||||
ret = msm_pcie_pm_control(MSM_PCIE_RESUME, mhi_cntrl->bus, pci_dev,
|
|
||||||
NULL, 0);
|
|
||||||
MHI_LOG("msm_pcie_pm_control(MSM_PCIE_RESUME), ret:%d\n", ret);
|
|
||||||
if (ret) {
|
|
||||||
MHI_ERR("Link training failed, ret:%d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pci_set_power_state(pci_dev, PCI_D0);
|
|
||||||
if (ret) {
|
|
||||||
MHI_ERR("Failed to set PCI_D0 state, ret:%d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pci_enable_device(pci_dev);
|
|
||||||
if (ret) {
|
|
||||||
MHI_ERR("Failed to enable device, ret:%d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pci_load_and_free_saved_state(pci_dev, &arch_info->pcie_state);
|
|
||||||
if (ret)
|
|
||||||
MHI_LOG("Failed to load saved cfg state\n");
|
|
||||||
|
|
||||||
pci_restore_state(pci_dev);
|
|
||||||
pci_set_master(pci_dev);
|
|
||||||
|
|
||||||
MHI_LOG("Exited\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,14 +4,10 @@
|
|||||||
#ifndef _MHI_H_
|
#ifndef _MHI_H_
|
||||||
#define _MHI_H_
|
#define _MHI_H_
|
||||||
|
|
||||||
#define PCIE_MHI_DRIVER_VERSION "V1.3.6"
|
#define PCIE_MHI_DRIVER_VERSION "V1.3.4"
|
||||||
#define ENABLE_MHI_MON
|
#define ENABLE_MHI_MON
|
||||||
//#define ENABLE_IP_SW0
|
//#define ENABLE_IP_SW0
|
||||||
|
|
||||||
// #define ENABLE_ADPL
|
|
||||||
|
|
||||||
// #define ENABLE_QDSS
|
|
||||||
|
|
||||||
#include <linux/miscdevice.h>
|
#include <linux/miscdevice.h>
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
@ -86,8 +82,7 @@ typedef enum
|
|||||||
MHI_CLIENT_IP_HW_0_OUT = 100,
|
MHI_CLIENT_IP_HW_0_OUT = 100,
|
||||||
MHI_CLIENT_IP_HW_0_IN = 101,
|
MHI_CLIENT_IP_HW_0_IN = 101,
|
||||||
MHI_CLIENT_ADPL = 102,
|
MHI_CLIENT_ADPL = 102,
|
||||||
MHI_CLIENT_IP_HW_QDSS = 103,
|
MHI_CLIENT_RESERVED_5_LOWER = 103,
|
||||||
// MHI_CLIENT_RESERVED_5_LOWER = 103,
|
|
||||||
MHI_CLIENT_RESERVED_5_UPPER = 127,
|
MHI_CLIENT_RESERVED_5_UPPER = 127,
|
||||||
MHI_MAX_CHANNELS = 128
|
MHI_MAX_CHANNELS = 128
|
||||||
}MHI_CLIENT_CHANNEL_TYPE;
|
}MHI_CLIENT_CHANNEL_TYPE;
|
||||||
@ -103,12 +98,7 @@ typedef enum
|
|||||||
#endif
|
#endif
|
||||||
IPA_OUT_EVENT_RING,
|
IPA_OUT_EVENT_RING,
|
||||||
IPA_IN_EVENT_RING,
|
IPA_IN_EVENT_RING,
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
ADPL_EVT_RING,
|
ADPL_EVT_RING,
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
QDSS_EVT_RING,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MAX_EVT_RING_IDX
|
MAX_EVT_RING_IDX
|
||||||
}MHI_EVT_RING_IDX;
|
}MHI_EVT_RING_IDX;
|
||||||
@ -119,7 +109,7 @@ typedef enum
|
|||||||
#define MAX_NUM_MHI_DEVICES 1
|
#define MAX_NUM_MHI_DEVICES 1
|
||||||
#define NUM_MHI_XFER_RINGS 128
|
#define NUM_MHI_XFER_RINGS 128
|
||||||
#define NUM_MHI_EVT_RINGS MAX_EVT_RING_IDX
|
#define NUM_MHI_EVT_RINGS MAX_EVT_RING_IDX
|
||||||
#define NUM_MHI_HW_EVT_RINGS 4
|
#define NUM_MHI_HW_EVT_RINGS 3
|
||||||
#define NUM_MHI_XFER_RING_ELEMENTS 16
|
#define NUM_MHI_XFER_RING_ELEMENTS 16
|
||||||
#define NUM_MHI_EVT_RING_ELEMENTS (NUM_MHI_IPA_IN_RING_ELEMENTS*2) //must *2, event ring full will make x55 dump
|
#define NUM_MHI_EVT_RING_ELEMENTS (NUM_MHI_IPA_IN_RING_ELEMENTS*2) //must *2, event ring full will make x55 dump
|
||||||
#define NUM_MHI_IPA_IN_RING_ELEMENTS 512
|
#define NUM_MHI_IPA_IN_RING_ELEMENTS 512
|
||||||
@ -127,14 +117,6 @@ typedef enum
|
|||||||
#define NUM_MHI_DIAG_IN_RING_ELEMENTS 128
|
#define NUM_MHI_DIAG_IN_RING_ELEMENTS 128
|
||||||
#define NUM_MHI_SW_IP_RING_ELEMENTS 512
|
#define NUM_MHI_SW_IP_RING_ELEMENTS 512
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
#define NUM_MHI_ADPL_RING_ELEMENTS 256
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
#define NUM_MHI_QDSS_RING_ELEMENTS 256
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* for if set Interrupt moderation time as 1ms,
|
* for if set Interrupt moderation time as 1ms,
|
||||||
and transfer more than NUM_MHI_CHAN_RING_ELEMENTS data are sent to the modem in 1ms.
|
and transfer more than NUM_MHI_CHAN_RING_ELEMENTS data are sent to the modem in 1ms.
|
||||||
|
@ -200,7 +200,7 @@ static int __mhi_download_rddm_in_panic(struct mhi_controller *mhi_cntrl)
|
|||||||
lower_32_bits(mhi_buf->dma_addr));
|
lower_32_bits(mhi_buf->dma_addr));
|
||||||
|
|
||||||
mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
|
mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||||
sequence_id = get_random_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
sequence_id = get_random_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
||||||
#else
|
#else
|
||||||
sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
||||||
@ -315,8 +315,7 @@ int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl, bool in_panic)
|
|||||||
lower_32_bits(mhi_buf->dma_addr));
|
lower_32_bits(mhi_buf->dma_addr));
|
||||||
|
|
||||||
mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
|
mhi_write_reg(mhi_cntrl, base, BHIE_RXVECSIZE_OFFS, mhi_buf->len);
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
|
|
||||||
sequence_id = get_random_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
sequence_id = get_random_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
||||||
#else
|
#else
|
||||||
sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
sequence_id = prandom_u32() & BHIE_RXVECSTATUS_SEQNUM_BMSK;
|
||||||
@ -371,11 +370,12 @@ static int mhi_fw_load_amss(struct mhi_controller *mhi_cntrl,
|
|||||||
lower_32_bits(mhi_buf->dma_addr));
|
lower_32_bits(mhi_buf->dma_addr));
|
||||||
|
|
||||||
mhi_write_reg(mhi_cntrl, base, BHIE_TXVECSIZE_OFFS, mhi_buf->len);
|
mhi_write_reg(mhi_cntrl, base, BHIE_TXVECSIZE_OFFS, mhi_buf->len);
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||||
mhi_cntrl->sequence_id = get_random_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK;
|
mhi_cntrl->sequence_id = get_random_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK;
|
||||||
#else
|
#else
|
||||||
mhi_cntrl->sequence_id = prandom_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK;
|
mhi_cntrl->sequence_id = prandom_u32() & BHIE_TXVECSTATUS_SEQNUM_BMSK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS,
|
mhi_write_reg_field(mhi_cntrl, base, BHIE_TXVECDB_OFFS,
|
||||||
BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT,
|
BHIE_TXVECDB_SEQNUM_BMSK, BHIE_TXVECDB_SEQNUM_SHFT,
|
||||||
mhi_cntrl->sequence_id);
|
mhi_cntrl->sequence_id);
|
||||||
@ -651,11 +651,12 @@ void mhi_fw_load_worker(struct work_struct *work)
|
|||||||
ret = mhi_fw_load_sbl(mhi_cntrl, dma_addr, size);
|
ret = mhi_fw_load_sbl(mhi_cntrl, dma_addr, size);
|
||||||
mhi_free_coherent(mhi_cntrl, size, buf, dma_addr);
|
mhi_free_coherent(mhi_cntrl, size, buf, dma_addr);
|
||||||
|
|
||||||
/* error or in edl, we're done */
|
if (!mhi_cntrl->fbc_download || ret || mhi_cntrl->ee == MHI_EE_EDL)
|
||||||
if (ret || mhi_cntrl->ee == MHI_EE_EDL) {
|
|
||||||
release_firmware(firmware);
|
release_firmware(firmware);
|
||||||
|
|
||||||
|
/* error or in edl, we're done */
|
||||||
|
if (ret || mhi_cntrl->ee == MHI_EE_EDL)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
write_lock_irq(&mhi_cntrl->pm_lock);
|
write_lock_irq(&mhi_cntrl->pm_lock);
|
||||||
mhi_cntrl->dev_state = MHI_STATE_RESET;
|
mhi_cntrl->dev_state = MHI_STATE_RESET;
|
||||||
@ -687,10 +688,8 @@ void mhi_fw_load_worker(struct work_struct *work)
|
|||||||
TO_MHI_STATE_STR(mhi_cntrl->dev_state),
|
TO_MHI_STATE_STR(mhi_cntrl->dev_state),
|
||||||
TO_MHI_EXEC_STR(mhi_cntrl->ee), ret);
|
TO_MHI_EXEC_STR(mhi_cntrl->ee), ret);
|
||||||
|
|
||||||
if (!mhi_cntrl->fbc_download) {
|
if (!mhi_cntrl->fbc_download)
|
||||||
release_firmware(firmware);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
MHI_ERR("Did not transition to READY state\n");
|
MHI_ERR("Did not transition to READY state\n");
|
||||||
@ -847,10 +846,7 @@ long bhi_write_image(struct mhi_controller *mhi_cntrl, void __user *ubuf)
|
|||||||
MHI_ERR("IOCTL_BHI_WRITEIMAGE copy size error, ret = %ld\n", ret);
|
MHI_ERR("IOCTL_BHI_WRITEIMAGE copy size error, ret = %ld\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (size <= 0) {
|
|
||||||
MHI_ERR("IOCTL_BHI_WRITEIMAGE copy size error, size\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
ret = BhiWrite(mhi_cntrl, ubuf+sizeof(size), size);
|
ret = BhiWrite(mhi_cntrl, ubuf+sizeof(size), size);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
MHI_ERR("IOCTL_BHI_WRITEIMAGE BhiWrite error, ret = %ld\n", ret);
|
MHI_ERR("IOCTL_BHI_WRITEIMAGE BhiWrite error, ret = %ld\n", ret);
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/uaccess.h>
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 4,11,0 ))
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 4,11,0 ))
|
||||||
@ -28,7 +27,6 @@ struct mhi_controller_map {
|
|||||||
u32 domain;
|
u32 domain;
|
||||||
u32 bus;
|
u32 bus;
|
||||||
u32 slot;
|
u32 slot;
|
||||||
struct mhi_controller *mhi_cntrl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_MHI_CONTROLLER 16
|
#define MAX_MHI_CONTROLLER 16
|
||||||
@ -390,7 +388,7 @@ static void mon_text_complete(void *data, u32 chan, dma_addr_t wp, struct mhi_tr
|
|||||||
mon_text_event(rp, chan, wp, mhi_tre, NULL, 0, 'E');
|
mon_text_event(rp, chan, wp, mhi_tre, NULL, 0, 'E');
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mon_reader_add(struct mhi_controller *mbus, struct mon_reader *r)
|
void mon_reader_add(struct mhi_controller *mbus, struct mon_reader *r)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
@ -562,9 +560,9 @@ static ssize_t mon_text_read_u(struct file *file, char __user *buf,
|
|||||||
ptr.limit = rp->printf_size;
|
ptr.limit = rp->printf_size;
|
||||||
|
|
||||||
ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
|
ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
|
||||||
"%u %c %03d WP:%llx TRE: %llx %08x %08x",
|
"%u %c %03d WP:%llx TRE: %llx %08x %08x",
|
||||||
ep->tstamp, ep->type, ep->chan, (long long unsigned int)ep->wp,
|
ep->tstamp, ep->type, ep->chan, ep->wp,
|
||||||
ep->mhi_tre.ptr, ep->mhi_tre.dword[0], ep->mhi_tre.dword[1]);
|
ep->mhi_tre.ptr, ep->mhi_tre.dword[0], ep->mhi_tre.dword[1]);
|
||||||
|
|
||||||
if (ep->len) {
|
if (ep->len) {
|
||||||
struct mon_text_ptr *p = &ptr;
|
struct mon_text_ptr *p = &ptr;
|
||||||
@ -653,7 +651,7 @@ static const struct file_operations mon_fops_text_u = {
|
|||||||
void mhi_init_debugfs(struct mhi_controller *mhi_cntrl)
|
void mhi_init_debugfs(struct mhi_controller *mhi_cntrl)
|
||||||
{
|
{
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
char node[64];
|
char node[32];
|
||||||
|
|
||||||
#ifdef ENABLE_MHI_MON
|
#ifdef ENABLE_MHI_MON
|
||||||
struct mhi_controller *mbus = mhi_cntrl;
|
struct mhi_controller *mbus = mhi_cntrl;
|
||||||
@ -665,11 +663,11 @@ void mhi_init_debugfs(struct mhi_controller *mhi_cntrl)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!mhi_cntrl->parent)
|
if (!mhi_cntrl->parent)
|
||||||
snprintf(node, sizeof(node), "mhi_%04x_%02x:%02x.%02x",
|
snprintf(node, sizeof(node), "mhi_%04x_%02u:%02u.%02u",
|
||||||
mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus,
|
mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus,
|
||||||
mhi_cntrl->slot);
|
mhi_cntrl->slot);
|
||||||
else
|
else
|
||||||
snprintf(node, sizeof(node), "%04x_%02x:%02x.%02x",
|
snprintf(node, sizeof(node), "%04x_%02u:%02u.%02u",
|
||||||
mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus,
|
mhi_cntrl->dev_id, mhi_cntrl->domain, mhi_cntrl->bus,
|
||||||
mhi_cntrl->slot);
|
mhi_cntrl->slot);
|
||||||
|
|
||||||
@ -1011,7 +1009,7 @@ exit_timesync:
|
|||||||
|
|
||||||
int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
|
int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
|
||||||
{
|
{
|
||||||
u32 val = 0;
|
u32 val;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
struct mhi_chan *mhi_chan;
|
struct mhi_chan *mhi_chan;
|
||||||
struct mhi_event *mhi_event;
|
struct mhi_event *mhi_event;
|
||||||
@ -1088,7 +1086,7 @@ int mhi_init_mmio(struct mhi_controller *mhi_cntrl)
|
|||||||
MHIDATALIMIT_LOWER, U32_MAX, 0,
|
MHIDATALIMIT_LOWER, U32_MAX, 0,
|
||||||
lower_32_bits(mhi_cntrl->iova_stop),
|
lower_32_bits(mhi_cntrl->iova_stop),
|
||||||
},
|
},
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
MHI_LOG("Initializing MMIO\n");
|
MHI_LOG("Initializing MMIO\n");
|
||||||
@ -1196,21 +1194,6 @@ int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl,
|
|||||||
tre_ring->dma_handle = mhi_cntrl->mhi_ctxt->ctrl_seg_addr + offsetof(struct mhi_ctrl_seg, sw_out_chan_ring[mhi_chan->ring]);
|
tre_ring->dma_handle = mhi_cntrl->mhi_ctxt->ctrl_seg_addr + offsetof(struct mhi_ctrl_seg, sw_out_chan_ring[mhi_chan->ring]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
else if (MHI_CLIENT_ADPL == mhi_chan->chan) {
|
|
||||||
tre_ring->pre_aligned = &mhi_cntrl->mhi_ctxt->ctrl_seg->adpl_in_chan_ring[mhi_chan->ring];
|
|
||||||
tre_ring->dma_handle = mhi_cntrl->mhi_ctxt->ctrl_seg_addr + offsetof(struct mhi_ctrl_seg, adpl_in_chan_ring[mhi_chan->ring]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
else if (MHI_CLIENT_IP_HW_QDSS == mhi_chan->chan) {
|
|
||||||
tre_ring->pre_aligned = &mhi_cntrl->mhi_ctxt->ctrl_seg->qdss_in_chan_ring[mhi_chan->ring];
|
|
||||||
tre_ring->dma_handle = mhi_cntrl->mhi_ctxt->ctrl_seg_addr + offsetof(struct mhi_ctrl_seg, qdss_in_chan_ring[mhi_chan->ring]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
else if (MHI_CLIENT_DIAG_IN == mhi_chan->chan) {
|
else if (MHI_CLIENT_DIAG_IN == mhi_chan->chan) {
|
||||||
tre_ring->pre_aligned = &mhi_cntrl->mhi_ctxt->ctrl_seg->diag_in_chan_ring[mhi_chan->ring];
|
tre_ring->pre_aligned = &mhi_cntrl->mhi_ctxt->ctrl_seg->diag_in_chan_ring[mhi_chan->ring];
|
||||||
tre_ring->dma_handle = mhi_cntrl->mhi_ctxt->ctrl_seg_addr + offsetof(struct mhi_ctrl_seg, diag_in_chan_ring[mhi_chan->ring]);
|
tre_ring->dma_handle = mhi_cntrl->mhi_ctxt->ctrl_seg_addr + offsetof(struct mhi_ctrl_seg, diag_in_chan_ring[mhi_chan->ring]);
|
||||||
@ -1623,21 +1606,11 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
mhi_event->er_index = i;
|
mhi_event->er_index = i;
|
||||||
|
|
||||||
mhi_event->ring.elements = NUM_MHI_EVT_RING_ELEMENTS; //Event ring length in elements
|
mhi_event->ring.elements = NUM_MHI_EVT_RING_ELEMENTS; //Event ring length in elements
|
||||||
if (i == PRIMARY_EVENT_RING)
|
if (i == PRIMARY_EVENT_RING || i == ADPL_EVT_RING)
|
||||||
mhi_event->ring.elements = 256; //256 is enough, and 1024 some times make driver fail to open channel (reason is x6x fail to malloc)
|
mhi_event->ring.elements = 256; //256 is enough, and 1024 some times make driver fail to open channel (reason is x6x fail to malloc)
|
||||||
|
|
||||||
mhi_event->intmod = 1; //Interrupt moderation time in ms
|
mhi_event->intmod = 1; //Interrupt moderation time in ms
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
if (i == ADPL_EVT_RING)
|
|
||||||
mhi_event->ring.elements = 256;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
if (i == QDSS_EVT_RING)
|
|
||||||
mhi_event->ring.elements = 512;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* see mhi_netdev_status_cb(), when interrupt come, the napi_poll maybe scheduled, so can reduce interrupts
|
/* see mhi_netdev_status_cb(), when interrupt come, the napi_poll maybe scheduled, so can reduce interrupts
|
||||||
root@OpenWrt:/# cat /proc/interrupts | grep mhi
|
root@OpenWrt:/# cat /proc/interrupts | grep mhi
|
||||||
root@OpenWrt:/# cat /sys/kernel/debug/mhi_q/mhi_netdev/pcie_mhi_0306_00.01.00_0/rx_int
|
root@OpenWrt:/# cat /sys/kernel/debug/mhi_q/mhi_netdev/pcie_mhi_0306_00.01.00_0/rx_int
|
||||||
@ -1650,16 +1623,6 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
mhi_event->intmod = 5;
|
mhi_event->intmod = 5;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
if (i == ADPL_EVT_RING)
|
|
||||||
mhi_event->intmod = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
if (i == QDSS_EVT_RING)
|
|
||||||
mhi_event->intmod = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mhi_event->msi = 1 + i + mhi_cntrl->msi_irq_base; //MSI associated with this event ring
|
mhi_event->msi = 1 + i + mhi_cntrl->msi_irq_base; //MSI associated with this event ring
|
||||||
|
|
||||||
if (i == IPA_OUT_EVENT_RING)
|
if (i == IPA_OUT_EVENT_RING)
|
||||||
@ -1672,16 +1635,6 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
else if (i == SW_0_IN_EVT_RING)
|
else if (i == SW_0_IN_EVT_RING)
|
||||||
mhi_event->chan = MHI_CLIENT_IP_SW_0_IN;
|
mhi_event->chan = MHI_CLIENT_IP_SW_0_IN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
else if (i == ADPL_EVT_RING)
|
|
||||||
mhi_event->chan = MHI_CLIENT_ADPL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
else if (i == QDSS_EVT_RING)
|
|
||||||
mhi_event->chan = MHI_CLIENT_IP_HW_QDSS;
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
mhi_event->chan = 0;
|
mhi_event->chan = 0;
|
||||||
|
|
||||||
@ -1706,16 +1659,6 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
else if (i == SW_0_OUT_EVT_RING || i == SW_0_IN_EVT_RING)
|
else if (i == SW_0_OUT_EVT_RING || i == SW_0_IN_EVT_RING)
|
||||||
mhi_event->data_type = MHI_ER_DATA_ELEMENT_TYPE;
|
mhi_event->data_type = MHI_ER_DATA_ELEMENT_TYPE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
else if (i == ADPL_EVT_RING)
|
|
||||||
mhi_event->data_type = MHI_ER_DATA_ELEMENT_TYPE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
else if (i == QDSS_EVT_RING)
|
|
||||||
mhi_event->data_type = MHI_ER_DATA_ELEMENT_TYPE;
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
mhi_event->data_type = MHI_ER_CTRL_ELEMENT_TYPE;
|
mhi_event->data_type = MHI_ER_CTRL_ELEMENT_TYPE;
|
||||||
|
|
||||||
@ -1731,14 +1674,7 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == IPA_OUT_EVENT_RING || i == IPA_IN_EVENT_RING
|
if (i == IPA_OUT_EVENT_RING || i == IPA_IN_EVENT_RING)
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
|| i == ADPL_EVT_RING
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
|| i == QDSS_EVT_RING
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
mhi_event->hw_ring = true;
|
mhi_event->hw_ring = true;
|
||||||
else
|
else
|
||||||
mhi_event->hw_ring = false;
|
mhi_event->hw_ring = false;
|
||||||
@ -1778,9 +1714,8 @@ static struct chan_cfg_t chan_cfg[] = {
|
|||||||
{"DIAG", MHI_CLIENT_DIAG_OUT, NUM_MHI_CHAN_RING_ELEMENTS},
|
{"DIAG", MHI_CLIENT_DIAG_OUT, NUM_MHI_CHAN_RING_ELEMENTS},
|
||||||
{"DIAG", MHI_CLIENT_DIAG_IN, NUM_MHI_DIAG_IN_RING_ELEMENTS},
|
{"DIAG", MHI_CLIENT_DIAG_IN, NUM_MHI_DIAG_IN_RING_ELEMENTS},
|
||||||
//"Qualcomm PCIe QDSS Data"
|
//"Qualcomm PCIe QDSS Data"
|
||||||
//"Do not use this QDSS. xingduo.du 2023-02-16"
|
{"QDSS", MHI_CLIENT_QDSS_OUT, NUM_MHI_CHAN_RING_ELEMENTS},
|
||||||
// {"QDSS", MHI_CLIENT_QDSS_OUT, NUM_MHI_CHAN_RING_ELEMENTS},
|
{"QDSS", MHI_CLIENT_QDSS_IN, NUM_MHI_CHAN_RING_ELEMENTS},
|
||||||
// {"QDSS", MHI_CLIENT_QDSS_IN, NUM_MHI_CHAN_RING_ELEMENTS},
|
|
||||||
//"Qualcomm PCIe EFS"
|
//"Qualcomm PCIe EFS"
|
||||||
{"EFS", MHI_CLIENT_EFS_OUT, NUM_MHI_CHAN_RING_ELEMENTS},
|
{"EFS", MHI_CLIENT_EFS_OUT, NUM_MHI_CHAN_RING_ELEMENTS},
|
||||||
{"EFS", MHI_CLIENT_EFS_IN, NUM_MHI_CHAN_RING_ELEMENTS},
|
{"EFS", MHI_CLIENT_EFS_IN, NUM_MHI_CHAN_RING_ELEMENTS},
|
||||||
@ -1818,13 +1753,6 @@ static struct chan_cfg_t chan_cfg[] = {
|
|||||||
//"Qualcomm PCIe WWAN Adapter"
|
//"Qualcomm PCIe WWAN Adapter"
|
||||||
{"IP_HW0", MHI_CLIENT_IP_HW_0_OUT, NUM_MHI_IPA_OUT_RING_ELEMENTS},
|
{"IP_HW0", MHI_CLIENT_IP_HW_0_OUT, NUM_MHI_IPA_OUT_RING_ELEMENTS},
|
||||||
{"IP_HW0", MHI_CLIENT_IP_HW_0_IN, NUM_MHI_IPA_IN_RING_ELEMENTS},
|
{"IP_HW0", MHI_CLIENT_IP_HW_0_IN, NUM_MHI_IPA_IN_RING_ELEMENTS},
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
{"ADPL", MHI_CLIENT_ADPL, NUM_MHI_ADPL_RING_ELEMENTS},
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
{"QDSS", MHI_CLIENT_IP_HW_QDSS, NUM_MHI_QDSS_RING_ELEMENTS},
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int mhi_netdev_mbin_enabled(void);
|
extern int mhi_netdev_mbin_enabled(void);
|
||||||
@ -1878,14 +1806,7 @@ static int of_parse_ch_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
mhi_chan->buf_ring.elements = mhi_chan->tre_ring.elements;
|
mhi_chan->buf_ring.elements = mhi_chan->tre_ring.elements;
|
||||||
|
|
||||||
if (chan == MHI_CLIENT_IP_HW_0_OUT || chan == MHI_CLIENT_IP_HW_0_IN || chan == MHI_CLIENT_DIAG_IN
|
if (chan == MHI_CLIENT_IP_HW_0_OUT || chan == MHI_CLIENT_IP_HW_0_IN || chan == MHI_CLIENT_DIAG_IN
|
||||||
|| chan == MHI_CLIENT_IP_SW_0_OUT || chan == MHI_CLIENT_IP_SW_0_IN
|
|| chan == MHI_CLIENT_IP_SW_0_OUT || chan == MHI_CLIENT_IP_SW_0_IN) {
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
|| chan == MHI_CLIENT_ADPL
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
|| chan == MHI_CLIENT_IP_HW_QDSS
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
mhi_chan->ring = 0;
|
mhi_chan->ring = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1903,29 +1824,11 @@ static int of_parse_ch_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
else if (chan == MHI_CLIENT_IP_SW_0_IN)
|
else if (chan == MHI_CLIENT_IP_SW_0_IN)
|
||||||
mhi_chan->er_index = SW_0_IN_EVT_RING;
|
mhi_chan->er_index = SW_0_IN_EVT_RING;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
else if (chan == MHI_CLIENT_ADPL)
|
|
||||||
mhi_chan->er_index = ADPL_EVT_RING;
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
else if (chan == MHI_CLIENT_IP_HW_QDSS)
|
|
||||||
mhi_chan->er_index = QDSS_EVT_RING;
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
mhi_chan->er_index = PRIMARY_EVENT_RING;
|
mhi_chan->er_index = PRIMARY_EVENT_RING;
|
||||||
|
|
||||||
mhi_chan->dir = CHAN_INBOUND(chan) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
mhi_chan->dir = CHAN_INBOUND(chan) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
if (chan == MHI_CLIENT_ADPL)
|
|
||||||
mhi_chan->dir = DMA_FROM_DEVICE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
if (chan == MHI_CLIENT_IP_HW_QDSS)
|
|
||||||
mhi_chan->dir = DMA_FROM_DEVICE;
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* For most channels, chtype is identical to channel directions,
|
* For most channels, chtype is identical to channel directions,
|
||||||
* if not defined, assign ch direction to chtype
|
* if not defined, assign ch direction to chtype
|
||||||
@ -1944,14 +1847,6 @@ static int of_parse_ch_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
mhi_chan->xfer_type = MHI_XFER_SKB;
|
mhi_chan->xfer_type = MHI_XFER_SKB;
|
||||||
else if (chan == MHI_CLIENT_IP_HW_0_IN || chan == MHI_CLIENT_IP_SW_0_IN)
|
else if (chan == MHI_CLIENT_IP_HW_0_IN || chan == MHI_CLIENT_IP_SW_0_IN)
|
||||||
mhi_chan->xfer_type = MHI_XFER_SKB; //MHI_XFER_DMA;
|
mhi_chan->xfer_type = MHI_XFER_SKB; //MHI_XFER_DMA;
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
else if (chan == MHI_CLIENT_ADPL)
|
|
||||||
mhi_chan->xfer_type = MHI_XFER_BUFFER;
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
else if (chan == MHI_CLIENT_IP_HW_QDSS)
|
|
||||||
mhi_chan->xfer_type = MHI_XFER_BUFFER;
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
mhi_chan->xfer_type = MHI_XFER_BUFFER;
|
mhi_chan->xfer_type = MHI_XFER_BUFFER;
|
||||||
|
|
||||||
@ -2009,14 +1904,6 @@ static int of_parse_ch_cfg(struct mhi_controller *mhi_cntrl,
|
|||||||
if (chan == MHI_CLIENT_IP_HW_0_OUT || chan == MHI_CLIENT_IP_HW_0_IN)
|
if (chan == MHI_CLIENT_IP_HW_0_OUT || chan == MHI_CLIENT_IP_HW_0_IN)
|
||||||
mhi_chan->db_cfg.brstmode = MHI_BRSTMODE_ENABLE;
|
mhi_chan->db_cfg.brstmode = MHI_BRSTMODE_ENABLE;
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
if (chan == MHI_CLIENT_ADPL)
|
|
||||||
mhi_chan->db_cfg.brstmode = MHI_BRSTMODE_DISABLE;
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
if (chan == MHI_CLIENT_IP_HW_QDSS)
|
|
||||||
mhi_chan->db_cfg.brstmode = MHI_BRSTMODE_DISABLE;
|
|
||||||
#endif
|
|
||||||
if (MHI_INVALID_BRSTMODE(mhi_chan->db_cfg.brstmode))
|
if (MHI_INVALID_BRSTMODE(mhi_chan->db_cfg.brstmode))
|
||||||
goto error_chan_cfg;
|
goto error_chan_cfg;
|
||||||
|
|
||||||
@ -2055,17 +1942,7 @@ static int of_parse_dt(struct mhi_controller *mhi_cntrl,
|
|||||||
ret = of_parse_ev_cfg(mhi_cntrl, of_node);
|
ret = of_parse_ev_cfg(mhi_cntrl, of_node);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ev_cfg;
|
goto error_ev_cfg;
|
||||||
#if defined(QCOM_AP_QCA6490_DMA_IOMMU)
|
|
||||||
/* for QCS6490 iommu-dma is fastmap
|
|
||||||
for SG845 iommu-dma is set in driver
|
|
||||||
for ipq iommu-dma is disabled
|
|
||||||
*/
|
|
||||||
const char *str;
|
|
||||||
ret = of_property_read_string(of_node, "qcom,iommu-dma", &str);
|
|
||||||
if (ret)
|
|
||||||
MHI_ERR("mhi qcom,iommu-dma need set");
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#if 0
|
#if 0
|
||||||
ret = of_property_read_u32(of_node, "mhi,timeout",
|
ret = of_property_read_u32(of_node, "mhi,timeout",
|
||||||
&mhi_cntrl->timeout_ms);
|
&mhi_cntrl->timeout_ms);
|
||||||
@ -2119,7 +1996,6 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)
|
|||||||
mhi_controller_minors[i].domain = mhi_cntrl->domain;
|
mhi_controller_minors[i].domain = mhi_cntrl->domain;
|
||||||
mhi_controller_minors[i].bus = mhi_cntrl->bus;
|
mhi_controller_minors[i].bus = mhi_cntrl->bus;
|
||||||
mhi_controller_minors[i].slot = mhi_cntrl->slot;
|
mhi_controller_minors[i].slot = mhi_cntrl->slot;
|
||||||
mhi_controller_minors[i].mhi_cntrl = mhi_cntrl;
|
|
||||||
mhi_cntrl->cntrl_idx = i;
|
mhi_cntrl->cntrl_idx = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2672,11 +2548,7 @@ static int __init mhi_cntrl_init(void)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mhi_cntrl_drv.major = ret;
|
mhi_cntrl_drv.major = ret;
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
|
|
||||||
mhi_cntrl_drv.class = class_create(MHI_CNTRL_DRIVER_NAME);
|
|
||||||
#else
|
|
||||||
mhi_cntrl_drv.class = class_create(THIS_MODULE, MHI_CNTRL_DRIVER_NAME);
|
mhi_cntrl_drv.class = class_create(THIS_MODULE, MHI_CNTRL_DRIVER_NAME);
|
||||||
#endif
|
|
||||||
if (IS_ERR(mhi_cntrl_drv.class)) {
|
if (IS_ERR(mhi_cntrl_drv.class)) {
|
||||||
unregister_chrdev(mhi_cntrl_drv.major, MHI_CNTRL_DRIVER_NAME);
|
unregister_chrdev(mhi_cntrl_drv.major, MHI_CNTRL_DRIVER_NAME);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -860,15 +860,6 @@ struct mhi_ctrl_seg
|
|||||||
struct mhi_tre sw_in_chan_ring[NUM_MHI_SW_IP_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_IN_RING_ELEMENTS*16);
|
struct mhi_tre sw_in_chan_ring[NUM_MHI_SW_IP_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_IN_RING_ELEMENTS*16);
|
||||||
struct mhi_tre sw_out_chan_ring[NUM_MHI_SW_IP_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_OUT_RING_ELEMENTS*16);
|
struct mhi_tre sw_out_chan_ring[NUM_MHI_SW_IP_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_OUT_RING_ELEMENTS*16);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
struct mhi_tre adpl_in_chan_ring[NUM_MHI_ADPL_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_IN_RING_ELEMENTS*16);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
struct mhi_tre qdss_in_chan_ring[NUM_MHI_QDSS_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_IN_RING_ELEMENTS*16);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct mhi_tre diag_in_chan_ring[NUM_MHI_DIAG_IN_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_OUT_RING_ELEMENTS*16);
|
struct mhi_tre diag_in_chan_ring[NUM_MHI_DIAG_IN_RING_ELEMENTS] __packed __aligned(NUM_MHI_IPA_OUT_RING_ELEMENTS*16);
|
||||||
struct mhi_tre chan_ring[NUM_MHI_CHAN_RING_ELEMENTS*2*12] __packed __aligned(NUM_MHI_CHAN_RING_ELEMENTS*16);
|
struct mhi_tre chan_ring[NUM_MHI_CHAN_RING_ELEMENTS*2*12] __packed __aligned(NUM_MHI_CHAN_RING_ELEMENTS*16);
|
||||||
struct mhi_tre event_ring[NUM_MHI_EVT_RINGS][NUM_MHI_EVT_RING_ELEMENTS] __packed __aligned(NUM_MHI_EVT_RING_ELEMENTS*16);
|
struct mhi_tre event_ring[NUM_MHI_EVT_RINGS][NUM_MHI_EVT_RING_ELEMENTS] __packed __aligned(NUM_MHI_EVT_RING_ELEMENTS*16);
|
||||||
|
@ -919,7 +919,7 @@ static void mhi_create_time_sync_dev(struct mhi_controller *mhi_cntrl)
|
|||||||
|
|
||||||
mhi_dev->dev_type = MHI_TIMESYNC_TYPE;
|
mhi_dev->dev_type = MHI_TIMESYNC_TYPE;
|
||||||
mhi_dev->chan_name = "TIME_SYNC";
|
mhi_dev->chan_name = "TIME_SYNC";
|
||||||
dev_set_name(&mhi_dev->dev, "%04x_%02x.%02x.%02x_%s", mhi_dev->dev_id,
|
dev_set_name(&mhi_dev->dev, "%04x_%02u.%02u.%02u_%s", mhi_dev->dev_id,
|
||||||
mhi_dev->domain, mhi_dev->bus, mhi_dev->slot,
|
mhi_dev->domain, mhi_dev->bus, mhi_dev->slot,
|
||||||
mhi_dev->chan_name);
|
mhi_dev->chan_name);
|
||||||
|
|
||||||
@ -1012,7 +1012,7 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mhi_dev->chan_name = mhi_chan->name;
|
mhi_dev->chan_name = mhi_chan->name;
|
||||||
dev_set_name(&mhi_dev->dev, "%04x_%02x.%02x.%02x_%s",
|
dev_set_name(&mhi_dev->dev, "%04x_%02u.%02u.%02u_%s",
|
||||||
mhi_dev->dev_id, mhi_dev->domain, mhi_dev->bus,
|
mhi_dev->dev_id, mhi_dev->domain, mhi_dev->bus,
|
||||||
mhi_dev->slot, mhi_dev->chan_name);
|
mhi_dev->slot, mhi_dev->chan_name);
|
||||||
|
|
||||||
|
@ -748,8 +748,6 @@ void mhi_pm_ready_worker(struct work_struct *work)
|
|||||||
schedule_delayed_work(&mhi_cntrl->ready_worker, msecs_to_jiffies(10));
|
schedule_delayed_work(&mhi_cntrl->ready_worker, msecs_to_jiffies(10));
|
||||||
else if (ee == MHI_EE_AMSS || ee == MHI_EE_SBL)
|
else if (ee == MHI_EE_AMSS || ee == MHI_EE_SBL)
|
||||||
mhi_queue_state_transition(mhi_cntrl, MHI_ST_TRANSITION_READY);
|
mhi_queue_state_transition(mhi_cntrl, MHI_ST_TRANSITION_READY);
|
||||||
else if (ee == MHI_EE_EDL)
|
|
||||||
mhi_queue_state_transition(mhi_cntrl, MHI_ST_TRANSITION_PBL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mhi_pm_st_worker(struct work_struct *work)
|
void mhi_pm_st_worker(struct work_struct *work)
|
||||||
|
@ -30,16 +30,9 @@
|
|||||||
#include <net/ipv6.h>
|
#include <net/ipv6.h>
|
||||||
#include <net/tcp.h>
|
#include <net/tcp.h>
|
||||||
#include <linux/usb/cdc.h>
|
#include <linux/usb/cdc.h>
|
||||||
|
|
||||||
//#define CONFIG_IPQ5018_RATE_CONTROL //Only used with spf11.5 for IPQ5018
|
|
||||||
#if defined(CONFIG_IPQ5018_RATE_CONTROL)
|
|
||||||
//#include <linux/jiffies.h>
|
|
||||||
#include <asm/arch_timer.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../core/mhi.h"
|
#include "../core/mhi.h"
|
||||||
|
|
||||||
//#define MHI_NETDEV_ONE_CARD_MODE
|
//#define MHI_NETDEV_ONE_CARD_MODE
|
||||||
//#define ANDROID_gki //some fuction not allow used in this TEST
|
|
||||||
|
|
||||||
#ifndef ETH_P_MAP
|
#ifndef ETH_P_MAP
|
||||||
#define ETH_P_MAP 0xDA1A
|
#define ETH_P_MAP 0xDA1A
|
||||||
@ -68,15 +61,13 @@ struct rmnet_nss_cb {
|
|||||||
int (*nss_tx)(struct sk_buff *skb);
|
int (*nss_tx)(struct sk_buff *skb);
|
||||||
};
|
};
|
||||||
static struct rmnet_nss_cb __read_mostly *nss_cb = NULL;
|
static struct rmnet_nss_cb __read_mostly *nss_cb = NULL;
|
||||||
#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018) || defined(CONFIG_PINCTRL_IPQ8074)
|
#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018)
|
||||||
//#ifdef CONFIG_RMNET_DATA //spf12.x have no macro defined, just for spf11.x
|
#ifdef CONFIG_RMNET_DATA
|
||||||
#define CONFIG_QCA_NSS_DRV
|
#define CONFIG_QCA_NSS_DRV
|
||||||
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */ //for spf11.x
|
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */
|
||||||
/* define at qsdk/qca/src/datarmnet/core/rmnet_config.c */ //for spf12.x
|
|
||||||
/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */
|
/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */
|
||||||
/* need add DEPENDS:= kmod-rmnet-core in feeds/makefile */
|
|
||||||
extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly;
|
extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly;
|
||||||
//#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const unsigned char node_id[ETH_ALEN] = {0x02, 0x50, 0xf4, 0x00, 0x00, 0x00};
|
static const unsigned char node_id[ETH_ALEN] = {0x02, 0x50, 0xf4, 0x00, 0x00, 0x00};
|
||||||
@ -320,7 +311,6 @@ struct mhi_netdev {
|
|||||||
MHI_MBIM_CTX mbim_ctx;
|
MHI_MBIM_CTX mbim_ctx;
|
||||||
|
|
||||||
u32 mru;
|
u32 mru;
|
||||||
u32 max_mtu;
|
|
||||||
const char *interface_name;
|
const char *interface_name;
|
||||||
struct napi_struct napi;
|
struct napi_struct napi;
|
||||||
struct net_device *ndev;
|
struct net_device *ndev;
|
||||||
@ -352,7 +342,7 @@ struct mhi_netdev {
|
|||||||
uint use_rmnet_usb;
|
uint use_rmnet_usb;
|
||||||
RMNET_INFO rmnet_info;
|
RMNET_INFO rmnet_info;
|
||||||
|
|
||||||
#if defined(CONFIG_IPQ5018_RATE_CONTROL)
|
#if defined(CONFIG_PINCTRL_IPQ5018)
|
||||||
u64 first_jiffy;
|
u64 first_jiffy;
|
||||||
u64 bytes_received_1;
|
u64 bytes_received_1;
|
||||||
u64 bytes_received_2;
|
u64 bytes_received_2;
|
||||||
@ -451,20 +441,18 @@ static int bridge_arp_reply(struct net_device *net, struct sk_buff *skb, uint br
|
|||||||
pr_info("%s sip = %d.%d.%d.%d, tip=%d.%d.%d.%d, ipv4=%d.%d.%d.%d\n", netdev_name(net),
|
pr_info("%s sip = %d.%d.%d.%d, tip=%d.%d.%d.%d, ipv4=%d.%d.%d.%d\n", netdev_name(net),
|
||||||
sip[0], sip[1], sip[2], sip[3], tip[0], tip[1], tip[2], tip[3], ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
|
sip[0], sip[1], sip[2], sip[3], tip[0], tip[1], tip[2], tip[3], ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
|
||||||
//wwan0 sip = 10.151.137.255, tip=10.151.138.0, ipv4=10.151.137.255
|
//wwan0 sip = 10.151.137.255, tip=10.151.138.0, ipv4=10.151.137.255
|
||||||
#ifndef ANDROID_gki
|
|
||||||
if (tip[0] == ipv4[0] && tip[1] == ipv4[1] && (tip[2]&0xFC) == (ipv4[2]&0xFC) && tip[3] != ipv4[3])
|
if (tip[0] == ipv4[0] && tip[1] == ipv4[1] && (tip[2]&0xFC) == (ipv4[2]&0xFC) && tip[3] != ipv4[3])
|
||||||
reply = arp_create(ARPOP_REPLY, ETH_P_ARP, *((__be32 *)sip), net, *((__be32 *)tip), sha, default_modem_addr, sha);
|
reply = arp_create(ARPOP_REPLY, ETH_P_ARP, *((__be32 *)sip), net, *((__be32 *)tip), sha, default_modem_addr, sha);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (reply) {
|
if (reply) {
|
||||||
skb_reset_mac_header(reply);
|
skb_reset_mac_header(reply);
|
||||||
__skb_pull(reply, skb_network_offset(reply));
|
__skb_pull(reply, skb_network_offset(reply));
|
||||||
reply->ip_summed = CHECKSUM_UNNECESSARY;
|
reply->ip_summed = CHECKSUM_UNNECESSARY;
|
||||||
reply->pkt_type = PACKET_HOST;
|
reply->pkt_type = PACKET_HOST;
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0))
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
netif_rx(reply);
|
|
||||||
#else
|
|
||||||
netif_rx_ni(reply);
|
netif_rx_ni(reply);
|
||||||
|
#else
|
||||||
|
netif_rx(reply);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -855,12 +843,12 @@ static void rmnet_vnd_upate_rx_stats(struct net_device *net,
|
|||||||
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
|
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
|
||||||
|
|
||||||
u64_stats_update_begin(&stats64->syncp);
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
stats64->rx_packets += rx_packets;
|
stats64->rx_packets += rx_packets;
|
||||||
stats64->rx_bytes += rx_bytes;
|
stats64->rx_bytes += rx_bytes;
|
||||||
#else
|
#else
|
||||||
u64_stats_add(&stats64->rx_packets, rx_packets);
|
u64_stats_add(&stats64->rx_packets, rx_packets);
|
||||||
u64_stats_add(&stats64->rx_bytes, rx_bytes);
|
u64_stats_add(&stats64->rx_bytes,rx_bytes);
|
||||||
#endif
|
#endif
|
||||||
u64_stats_update_end(&stats64->syncp);
|
u64_stats_update_end(&stats64->syncp);
|
||||||
#else
|
#else
|
||||||
@ -876,12 +864,12 @@ static void rmnet_vnd_upate_tx_stats(struct net_device *net,
|
|||||||
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
|
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
|
||||||
|
|
||||||
u64_stats_update_begin(&stats64->syncp);
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
stats64->tx_packets += tx_packets;
|
stats64->tx_packets += tx_packets;
|
||||||
stats64->tx_bytes += tx_bytes;
|
stats64->tx_bytes += tx_bytes;
|
||||||
#else
|
#else
|
||||||
u64_stats_add(&stats64->tx_packets, tx_packets);
|
u64_stats_add(&stats64->tx_packets, tx_packets);
|
||||||
u64_stats_add(&stats64->tx_bytes, tx_bytes);
|
u64_stats_add(&stats64->tx_bytes,tx_bytes);
|
||||||
#endif
|
#endif
|
||||||
u64_stats_update_end(&stats64->syncp);
|
u64_stats_update_end(&stats64->syncp);
|
||||||
#else
|
#else
|
||||||
@ -891,44 +879,13 @@ static void rmnet_vnd_upate_tx_stats(struct net_device *net,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MHI_NETDEV_STATUS64)
|
#if defined(MHI_NETDEV_STATUS64)
|
||||||
#ifdef ANDROID_gki
|
|
||||||
static void _netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
|
|
||||||
const struct net_device_stats *netdev_stats)
|
|
||||||
{
|
|
||||||
#if BITS_PER_LONG == 64
|
|
||||||
BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats));
|
|
||||||
memcpy(stats64, netdev_stats, sizeof(*netdev_stats));
|
|
||||||
/* zero out counters that only exist in rtnl_link_stats64 */
|
|
||||||
memset((char *)stats64 + sizeof(*netdev_stats), 0,
|
|
||||||
sizeof(*stats64) - sizeof(*netdev_stats));
|
|
||||||
#else
|
|
||||||
size_t i, n = sizeof(*netdev_stats) / sizeof(unsigned long);
|
|
||||||
const unsigned long *src = (const unsigned long *)netdev_stats;
|
|
||||||
u64 *dst = (u64 *)stats64;
|
|
||||||
|
|
||||||
BUILD_BUG_ON(n > sizeof(*stats64) / sizeof(u64));
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
dst[i] = src[i];
|
|
||||||
/* zero out counters that only exist in rtnl_link_stats64 */
|
|
||||||
memset((char *)stats64 + n * sizeof(u64), 0,
|
|
||||||
sizeof(*stats64) - n * sizeof(u64));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void my_netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
|
|
||||||
const struct net_device_stats *netdev_stats)
|
|
||||||
{
|
|
||||||
netdev_stats_to_stats64(stats64, netdev_stats);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats)
|
static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats)
|
||||||
{
|
{
|
||||||
struct qmap_priv *dev = netdev_priv(net);
|
struct qmap_priv *dev = netdev_priv(net);
|
||||||
unsigned int start;
|
unsigned int start;
|
||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
my_netdev_stats_to_stats64(stats, &net->stats);
|
netdev_stats_to_stats64(stats, &net->stats);
|
||||||
|
|
||||||
if (nss_cb && dev->use_qca_nss) { // rmnet_nss.c:rmnet_nss_tx() will update rx stats
|
if (nss_cb && dev->use_qca_nss) { // rmnet_nss.c:rmnet_nss_tx() will update rx stats
|
||||||
stats->rx_packets = 0;
|
stats->rx_packets = 0;
|
||||||
@ -937,7 +894,6 @@ static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net,
|
|||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
struct pcpu_sw_netstats *stats64;
|
struct pcpu_sw_netstats *stats64;
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
|
|
||||||
u64 rx_packets, rx_bytes;
|
u64 rx_packets, rx_bytes;
|
||||||
u64 tx_packets, tx_bytes;
|
u64 tx_packets, tx_bytes;
|
||||||
|
|
||||||
@ -945,35 +901,23 @@ static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net,
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
rx_packets = stats64->rx_packets;
|
rx_packets = stats64->rx_packets;
|
||||||
rx_bytes = stats64->rx_bytes;
|
rx_bytes = stats64->rx_bytes;
|
||||||
tx_packets = stats64->tx_packets;
|
tx_packets = stats64->tx_packets;
|
||||||
tx_bytes = stats64->tx_bytes;
|
tx_bytes = stats64->tx_bytes;
|
||||||
|
#else
|
||||||
|
rx_packets = u64_stats_read(&stats64->rx_packets);
|
||||||
|
rx_bytes = u64_stats_read(&stats64->rx_bytes);
|
||||||
|
tx_packets = u64_stats_read(&stats64->tx_packets);
|
||||||
|
tx_bytes = u64_stats_read(&stats64->tx_bytes);
|
||||||
|
#endif
|
||||||
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
||||||
|
|
||||||
stats->rx_packets += rx_packets;
|
stats->rx_packets += rx_packets;
|
||||||
stats->rx_bytes += rx_bytes;
|
stats->rx_bytes += rx_bytes;
|
||||||
stats->tx_packets += tx_packets;
|
stats->tx_packets += tx_packets;
|
||||||
stats->tx_bytes += tx_bytes;
|
stats->tx_bytes += tx_bytes;
|
||||||
#else
|
|
||||||
u64_stats_t rx_packets, rx_bytes;
|
|
||||||
u64_stats_t tx_packets, tx_bytes;
|
|
||||||
|
|
||||||
stats64 = per_cpu_ptr(dev->stats64, cpu);
|
|
||||||
|
|
||||||
do {
|
|
||||||
start = u64_stats_fetch_begin(&stats64->syncp);
|
|
||||||
rx_packets = stats64->rx_packets;
|
|
||||||
rx_bytes = stats64->rx_bytes;
|
|
||||||
tx_packets = stats64->tx_packets;
|
|
||||||
tx_bytes = stats64->tx_bytes;
|
|
||||||
} while (u64_stats_fetch_retry(&stats64->syncp, start));
|
|
||||||
|
|
||||||
stats->rx_packets += u64_stats_read(&rx_packets);
|
|
||||||
stats->rx_bytes += u64_stats_read(&rx_bytes);
|
|
||||||
stats->tx_packets += u64_stats_read(&tx_packets);
|
|
||||||
stats->tx_bytes += u64_stats_read(&tx_bytes);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return stats;
|
return stats;
|
||||||
@ -1111,22 +1055,8 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
|
|||||||
|
|
||||||
static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu)
|
static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu)
|
||||||
{
|
{
|
||||||
struct mhi_netdev *mhi_netdev;
|
if (new_mtu < 0 || new_mtu > 1500)
|
||||||
|
|
||||||
mhi_netdev = (struct mhi_netdev *)ndev_to_mhi(rmnet_dev);
|
|
||||||
|
|
||||||
if (mhi_netdev == NULL) {
|
|
||||||
printk("warning, mhi_netdev == null\n");
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
if (new_mtu < 0 )
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (new_mtu > mhi_netdev->max_mtu) {
|
|
||||||
printk("warning, set mtu=%d greater than max mtu=%d\n", new_mtu, mhi_netdev->max_mtu);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rmnet_dev->mtu = new_mtu;
|
rmnet_dev->mtu = new_mtu;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1278,7 +1208,7 @@ static void rmnet_mbim_rx_handler(void *dev, struct sk_buff *skb_in)
|
|||||||
MSG_ERR("unsupported tci %d by now\n", tci);
|
MSG_ERR("unsupported tci %d by now\n", tci);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
tci = abs(tci);
|
|
||||||
qmap_net = pQmapDev->mpQmapNetDev[qmap_mode == 1 ? 0 : tci - 1];
|
qmap_net = pQmapDev->mpQmapNetDev[qmap_mode == 1 ? 0 : tci - 1];
|
||||||
|
|
||||||
dpe16 = ndp16->dpe16;
|
dpe16 = ndp16->dpe16;
|
||||||
@ -1407,21 +1337,8 @@ static void rmnet_qmi_rx_handler(void *dev, struct sk_buff *skb_in)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
skb_len -= dl_minimum_padding;
|
skb_len -= dl_minimum_padding;
|
||||||
|
if (skb_len > 1500) {
|
||||||
mux_id = map_header->mux_id - QUECTEL_QMAP_MUX_ID;
|
netdev_info(ndev, "drop skb_len=%x larger than 1500\n", skb_len);
|
||||||
if (mux_id >= pQmapDev->qmap_mode) {
|
|
||||||
netdev_info(ndev, "drop qmap unknow mux_id %x\n", map_header->mux_id);
|
|
||||||
goto error_pkt;
|
|
||||||
}
|
|
||||||
mux_id = abs(mux_id);
|
|
||||||
qmap_net = pQmapDev->mpQmapNetDev[mux_id];
|
|
||||||
if (qmap_net == NULL) {
|
|
||||||
netdev_info(ndev, "drop qmap unknow mux_id %x\n", map_header->mux_id);
|
|
||||||
goto skip_pkt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skb_len > qmap_net->mtu) {
|
|
||||||
netdev_info(ndev, "drop skb_len=%x larger than qmap mtu=%d\n", skb_len, qmap_net->mtu);
|
|
||||||
goto error_pkt;
|
goto error_pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1462,6 +1379,19 @@ static void rmnet_qmi_rx_handler(void *dev, struct sk_buff *skb_in)
|
|||||||
netdev_info(ndev, "unknow skb->protocol %02x\n", skb_in->data[hdr_size]);
|
netdev_info(ndev, "unknow skb->protocol %02x\n", skb_in->data[hdr_size]);
|
||||||
goto error_pkt;
|
goto error_pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mux_id = map_header->mux_id - QUECTEL_QMAP_MUX_ID;
|
||||||
|
if (mux_id >= pQmapDev->qmap_mode) {
|
||||||
|
netdev_info(ndev, "drop qmap unknow mux_id %x\n", map_header->mux_id);
|
||||||
|
goto error_pkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
qmap_net = pQmapDev->mpQmapNetDev[mux_id];
|
||||||
|
|
||||||
|
if (qmap_net == NULL) {
|
||||||
|
netdev_info(ndev, "drop qmap unknow mux_id %x\n", map_header->mux_id);
|
||||||
|
goto skip_pkt;
|
||||||
|
}
|
||||||
|
|
||||||
//for Qualcomm's SFE, do not use skb_clone(), or SFE 's performace is very bad.
|
//for Qualcomm's SFE, do not use skb_clone(), or SFE 's performace is very bad.
|
||||||
//for Qualcomm's NSS, do not use skb_clone(), or NSS 's performace is very bad.
|
//for Qualcomm's NSS, do not use skb_clone(), or NSS 's performace is very bad.
|
||||||
@ -1575,8 +1505,7 @@ static struct net_device * rmnet_vnd_register_device(struct mhi_netdev *pQmapDev
|
|||||||
struct qmap_priv *priv;
|
struct qmap_priv *priv;
|
||||||
int err;
|
int err;
|
||||||
int use_qca_nss = !!nss_cb;
|
int use_qca_nss = !!nss_cb;
|
||||||
unsigned char temp_addr[ETH_ALEN];
|
u8 maddr[ETH_ALEN];
|
||||||
|
|
||||||
qmap_net = alloc_etherdev(sizeof(*priv));
|
qmap_net = alloc_etherdev(sizeof(*priv));
|
||||||
if (!qmap_net)
|
if (!qmap_net)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1589,21 +1518,11 @@ static struct net_device * rmnet_vnd_register_device(struct mhi_netdev *pQmapDev
|
|||||||
priv->pQmapDev = pQmapDev;
|
priv->pQmapDev = pQmapDev;
|
||||||
priv->qmap_version = pQmapDev->qmap_version;
|
priv->qmap_version = pQmapDev->qmap_version;
|
||||||
priv->mux_id = mux_id;
|
priv->mux_id = mux_id;
|
||||||
sprintf(qmap_net->name, "%.12s.%d", real_dev->name, offset_id + 1);
|
sprintf(qmap_net->name, "%s.%d", real_dev->name, offset_id + 1);
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
|
ether_addr_copy(maddr, real_dev->dev_addr);
|
||||||
__dev_addr_set(qmap_net, real_dev->dev_addr, ETH_ALEN);
|
maddr[5]= offset_id + 1;
|
||||||
#else
|
ether_addr_copy((u8*)qmap_net->dev_addr, maddr);
|
||||||
memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
|
//eth_random_addr(qmap_net->dev_addr);
|
||||||
#endif
|
|
||||||
//qmap_net->dev_addr[5] = offset_id + 1;
|
|
||||||
//eth_random_addr(qmap_net->dev_addr);
|
|
||||||
memcpy(temp_addr, qmap_net->dev_addr, ETH_ALEN);
|
|
||||||
temp_addr[5] = offset_id + 1;
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
|
|
||||||
__dev_addr_set(qmap_net, temp_addr, ETH_ALEN);
|
|
||||||
#else
|
|
||||||
memcpy(qmap_net->dev_addr, temp_addr, ETH_ALEN);
|
|
||||||
#endif
|
|
||||||
#if defined(MHI_NETDEV_STATUS64)
|
#if defined(MHI_NETDEV_STATUS64)
|
||||||
priv->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
priv->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
||||||
if (!priv->stats64)
|
if (!priv->stats64)
|
||||||
@ -1630,16 +1549,11 @@ static struct net_device * rmnet_vnd_register_device(struct mhi_netdev *pQmapDev
|
|||||||
qmap_net->netdev_ops = &rmnet_vnd_ops;
|
qmap_net->netdev_ops = &rmnet_vnd_ops;
|
||||||
qmap_net->flags |= IFF_NOARP;
|
qmap_net->flags |= IFF_NOARP;
|
||||||
qmap_net->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
|
qmap_net->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
||||||
qmap_net->max_mtu = pQmapDev->max_mtu;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (nss_cb && use_qca_nss) {
|
if (nss_cb && use_qca_nss) {
|
||||||
rmnet_vnd_rawip_setup(qmap_net);
|
rmnet_vnd_rawip_setup(qmap_net);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_PINCTRL_IPQ9574
|
|
||||||
rmnet_vnd_rawip_setup(qmap_net);
|
|
||||||
#endif
|
|
||||||
if (pQmapDev->net_type == MHI_NET_MBIM) {
|
if (pQmapDev->net_type == MHI_NET_MBIM) {
|
||||||
qmap_net->needed_headroom = sizeof(struct mhi_mbim_hdr);
|
qmap_net->needed_headroom = sizeof(struct mhi_mbim_hdr);
|
||||||
}
|
}
|
||||||
@ -1812,13 +1726,14 @@ static void mhi_netdev_upate_rx_stats(struct mhi_netdev *mhi_netdev,
|
|||||||
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(mhi_netdev->stats64);
|
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(mhi_netdev->stats64);
|
||||||
|
|
||||||
u64_stats_update_begin(&stats64->syncp);
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
stats64->rx_packets += rx_packets;
|
stats64->rx_packets += rx_packets;
|
||||||
stats64->rx_bytes += rx_bytes;
|
stats64->rx_bytes += rx_bytes;
|
||||||
#else
|
#else
|
||||||
u64_stats_add(&stats64->rx_packets, rx_packets);
|
u64_stats_add(&stats64->rx_packets, rx_packets);
|
||||||
u64_stats_add(&stats64->rx_bytes, rx_bytes);
|
u64_stats_add(&stats64->rx_bytes,rx_bytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u64_stats_update_begin(&stats64->syncp);
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
#else
|
#else
|
||||||
mhi_netdev->ndev->stats.rx_packets += rx_packets;
|
mhi_netdev->ndev->stats.rx_packets += rx_packets;
|
||||||
@ -1832,13 +1747,14 @@ static void mhi_netdev_upate_tx_stats(struct mhi_netdev *mhi_netdev,
|
|||||||
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(mhi_netdev->stats64);
|
struct pcpu_sw_netstats *stats64 = this_cpu_ptr(mhi_netdev->stats64);
|
||||||
|
|
||||||
u64_stats_update_begin(&stats64->syncp);
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
stats64->tx_packets += tx_packets;
|
stats64->tx_packets += tx_packets;
|
||||||
stats64->tx_bytes += tx_bytes;
|
stats64->tx_bytes += tx_bytes;
|
||||||
#else
|
#else
|
||||||
u64_stats_add(&stats64->tx_packets, tx_packets);
|
u64_stats_add(&stats64->tx_packets, tx_packets);
|
||||||
u64_stats_add(&stats64->tx_bytes, tx_bytes);
|
u64_stats_add(&stats64->tx_bytes,tx_bytes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u64_stats_update_begin(&stats64->syncp);
|
u64_stats_update_begin(&stats64->syncp);
|
||||||
#else
|
#else
|
||||||
mhi_netdev->ndev->stats.tx_packets += tx_packets;
|
mhi_netdev->ndev->stats.tx_packets += tx_packets;
|
||||||
@ -2090,9 +2006,7 @@ static netdev_tx_t mhi_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
//qmap_hex_dump(__func__, skb->data, 32);
|
//qmap_hex_dump(__func__, skb->data, 32);
|
||||||
|
|
||||||
#ifdef MHI_NETDEV_ONE_CARD_MODE
|
#ifdef MHI_NETDEV_ONE_CARD_MODE
|
||||||
//printk("%s dev->type=%d\n", __func__, dev->type);
|
if (dev->type == ARPHRD_ETHER) {
|
||||||
|
|
||||||
if (dev->type == ARPHRD_ETHER) {
|
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
|
|
||||||
#ifdef QUECTEL_BRIDGE_MODE
|
#ifdef QUECTEL_BRIDGE_MODE
|
||||||
@ -2154,8 +2068,6 @@ static netdev_tx_t mhi_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||||||
|
|
||||||
res = mhi_queue_transfer(mhi_dev, DMA_TO_DEVICE, skb, skb->len,
|
res = mhi_queue_transfer(mhi_dev, DMA_TO_DEVICE, skb, skb->len,
|
||||||
MHI_EOT);
|
MHI_EOT);
|
||||||
|
|
||||||
//printk("%s transfer res=%d\n", __func__, res);
|
|
||||||
if (unlikely(res)) {
|
if (unlikely(res)) {
|
||||||
dev_kfree_skb_any(skb);
|
dev_kfree_skb_any(skb);
|
||||||
dev->stats.tx_errors++;
|
dev->stats.tx_errors++;
|
||||||
@ -2178,7 +2090,6 @@ static struct rtnl_link_stats64 * _mhi_netdev_get_stats64(struct net_device *nde
|
|||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
struct pcpu_sw_netstats *stats64;
|
struct pcpu_sw_netstats *stats64;
|
||||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0))
|
|
||||||
u64 rx_packets, rx_bytes;
|
u64 rx_packets, rx_bytes;
|
||||||
u64 tx_packets, tx_bytes;
|
u64 tx_packets, tx_bytes;
|
||||||
|
|
||||||
@ -2186,35 +2097,23 @@ static struct rtnl_link_stats64 * _mhi_netdev_get_stats64(struct net_device *nde
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
start = u64_stats_fetch_begin_irq(&stats64->syncp);
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,18,0)
|
||||||
rx_packets = stats64->rx_packets;
|
rx_packets = stats64->rx_packets;
|
||||||
rx_bytes = stats64->rx_bytes;
|
rx_bytes = stats64->rx_bytes;
|
||||||
tx_packets = stats64->tx_packets;
|
tx_packets = stats64->tx_packets;
|
||||||
tx_bytes = stats64->tx_bytes;
|
tx_bytes = stats64->tx_bytes;
|
||||||
|
#else
|
||||||
|
rx_packets = u64_stats_read(&stats64->rx_packets);
|
||||||
|
rx_bytes = u64_stats_read(&stats64->rx_bytes);
|
||||||
|
tx_packets = u64_stats_read(&stats64->tx_packets);
|
||||||
|
tx_bytes = u64_stats_read(&stats64->tx_bytes);
|
||||||
|
#endif
|
||||||
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
} while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
|
||||||
|
|
||||||
stats->rx_packets += rx_packets;
|
stats->rx_packets += rx_packets;
|
||||||
stats->rx_bytes += rx_bytes;
|
stats->rx_bytes += rx_bytes;
|
||||||
stats->tx_packets += tx_packets;
|
stats->tx_packets += tx_packets;
|
||||||
stats->tx_bytes += tx_bytes;
|
stats->tx_bytes += tx_bytes;
|
||||||
#else
|
|
||||||
u64_stats_t rx_packets, rx_bytes;
|
|
||||||
u64_stats_t tx_packets, tx_bytes;
|
|
||||||
|
|
||||||
stats64 = per_cpu_ptr(mhi_netdev->stats64, cpu);
|
|
||||||
|
|
||||||
do {
|
|
||||||
start = u64_stats_fetch_begin(&stats64->syncp);
|
|
||||||
rx_packets = stats64->rx_packets;
|
|
||||||
rx_bytes = stats64->rx_bytes;
|
|
||||||
tx_packets = stats64->tx_packets;
|
|
||||||
tx_bytes = stats64->tx_bytes;
|
|
||||||
} while (u64_stats_fetch_retry(&stats64->syncp, start));
|
|
||||||
|
|
||||||
stats->rx_packets += u64_stats_read(&rx_packets);
|
|
||||||
stats->rx_bytes += u64_stats_read(&rx_bytes);
|
|
||||||
stats->tx_packets += u64_stats_read(&tx_packets);
|
|
||||||
stats->tx_bytes += u64_stats_read(&tx_bytes);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return stats;
|
return stats;
|
||||||
@ -2323,11 +2222,7 @@ static void mhi_netdev_setup(struct net_device *dev)
|
|||||||
ether_setup(dev);
|
ether_setup(dev);
|
||||||
|
|
||||||
dev->ethtool_ops = &mhi_netdev_ethtool_ops;
|
dev->ethtool_ops = &mhi_netdev_ethtool_ops;
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
|
|
||||||
__dev_addr_set (dev, node_id, sizeof node_id);
|
|
||||||
#else
|
|
||||||
memcpy (dev->dev_addr, node_id, sizeof node_id);
|
memcpy (dev->dev_addr, node_id, sizeof node_id);
|
||||||
#endif
|
|
||||||
/* set this after calling ether_setup */
|
/* set this after calling ether_setup */
|
||||||
dev->header_ops = 0; /* No header */
|
dev->header_ops = 0; /* No header */
|
||||||
dev->hard_header_len = 0;
|
dev->hard_header_len = 0;
|
||||||
@ -2414,11 +2309,7 @@ static int mhi_netdev_enable_iface(struct mhi_netdev *mhi_netdev)
|
|||||||
mhi_netdev->ndev->mtu = mhi_netdev->mru;
|
mhi_netdev->ndev->mtu = mhi_netdev->mru;
|
||||||
}
|
}
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||||
mhi_netdev->ndev->max_mtu = mhi_netdev->max_mtu; //first net card
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
|
|
||||||
netif_napi_add_weight(mhi_netdev->ndev, &mhi_netdev->napi, mhi_netdev_poll, poll_weight);
|
netif_napi_add_weight(mhi_netdev->ndev, &mhi_netdev->napi, mhi_netdev_poll, poll_weight);
|
||||||
#else
|
#else
|
||||||
netif_napi_add(mhi_netdev->ndev, &mhi_netdev->napi, mhi_netdev_poll, poll_weight);
|
netif_napi_add(mhi_netdev->ndev, &mhi_netdev->napi, mhi_netdev_poll, poll_weight);
|
||||||
@ -2519,7 +2410,7 @@ static void mhi_netdev_xfer_dl_cb(struct mhi_device *mhi_dev,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_IPQ5018_RATE_CONTROL)
|
#if defined(CONFIG_PINCTRL_IPQ5018)
|
||||||
if (likely(mhi_netdev->mhi_rate_control)) {
|
if (likely(mhi_netdev->mhi_rate_control)) {
|
||||||
u32 time_interval = 0;
|
u32 time_interval = 0;
|
||||||
u32 time_difference = 0;
|
u32 time_difference = 0;
|
||||||
@ -2529,11 +2420,7 @@ static void mhi_netdev_xfer_dl_cb(struct mhi_device *mhi_dev,
|
|||||||
struct net_device *ndev = mhi_netdev->ndev;
|
struct net_device *ndev = mhi_netdev->ndev;
|
||||||
|
|
||||||
if (mhi_netdev->first_jiffy) {
|
if (mhi_netdev->first_jiffy) {
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
|
|
||||||
second_jiffy = arch_counter_get_cntvct();
|
second_jiffy = arch_counter_get_cntvct();
|
||||||
#else
|
|
||||||
second_jiffy = __arch_counter_get_cntvct();
|
|
||||||
#endif
|
|
||||||
bytes_received_2 = mhi_netdev->bytes_received_2;
|
bytes_received_2 = mhi_netdev->bytes_received_2;
|
||||||
if ((second_jiffy > mhi_netdev->first_jiffy) &&
|
if ((second_jiffy > mhi_netdev->first_jiffy) &&
|
||||||
(bytes_received_2 > mhi_netdev->bytes_received_1)) {
|
(bytes_received_2 > mhi_netdev->bytes_received_1)) {
|
||||||
@ -2574,12 +2461,7 @@ static void mhi_netdev_xfer_dl_cb(struct mhi_device *mhi_dev,
|
|||||||
mhi_netdev->bytes_received_1 = bytes_received_2;
|
mhi_netdev->bytes_received_1 = bytes_received_2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
|
|
||||||
mhi_netdev->first_jiffy = arch_counter_get_cntvct();
|
mhi_netdev->first_jiffy = arch_counter_get_cntvct();
|
||||||
#else
|
|
||||||
mhi_netdev->first_jiffy = __arch_counter_get_cntvct();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cntfrq = arch_timer_get_cntfrq();
|
cntfrq = arch_timer_get_cntfrq();
|
||||||
mhi_netdev->cntfrq_per_msec = cntfrq / 1000;
|
mhi_netdev->cntfrq_per_msec = cntfrq / 1000;
|
||||||
}
|
}
|
||||||
@ -2829,11 +2711,7 @@ static void mhi_netdev_remove(struct mhi_device *mhi_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
#ifdef ANDROID_gki
|
|
||||||
if (mhi_netdev->ndev && rtnl_dereference(mhi_netdev->ndev->rx_handler))
|
|
||||||
#else
|
|
||||||
if (netdev_is_rx_handler_busy(mhi_netdev->ndev))
|
if (netdev_is_rx_handler_busy(mhi_netdev->ndev))
|
||||||
#endif
|
|
||||||
netdev_rx_handler_unregister(mhi_netdev->ndev);
|
netdev_rx_handler_unregister(mhi_netdev->ndev);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
#endif
|
#endif
|
||||||
@ -2891,16 +2769,13 @@ static int mhi_netdev_probe(struct mhi_device *mhi_dev,
|
|||||||
mhi_netdev->mhi_dev = mhi_dev;
|
mhi_netdev->mhi_dev = mhi_dev;
|
||||||
mhi_device_set_devdata(mhi_dev, mhi_netdev);
|
mhi_device_set_devdata(mhi_dev, mhi_netdev);
|
||||||
|
|
||||||
mhi_netdev->mru = (15*1024); ///etc/data/qnicorn_config.xml dataformat_agg_dl_size 15*1024
|
mhi_netdev->mru = 15360; ///etc/data/qnicorn_config.xml dataformat_agg_dl_size 15*1024
|
||||||
mhi_netdev->max_mtu = mhi_netdev->mru - (sizeof(struct rmnet_map_v5_csum_header) + sizeof(struct rmnet_map_header));
|
|
||||||
if (mhi_netdev->net_type == MHI_NET_MBIM) {
|
if (mhi_netdev->net_type == MHI_NET_MBIM) {
|
||||||
mhi_netdev->mru = ncmNTBParams.dwNtbInMaxSize;
|
mhi_netdev->mru = ncmNTBParams.dwNtbInMaxSize;
|
||||||
mhi_netdev->mbim_ctx.rx_max = mhi_netdev->mru;
|
mhi_netdev->mbim_ctx.rx_max = mhi_netdev->mru;
|
||||||
mhi_netdev->max_mtu = mhi_netdev->mru - sizeof(struct mhi_mbim_hdr);
|
|
||||||
}
|
}
|
||||||
else if (mhi_netdev->net_type == MHI_NET_ETHER) {
|
else if (mhi_netdev->net_type == MHI_NET_ETHER) {
|
||||||
mhi_netdev->mru = 8*1024;
|
mhi_netdev->mru = 8*1024;
|
||||||
mhi_netdev->max_mtu = mhi_netdev->mru;
|
|
||||||
}
|
}
|
||||||
mhi_netdev->qmap_size = mhi_netdev->mru;
|
mhi_netdev->qmap_size = mhi_netdev->mru;
|
||||||
|
|
||||||
@ -2983,7 +2858,7 @@ static int mhi_netdev_probe(struct mhi_device *mhi_dev,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_IPQ5018_RATE_CONTROL)
|
#if defined(CONFIG_PINCTRL_IPQ5018)
|
||||||
mhi_netdev->mhi_rate_control = 1;
|
mhi_netdev->mhi_rate_control = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2993,8 +2868,7 @@ static int mhi_netdev_probe(struct mhi_device *mhi_dev,
|
|||||||
static const struct mhi_device_id mhi_netdev_match_table[] = {
|
static const struct mhi_device_id mhi_netdev_match_table[] = {
|
||||||
{ .chan = "IP_HW0" },
|
{ .chan = "IP_HW0" },
|
||||||
{ .chan = "IP_SW0" },
|
{ .chan = "IP_SW0" },
|
||||||
// ADPL do not register as a netcard. xingduo.du 2023-02-20
|
{ .chan = "IP_HW_ADPL" },
|
||||||
// { .chan = "IP_HW_ADPL" },
|
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3019,7 +2893,7 @@ int __init mhi_device_netdev_init(struct dentry *parent)
|
|||||||
printk(KERN_ERR "mhi_device_netdev_init: driver load must after '/etc/modules.d/42-rmnet-nss'\n");
|
printk(KERN_ERR "mhi_device_netdev_init: driver load must after '/etc/modules.d/42-rmnet-nss'\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mhi_netdev_create_debugfs_dir(parent);
|
mhi_netdev_create_debugfs_dir(parent);
|
||||||
|
|
||||||
return mhi_driver_register(&mhi_netdev_driver);
|
return mhi_driver_register(&mhi_netdev_driver);
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
static inline void *ipc_log_context_create(int max_num_pages,
|
static inline void *ipc_log_context_create(int max_num_pages,
|
||||||
const char *modname, uint16_t user_version)
|
const char *modname, uint16_t user_version)
|
||||||
@ -98,44 +99,6 @@ module_param( uci_msg_lvl, uint, S_IRUGO | S_IWUSR);
|
|||||||
#define MAX_UCI_DEVICES (64)
|
#define MAX_UCI_DEVICES (64)
|
||||||
#define QUEC_MHI_UCI_ALWAYS_OPEN //by now, sdx20 can not handle "start-reset-start" operation, so the simply solution is keep start state
|
#define QUEC_MHI_UCI_ALWAYS_OPEN //by now, sdx20 can not handle "start-reset-start" operation, so the simply solution is keep start state
|
||||||
|
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
|
|
||||||
#ifdef TCGETS2
|
|
||||||
__weak int user_termios_to_kernel_termios(struct ktermios *k,
|
|
||||||
struct termios2 __user *u)
|
|
||||||
{
|
|
||||||
return copy_from_user(k, u, sizeof(struct termios2));
|
|
||||||
}
|
|
||||||
__weak int kernel_termios_to_user_termios(struct termios2 __user *u,
|
|
||||||
struct ktermios *k)
|
|
||||||
{
|
|
||||||
return copy_to_user(u, k, sizeof(struct termios2));
|
|
||||||
}
|
|
||||||
__weak int user_termios_to_kernel_termios_1(struct ktermios *k,
|
|
||||||
struct termios __user *u)
|
|
||||||
{
|
|
||||||
return copy_from_user(k, u, sizeof(struct termios));
|
|
||||||
}
|
|
||||||
__weak int kernel_termios_to_user_termios_1(struct termios __user *u,
|
|
||||||
struct ktermios *k)
|
|
||||||
{
|
|
||||||
return copy_to_user(u, k, sizeof(struct termios));
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
__weak int user_termios_to_kernel_termios(struct ktermios *k,
|
|
||||||
struct termios __user *u)
|
|
||||||
{
|
|
||||||
return copy_from_user(k, u, sizeof(struct termios));
|
|
||||||
}
|
|
||||||
__weak int kernel_termios_to_user_termios(struct termios __user *u,
|
|
||||||
struct ktermios *k)
|
|
||||||
{
|
|
||||||
return copy_to_user(u, k, sizeof(struct termios));
|
|
||||||
}
|
|
||||||
#endif /* TCGETS2 */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
|
static DECLARE_BITMAP(uci_minors, MAX_UCI_DEVICES);
|
||||||
static struct mhi_uci_drv mhi_uci_drv;
|
static struct mhi_uci_drv mhi_uci_drv;
|
||||||
|
|
||||||
@ -197,7 +160,20 @@ static int mhi_queue_inbound(struct uci_dev *uci_dev)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
|
||||||
|
#ifdef TCGETS2
|
||||||
|
static int kernel_termios_to_user_termios_1(struct termios __user *u,
|
||||||
|
struct ktermios *k)
|
||||||
|
{
|
||||||
|
return copy_to_user(u, k, sizeof(struct termios));
|
||||||
|
}
|
||||||
|
static int user_termios_to_kernel_termios_1(struct ktermios *k,
|
||||||
|
struct termios __user *u)
|
||||||
|
{
|
||||||
|
return copy_from_user(k, u, sizeof(struct termios));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
static long mhi_uci_ioctl(struct file *file,
|
static long mhi_uci_ioctl(struct file *file,
|
||||||
unsigned int cmd,
|
unsigned int cmd,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
@ -295,8 +271,7 @@ static unsigned int mhi_uci_poll(struct file *file, poll_table *wait)
|
|||||||
unsigned int mask = 0;
|
unsigned int mask = 0;
|
||||||
|
|
||||||
poll_wait(file, &uci_dev->dl_chan.wq, wait);
|
poll_wait(file, &uci_dev->dl_chan.wq, wait);
|
||||||
// ADPL and QDSS do not need poll write. xingduo.du 2023-02-16
|
poll_wait(file, &uci_dev->ul_chan.wq, wait);
|
||||||
// poll_wait(file, &uci_dev->ul_chan.wq, wait);
|
|
||||||
|
|
||||||
uci_chan = &uci_dev->dl_chan;
|
uci_chan = &uci_dev->dl_chan;
|
||||||
spin_lock_bh(&uci_chan->lock);
|
spin_lock_bh(&uci_chan->lock);
|
||||||
@ -308,26 +283,22 @@ static unsigned int mhi_uci_poll(struct file *file, poll_table *wait)
|
|||||||
}
|
}
|
||||||
spin_unlock_bh(&uci_chan->lock);
|
spin_unlock_bh(&uci_chan->lock);
|
||||||
|
|
||||||
// ADPL and QDSS are single channel, ul_chan not be initilized. xingduo.du 2023-02-27
|
uci_chan = &uci_dev->ul_chan;
|
||||||
if (mhi_dev->ul_chan) {
|
spin_lock_bh(&uci_chan->lock);
|
||||||
poll_wait(file, &uci_dev->ul_chan.wq, wait);
|
if (!uci_dev->enabled) {
|
||||||
uci_chan = &uci_dev->ul_chan;
|
mask |= POLLERR;
|
||||||
spin_lock_bh(&uci_chan->lock);
|
} else if (mhi_get_no_free_descriptors(mhi_dev, DMA_TO_DEVICE) > 0) {
|
||||||
if (!uci_dev->enabled) {
|
MSG_VERB("Client can write to node\n");
|
||||||
mask |= POLLERR;
|
mask |= POLLOUT | POLLWRNORM;
|
||||||
} else if (mhi_get_no_free_descriptors(mhi_dev, DMA_TO_DEVICE) > 0) {
|
|
||||||
MSG_VERB("Client can write to node\n");
|
|
||||||
mask |= POLLOUT | POLLWRNORM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uci_dev->enabled)
|
|
||||||
mask |= POLLHUP;
|
|
||||||
if (uci_dev->rx_error)
|
|
||||||
mask |= POLLERR;
|
|
||||||
|
|
||||||
spin_unlock_bh(&uci_chan->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!uci_dev->enabled)
|
||||||
|
mask |= POLLHUP;
|
||||||
|
if (uci_dev->rx_error)
|
||||||
|
mask |= POLLERR;
|
||||||
|
|
||||||
|
spin_unlock_bh(&uci_chan->lock);
|
||||||
|
|
||||||
MSG_LOG("Client attempted to poll, returning mask 0x%x\n", mask);
|
MSG_LOG("Client attempted to poll, returning mask 0x%x\n", mask);
|
||||||
|
|
||||||
return mask;
|
return mask;
|
||||||
@ -822,10 +793,6 @@ static void mhi_dl_xfer_cb(struct mhi_device *mhi_dev,
|
|||||||
unsigned nr_trb = uci_dev->nr_trb;
|
unsigned nr_trb = uci_dev->nr_trb;
|
||||||
|
|
||||||
buf = &uci_dev->uci_buf[nr_trb];
|
buf = &uci_dev->uci_buf[nr_trb];
|
||||||
if (buf == NULL) {
|
|
||||||
MSG_ERR("buf = NULL");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (buf->nr_trb != nr_trb || buf->data != mhi_result->buf_addr)
|
if (buf->nr_trb != nr_trb || buf->data != mhi_result->buf_addr)
|
||||||
{
|
{
|
||||||
uci_dev->rx_error++;
|
uci_dev->rx_error++;
|
||||||
@ -908,8 +875,7 @@ static void mhi_dl_xfer_cb(struct mhi_device *mhi_dev,
|
|||||||
wake_up(&uci_chan->wq);
|
wake_up(&uci_chan->wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// repaire sdx6x module can not read qdb file. xingduo.du 2023-01-18
|
#define DIAG_MAX_PCIE_PKT_SZ 2048 //define by module
|
||||||
#define DIAG_MAX_PCIE_PKT_SZ 8192 //define by module
|
|
||||||
|
|
||||||
/* .driver_data stores max mtu */
|
/* .driver_data stores max mtu */
|
||||||
static const struct mhi_device_id mhi_uci_match_table[] = {
|
static const struct mhi_device_id mhi_uci_match_table[] = {
|
||||||
@ -921,12 +887,6 @@ static const struct mhi_device_id mhi_uci_match_table[] = {
|
|||||||
{ .chan = "QMI0", .driver_data = 0x1000 },
|
{ .chan = "QMI0", .driver_data = 0x1000 },
|
||||||
{ .chan = "QMI1", .driver_data = 0x1000 },
|
{ .chan = "QMI1", .driver_data = 0x1000 },
|
||||||
{ .chan = "DUN", .driver_data = 0x1000 },
|
{ .chan = "DUN", .driver_data = 0x1000 },
|
||||||
#ifdef ENABLE_ADPL
|
|
||||||
{ .chan = "ADPL", .driver_data = 0x1000 },
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_QDSS
|
|
||||||
{ .chan = "QDSS", .driver_data = 0x1000 },
|
|
||||||
#endif
|
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -951,11 +911,7 @@ int mhi_device_uci_init(void)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mhi_uci_drv.major = ret;
|
mhi_uci_drv.major = ret;
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
|
|
||||||
mhi_uci_drv.class = class_create(MHI_UCI_DRIVER_NAME);
|
|
||||||
#else
|
|
||||||
mhi_uci_drv.class = class_create(THIS_MODULE, MHI_UCI_DRIVER_NAME);
|
mhi_uci_drv.class = class_create(THIS_MODULE, MHI_UCI_DRIVER_NAME);
|
||||||
#endif
|
|
||||||
if (IS_ERR(mhi_uci_drv.class)) {
|
if (IS_ERR(mhi_uci_drv.class)) {
|
||||||
unregister_chrdev(mhi_uci_drv.major, MHI_UCI_DRIVER_NAME);
|
unregister_chrdev(mhi_uci_drv.major, MHI_UCI_DRIVER_NAME);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:= quectel-CM-5G
|
PKG_NAME:= quectel-CM-5G
|
||||||
PKG_VERSION:=1.6.5
|
PKG_VERSION:=1.6.4
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -9,7 +9,7 @@ CC:=$(CROSS-COMPILE)gcc
|
|||||||
endif
|
endif
|
||||||
LD:=$(CROSS-COMPILE)ld
|
LD:=$(CROSS-COMPILE)ld
|
||||||
|
|
||||||
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c MPQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c
|
||||||
QL_CM_SRC+=atc.c atchannel.c at_tok.c
|
QL_CM_SRC+=atc.c atchannel.c at_tok.c
|
||||||
#QL_CM_SRC+=qrtr.c rmnetctl.c
|
#QL_CM_SRC+=qrtr.c rmnetctl.c
|
||||||
ifeq (1,1)
|
ifeq (1,1)
|
||||||
@ -21,26 +21,25 @@ QL_CM_DHCP=udhcpc_netlink.c
|
|||||||
QL_CM_DHCP+=${LIBMNL}
|
QL_CM_DHCP+=${LIBMNL}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS += -Wall -Wextra -Werror -O1 #-s
|
|
||||||
LDFLAGS += -lpthread -ldl -lrt
|
LDFLAGS += -lpthread -ldl -lrt
|
||||||
|
|
||||||
release: clean qmi-proxy mbim-proxy atc-proxy #qrtr-proxy
|
release: clean qmi-proxy mbim-proxy atc-proxy #qrtr-proxy
|
||||||
$(CC) ${CFLAGS} ${QL_CM_SRC} ${QL_CM_DHCP} -o out/quectel-CM ${LDFLAGS}
|
$(CC) ${CFLAGS} ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM ${LDFLAGS}
|
||||||
|
|
||||||
debug: clean
|
debug: clean
|
||||||
$(CC) ${CFLAGS} -g -DCM_DEBUG ${QL_CM_SRC} ${QL_CM_DHCP} -o out/quectel-CM -lpthread -ldl -lrt
|
$(CC) ${CFLAGS} -g -DCM_DEBUG ${QL_CM_SRC} ${QL_CM_DHCP} -o quectel-CM -lpthread -ldl -lrt
|
||||||
|
|
||||||
qmi-proxy:
|
qmi-proxy:
|
||||||
$(CC) ${CFLAGS} quectel-qmi-proxy.c -o out/quectel-qmi-proxy ${LDFLAGS}
|
$(CC) ${CFLAGS} quectel-qmi-proxy.c -o quectel-qmi-proxy ${LDFLAGS}
|
||||||
|
|
||||||
mbim-proxy:
|
mbim-proxy:
|
||||||
$(CC) ${CFLAGS} quectel-mbim-proxy.c -o out/quectel-mbim-proxy ${LDFLAGS}
|
$(CC) ${CFLAGS} quectel-mbim-proxy.c -o quectel-mbim-proxy ${LDFLAGS}
|
||||||
|
|
||||||
qrtr-proxy:
|
qrtr-proxy:
|
||||||
$(CC) ${CFLAGS} quectel-qrtr-proxy.c -o out/quectel-qrtr-proxy ${LDFLAGS}
|
$(CC) ${CFLAGS} quectel-qrtr-proxy.c -o quectel-qrtr-proxy ${LDFLAGS}
|
||||||
|
|
||||||
atc-proxy:
|
atc-proxy:
|
||||||
$(CC) ${CFLAGS} quectel-atc-proxy.c atchannel.c at_tok.c util.c -o out/quectel-atc-proxy ${LDFLAGS}
|
$(CC) ${CFLAGS} quectel-atc-proxy.c atchannel.c at_tok.c util.c -o quectel-atc-proxy ${LDFLAGS}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cd out/; rm -rf *.o libmnl/*.o quectel-CM quectel-qmi-proxy quectel-mbim-proxy quectel-atc-proxy
|
rm -rf *.o libmnl/*.o quectel-CM quectel-qmi-proxy quectel-mbim-proxy quectel-atc-proxy
|
||||||
|
@ -1,394 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
@file QCQCTL.h
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This module contains QMI QCTL module.
|
|
||||||
|
|
||||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
|
||||||
None.
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef QCQCTL_H
|
|
||||||
#define QCQCTL_H
|
|
||||||
|
|
||||||
#include "QCQMI.h"
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
// ================= QMICTL ==================
|
|
||||||
|
|
||||||
// QMICTL Control Flags
|
|
||||||
#define QMICTL_CTL_FLAG_CMD 0x00
|
|
||||||
#define QMICTL_CTL_FLAG_RSP 0x01
|
|
||||||
#define QMICTL_CTL_FLAG_IND 0x02
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
typedef struct _QMICTL_TRANSACTION_ITEM
|
|
||||||
{
|
|
||||||
LIST_ENTRY List;
|
|
||||||
UCHAR TransactionId; // QMICTL transaction id
|
|
||||||
PVOID Context; // Adapter or IocDev
|
|
||||||
PIRP Irp;
|
|
||||||
} QMICTL_TRANSACTION_ITEM, *PQMICTL_TRANSACTION_ITEM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _QCQMICTL_MSG_HDR
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType;
|
|
||||||
USHORT Length;
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_MSG_HDR, *PQCQMICTL_MSG_HDR;
|
|
||||||
|
|
||||||
#define QCQMICTL_MSG_HDR_SIZE sizeof(QCQMICTL_MSG_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCQMICTL_MSG_HDR_RESP
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // 0x02 - result code
|
|
||||||
USHORT TLVLength; // 4
|
|
||||||
USHORT QMUXResult; // QMI_RESULT_SUCCESS
|
|
||||||
// QMI_RESULT_FAILURE
|
|
||||||
USHORT QMUXError; // QMI_ERR_INVALID_ARG
|
|
||||||
// QMI_ERR_NO_MEMORY
|
|
||||||
// QMI_ERR_INTERNAL
|
|
||||||
// QMI_ERR_FAULT
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_MSG_HDR_RESP, *PQCQMICTL_MSG_HDR_RESP;
|
|
||||||
|
|
||||||
typedef struct _QCQMICTL_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 00-cmd, 01-rsp, 10-ind
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR Payload;
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_MSG, *PQCQMICTL_MSG;
|
|
||||||
|
|
||||||
// TLV Header
|
|
||||||
typedef struct _QCQMICTL_TLV_HDR
|
|
||||||
{
|
|
||||||
UCHAR TLVType;
|
|
||||||
USHORT TLVLength;
|
|
||||||
} __attribute__ ((packed)) QCQMICTL_TLV_HDR, *PQCQMICTL_TLV_HDR;
|
|
||||||
|
|
||||||
#define QCQMICTL_TLV_HDR_SIZE sizeof(QCQMICTL_TLV_HDR)
|
|
||||||
|
|
||||||
// QMICTL Type
|
|
||||||
#define QMICTL_SET_INSTANCE_ID_REQ 0x0020
|
|
||||||
#define QMICTL_SET_INSTANCE_ID_RESP 0x0020
|
|
||||||
#define QMICTL_GET_VERSION_REQ 0x0021
|
|
||||||
#define QMICTL_GET_VERSION_RESP 0x0021
|
|
||||||
#define QMICTL_GET_CLIENT_ID_REQ 0x0022
|
|
||||||
#define QMICTL_GET_CLIENT_ID_RESP 0x0022
|
|
||||||
#define QMICTL_RELEASE_CLIENT_ID_REQ 0x0023
|
|
||||||
#define QMICTL_RELEASE_CLIENT_ID_RESP 0x0023
|
|
||||||
#define QMICTL_REVOKE_CLIENT_ID_IND 0x0024
|
|
||||||
#define QMICTL_INVALID_CLIENT_ID_IND 0x0025
|
|
||||||
#define QMICTL_SET_DATA_FORMAT_REQ 0x0026
|
|
||||||
#define QMICTL_SET_DATA_FORMAT_RESP 0x0026
|
|
||||||
#define QMICTL_SYNC_REQ 0x0027
|
|
||||||
#define QMICTL_SYNC_RESP 0x0027
|
|
||||||
#define QMICTL_SYNC_IND 0x0027
|
|
||||||
#define QMI_MESSAGE_CTL_INTERNAL_PROXY_OPEN 0xFF00
|
|
||||||
|
|
||||||
#define QMICTL_FLAG_REQUEST 0x00
|
|
||||||
#define QMICTL_FLAG_RESPONSE 0x01
|
|
||||||
#define QMICTL_FLAG_INDICATION 0x02
|
|
||||||
|
|
||||||
// QMICTL Message Definitions
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_INSTANCE_ID_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_REQ
|
|
||||||
USHORT Length; // 4
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR Value; // Host-unique QMI instance for this device driver
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_INSTANCE_ID_REQ_MSG, *PQMICTL_SET_INSTANCE_ID_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_INSTANCE_ID_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_INSTANCE_ID_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult;
|
|
||||||
USHORT QMIError;
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // 0x0002
|
|
||||||
USHORT QMI_ID; // Upper byte is assigned by MSM,
|
|
||||||
// lower assigned by host
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_INSTANCE_ID_RESP_MSG, *PQMICTL_SET_INSTANCE_ID_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_VERSION_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_VERSION_REQ
|
|
||||||
USHORT Length; // 0
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // var
|
|
||||||
UCHAR QMUXTypes; // List of one byte QMUX_TYPE values
|
|
||||||
// 0xFF returns a list of versions for all
|
|
||||||
// QMUX_TYPEs implemented on the device
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_VERSION_REQ_MSG, *PQMICTL_GET_VERSION_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMUX_TYPE_VERSION_STRUCT
|
|
||||||
{
|
|
||||||
UCHAR QMUXType;
|
|
||||||
USHORT MajorVersion;
|
|
||||||
USHORT MinorVersion;
|
|
||||||
} __attribute__ ((packed)) QMUX_TYPE_VERSION_STRUCT, *PQMUX_TYPE_VERSION_STRUCT;
|
|
||||||
|
|
||||||
typedef struct _ADDENDUM_VERSION_PREAMBLE
|
|
||||||
{
|
|
||||||
UCHAR LabelLength;
|
|
||||||
UCHAR Label;
|
|
||||||
} __attribute__ ((packed)) ADDENDUM_VERSION_PREAMBLE, *PADDENDUM_VERSION_PREAMBLE;
|
|
||||||
|
|
||||||
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_VERSION 0x01
|
|
||||||
#define QMICTL_GET_VERSION_RSP_TLV_TYPE_ADD_VERSION 0x10
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_VERSION_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_VERSION_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult;
|
|
||||||
USHORT QMIError;
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // var
|
|
||||||
UCHAR NumElements; // Num of QMUX_TYPE_VERSION_STRUCT
|
|
||||||
QMUX_TYPE_VERSION_STRUCT TypeVersion[0];
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_VERSION_RESP_MSG, *PQMICTL_GET_VERSION_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_CLIENT_ID_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_REQ
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR QMIType; // QMUX type
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_CLIENT_ID_REQ_MSG, *PQMICTL_GET_CLIENT_ID_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_GET_CLIENT_ID_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_GET_CLIENT_ID_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult; // result code
|
|
||||||
USHORT QMIError; // error code
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // 2
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_GET_CLIENT_ID_RESP_MSG, *PQMICTL_GET_CLIENT_ID_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_RELEASE_CLIENT_ID_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_REQ
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 0x0002
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_RELEASE_CLIENT_ID_REQ_MSG, *PQMICTL_RELEASE_CLIENT_ID_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_RELEASE_CLIENT_ID_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_RELEASE_CLIENT_ID_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult; // result code
|
|
||||||
USHORT QMIError; // error code
|
|
||||||
UCHAR TLV2Type; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLV2Length; // 2
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_RELEASE_CLIENT_ID_RESP_MSG, *PQMICTL_RELEASE_CLIENT_ID_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_REVOKE_CLIENT_ID_IND_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 0x0002
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_REVOKE_CLIENT_ID_IND_MSG, *PQMICTL_REVOKE_CLIENT_ID_IND_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_INVALID_CLIENT_ID_IND_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 0x0002
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QMICTL_INVALID_CLIENT_ID_IND_MSG, *PQMICTL_INVALID_CLIENT_ID_IND_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_REQ
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_REQUIRED_PARAMETER
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR DataFormat; // 0-default; 1-QoS hdr present
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_DATA_FORMAT_REQ_MSG, *PQMICTL_SET_DATA_FORMAT_REQ_MSG;
|
|
||||||
|
|
||||||
#ifdef QC_IP_MODE
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_LINK_PROTO 0x10
|
|
||||||
#define SET_DATA_FORMAT_LINK_PROTO_ETH 0x0001
|
|
||||||
#define SET_DATA_FORMAT_LINK_PROTO_IP 0x0002
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // Link-Layer Protocol
|
|
||||||
USHORT TLVLength; // 2
|
|
||||||
USHORT LinkProt; // 0x1: ETH; 0x2: IP
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_LINK_PROT, *PQMICTL_SET_DATA_FORMAT_TLV_LINK_PROT;
|
|
||||||
|
|
||||||
#ifdef QCMP_UL_TLP
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_UL_TLP 0x11
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_UL_TLP
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // 0x11, Uplink TLP Setting
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR UlTlpSetting; // 0x0: Disable; 0x01: Enable
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_UL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_UL_TLP;
|
|
||||||
#endif // QCMP_UL_TLP
|
|
||||||
|
|
||||||
#ifdef QCMP_DL_TLP
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_DL_TLP 0x13
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_DL_TLP
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // 0x11, Uplink TLP Setting
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR DlTlpSetting; // 0x0: Disable; 0x01: Enable
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_DL_TLP, *PQMICTL_SET_DATA_FORMAT_TLV_DL_TLP;
|
|
||||||
#endif // QCMP_DL_TLP
|
|
||||||
|
|
||||||
#endif // QC_IP_MODE
|
|
||||||
|
|
||||||
#ifdef MP_QCQOS_ENABLED
|
|
||||||
#define SET_DATA_FORMAT_TLV_TYPE_QOS_SETTING 0x12
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING
|
|
||||||
{
|
|
||||||
UCHAR TLVType; // 0x12, QoS setting
|
|
||||||
USHORT TLVLength; // 1
|
|
||||||
UCHAR QosSetting; // 0x0: Disable; 0x01: Enable
|
|
||||||
} QMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING, *PQMICTL_SET_DATA_FORMAT_TLV_QOS_SETTING;
|
|
||||||
#endif // MP_QCQOS_ENABLED
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SET_DATA_FORMAT_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult; // result code
|
|
||||||
USHORT QMIError; // error code
|
|
||||||
} __attribute__ ((packed)) QMICTL_SET_DATA_FORMAT_RESP_MSG, *PQMICTL_SET_DATA_FORMAT_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SYNC_REQ_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_REQUEST
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_CTL_SYNC_REQ
|
|
||||||
USHORT Length; // 0
|
|
||||||
} __attribute__ ((packed)) QMICTL_SYNC_REQ_MSG, *PQMICTL_SYNC_REQ_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SYNC_RESP_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_CTL_SYNC_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
USHORT QMIResult;
|
|
||||||
USHORT QMIError;
|
|
||||||
} __attribute__ ((packed)) QMICTL_SYNC_RESP_MSG, *PQMICTL_SYNC_RESP_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_SYNC_IND_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_INDICATION
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_REVOKE_CLIENT_ID_IND
|
|
||||||
USHORT Length;
|
|
||||||
} __attribute__ ((packed)) QMICTL_SYNC_IND_MSG, *PQMICTL_SYNC_IND_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_LIBQMI_PROXY_OPEN_MSG
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // QMICTL_FLAG_RESPONSE
|
|
||||||
UCHAR TransactionId;
|
|
||||||
USHORT QMICTLType; // QMICTL_SET_DATA_FORMAT_RESP
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // QCTLV_TYPE_RESULT_CODE
|
|
||||||
USHORT TLVLength; // 0x0004
|
|
||||||
char device_path[0]; // result code
|
|
||||||
} __attribute__ ((packed)) QMICTL_LIBQMI_PROXY_OPEN_MSG, *PQMICTL_LIBQMI_PROXY_OPEN_MSG;
|
|
||||||
|
|
||||||
typedef struct _QMICTL_MSG
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
// Message Header
|
|
||||||
QCQMICTL_MSG_HDR QMICTLMsgHdr;
|
|
||||||
QCQMICTL_MSG_HDR_RESP QMICTLMsgHdrRsp;
|
|
||||||
|
|
||||||
// QMICTL Message
|
|
||||||
QMICTL_SET_INSTANCE_ID_REQ_MSG SetInstanceIdReq;
|
|
||||||
QMICTL_SET_INSTANCE_ID_RESP_MSG SetInstanceIdRsp;
|
|
||||||
QMICTL_GET_VERSION_REQ_MSG GetVersionReq;
|
|
||||||
QMICTL_GET_VERSION_RESP_MSG GetVersionRsp;
|
|
||||||
QMICTL_GET_CLIENT_ID_REQ_MSG GetClientIdReq;
|
|
||||||
QMICTL_GET_CLIENT_ID_RESP_MSG GetClientIdRsp;
|
|
||||||
QMICTL_RELEASE_CLIENT_ID_REQ_MSG ReleaseClientIdReq;
|
|
||||||
QMICTL_RELEASE_CLIENT_ID_RESP_MSG ReleaseClientIdRsp;
|
|
||||||
QMICTL_REVOKE_CLIENT_ID_IND_MSG RevokeClientIdInd;
|
|
||||||
QMICTL_INVALID_CLIENT_ID_IND_MSG InvalidClientIdInd;
|
|
||||||
QMICTL_SET_DATA_FORMAT_REQ_MSG SetDataFormatReq;
|
|
||||||
QMICTL_SET_DATA_FORMAT_RESP_MSG SetDataFormatRsp;
|
|
||||||
QMICTL_SYNC_REQ_MSG SyncReq;
|
|
||||||
QMICTL_SYNC_RESP_MSG SyncRsp;
|
|
||||||
QMICTL_SYNC_IND_MSG SyncInd;
|
|
||||||
QMICTL_LIBQMI_PROXY_OPEN_MSG LibQmiProxyOpenReq;
|
|
||||||
};
|
|
||||||
} __attribute__ ((packed)) QMICTL_MSG, *PQMICTL_MSG;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif //QCQCTL_H
|
|
@ -1,320 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
@file QCQMI.h
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This module contains QMI module.
|
|
||||||
|
|
||||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
|
||||||
None.
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef USBQMI_H
|
|
||||||
#define USBQMI_H
|
|
||||||
|
|
||||||
typedef uint8_t uint8;
|
|
||||||
typedef int8_t int8;
|
|
||||||
typedef uint16_t uint16;
|
|
||||||
typedef int16_t int16;
|
|
||||||
typedef uint32_t uint32;
|
|
||||||
typedef uint64_t uint64;
|
|
||||||
|
|
||||||
typedef signed char CHAR;
|
|
||||||
typedef unsigned char UCHAR;
|
|
||||||
typedef short SHORT;
|
|
||||||
typedef unsigned short USHORT;
|
|
||||||
typedef int INT;
|
|
||||||
typedef unsigned int UINT;
|
|
||||||
typedef long LONG;
|
|
||||||
typedef unsigned int ULONG;
|
|
||||||
typedef unsigned long long ULONG64;
|
|
||||||
typedef signed char *PCHAR;
|
|
||||||
typedef unsigned char *PUCHAR;
|
|
||||||
typedef int *PINT;
|
|
||||||
typedef int BOOL;
|
|
||||||
|
|
||||||
#define TRUE (1 == 1)
|
|
||||||
#define FALSE (1 != 1)
|
|
||||||
|
|
||||||
#define QMICTL_SUPPORTED_MAJOR_VERSION 1
|
|
||||||
#define QMICTL_SUPPORTED_MINOR_VERSION 0
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
// ========= USB Control Message ==========
|
|
||||||
|
|
||||||
#define USB_CTL_MSG_TYPE_QMI 0x01
|
|
||||||
|
|
||||||
// USB Control Message
|
|
||||||
typedef struct _QCUSB_CTL_MSG_HDR
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
} __attribute__ ((packed)) QCUSB_CTL_MSG_HDR, *PQCUSB_CTL_MSG_HDR;
|
|
||||||
|
|
||||||
#define QCUSB_CTL_MSG_HDR_SIZE sizeof(QCUSB_CTL_MSG_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCUSB_CTL_MSG
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
UCHAR Message;
|
|
||||||
} __attribute__ ((packed)) QCUSB_CTL_MSG, *PQCUSB_CTL_MSG;
|
|
||||||
|
|
||||||
#define QCTLV_TYPE_REQUIRED_PARAMETER 0x01
|
|
||||||
#define QCTLV_TYPE_RESULT_CODE 0x02
|
|
||||||
|
|
||||||
// ================= QMI ==================
|
|
||||||
|
|
||||||
// Define QMI Type
|
|
||||||
typedef enum _QMI_SERVICE_TYPE
|
|
||||||
{
|
|
||||||
QMUX_TYPE_CTL = 0x00,
|
|
||||||
QMUX_TYPE_WDS = 0x01,
|
|
||||||
QMUX_TYPE_DMS = 0x02,
|
|
||||||
QMUX_TYPE_NAS = 0x03,
|
|
||||||
QMUX_TYPE_QOS = 0x04,
|
|
||||||
QMUX_TYPE_WMS = 0x05,
|
|
||||||
QMUX_TYPE_PDS = 0x06,
|
|
||||||
QMUX_TYPE_UIM = 0x0B,
|
|
||||||
QMUX_TYPE_WDS_IPV6 = 0x11,
|
|
||||||
QMUX_TYPE_WDS_ADMIN = 0x1A,
|
|
||||||
QMUX_TYPE_COEX = 0x22,
|
|
||||||
QMUX_TYPE_MAX = 0xFF,
|
|
||||||
QMUX_TYPE_ALL = 0xFF
|
|
||||||
} QMI_SERVICE_TYPE;
|
|
||||||
|
|
||||||
typedef enum _QMI_RESULT_CODE_TYPE
|
|
||||||
{
|
|
||||||
QMI_RESULT_SUCCESS = 0x0000,
|
|
||||||
QMI_RESULT_FAILURE = 0x0001
|
|
||||||
} QMI_RESULT_CODE_TYPE;
|
|
||||||
|
|
||||||
typedef enum _QMI_ERROR_CODE_TYPE
|
|
||||||
{
|
|
||||||
QMI_ERR_NONE = 0x0000
|
|
||||||
,QMI_ERR_MALFORMED_MSG = 0x0001
|
|
||||||
,QMI_ERR_NO_MEMORY = 0x0002
|
|
||||||
,QMI_ERR_INTERNAL = 0x0003
|
|
||||||
,QMI_ERR_ABORTED = 0x0004
|
|
||||||
,QMI_ERR_CLIENT_IDS_EXHAUSTED = 0x0005
|
|
||||||
,QMI_ERR_UNABORTABLE_TRANSACTION = 0x0006
|
|
||||||
,QMI_ERR_INVALID_CLIENT_ID = 0x0007
|
|
||||||
,QMI_ERR_NO_THRESHOLDS = 0x0008
|
|
||||||
,QMI_ERR_INVALID_HANDLE = 0x0009
|
|
||||||
,QMI_ERR_INVALID_PROFILE = 0x000A
|
|
||||||
,QMI_ERR_INVALID_PINID = 0x000B
|
|
||||||
,QMI_ERR_INCORRECT_PIN = 0x000C
|
|
||||||
,QMI_ERR_NO_NETWORK_FOUND = 0x000D
|
|
||||||
,QMI_ERR_CALL_FAILED = 0x000E
|
|
||||||
,QMI_ERR_OUT_OF_CALL = 0x000F
|
|
||||||
,QMI_ERR_NOT_PROVISIONED = 0x0010
|
|
||||||
,QMI_ERR_MISSING_ARG = 0x0011
|
|
||||||
,QMI_ERR_ARG_TOO_LONG = 0x0013
|
|
||||||
,QMI_ERR_INVALID_TX_ID = 0x0016
|
|
||||||
,QMI_ERR_DEVICE_IN_USE = 0x0017
|
|
||||||
,QMI_ERR_OP_NETWORK_UNSUPPORTED = 0x0018
|
|
||||||
,QMI_ERR_OP_DEVICE_UNSUPPORTED = 0x0019
|
|
||||||
,QMI_ERR_NO_EFFECT = 0x001A
|
|
||||||
,QMI_ERR_NO_FREE_PROFILE = 0x001B
|
|
||||||
,QMI_ERR_INVALID_PDP_TYPE = 0x001C
|
|
||||||
,QMI_ERR_INVALID_TECH_PREF = 0x001D
|
|
||||||
,QMI_ERR_INVALID_PROFILE_TYPE = 0x001E
|
|
||||||
,QMI_ERR_INVALID_SERVICE_TYPE = 0x001F
|
|
||||||
,QMI_ERR_INVALID_REGISTER_ACTION = 0x0020
|
|
||||||
,QMI_ERR_INVALID_PS_ATTACH_ACTION = 0x0021
|
|
||||||
,QMI_ERR_AUTHENTICATION_FAILED = 0x0022
|
|
||||||
,QMI_ERR_PIN_BLOCKED = 0x0023
|
|
||||||
,QMI_ERR_PIN_PERM_BLOCKED = 0x0024
|
|
||||||
,QMI_ERR_SIM_NOT_INITIALIZED = 0x0025
|
|
||||||
,QMI_ERR_MAX_QOS_REQUESTS_IN_USE = 0x0026
|
|
||||||
,QMI_ERR_INCORRECT_FLOW_FILTER = 0x0027
|
|
||||||
,QMI_ERR_NETWORK_QOS_UNAWARE = 0x0028
|
|
||||||
,QMI_ERR_INVALID_QOS_ID = 0x0029
|
|
||||||
,QMI_ERR_INVALID_ID = 0x0029
|
|
||||||
,QMI_ERR_REQUESTED_NUM_UNSUPPORTED = 0x002A
|
|
||||||
,QMI_ERR_INTERFACE_NOT_FOUND = 0x002B
|
|
||||||
,QMI_ERR_FLOW_SUSPENDED = 0x002C
|
|
||||||
,QMI_ERR_INVALID_DATA_FORMAT = 0x002D
|
|
||||||
,QMI_ERR_GENERAL = 0x002E
|
|
||||||
,QMI_ERR_UNKNOWN = 0x002F
|
|
||||||
,QMI_ERR_INVALID_ARG = 0x0030
|
|
||||||
,QMI_ERR_INVALID_INDEX = 0x0031
|
|
||||||
,QMI_ERR_NO_ENTRY = 0x0032
|
|
||||||
,QMI_ERR_DEVICE_STORAGE_FULL = 0x0033
|
|
||||||
,QMI_ERR_DEVICE_NOT_READY = 0x0034
|
|
||||||
,QMI_ERR_NETWORK_NOT_READY = 0x0035
|
|
||||||
,QMI_ERR_CAUSE_CODE = 0x0036
|
|
||||||
,QMI_ERR_MESSAGE_NOT_SENT = 0x0037
|
|
||||||
,QMI_ERR_MESSAGE_DELIVERY_FAILURE = 0x0038
|
|
||||||
,QMI_ERR_INVALID_MESSAGE_ID = 0x0039
|
|
||||||
,QMI_ERR_ENCODING = 0x003A
|
|
||||||
,QMI_ERR_AUTHENTICATION_LOCK = 0x003B
|
|
||||||
,QMI_ERR_INVALID_TRANSITION = 0x003C
|
|
||||||
,QMI_ERR_NOT_A_MCAST_IFACE = 0x003D
|
|
||||||
,QMI_ERR_MAX_MCAST_REQUESTS_IN_USE = 0x003E
|
|
||||||
,QMI_ERR_INVALID_MCAST_HANDLE = 0x003F
|
|
||||||
,QMI_ERR_INVALID_IP_FAMILY_PREF = 0x0040
|
|
||||||
,QMI_ERR_SESSION_INACTIVE = 0x0041
|
|
||||||
,QMI_ERR_SESSION_INVALID = 0x0042
|
|
||||||
,QMI_ERR_SESSION_OWNERSHIP = 0x0043
|
|
||||||
,QMI_ERR_INSUFFICIENT_RESOURCES = 0x0044
|
|
||||||
,QMI_ERR_DISABLED = 0x0045
|
|
||||||
,QMI_ERR_INVALID_OPERATION = 0x0046
|
|
||||||
,QMI_ERR_INVALID_QMI_CMD = 0x0047
|
|
||||||
,QMI_ERR_TPDU_TYPE = 0x0048
|
|
||||||
,QMI_ERR_SMSC_ADDR = 0x0049
|
|
||||||
,QMI_ERR_INFO_UNAVAILABLE = 0x004A
|
|
||||||
,QMI_ERR_SEGMENT_TOO_LONG = 0x004B
|
|
||||||
,QMI_ERR_SEGMENT_ORDER = 0x004C
|
|
||||||
,QMI_ERR_BUNDLING_NOT_SUPPORTED = 0x004D
|
|
||||||
,QMI_ERR_OP_PARTIAL_FAILURE = 0x004E
|
|
||||||
,QMI_ERR_POLICY_MISMATCH = 0x004F
|
|
||||||
,QMI_ERR_SIM_FILE_NOT_FOUND = 0x0050
|
|
||||||
,QMI_ERR_EXTENDED_INTERNAL = 0x0051
|
|
||||||
,QMI_ERR_ACCESS_DENIED = 0x0052
|
|
||||||
,QMI_ERR_HARDWARE_RESTRICTED = 0x0053
|
|
||||||
,QMI_ERR_ACK_NOT_SENT = 0x0054
|
|
||||||
,QMI_ERR_INJECT_TIMEOUT = 0x0055
|
|
||||||
,QMI_ERR_INCOMPATIBLE_STATE = 0x005A
|
|
||||||
,QMI_ERR_FDN_RESTRICT = 0x005B
|
|
||||||
,QMI_ERR_SUPS_FAILURE_CAUSE = 0x005C
|
|
||||||
,QMI_ERR_NO_RADIO = 0x005D
|
|
||||||
,QMI_ERR_NOT_SUPPORTED = 0x005E
|
|
||||||
,QMI_ERR_NO_SUBSCRIPTION = 0x005F
|
|
||||||
,QMI_ERR_CARD_CALL_CONTROL_FAILED = 0x0060
|
|
||||||
,QMI_ERR_NETWORK_ABORTED = 0x0061
|
|
||||||
,QMI_ERR_MSG_BLOCKED = 0x0062
|
|
||||||
,QMI_ERR_INVALID_SESSION_TYPE = 0x0064
|
|
||||||
,QMI_ERR_INVALID_PB_TYPE = 0x0065
|
|
||||||
,QMI_ERR_NO_SIM = 0x0066
|
|
||||||
,QMI_ERR_PB_NOT_READY = 0x0067
|
|
||||||
,QMI_ERR_PIN_RESTRICTION = 0x0068
|
|
||||||
,QMI_ERR_PIN2_RESTRICTION = 0x0069
|
|
||||||
,QMI_ERR_PUK_RESTRICTION = 0x006A
|
|
||||||
,QMI_ERR_PUK2_RESTRICTION = 0x006B
|
|
||||||
,QMI_ERR_PB_ACCESS_RESTRICTED = 0x006C
|
|
||||||
,QMI_ERR_PB_DELETE_IN_PROG = 0x006D
|
|
||||||
,QMI_ERR_PB_TEXT_TOO_LONG = 0x006E
|
|
||||||
,QMI_ERR_PB_NUMBER_TOO_LONG = 0x006F
|
|
||||||
,QMI_ERR_PB_HIDDEN_KEY_RESTRICTION = 0x0070
|
|
||||||
} QMI_ERROR_CODE_TYPE;
|
|
||||||
|
|
||||||
#define QCQMI_CTL_FLAG_SERVICE 0x80
|
|
||||||
#define QCQMI_CTL_FLAG_CTL_POINT 0x00
|
|
||||||
|
|
||||||
typedef struct _QCQMI_HDR
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR CtlFlags; // reserved
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
} __attribute__ ((packed)) QCQMI_HDR, *PQCQMI_HDR;
|
|
||||||
|
|
||||||
#define QCQMI_HDR_SIZE (sizeof(QCQMI_HDR)-1)
|
|
||||||
|
|
||||||
typedef struct _QCQMI
|
|
||||||
{
|
|
||||||
UCHAR IFType;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR CtlFlags; // reserved
|
|
||||||
UCHAR QMIType;
|
|
||||||
UCHAR ClientId;
|
|
||||||
UCHAR SDU;
|
|
||||||
} __attribute__ ((packed)) QCQMI, *PQCQMI;
|
|
||||||
|
|
||||||
typedef struct _QMI_SERVICE_VERSION
|
|
||||||
{
|
|
||||||
USHORT Major;
|
|
||||||
USHORT Minor;
|
|
||||||
USHORT AddendumMajor;
|
|
||||||
USHORT AddendumMinor;
|
|
||||||
} __attribute__ ((packed)) QMI_SERVICE_VERSION, *PQMI_SERVICE_VERSION;
|
|
||||||
|
|
||||||
// ================= QMUX ==================
|
|
||||||
|
|
||||||
#define QMUX_MSG_OVERHEAD_BYTES 4 // Type(USHORT) Length(USHORT) -- header
|
|
||||||
|
|
||||||
#define QMUX_BROADCAST_CID 0xFF
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_HDR
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 0: single QMUX Msg; 1:
|
|
||||||
USHORT TransactionId;
|
|
||||||
} __attribute__ ((packed)) QCQMUX_HDR, *PQCQMUX_HDR;
|
|
||||||
|
|
||||||
typedef struct _QCQMUX
|
|
||||||
{
|
|
||||||
UCHAR CtlFlags; // 0: single QMUX Msg; 1:
|
|
||||||
USHORT TransactionId;
|
|
||||||
UCHAR Message; // Type(2), Length(2), Value
|
|
||||||
} __attribute__ ((packed)) QCQMUX, *PQCQMUX;
|
|
||||||
|
|
||||||
#define QCQMUX_HDR_SIZE sizeof(QCQMUX_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_MSG_HDR
|
|
||||||
{
|
|
||||||
USHORT Type;
|
|
||||||
USHORT Length;
|
|
||||||
} __attribute__ ((packed)) QCQMUX_MSG_HDR, *PQCQMUX_MSG_HDR;
|
|
||||||
|
|
||||||
#define QCQMUX_MSG_HDR_SIZE sizeof(QCQMUX_MSG_HDR)
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_MSG_HDR_RESP
|
|
||||||
{
|
|
||||||
USHORT Type;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR TLVType; // 0x02 - result code
|
|
||||||
USHORT TLVLength; // 4
|
|
||||||
USHORT QMUXResult; // QMI_RESULT_SUCCESS
|
|
||||||
// QMI_RESULT_FAILURE
|
|
||||||
USHORT QMUXError; // QMI_ERR_INVALID_ARG
|
|
||||||
// QMI_ERR_NO_MEMORY
|
|
||||||
// QMI_ERR_INTERNAL
|
|
||||||
// QMI_ERR_FAULT
|
|
||||||
} __attribute__ ((packed)) QCQMUX_MSG_HDR_RESP, *PQCQMUX_MSG_HDR_RESP;
|
|
||||||
|
|
||||||
typedef struct _QCQMUX_TLV
|
|
||||||
{
|
|
||||||
UCHAR Type;
|
|
||||||
USHORT Length;
|
|
||||||
UCHAR Value;
|
|
||||||
} __attribute__ ((packed)) QCQMUX_TLV, *PQCQMUX_TLV;
|
|
||||||
|
|
||||||
typedef struct _QMI_TLV_HDR
|
|
||||||
{
|
|
||||||
UCHAR TLVType;
|
|
||||||
USHORT TLVLength;
|
|
||||||
} __attribute__ ((packed)) QMI_TLV_HDR, *PQMI_TLV_HDR;
|
|
||||||
|
|
||||||
typedef struct _QMI_TLV
|
|
||||||
{
|
|
||||||
UCHAR TLVType;
|
|
||||||
USHORT TLVLength;
|
|
||||||
union {
|
|
||||||
int8_t s8;
|
|
||||||
uint8_t u8;
|
|
||||||
int16_t s16;
|
|
||||||
uint16_t u16;
|
|
||||||
int32_t s32;
|
|
||||||
uint32_t u32;
|
|
||||||
uint64_t u64;
|
|
||||||
};
|
|
||||||
} __attribute__ ((packed)) QMI_TLV, *PQMI_TLV;
|
|
||||||
|
|
||||||
// QMUX Message Definitions -- QMI SDU
|
|
||||||
#define QMUX_CTL_FLAG_SINGLE_MSG 0x00
|
|
||||||
#define QMUX_CTL_FLAG_COMPOUND_MSG 0x01
|
|
||||||
#define QMUX_CTL_FLAG_TYPE_CMD 0x00
|
|
||||||
#define QMUX_CTL_FLAG_TYPE_RSP 0x02
|
|
||||||
#define QMUX_CTL_FLAG_TYPE_IND 0x04
|
|
||||||
#define QMUX_CTL_FLAG_MASK_COMPOUND 0x01
|
|
||||||
#define QMUX_CTL_FLAG_MASK_TYPE 0x06 // 00-cmd, 01-rsp, 10-ind
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
#endif // USBQMI_H
|
|
@ -1,477 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
@file MPQMUX.c
|
|
||||||
@brief QMI mux.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
|
|
||||||
|
|
||||||
INITIALIZATION AND SEQUENCING REQUIREMENTS
|
|
||||||
None.
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include "QMIThread.h"
|
|
||||||
static char line[1024];
|
|
||||||
static pthread_mutex_t dumpQMIMutex = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
#undef dbg
|
|
||||||
#define dbg( format, arg... ) do {if (strlen(line) < sizeof(line)) snprintf(&line[strlen(line)], sizeof(line) - strlen(line), format, ## arg);} while (0)
|
|
||||||
|
|
||||||
PQMI_TLV_HDR GetTLV (PQCQMUX_MSG_HDR pQMUXMsgHdr, int TLVType);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
UINT type;
|
|
||||||
const char *name;
|
|
||||||
} QMI_NAME_T;
|
|
||||||
|
|
||||||
#define qmi_name_item(type) {type, #type}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static const QMI_NAME_T qmi_IFType[] = {
|
|
||||||
{USB_CTL_MSG_TYPE_QMI, "USB_CTL_MSG_TYPE_QMI"},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmi_CtlFlags[] = {
|
|
||||||
qmi_name_item(QMICTL_CTL_FLAG_CMD),
|
|
||||||
qmi_name_item(QCQMI_CTL_FLAG_SERVICE),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmi_QMIType[] = {
|
|
||||||
qmi_name_item(QMUX_TYPE_CTL),
|
|
||||||
qmi_name_item(QMUX_TYPE_WDS),
|
|
||||||
qmi_name_item(QMUX_TYPE_DMS),
|
|
||||||
qmi_name_item(QMUX_TYPE_NAS),
|
|
||||||
qmi_name_item(QMUX_TYPE_QOS),
|
|
||||||
qmi_name_item(QMUX_TYPE_WMS),
|
|
||||||
qmi_name_item(QMUX_TYPE_PDS),
|
|
||||||
qmi_name_item(QMUX_TYPE_WDS_ADMIN),
|
|
||||||
qmi_name_item(QMUX_TYPE_COEX),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmi_ctl_CtlFlags[] = {
|
|
||||||
qmi_name_item(QMICTL_FLAG_REQUEST),
|
|
||||||
qmi_name_item(QMICTL_FLAG_RESPONSE),
|
|
||||||
qmi_name_item(QMICTL_FLAG_INDICATION),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_ctl_QMICTLType[] = {
|
|
||||||
// QMICTL Type
|
|
||||||
qmi_name_item(QMICTL_SET_INSTANCE_ID_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMICTL_SET_INSTANCE_ID_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMICTL_GET_VERSION_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMICTL_GET_VERSION_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMICTL_GET_CLIENT_ID_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMICTL_GET_CLIENT_ID_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMICTL_RELEASE_CLIENT_ID_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMICTL_REVOKE_CLIENT_ID_IND), // 0x0024
|
|
||||||
qmi_name_item(QMICTL_INVALID_CLIENT_ID_IND), // 0x0025
|
|
||||||
qmi_name_item(QMICTL_SET_DATA_FORMAT_REQ), // 0x0026
|
|
||||||
qmi_name_item(QMICTL_SET_DATA_FORMAT_RESP), // 0x0026
|
|
||||||
qmi_name_item(QMICTL_SYNC_REQ), // 0x0027
|
|
||||||
qmi_name_item(QMICTL_SYNC_RESP), // 0x0027
|
|
||||||
qmi_name_item(QMICTL_SYNC_IND), // 0x0027
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_CtlFlags[] = {
|
|
||||||
qmi_name_item(QMUX_CTL_FLAG_TYPE_CMD),
|
|
||||||
qmi_name_item(QMUX_CTL_FLAG_TYPE_RSP),
|
|
||||||
qmi_name_item(QMUX_CTL_FLAG_TYPE_IND),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_wds_Type[] = {
|
|
||||||
qmi_name_item(QMIWDS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item(QMIWDS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item(QMIWDS_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_START_NETWORK_INTERFACE_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_STOP_NETWORK_INTERFACE_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_SRVC_STATUS_IND), // 0x0022
|
|
||||||
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMIWDS_GET_CURRENT_CHANNEL_RATE_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMIWDS_GET_PKT_STATISTICS_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ), // 0x0028
|
|
||||||
qmi_name_item(QMIWDS_MODIFY_PROFILE_SETTINGS_RESP), // 0x0028
|
|
||||||
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_REQ), // 0x002B
|
|
||||||
qmi_name_item(QMIWDS_GET_PROFILE_SETTINGS_RESP), // 0x002BD
|
|
||||||
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_REQ), // 0x002C
|
|
||||||
qmi_name_item(QMIWDS_GET_DEFAULT_SETTINGS_RESP), // 0x002C
|
|
||||||
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_REQ), // 0x002D
|
|
||||||
qmi_name_item(QMIWDS_GET_RUNTIME_SETTINGS_RESP), // 0x002D
|
|
||||||
qmi_name_item(QMIWDS_GET_MIP_MODE_REQ), // 0x002F
|
|
||||||
qmi_name_item(QMIWDS_GET_MIP_MODE_RESP), // 0x002F
|
|
||||||
qmi_name_item(QMIWDS_GET_DATA_BEARER_REQ), // 0x0037
|
|
||||||
qmi_name_item(QMIWDS_GET_DATA_BEARER_RESP), // 0x0037
|
|
||||||
qmi_name_item(QMIWDS_DUN_CALL_INFO_REQ), // 0x0038
|
|
||||||
qmi_name_item(QMIWDS_DUN_CALL_INFO_RESP), // 0x0038
|
|
||||||
qmi_name_item(QMIWDS_DUN_CALL_INFO_IND), // 0x0038
|
|
||||||
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ), // 0x004D
|
|
||||||
qmi_name_item(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_RESP), // 0x004D
|
|
||||||
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_REQ), // 0x0051
|
|
||||||
qmi_name_item(QMIWDS_SET_AUTO_CONNECT_RESP), // 0x0051
|
|
||||||
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_REQ), // 0x00A2
|
|
||||||
qmi_name_item(QMIWDS_BIND_MUX_DATA_PORT_RESP), // 0x00A2
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_dms_Type[] = {
|
|
||||||
// ======================= DMS ==============================
|
|
||||||
qmi_name_item(QMIDMS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item(QMIDMS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item(QMIDMS_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_CAP_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_CAP_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MFR_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MFR_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_MODEL_ID_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_REV_ID_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMIDMS_GET_MSISDN_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMIDMS_GET_MSISDN_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_REQ), // 0x0025
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_SERIAL_NUMBERS_RESP), // 0x0025
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_REQ), // 0x0027
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_PIN_PROTECTION_RESP), // 0x0027
|
|
||||||
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_REQ), // 0x0028
|
|
||||||
qmi_name_item(QMIDMS_UIM_VERIFY_PIN_RESP), // 0x0028
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_REQ), // 0x0029
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_PIN_RESP), // 0x0029
|
|
||||||
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_REQ), // 0x002A
|
|
||||||
qmi_name_item(QMIDMS_UIM_CHANGE_PIN_RESP), // 0x002A
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_REQ), // 0x002B
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_PIN_STATUS_RESP), // 0x002B
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_REQ), // 0x002C
|
|
||||||
qmi_name_item(QMIDMS_GET_DEVICE_HARDWARE_REV_RESP), // 0x002C
|
|
||||||
qmi_name_item(QMIDMS_GET_OPERATING_MODE_REQ), // 0x002D
|
|
||||||
qmi_name_item(QMIDMS_GET_OPERATING_MODE_RESP), // 0x002D
|
|
||||||
qmi_name_item(QMIDMS_SET_OPERATING_MODE_REQ), // 0x002E
|
|
||||||
qmi_name_item(QMIDMS_SET_OPERATING_MODE_RESP), // 0x002E
|
|
||||||
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_REQ), // 0x0031
|
|
||||||
qmi_name_item(QMIDMS_GET_ACTIVATED_STATUS_RESP), // 0x0031
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_REQ), // 0x0032
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_AUTOMATIC_RESP), // 0x0032
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_REQ), // 0x0033
|
|
||||||
qmi_name_item(QMIDMS_ACTIVATE_MANUAL_RESP), // 0x0033
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_ICCID_REQ), // 0x003C
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_ICCID_RESP), // 0x003C
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_REQ), // 0x0040
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_CK_STATUS_RESP), // 0x0040
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_REQ), // 0x0041
|
|
||||||
qmi_name_item(QMIDMS_UIM_SET_CK_PROTECTION_RESP), // 0x0041
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_REQ), // 0x0042
|
|
||||||
qmi_name_item(QMIDMS_UIM_UNBLOCK_CK_RESP), // 0x0042
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_IMSI_REQ), // 0x0043
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_IMSI_RESP), // 0x0043
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_STATE_REQ), // 0x0044
|
|
||||||
qmi_name_item(QMIDMS_UIM_GET_STATE_RESP), // 0x0044
|
|
||||||
qmi_name_item(QMIDMS_GET_BAND_CAP_REQ), // 0x0045
|
|
||||||
qmi_name_item(QMIDMS_GET_BAND_CAP_RESP), // 0x0045
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_qos_Type[] = {
|
|
||||||
qmi_name_item( QMI_QOS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item( QMI_QOS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item( QMI_QOS_SET_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item( QMI_QOS_BIND_DATA_PORT_REQ), // 0x002B
|
|
||||||
qmi_name_item( QMI_QOS_BIND_DATA_PORT_RESP), // 0x002B
|
|
||||||
qmi_name_item( QMI_QOS_INDICATION_REGISTER_REQ), // 0x002F
|
|
||||||
qmi_name_item( QMI_QOS_INDICATION_REGISTER_RESP), // 0x002F
|
|
||||||
qmi_name_item( QMI_QOS_GLOBAL_QOS_FLOW_IND), // 0x0031
|
|
||||||
qmi_name_item( QMI_QOS_GET_QOS_INFO_REQ), // 0x0033
|
|
||||||
qmi_name_item( QMI_QOS_GET_QOS_INFO_RESP), // 0x0033
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_nas_Type[] = {
|
|
||||||
// ======================= NAS ==============================
|
|
||||||
qmi_name_item(QMINAS_SET_EVENT_REPORT_REQ), // 0x0002
|
|
||||||
qmi_name_item(QMINAS_SET_EVENT_REPORT_RESP), // 0x0002
|
|
||||||
qmi_name_item(QMINAS_EVENT_REPORT_IND), // 0x0002
|
|
||||||
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMINAS_GET_SIGNAL_STRENGTH_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMINAS_PERFORM_NETWORK_SCAN_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMINAS_INITIATE_NW_REGISTER_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMINAS_INITIATE_ATTACH_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMINAS_INITIATE_ATTACH_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMINAS_GET_SERVING_SYSTEM_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMINAS_SERVING_SYSTEM_IND), // 0x0024
|
|
||||||
qmi_name_item(QMINAS_GET_HOME_NETWORK_REQ), // 0x0025
|
|
||||||
qmi_name_item(QMINAS_GET_HOME_NETWORK_RESP), // 0x0025
|
|
||||||
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_REQ), // 0x0026
|
|
||||||
qmi_name_item(QMINAS_GET_PREFERRED_NETWORK_RESP), // 0x0026
|
|
||||||
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_REQ), // 0x0027
|
|
||||||
qmi_name_item(QMINAS_SET_PREFERRED_NETWORK_RESP), // 0x0027
|
|
||||||
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_REQ), // 0x0028
|
|
||||||
qmi_name_item(QMINAS_GET_FORBIDDEN_NETWORK_RESP), // 0x0028
|
|
||||||
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_REQ), // 0x0029
|
|
||||||
qmi_name_item(QMINAS_SET_FORBIDDEN_NETWORK_RESP), // 0x0029
|
|
||||||
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_REQ), // 0x002A
|
|
||||||
qmi_name_item(QMINAS_SET_TECHNOLOGY_PREF_RESP), // 0x002A
|
|
||||||
qmi_name_item(QMINAS_GET_RF_BAND_INFO_REQ), // 0x0031
|
|
||||||
qmi_name_item(QMINAS_GET_RF_BAND_INFO_RESP), // 0x0031
|
|
||||||
qmi_name_item(QMINAS_GET_CELL_LOCATION_INFO_REQ),
|
|
||||||
qmi_name_item(QMINAS_GET_CELL_LOCATION_INFO_RESP),
|
|
||||||
qmi_name_item(QMINAS_GET_PLMN_NAME_REQ), // 0x0044
|
|
||||||
qmi_name_item(QMINAS_GET_PLMN_NAME_RESP), // 0x0044
|
|
||||||
qmi_name_item(QUECTEL_PACKET_TRANSFER_START_IND), // 0X100
|
|
||||||
qmi_name_item(QUECTEL_PACKET_TRANSFER_END_IND), // 0X101
|
|
||||||
qmi_name_item(QMINAS_GET_SYS_INFO_REQ), // 0x004D
|
|
||||||
qmi_name_item(QMINAS_GET_SYS_INFO_RESP), // 0x004D
|
|
||||||
qmi_name_item(QMINAS_SYS_INFO_IND), // 0x004D
|
|
||||||
qmi_name_item(QMINAS_GET_SIG_INFO_REQ),
|
|
||||||
qmi_name_item(QMINAS_GET_SIG_INFO_RESP),
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_wms_Type[] = {
|
|
||||||
// ======================= WMS ==============================
|
|
||||||
qmi_name_item(QMIWMS_SET_EVENT_REPORT_REQ), // 0x0001
|
|
||||||
qmi_name_item(QMIWMS_SET_EVENT_REPORT_RESP), // 0x0001
|
|
||||||
qmi_name_item(QMIWMS_EVENT_REPORT_IND), // 0x0001
|
|
||||||
qmi_name_item(QMIWMS_RAW_SEND_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIWMS_RAW_SEND_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIWMS_RAW_WRITE_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIWMS_RAW_WRITE_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIWMS_RAW_READ_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMIWMS_RAW_READ_RESP), // 0x0022
|
|
||||||
qmi_name_item(QMIWMS_MODIFY_TAG_REQ), // 0x0023
|
|
||||||
qmi_name_item(QMIWMS_MODIFY_TAG_RESP), // 0x0023
|
|
||||||
qmi_name_item(QMIWMS_DELETE_REQ), // 0x0024
|
|
||||||
qmi_name_item(QMIWMS_DELETE_RESP), // 0x0024
|
|
||||||
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_REQ), // 0x0030
|
|
||||||
qmi_name_item(QMIWMS_GET_MESSAGE_PROTOCOL_RESP), // 0x0030
|
|
||||||
qmi_name_item(QMIWMS_LIST_MESSAGES_REQ), // 0x0031
|
|
||||||
qmi_name_item(QMIWMS_LIST_MESSAGES_RESP), // 0x0031
|
|
||||||
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_REQ), // 0x0034
|
|
||||||
qmi_name_item(QMIWMS_GET_SMSC_ADDRESS_RESP), // 0x0034
|
|
||||||
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_REQ), // 0x0035
|
|
||||||
qmi_name_item(QMIWMS_SET_SMSC_ADDRESS_RESP), // 0x0035
|
|
||||||
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_REQ), // 0x0036
|
|
||||||
qmi_name_item(QMIWMS_GET_STORE_MAX_SIZE_RESP), // 0x0036
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_wds_admin_Type[] = {
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_REQ), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_DATA_FORMAT_RESP), // 0x0020
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_REQ), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_DATA_FORMAT_RESP), // 0x0021
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_REQ), // 0x002B
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_SET_QMAP_SETTINGS_RESP), // 0x002B
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_REQ), // 0x002C
|
|
||||||
qmi_name_item(QMIWDS_ADMIN_GET_QMAP_SETTINGS_RESP), // 0x002C
|
|
||||||
qmi_name_item(QMI_WDA_SET_LOOPBACK_CONFIG_REQ), // 0x002F
|
|
||||||
qmi_name_item(QMI_WDA_SET_LOOPBACK_CONFIG_RESP), // 0x002F
|
|
||||||
qmi_name_item(QMI_WDA_SET_LOOPBACK_CONFIG_IND), // 0x002F
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_uim_Type[] = {
|
|
||||||
qmi_name_item( QMIUIM_READ_TRANSPARENT_REQ), // 0x0020
|
|
||||||
qmi_name_item( QMIUIM_READ_TRANSPARENT_RESP), // 0x0020
|
|
||||||
qmi_name_item( QMIUIM_READ_TRANSPARENT_IND), // 0x0020
|
|
||||||
qmi_name_item( QMIUIM_READ_RECORD_REQ), // 0x0021
|
|
||||||
qmi_name_item( QMIUIM_READ_RECORD_RESP), // 0x0021
|
|
||||||
qmi_name_item( QMIUIM_READ_RECORD_IND), // 0x0021
|
|
||||||
qmi_name_item( QMIUIM_WRITE_TRANSPARENT_REQ), // 0x0022
|
|
||||||
qmi_name_item( QMIUIM_WRITE_TRANSPARENT_RESP), // 0x0022
|
|
||||||
qmi_name_item( QMIUIM_WRITE_TRANSPARENT_IND), // 0x0022
|
|
||||||
qmi_name_item( QMIUIM_WRITE_RECORD_REQ), // 0x0023
|
|
||||||
qmi_name_item( QMIUIM_WRITE_RECORD_RESP), // 0x0023
|
|
||||||
qmi_name_item( QMIUIM_WRITE_RECORD_IND), // 0x0023
|
|
||||||
qmi_name_item( QMIUIM_SET_PIN_PROTECTION_REQ), // 0x0025
|
|
||||||
qmi_name_item( QMIUIM_SET_PIN_PROTECTION_RESP), // 0x0025
|
|
||||||
qmi_name_item( QMIUIM_SET_PIN_PROTECTION_IND), // 0x0025
|
|
||||||
qmi_name_item( QMIUIM_VERIFY_PIN_REQ), // 0x0026
|
|
||||||
qmi_name_item( QMIUIM_VERIFY_PIN_RESP), // 0x0026
|
|
||||||
qmi_name_item( QMIUIM_VERIFY_PIN_IND), // 0x0026
|
|
||||||
qmi_name_item( QMIUIM_UNBLOCK_PIN_REQ), // 0x0027
|
|
||||||
qmi_name_item( QMIUIM_UNBLOCK_PIN_RESP), // 0x0027
|
|
||||||
qmi_name_item( QMIUIM_UNBLOCK_PIN_IND), // 0x0027
|
|
||||||
qmi_name_item( QMIUIM_CHANGE_PIN_REQ), // 0x0028
|
|
||||||
qmi_name_item( QMIUIM_CHANGE_PIN_RESP), // 0x0028
|
|
||||||
qmi_name_item( QMIUIM_CHANGE_PIN_IND), // 0x0028
|
|
||||||
qmi_name_item( QMIUIM_DEPERSONALIZATION_REQ), // 0x0029
|
|
||||||
qmi_name_item( QMIUIM_DEPERSONALIZATION_RESP), // 0x0029
|
|
||||||
qmi_name_item( QMIUIM_EVENT_REG_REQ), // 0x002E
|
|
||||||
qmi_name_item( QMIUIM_EVENT_REG_RESP), // 0x002E
|
|
||||||
qmi_name_item( QMIUIM_GET_CARD_STATUS_REQ), // 0x002F
|
|
||||||
qmi_name_item( QMIUIM_GET_CARD_STATUS_RESP), // 0x002F
|
|
||||||
qmi_name_item( QMIUIM_STATUS_CHANGE_IND), // 0x0032
|
|
||||||
};
|
|
||||||
|
|
||||||
static const QMI_NAME_T qmux_coex_Type[] = {
|
|
||||||
qmi_name_item(QMI_COEX_GET_WWAN_STATE_REQ), // 0x0022
|
|
||||||
qmi_name_item(QMI_COEX_GET_WWAN_STATE_RESP), // 0x0022
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char * qmi_name_get(const QMI_NAME_T *table, size_t size, int type, const char *tag) {
|
|
||||||
static char unknow[40];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (qmux_CtlFlags == table) {
|
|
||||||
if (!strcmp(tag, "_REQ"))
|
|
||||||
tag = "_CMD";
|
|
||||||
else if (!strcmp(tag, "_RESP"))
|
|
||||||
tag = "_RSP";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++) {
|
|
||||||
if (table[i].type == (UINT)type) {
|
|
||||||
if (!tag || (strstr(table[i].name, tag)))
|
|
||||||
return table[i].name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sprintf(unknow, "unknow_%x", type);
|
|
||||||
return unknow;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define QMI_NAME(table, type) qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, 0)
|
|
||||||
#define QMUX_NAME(table, type, tag) qmi_name_get(table, sizeof(table) / sizeof(table[0]), type, tag)
|
|
||||||
|
|
||||||
void dump_tlv(PQCQMUX_MSG_HDR pQMUXMsgHdr) {
|
|
||||||
int TLVFind = 0;
|
|
||||||
int i;
|
|
||||||
//dbg("QCQMUX_TLV-----------------------------------\n");
|
|
||||||
//dbg("{Type,\tLength,\tValue}\n");
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
PQMI_TLV_HDR TLVHdr = GetTLV(pQMUXMsgHdr, 0x1000 + (++TLVFind));
|
|
||||||
if (TLVHdr == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
//if ((TLVHdr->TLVType == 0x02) && ((USHORT *)(TLVHdr+1))[0])
|
|
||||||
{
|
|
||||||
dbg("{%02x,\t%04x,\t", TLVHdr->TLVType, le16_to_cpu(TLVHdr->TLVLength));
|
|
||||||
for (i = 0; i < le16_to_cpu(TLVHdr->TLVLength); i++) {
|
|
||||||
dbg("%02x ", ((UCHAR *)(TLVHdr+1))[i]);
|
|
||||||
}
|
|
||||||
dbg("}\n");
|
|
||||||
}
|
|
||||||
} // while
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_ctl(PQCQMICTL_MSG_HDR CTLHdr) {
|
|
||||||
const char *tag;
|
|
||||||
|
|
||||||
//dbg("QCQMICTL_MSG--------------------------------------------\n");
|
|
||||||
//dbg("CtlFlags: %02x\t\t%s\n", CTLHdr->CtlFlags, QMI_NAME(qmi_ctl_CtlFlags, CTLHdr->CtlFlags));
|
|
||||||
dbg("TransactionId: %02x\n", CTLHdr->TransactionId);
|
|
||||||
switch (CTLHdr->CtlFlags) {
|
|
||||||
case QMICTL_FLAG_REQUEST: tag = "_REQ"; break;
|
|
||||||
case QMICTL_FLAG_RESPONSE: tag = "_RESP"; break;
|
|
||||||
case QMICTL_FLAG_INDICATION: tag = "_IND"; break;
|
|
||||||
default: tag = 0; break;
|
|
||||||
}
|
|
||||||
dbg("QMICTLType: %04x\t%s\n", le16_to_cpu(CTLHdr->QMICTLType),
|
|
||||||
QMUX_NAME(qmux_ctl_QMICTLType, le16_to_cpu(CTLHdr->QMICTLType), tag));
|
|
||||||
dbg("Length: %04x\n", le16_to_cpu(CTLHdr->Length));
|
|
||||||
|
|
||||||
dump_tlv((PQCQMUX_MSG_HDR)(&CTLHdr->QMICTLType));
|
|
||||||
}
|
|
||||||
|
|
||||||
int dump_qmux(QMI_SERVICE_TYPE serviceType, PQCQMUX_HDR QMUXHdr) {
|
|
||||||
PQCQMUX_MSG_HDR QMUXMsgHdr = (PQCQMUX_MSG_HDR) (QMUXHdr + 1);
|
|
||||||
const char *tag;
|
|
||||||
|
|
||||||
//dbg("QCQMUX--------------------------------------------\n");
|
|
||||||
switch (QMUXHdr->CtlFlags&QMUX_CTL_FLAG_MASK_TYPE) {
|
|
||||||
case QMUX_CTL_FLAG_TYPE_CMD: tag = "_REQ"; break;
|
|
||||||
case QMUX_CTL_FLAG_TYPE_RSP: tag = "_RESP"; break;
|
|
||||||
case QMUX_CTL_FLAG_TYPE_IND: tag = "_IND"; break;
|
|
||||||
default: tag = 0; break;
|
|
||||||
}
|
|
||||||
//dbg("CtlFlags: %02x\t\t%s\n", QMUXHdr->CtlFlags, QMUX_NAME(qmux_CtlFlags, QMUXHdr->CtlFlags, tag));
|
|
||||||
dbg("TransactionId: %04x\n", le16_to_cpu(QMUXHdr->TransactionId));
|
|
||||||
|
|
||||||
//dbg("QCQMUX_MSG_HDR-----------------------------------\n");
|
|
||||||
switch (serviceType) {
|
|
||||||
case QMUX_TYPE_DMS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_dms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_NAS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_nas_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_WDS:
|
|
||||||
case QMUX_TYPE_WDS_IPV6:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_wds_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_WMS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_wms_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_WDS_ADMIN:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_wds_admin_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_UIM:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_uim_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_PDS:
|
|
||||||
case QMUX_TYPE_QOS:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_qos_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_COEX:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type),
|
|
||||||
QMUX_NAME(qmux_coex_Type, le16_to_cpu(QMUXMsgHdr->Type), tag));
|
|
||||||
break;
|
|
||||||
case QMUX_TYPE_CTL:
|
|
||||||
default:
|
|
||||||
dbg("Type: %04x\t%s\n", le16_to_cpu(QMUXMsgHdr->Type), "PDS/QOS/CTL/unknown!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dbg("Length: %04x\n", le16_to_cpu(QMUXMsgHdr->Length));
|
|
||||||
|
|
||||||
dump_tlv(QMUXMsgHdr);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_qmi(void *dataBuffer, int dataLen)
|
|
||||||
{
|
|
||||||
PQCQMI_HDR QMIHdr = (PQCQMI_HDR)dataBuffer;
|
|
||||||
PQCQMUX_HDR QMUXHdr = (PQCQMUX_HDR) (QMIHdr + 1);
|
|
||||||
PQCQMICTL_MSG_HDR CTLHdr = (PQCQMICTL_MSG_HDR) (QMIHdr + 1);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!debug_qmi)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&dumpQMIMutex);
|
|
||||||
line[0] = 0;
|
|
||||||
for (i = 0; i < dataLen; i++) {
|
|
||||||
dbg("%02x ", ((unsigned char *)dataBuffer)[i]);
|
|
||||||
}
|
|
||||||
dbg_time("%s", line);
|
|
||||||
line[0] = 0;
|
|
||||||
|
|
||||||
//dbg("QCQMI_HDR-----------------------------------------");
|
|
||||||
//dbg("IFType: %02x\t\t%s", QMIHdr->IFType, QMI_NAME(qmi_IFType, QMIHdr->IFType));
|
|
||||||
//dbg("Length: %04x", le16_to_cpu(QMIHdr->Length));
|
|
||||||
//dbg("CtlFlags: %02x\t\t%s", QMIHdr->CtlFlags, QMI_NAME(qmi_CtlFlags, QMIHdr->CtlFlags));
|
|
||||||
//dbg("QMIType: %02x\t\t%s", QMIHdr->QMIType, QMI_NAME(qmi_QMIType, QMIHdr->QMIType));
|
|
||||||
//dbg("ClientId: %02x", QMIHdr->ClientId);
|
|
||||||
|
|
||||||
if (QMIHdr->QMIType == QMUX_TYPE_CTL) {
|
|
||||||
dump_ctl(CTLHdr);
|
|
||||||
} else {
|
|
||||||
dump_qmux(QMIHdr->QMIType, QMUXHdr);
|
|
||||||
}
|
|
||||||
dbg_time("%s", line);
|
|
||||||
pthread_mutex_unlock(&dumpQMIMutex);
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -255,11 +255,11 @@ static USHORT WdsStartNwInterfaceReq(PQMUX_MSG pMUXMsg, void *arg) {
|
|||||||
TLVLength += (le16_to_cpu(pIpFamily->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
|
TLVLength += (le16_to_cpu(pIpFamily->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
|
||||||
|
|
||||||
//Set Profile Index
|
//Set Profile Index
|
||||||
if (profile->profile_index && !s_is_cdma) { //cdma only support one pdp, so no need to set profile index
|
if (profile->pdp && !s_is_cdma) { //cdma only support one pdp, so no need to set profile index
|
||||||
PQMIWDS_PROFILE_IDENTIFIER pProfileIndex = (PQMIWDS_PROFILE_IDENTIFIER)(pTLV + TLVLength);
|
PQMIWDS_PROFILE_IDENTIFIER pProfileIndex = (PQMIWDS_PROFILE_IDENTIFIER)(pTLV + TLVLength);
|
||||||
pProfileIndex->TLVLength = cpu_to_le16(0x01);
|
pProfileIndex->TLVLength = cpu_to_le16(0x01);
|
||||||
pProfileIndex->TLVType = 0x31;
|
pProfileIndex->TLVType = 0x31;
|
||||||
pProfileIndex->ProfileIndex = profile->profile_index;
|
pProfileIndex->ProfileIndex = profile->pdp;
|
||||||
if (s_is_cdma && s_hdr_personality == 0x02) {
|
if (s_is_cdma && s_hdr_personality == 0x02) {
|
||||||
pProfileIndex->TLVType = 0x32; //profile_index_3gpp2
|
pProfileIndex->TLVType = 0x32; //profile_index_3gpp2
|
||||||
pProfileIndex->ProfileIndex = 101;
|
pProfileIndex->ProfileIndex = 101;
|
||||||
@ -478,13 +478,6 @@ static USHORT UimReadTransparentIMSIReqSend(PQMUX_MSG pMUXMsg, void *arg) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_APN
|
#ifdef CONFIG_APN
|
||||||
|
|
||||||
static USHORT WdsGetProfileListReqSend(PQMUX_MSG pMUXMsg, void *arg) {
|
|
||||||
(void)(arg);
|
|
||||||
pMUXMsg->GetProfileListReq.Length = cpu_to_le16(sizeof(QMIWDS_GET_PROFILE_LIST_REQ_MSG) - 4);
|
|
||||||
return sizeof(QMIWDS_GET_PROFILE_LIST_REQ_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static USHORT WdsCreateProfileSettingsReqSend(PQMUX_MSG pMUXMsg, void *arg) {
|
static USHORT WdsCreateProfileSettingsReqSend(PQMUX_MSG pMUXMsg, void *arg) {
|
||||||
PROFILE_T *profile = (PROFILE_T *)arg;
|
PROFILE_T *profile = (PROFILE_T *)arg;
|
||||||
pMUXMsg->CreatetProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG) - 4);
|
pMUXMsg->CreatetProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG) - 4);
|
||||||
@ -503,7 +496,7 @@ static USHORT WdsGetProfileSettingsReqSend(PQMUX_MSG pMUXMsg, void *arg) {
|
|||||||
pMUXMsg->GetProfileSettingsReq.TLVType = 0x01;
|
pMUXMsg->GetProfileSettingsReq.TLVType = 0x01;
|
||||||
pMUXMsg->GetProfileSettingsReq.TLVLength = cpu_to_le16(0x02);
|
pMUXMsg->GetProfileSettingsReq.TLVLength = cpu_to_le16(0x02);
|
||||||
pMUXMsg->GetProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2
|
pMUXMsg->GetProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2
|
||||||
pMUXMsg->GetProfileSettingsReq.ProfileIndex = profile->profile_index;
|
pMUXMsg->GetProfileSettingsReq.ProfileIndex = profile->pdp;
|
||||||
return sizeof(QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG);
|
return sizeof(QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,7 +510,7 @@ static USHORT WdsModifyProfileSettingsReq(PQMUX_MSG pMUXMsg, void *arg) {
|
|||||||
pMUXMsg->ModifyProfileSettingsReq.TLVType = 0x01;
|
pMUXMsg->ModifyProfileSettingsReq.TLVType = 0x01;
|
||||||
pMUXMsg->ModifyProfileSettingsReq.TLVLength = cpu_to_le16(0x02);
|
pMUXMsg->ModifyProfileSettingsReq.TLVLength = cpu_to_le16(0x02);
|
||||||
pMUXMsg->ModifyProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2
|
pMUXMsg->ModifyProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2
|
||||||
pMUXMsg->ModifyProfileSettingsReq.ProfileIndex = profile->profile_index;
|
pMUXMsg->ModifyProfileSettingsReq.ProfileIndex = profile->pdp;
|
||||||
|
|
||||||
pTLV = (UCHAR *)(&pMUXMsg->ModifyProfileSettingsReq + 1);
|
pTLV = (UCHAR *)(&pMUXMsg->ModifyProfileSettingsReq + 1);
|
||||||
|
|
||||||
@ -766,8 +759,6 @@ static int requestSetEthMode(PROFILE_T *profile) {
|
|||||||
qmap_settings.rx_urb_size = profile->qmap_size; //SDX24&SDX55 support 32KB
|
qmap_settings.rx_urb_size = profile->qmap_size; //SDX24&SDX55 support 32KB
|
||||||
qmap_settings.ep_type = DATA_EP_TYPE_HSUSB;
|
qmap_settings.ep_type = DATA_EP_TYPE_HSUSB;
|
||||||
qmap_settings.iface_id = 0x04;
|
qmap_settings.iface_id = 0x04;
|
||||||
if(profile->usb_dev.idProduct == 0x0316) //X35 Rmnet interface is 3
|
|
||||||
qmap_settings.iface_id = 0x03;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qmap_settings.ul_data_aggregation_max_datagrams = 11; //by test result, 11 can get best TPUT
|
qmap_settings.ul_data_aggregation_max_datagrams = 11; //by test result, 11 can get best TPUT
|
||||||
@ -1867,9 +1858,8 @@ static int requestSetupDataCall(PROFILE_T *profile, int curIpFamily) {
|
|||||||
dbg_time("call_end_reason_verbose is %d", verbose_call_end_reason);
|
dbg_time("call_end_reason_verbose is %d", verbose_call_end_reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError);
|
|
||||||
free(pResponse);
|
free(pResponse);
|
||||||
return err;
|
return le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curIpFamily == IpFamilyV4) {
|
if (curIpFamily == IpFamilyV4) {
|
||||||
@ -2036,8 +2026,8 @@ static int requestSetProfile(PROFILE_T *profile) {
|
|||||||
const char *new_password = profile->password ? profile->password : "";
|
const char *new_password = profile->password ? profile->password : "";
|
||||||
const char *ipStr[] = {"IPV4", "NULL", "IPV6", "IPV4V6"};
|
const char *ipStr[] = {"IPV4", "NULL", "IPV6", "IPV4V6"};
|
||||||
|
|
||||||
dbg_time("%s[pdp:%d index:%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->profile_index, profile->apn, profile->user, profile->password, profile->auth,ipStr[profile->iptype]);
|
dbg_time("%s[%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->apn, profile->user, profile->password, profile->auth,ipStr[profile->iptype]);
|
||||||
if (!profile->profile_index)
|
if (!profile->pdp)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ( !strcmp(profile->old_apn, new_apn) && !strcmp(profile->old_user, new_user)
|
if ( !strcmp(profile->old_apn, new_apn) && !strcmp(profile->old_user, new_user)
|
||||||
@ -2067,9 +2057,6 @@ static int requestGetProfile(PROFILE_T *profile) {
|
|||||||
PQMIWDS_PASSWD pPassWd;
|
PQMIWDS_PASSWD pPassWd;
|
||||||
PQMIWDS_AUTH_PREFERENCE pAuthPref;
|
PQMIWDS_AUTH_PREFERENCE pAuthPref;
|
||||||
PQMIWDS_IPTYPE pIpType;
|
PQMIWDS_IPTYPE pIpType;
|
||||||
PQMIWDS_PDPCONTEXT pPdpContext;
|
|
||||||
PQMIWDS_PROFILELIST pProfileList;
|
|
||||||
|
|
||||||
const char *ipStr[] = {"IPV4", "NULL", "IPV6", "IPV4V6"};
|
const char *ipStr[] = {"IPV4", "NULL", "IPV6", "IPV4V6"};
|
||||||
|
|
||||||
profile->old_apn[0] = profile->old_user[0] = profile->old_password[0] = '\0';
|
profile->old_apn[0] = profile->old_user[0] = profile->old_password[0] = '\0';
|
||||||
@ -2086,52 +2073,19 @@ static int requestGetProfile(PROFILE_T *profile) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
_re_check:
|
_re_check:
|
||||||
pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_GET_PROFILE_LIST_REQ, WdsGetProfileListReqSend, profile);
|
pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_GET_PROFILE_SETTINGS_REQ, WdsGetProfileSettingsReqSend, profile);
|
||||||
err = QmiThreadSendQMI(pRequest, &pResponse);s_pResponse = malloc(le16_to_cpu(pResponse->QMIHdr.Length) + 1);
|
err = QmiThreadSendQMI(pRequest, &pResponse);
|
||||||
qmi_rsp_check_and_return();
|
if (err == 0 && pResponse && le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.QMUXResult)
|
||||||
|
&& le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.QMUXError) == QMI_ERR_EXTENDED_INTERNAL)
|
||||||
pProfileList = (PQMIWDS_PROFILELIST)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01);
|
|
||||||
uint8 profile_indexs[42] = {0};
|
|
||||||
uint8 profile_num = pProfileList->ProfileList[0];
|
|
||||||
if(profile_num >= 1)
|
|
||||||
{
|
{
|
||||||
uint8 j = 0;
|
free(pResponse);
|
||||||
uint8 k = 2;
|
pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_CREATE_PROFILE_REQ, WdsCreateProfileSettingsReqSend, profile);
|
||||||
for(int i=0; i<profile_num; i++)
|
|
||||||
{
|
|
||||||
profile_indexs[j++] = pProfileList->ProfileList[k];
|
|
||||||
if(pProfileList->ProfileList[++k] == 0)
|
|
||||||
k+=2;
|
|
||||||
else
|
|
||||||
k+=2+pProfileList->ProfileList[k];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(pResponse);
|
|
||||||
|
|
||||||
for(int i=0; i<profile_num; i++)
|
|
||||||
{
|
|
||||||
profile->profile_index = profile_indexs[i];
|
|
||||||
|
|
||||||
pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_GET_PROFILE_SETTINGS_REQ, WdsGetProfileSettingsReqSend, profile);
|
|
||||||
err = QmiThreadSendQMI(pRequest, &pResponse);
|
err = QmiThreadSendQMI(pRequest, &pResponse);
|
||||||
qmi_rsp_check_and_return();
|
qmi_rsp_check_and_return();
|
||||||
|
free(pResponse);
|
||||||
pPdpContext = (PQMIWDS_PDPCONTEXT)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x25);
|
goto _re_check;
|
||||||
if(pPdpContext->pdp_context == profile->pdp)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
free(pResponse);
|
|
||||||
|
|
||||||
if(i == profile_num-1)
|
|
||||||
{
|
|
||||||
pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_CREATE_PROFILE_REQ, WdsCreateProfileSettingsReqSend, profile);
|
|
||||||
err = QmiThreadSendQMI(pRequest, &pResponse);
|
|
||||||
qmi_rsp_check_and_return();
|
|
||||||
free(pResponse);
|
|
||||||
goto _re_check;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
qmi_rsp_check_and_return();
|
||||||
|
|
||||||
pApnName = (PQMIWDS_APNNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x14);
|
pApnName = (PQMIWDS_APNNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x14);
|
||||||
pUserName = (PQMIWDS_USERNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1B);
|
pUserName = (PQMIWDS_USERNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1B);
|
||||||
@ -2152,7 +2106,7 @@ _re_check:
|
|||||||
profile->old_iptype = pIpType->IPType;
|
profile->old_iptype = pIpType->IPType;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_time("%s[pdp:%d index:%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->profile_index, profile->old_apn, profile->old_user, profile->old_password, profile->old_auth, ipStr[profile->old_iptype]);
|
dbg_time("%s[%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->old_apn, profile->old_user, profile->old_password, profile->old_auth, ipStr[profile->old_iptype]);
|
||||||
|
|
||||||
free(pResponse);
|
free(pResponse);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -53,9 +53,9 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "qendian.h"
|
#include "qendian.h"
|
||||||
#include "QCQMI.h"
|
#include "MPQMI.h"
|
||||||
#include "QCQCTL.h"
|
#include "MPQCTL.h"
|
||||||
#include "QCQMUX.h"
|
#include "MPQMUX.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define DEVICE_CLASS_UNKNOWN 0
|
#define DEVICE_CLASS_UNKNOWN 0
|
||||||
@ -196,12 +196,10 @@ typedef struct __PROFILE {
|
|||||||
int iptype;
|
int iptype;
|
||||||
const char *pincode;
|
const char *pincode;
|
||||||
char proxy[32];
|
char proxy[32];
|
||||||
int pdp;//pdp_context
|
int pdp;
|
||||||
int profile_index;//profile_index
|
|
||||||
int enable_bridge;
|
int enable_bridge;
|
||||||
bool enable_ipv4;
|
bool enable_ipv4;
|
||||||
bool enable_ipv6;
|
bool enable_ipv6;
|
||||||
bool no_dhcp;
|
|
||||||
const char *logfile;
|
const char *logfile;
|
||||||
const char *usblogfile;
|
const char *usblogfile;
|
||||||
char expect_adapter[32];
|
char expect_adapter[32];
|
||||||
@ -223,7 +221,6 @@ typedef struct __PROFILE {
|
|||||||
UINT qos_id;
|
UINT qos_id;
|
||||||
#endif
|
#endif
|
||||||
int wda_client;
|
int wda_client;
|
||||||
uint32_t udhcpc_ip;
|
|
||||||
IPV4_T ipv4;
|
IPV4_T ipv4;
|
||||||
IPV6_T ipv6;
|
IPV6_T ipv6;
|
||||||
UINT PCSCFIpv4Addr1;
|
UINT PCSCFIpv4Addr1;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -264,8 +264,8 @@ static int QmiWwanDeInit(void) {
|
|||||||
{
|
{
|
||||||
if (qmiclientId[i] != 0)
|
if (qmiclientId[i] != 0)
|
||||||
{
|
{
|
||||||
QmiWwanReleaseClientID((QMUX_TYPE_WDS_IPV6 == i ? QMUX_TYPE_WDS : i), qmiclientId[i]);
|
QmiWwanReleaseClientID(i, qmiclientId[i]);
|
||||||
qmiclientId[i] = 0;
|
qmiclientId[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,26 +1,5 @@
|
|||||||
Release Notes
|
Release Notes
|
||||||
|
|
||||||
[V1.6.5]
|
|
||||||
Date: 1/22/2024
|
|
||||||
enhancement:
|
|
||||||
1. To support more modems such as EC200G
|
|
||||||
2. To support more modems such as X35 RG255C
|
|
||||||
3. To support big endian MCU work with Unisoc and ASR modems
|
|
||||||
|
|
||||||
[V1.6.5]
|
|
||||||
Date: 7/3/2023
|
|
||||||
enhancement:
|
|
||||||
1. Fix the issue of qmi client id leakage caused by kill 9 killing the client of quectel-qmi-proxy
|
|
||||||
2. Fix wds_ipv6 client ID can't be released issue
|
|
||||||
3. Fix wds_ipv6 client ID can't be released issue
|
|
||||||
4. Resolve PDP_ Context&Profile_ The issue of index mixing
|
|
||||||
5. Add parameter - d to obtain IP and DNS information through qmi
|
|
||||||
6. Fix mbim dialing. When the user does not specify apn through - s, prompt the user and exit the dialing program
|
|
||||||
7. Prioritize the use of IP commands for optimization, and use ifconfig if not available
|
|
||||||
8. Optimize and add/remove copyright
|
|
||||||
fix:
|
|
||||||
|
|
||||||
|
|
||||||
[V1.6.4]
|
[V1.6.4]
|
||||||
Date: 9/7/2022
|
Date: 9/7/2022
|
||||||
enhancement:
|
enhancement:
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -45,18 +45,6 @@ static int s_pdp;
|
|||||||
#define safe_free(__x) do { if (__x) { free((void *)__x); __x = NULL;}} while(0)
|
#define safe_free(__x) do { if (__x) { free((void *)__x); __x = NULL;}} while(0)
|
||||||
#define safe_at_response_free(__x) { if (__x) { at_response_free(__x); __x = NULL;}}
|
#define safe_at_response_free(__x) { if (__x) { at_response_free(__x); __x = NULL;}}
|
||||||
|
|
||||||
int check_mcu_endian()
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
int a;
|
|
||||||
char b;
|
|
||||||
}u;
|
|
||||||
|
|
||||||
u.a = 1;
|
|
||||||
return u.b;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define at_response_error(err, p_response) \
|
#define at_response_error(err, p_response) \
|
||||||
(err \
|
(err \
|
||||||
|| p_response == NULL \
|
|| p_response == NULL \
|
||||||
@ -515,7 +503,6 @@ AT< OK
|
|||||||
safe_at_response_free(p_response);
|
safe_at_response_free(p_response);
|
||||||
switch (cops_act) {
|
switch (cops_act) {
|
||||||
case 2: //UTRAN
|
case 2: //UTRAN
|
||||||
case 3: //GSM W/EGPRS
|
|
||||||
case 4: //UTRAN W/HSDPA
|
case 4: //UTRAN W/HSDPA
|
||||||
case 5: //UTRAN W/HSUPA
|
case 5: //UTRAN W/HSUPA
|
||||||
case 6: //UTRAN W/HSDPA and HSUPA
|
case 6: //UTRAN W/HSDPA and HSUPA
|
||||||
@ -712,11 +699,7 @@ static int at_netdevstatus(int pdp, unsigned int *pV4Addr) {
|
|||||||
else {
|
else {
|
||||||
sscanf(ipv4_address, "%02X%02X%02X%02X", &addr[3], &addr[2], &addr[1], &addr[0]);
|
sscanf(ipv4_address, "%02X%02X%02X%02X", &addr[3], &addr[2], &addr[1], &addr[0]);
|
||||||
}
|
}
|
||||||
if(check_mcu_endian()){
|
|
||||||
*pV4Addr = (addr[0]) | (addr[1]<<8) | (addr[2]<<16) | (addr[3]<<24);
|
*pV4Addr = (addr[0]) | (addr[1]<<8) | (addr[2]<<16) | (addr[3]<<24);
|
||||||
}else{
|
|
||||||
*pV4Addr = (addr[0])<<24 | (addr[1]<<16) | (addr[2]<<8) | (addr[3]<<0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -842,11 +825,7 @@ static int requestGetIPAddress(PROFILE_T *profile, int curIpFamily) {
|
|||||||
int addr[4] = {0, 0, 0, 0};
|
int addr[4] = {0, 0, 0, 0};
|
||||||
|
|
||||||
sscanf(ipv4, "%d.%d.%d.%d", &addr[0], &addr[1], &addr[2], &addr[3]);
|
sscanf(ipv4, "%d.%d.%d.%d", &addr[0], &addr[1], &addr[2], &addr[3]);
|
||||||
if(check_mcu_endian()){
|
|
||||||
v4Addr = (addr[0]) | (addr[1]<<8) | (addr[2]<<16) | (addr[3]<<24);
|
v4Addr = (addr[0]) | (addr[1]<<8) | (addr[2]<<16) | (addr[3]<<24);
|
||||||
}else{
|
|
||||||
v4Addr = (addr[0])<< 24 | (addr[1]<<16) | (addr[2]<<8) | (addr[3]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -32,21 +32,21 @@
|
|||||||
#include "QMIThread.h"
|
#include "QMIThread.h"
|
||||||
#include "ethtool-copy.h"
|
#include "ethtool-copy.h"
|
||||||
|
|
||||||
#define USB_CLASS_VENDOR_SPEC 0xff
|
#define USB_CLASS_VENDOR_SPEC 0xff
|
||||||
#define USB_CLASS_COMM 2
|
#define USB_CLASS_COMM 2
|
||||||
#define USB_CDC_SUBCLASS_ACM 0x02
|
#define USB_CDC_SUBCLASS_ACM 0x02
|
||||||
#define USB_CDC_SUBCLASS_ETHERNET 0x06
|
#define USB_CDC_SUBCLASS_ETHERNET 0x06
|
||||||
#define USB_CDC_SUBCLASS_NCM 0x0d
|
#define USB_CDC_SUBCLASS_NCM 0x0d
|
||||||
#define USB_CDC_SUBCLASS_MBIM 0x0e
|
#define USB_CDC_SUBCLASS_MBIM 0x0e
|
||||||
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
|
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
|
||||||
|
|
||||||
#define CM_MAX_PATHLEN 256
|
#define CM_MAX_PATHLEN 256
|
||||||
|
|
||||||
#define CM_INVALID_VAL (~((int)0))
|
#define CM_INVALID_VAL (~((int)0))
|
||||||
|
|
||||||
/* get first line from file 'fname'
|
/* get first line from file 'fname'
|
||||||
* And convert the content into a hex number, then return this number */
|
* And convert the content into a hex number, then return this number */
|
||||||
static int file_get_value(const char *fname, int base)
|
static int file_get_value(const char *fname, int base) {
|
||||||
{
|
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
long num;
|
long num;
|
||||||
char buff[32 + 1] = {'\0'};
|
char buff[32 + 1] = {'\0'};
|
||||||
@ -58,7 +58,7 @@ static int file_get_value(const char *fname, int base)
|
|||||||
goto error;
|
goto error;
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
num = (int)strtol(buff, &endptr, base);
|
num = (int) strtol(buff, &endptr, base);
|
||||||
if (errno == ERANGE && (num == LONG_MAX || num == LONG_MIN))
|
if (errno == ERANGE && (num == LONG_MAX || num == LONG_MIN))
|
||||||
goto error;
|
goto error;
|
||||||
/* if there is no digit in buff */
|
/* if there is no digit in buff */
|
||||||
@ -67,9 +67,9 @@ static int file_get_value(const char *fname, int base)
|
|||||||
|
|
||||||
if (debug_qmi)
|
if (debug_qmi)
|
||||||
dbg_time("(%s) = %lx", fname, num);
|
dbg_time("(%s) = %lx", fname, num);
|
||||||
return (int)num;
|
return (int) num;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (fp) fclose(fp);
|
if (fp) fclose(fp);
|
||||||
return CM_INVALID_VAL;
|
return CM_INVALID_VAL;
|
||||||
}
|
}
|
||||||
@ -78,8 +78,7 @@ error:
|
|||||||
* This function will search the directory 'dirname' and return the first child.
|
* This function will search the directory 'dirname' and return the first child.
|
||||||
* '.' and '..' is ignored by default
|
* '.' and '..' is ignored by default
|
||||||
*/
|
*/
|
||||||
static int dir_get_child(const char *dirname, char *buff, unsigned bufsize, const char *prefix)
|
static int dir_get_child(const char *dirname, char *buff, unsigned bufsize, const char *prefix) {
|
||||||
{
|
|
||||||
struct dirent *entptr = NULL;
|
struct dirent *entptr = NULL;
|
||||||
DIR *dirptr;
|
DIR *dirptr;
|
||||||
|
|
||||||
@ -102,14 +101,13 @@ static int dir_get_child(const char *dirname, char *buff, unsigned bufsize, cons
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int conf_get_val(const char *fname, const char *key)
|
static int conf_get_val(const char *fname, const char *key) {
|
||||||
{
|
|
||||||
char buff[128] = {'\0'};
|
char buff[128] = {'\0'};
|
||||||
FILE *fp = fopen(fname, "r");
|
FILE *fp = fopen(fname, "r");
|
||||||
if (!fp)
|
if (!fp)
|
||||||
return CM_INVALID_VAL;
|
return CM_INVALID_VAL;
|
||||||
|
|
||||||
while (fgets(buff, sizeof(buff)-1, fp)) {
|
while (fgets(buff, sizeof(buff) - 1, fp)) {
|
||||||
char prefix[128] = {'\0'};
|
char prefix[128] = {'\0'};
|
||||||
char tail[128] = {'\0'};
|
char tail[128] = {'\0'};
|
||||||
/* To eliminate cppcheck warnning: Assume string length is no more than 15 */
|
/* To eliminate cppcheck warnning: Assume string length is no more than 15 */
|
||||||
@ -190,17 +188,16 @@ static void query_usb_interface_info(char *path, struct usb_interface_info *p) {
|
|||||||
break;
|
break;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
strncpy(p->driver, &driver[n+1], sizeof(p->driver) - 1);
|
strncpy(p->driver, &driver[n + 1], sizeof(p->driver) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
path[offset] = '\0';
|
path[offset] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
static int detect_path_cdc_wdm_or_qcqmi(char *path, char *devname, size_t bufsize)
|
static int detect_path_cdc_wdm_or_qcqmi(char *path, char *devname, size_t bufsize) {
|
||||||
{
|
|
||||||
size_t offset = strlen(path);
|
size_t offset = strlen(path);
|
||||||
char tmp[32];
|
char tmp[32];
|
||||||
|
|
||||||
devname[0] = 0;
|
devname[0] = 0;
|
||||||
|
|
||||||
if (access(path, R_OK))
|
if (access(path, R_OK))
|
||||||
@ -223,7 +220,7 @@ static int detect_path_cdc_wdm_or_qcqmi(char *path, char *devname, size_t bufsiz
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
step_1:
|
step_1:
|
||||||
/* get device(qcqmiX|cdc-wdmX) */
|
/* get device(qcqmiX|cdc-wdmX) */
|
||||||
if (debug_qmi) dbg_time("%s", path);
|
if (debug_qmi) dbg_time("%s", path);
|
||||||
dir_get_child(path, tmp, sizeof(tmp), NULL);
|
dir_get_child(path, tmp, sizeof(tmp), NULL);
|
||||||
@ -232,8 +229,7 @@ step_1:
|
|||||||
|
|
||||||
/* There is a chance that, no device(qcqmiX|cdc-wdmX) is generated. We should warn user about that! */
|
/* There is a chance that, no device(qcqmiX|cdc-wdmX) is generated. We should warn user about that! */
|
||||||
snprintf(devname, bufsize, "/dev/%s", tmp);
|
snprintf(devname, bufsize, "/dev/%s", tmp);
|
||||||
if (access(devname, R_OK | F_OK) && errno == ENOENT)
|
if (access(devname, R_OK | F_OK) && errno == ENOENT) {
|
||||||
{
|
|
||||||
int major, minor;
|
int major, minor;
|
||||||
|
|
||||||
dbg_time("access %s failed, errno: %d (%s)", devname, errno, strerror(errno));
|
dbg_time("access %s failed, errno: %d (%s)", devname, errno, strerror(errno));
|
||||||
@ -243,9 +239,9 @@ step_1:
|
|||||||
major = conf_get_val(path, "MAJOR");
|
major = conf_get_val(path, "MAJOR");
|
||||||
minor = conf_get_val(path, "MINOR");
|
minor = conf_get_val(path, "MINOR");
|
||||||
|
|
||||||
if(major == CM_INVALID_VAL || minor == CM_INVALID_VAL)
|
if (major == CM_INVALID_VAL || minor == CM_INVALID_VAL)
|
||||||
dbg_time("get major and minor failed");
|
dbg_time("get major and minor failed");
|
||||||
else if (mknod(devname, S_IFCHR|0666, (((major & 0xfff) << 8) | (minor & 0xff) | ((minor & 0xfff00) << 12))))
|
else if (mknod(devname, S_IFCHR | 0666, (((major & 0xfff) << 8) | (minor & 0xff) | ((minor & 0xfff00) << 12))))
|
||||||
dbg_time("please mknod %s c %d %d", devname, major, minor);
|
dbg_time("please mknod %s c %d %d", devname, major, minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,11 +254,11 @@ step_1:
|
|||||||
* TRUE -> ok
|
* TRUE -> ok
|
||||||
*/
|
*/
|
||||||
BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize, PROFILE_T *profile) {
|
BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize, PROFILE_T *profile) {
|
||||||
struct dirent* ent = NULL;
|
struct dirent *ent = NULL;
|
||||||
DIR *pDir;
|
DIR *pDir;
|
||||||
const char *rootdir = "/sys/bus/usb/devices";
|
const char *rootdir = "/sys/bus/usb/devices";
|
||||||
struct {
|
struct {
|
||||||
char path[255*2];
|
char path[255 * 2];
|
||||||
} *pl;
|
} *pl;
|
||||||
pl = (typeof(pl)) malloc(sizeof(*pl));
|
pl = (typeof(pl)) malloc(sizeof(*pl));
|
||||||
memset(pl, 0x00, sizeof(*pl));
|
memset(pl, 0x00, sizeof(*pl));
|
||||||
@ -273,9 +269,9 @@ BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((ent = readdir(pDir)) != NULL) {
|
while ((ent = readdir(pDir)) != NULL) {
|
||||||
char netcard[32+1] = {'\0'};
|
char netcard[32 + 1] = {'\0'};
|
||||||
char devname[32+5] = {'\0'}; //+strlen("/dev/")
|
char devname[32 + 5] = {'\0'}; //+strlen("/dev/")
|
||||||
int netIntf;
|
int netIntf;
|
||||||
int driver_type;
|
int driver_type;
|
||||||
|
|
||||||
@ -289,15 +285,15 @@ BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize,
|
|||||||
|
|
||||||
if (profile->usb_dev.idVendor == 0x2c7c || profile->usb_dev.idVendor == 0x05c6) {
|
if (profile->usb_dev.idVendor == 0x2c7c || profile->usb_dev.idVendor == 0x05c6) {
|
||||||
dbg_time("Find %s/%s idVendor=0x%x idProduct=0x%x, bus=0x%03x, dev=0x%03x",
|
dbg_time("Find %s/%s idVendor=0x%x idProduct=0x%x, bus=0x%03x, dev=0x%03x",
|
||||||
rootdir, ent->d_name, profile->usb_dev.idVendor, profile->usb_dev.idProduct,
|
rootdir, ent->d_name, profile->usb_dev.idVendor, profile->usb_dev.idProduct,
|
||||||
profile->usb_dev.busnum, profile->usb_dev.devnum);
|
profile->usb_dev.busnum, profile->usb_dev.devnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get network interface */
|
/* get network interface */
|
||||||
/* NOTICE: there is a case that, bNumberInterface=6, but the net interface is 8 */
|
/* NOTICE: there is a case that, bNumberInterface=6, but the net interface is 8 */
|
||||||
/* toolchain-mips_24kc_gcc-5.4.0_musl donot support GLOB_BRACE */
|
/* toolchain-mips_24kc_gcc-5.4.0_musl donot support GLOB_BRACE */
|
||||||
/* RG500U's MBIM is at inteface 0 */
|
/* RG500U's MBIM is at inteface 0 */
|
||||||
for (netIntf = 0; netIntf < (profile->usb_dev.bNumInterfaces + 8); netIntf++) {
|
for (netIntf = 0; netIntf < (profile->usb_dev.bNumInterfaces + 8); netIntf++) {
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.%d/net", rootdir, ent->d_name, netIntf);
|
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.%d/net", rootdir, ent->d_name, netIntf);
|
||||||
dir_get_child(pl->path, netcard, sizeof(netcard), NULL);
|
dir_get_child(pl->path, netcard, sizeof(netcard), NULL);
|
||||||
if (netcard[0])
|
if (netcard[0])
|
||||||
@ -305,7 +301,7 @@ BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (netcard[0] == '\0') { //for centos 2.6.x
|
if (netcard[0] == '\0') { //for centos 2.6.x
|
||||||
const char *n= "usb0";
|
const char *n = "usb0";
|
||||||
const char *c = "qcqmi0";
|
const char *c = "qcqmi0";
|
||||||
|
|
||||||
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.4/net:%s", rootdir, ent->d_name, n);
|
snprintf(pl->path, sizeof(pl->path), "%s/%s:1.4/net:%s", rootdir, ent->d_name, n);
|
||||||
@ -334,31 +330,27 @@ BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize,
|
|||||||
|
|
||||||
if (driver_type == SOFTWARE_QMI || driver_type == SOFTWARE_MBIM) {
|
if (driver_type == SOFTWARE_QMI || driver_type == SOFTWARE_MBIM) {
|
||||||
detect_path_cdc_wdm_or_qcqmi(pl->path, devname, sizeof(devname));
|
detect_path_cdc_wdm_or_qcqmi(pl->path, devname, sizeof(devname));
|
||||||
}
|
} else if (driver_type == SOFTWARE_ECM_RNDIS_NCM) {
|
||||||
else if (driver_type == SOFTWARE_ECM_RNDIS_NCM)
|
|
||||||
{
|
|
||||||
int atIntf = -1;
|
int atIntf = -1;
|
||||||
|
|
||||||
if (profile->usb_dev.idVendor == 0x2c7c) { //Quectel
|
if (profile->usb_dev.idVendor == 0x2c7c) { //Quectel
|
||||||
switch (profile->usb_dev.idProduct) { //EC200U
|
switch (profile->usb_dev.idProduct) { //EC200U
|
||||||
case 0x0901: //EC200U
|
case 0x0901: //EC200U
|
||||||
case 0x0904: //EC200G
|
case 0x8101: //RG801H
|
||||||
case 0x8101: //RG801H
|
atIntf = 2;
|
||||||
atIntf = 2;
|
break;
|
||||||
break;
|
case 0x0900: //RG500U
|
||||||
case 0x0900: //RG500U
|
atIntf = 4;
|
||||||
atIntf = 4;
|
break;
|
||||||
break;
|
case 0x6026: //EC200T
|
||||||
case 0x6026: //EC200T
|
case 0x6005: //EC200A
|
||||||
case 0x6005: //EC200A
|
case 0x6002: //EC200S
|
||||||
case 0x6002: //EC200S
|
case 0x6001: //EC100Y
|
||||||
case 0x6001: //EC100Y
|
atIntf = 3;
|
||||||
case 0x6007: //EG915Q-NA in ECM mode, it also could set atIntf to 4
|
break;
|
||||||
atIntf = 3;
|
default:
|
||||||
break;
|
dbg_time("unknow at interface for USB idProduct:%04x\n", profile->usb_dev.idProduct);
|
||||||
default:
|
break;
|
||||||
dbg_time("unknow at interface for USB idProduct:%04x\n", profile->usb_dev.idProduct);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,7 +363,7 @@ BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netcard[0] && devname[0]) {
|
if (netcard[0] && devname[0]) {
|
||||||
if (devname[0] == '/')
|
if (devname[0] == '/')
|
||||||
snprintf(qmichannel, bufsize, "%s", devname);
|
snprintf(qmichannel, bufsize, "%s", devname);
|
||||||
@ -391,51 +383,76 @@ BOOL qmidevice_detect(char *qmichannel, char *usbnet_adapter, unsigned bufsize,
|
|||||||
}
|
}
|
||||||
free(pl);
|
free(pl);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
error:
|
error:
|
||||||
free(pl);
|
free(pl);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int isContain(const char *str1, const char *str2) {
|
||||||
|
if (strstr(str1, str2) != NULL) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void replaceStr(char *str, char *orig, char *rep) {
|
||||||
|
char buffer[1024];
|
||||||
|
char *p;
|
||||||
|
while (p = strstr(str, orig)) {
|
||||||
|
memcpy(buffer, str, p - str);
|
||||||
|
buffer[p - str] = '\0';
|
||||||
|
sprintf(buffer + strlen(buffer), "%s%s", rep, p + strlen(orig));
|
||||||
|
strcpy(str, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int mhidevice_detect(char *qmichannel, char *usbnet_adapter, PROFILE_T *profile) {
|
int mhidevice_detect(char *qmichannel, char *usbnet_adapter, PROFILE_T *profile) {
|
||||||
struct dirent* ent = NULL;
|
struct dirent *ent = NULL;
|
||||||
DIR *pDir;
|
DIR *pDir;
|
||||||
const char *rootdir_mhi[] = {"/sys/bus/mhi_q/devices", "/sys/bus/mhi/devices", NULL};
|
const char *rootdir_mhi[] = {"/sys/bus/mhi_q/devices", "/sys/bus/mhi/devices", NULL};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
char path[256];
|
char path[256];
|
||||||
int find = 0;
|
int find = 0;
|
||||||
|
|
||||||
while (rootdir_mhi[i]) {
|
while (rootdir_mhi[i]) {
|
||||||
const char *rootdir = rootdir_mhi[i++];
|
const char *rootdir = rootdir_mhi[i++];
|
||||||
|
dbg_time("rootdir : %s ", rootdir);
|
||||||
pDir = opendir(rootdir);
|
pDir = opendir(rootdir);
|
||||||
if (!pDir) {
|
if (!pDir) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT) {
|
||||||
dbg_time("opendir %s failed: %s", rootdir, strerror(errno));
|
dbg_time("opendir %s failed: %s", rootdir, strerror(errno));
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
while ((ent = readdir(pDir)) != NULL) {
|
||||||
while ((ent = readdir(pDir)) != NULL) {
|
|
||||||
char netcard[32] = {'\0'};
|
char netcard[32] = {'\0'};
|
||||||
char devname[32] = {'\0'};
|
char devname[32] = {'\0'};
|
||||||
int software_interface = SOFTWARE_QMI;
|
int software_interface = SOFTWARE_QMI;
|
||||||
char *pNode = NULL;
|
char *pNode = NULL;
|
||||||
|
|
||||||
pNode = strstr(ent->d_name, "_IP_HW0"); //0306_00.01.00_IP_HW0
|
pNode = strstr(ent->d_name, "_IP_HW0"); //0306_00.01.00_IP_HW0
|
||||||
if (!pNode)
|
if (!pNode) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *d_name[32];
|
||||||
|
strcpy(d_name, ent->d_name);
|
||||||
|
replaceStr(d_name, "_IP_HW0", "");
|
||||||
|
dbg_time("while -> pcie_name = : %s ", d_name);
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/%.32s/net", rootdir, ent->d_name);
|
snprintf(path, sizeof(path), "%s/%.32s/net", rootdir, ent->d_name);
|
||||||
dir_get_child(path, netcard, sizeof(netcard), NULL);
|
dir_get_child(path, netcard, sizeof(netcard), NULL);
|
||||||
if (!netcard[0])
|
if (!netcard[0]) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (usbnet_adapter[0] && strcmp(netcard, usbnet_adapter)) //not '-i x'
|
if (usbnet_adapter[0] && strcmp(netcard, usbnet_adapter)) { //not '-i x
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp(rootdir, "/sys/bus/mhi/devices")) {
|
if (!strcmp(rootdir, "/sys/bus/mhi/devices")) {
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_IPCR", rootdir, ent->d_name); // 13 is sizeof(0306_00.01.00)
|
// snprintf(path, sizeof(path), "%s/%.13s_IPCR", rootdir, ent->d_name); // 13 is sizeof(0306_00.01.00)
|
||||||
|
snprintf(path, sizeof(path), "%s/%s_IPCR", rootdir, d_name);
|
||||||
if (!access(path, F_OK)) {
|
if (!access(path, F_OK)) {
|
||||||
/* we also need 'cat /dev/mhi_0306_00.01.00_pipe_14' to enable rmnet as like USB's DTR
|
/* we also need 'cat /dev/mhi_0306_00.01.00_pipe_14' to enable rmnet as like USB's DTR
|
||||||
or will get error 'requestSetEthMode QMUXResult = 0x1, QMUXError = 0x46' */
|
or will get error 'requestSetEthMode QMUXResult = 0x1, QMUXError = 0x46' */
|
||||||
sprintf(usbnet_adapter, "%s", netcard);
|
sprintf(usbnet_adapter, "%s", netcard);
|
||||||
sprintf(qmichannel, "qrtr-%d", 3); // 3 is sdx modem's node id
|
sprintf(qmichannel, "qrtr-%d", 3); // 3 is sdx modem's node id
|
||||||
@ -446,42 +463,59 @@ int mhidevice_detect(char *qmichannel, char *usbnet_adapter, PROFILE_T *profile)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_IPCR", rootdir, ent->d_name);
|
//解决PCIE硬编码导致不兼容hv问题
|
||||||
|
snprintf(path, sizeof(path), "%s/%s_IPCR", rootdir, d_name);
|
||||||
if (access(path, F_OK)) {
|
if (access(path, F_OK)) {
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_QMI0", rootdir, ent->d_name);
|
snprintf(path, sizeof(path), "%s/%s_QMI0", rootdir, d_name);
|
||||||
if (access(path, F_OK)) {
|
if (access(path, F_OK)) {
|
||||||
snprintf(path, sizeof(path), "%s/%.13s_MBIM", rootdir, ent->d_name);
|
snprintf(path, sizeof(path), "%s/%s_MBIM", rootdir, d_name);
|
||||||
if (!access(path, F_OK))
|
if (!access(path, F_OK)) {
|
||||||
software_interface = SOFTWARE_MBIM;
|
software_interface = SOFTWARE_MBIM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (access(path, F_OK))
|
|
||||||
|
//原
|
||||||
|
// snprintf(path, sizeof(path), "%s/%.14s_IPCR", rootdir, ent->d_name);
|
||||||
|
// dbg_time("while -> path3 : %s ", path);
|
||||||
|
// if (access(path, F_OK)) {
|
||||||
|
// snprintf(path, sizeof(path), "%s/%.14s_QMI0", rootdir, ent->d_name);
|
||||||
|
// dbg_time("while -> path4 : %s ", path);
|
||||||
|
// if (access(path, F_OK)) {
|
||||||
|
// snprintf(path, sizeof(path), "%s/%.14s_MBIM", rootdir, ent->d_name);
|
||||||
|
// dbg_time("while -> path5 : %s ", path);
|
||||||
|
// if (!access(path, F_OK)) {
|
||||||
|
// software_interface = SOFTWARE_MBIM;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
dbg_time("while -> path_final : %s ", path);
|
||||||
|
if (access(path, F_OK)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
strncat(path, "/mhi_uci_q", sizeof(path)-1);
|
strncat(path, "/mhi_uci_q", sizeof(path) - 1);
|
||||||
dir_get_child(path, devname, sizeof(devname), NULL);
|
dir_get_child(path, devname, sizeof(devname), NULL);
|
||||||
if (!devname[0])
|
if (!devname[0]) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
dbg_time("while -> path_final_sub : %s ,dev_name: %s ", path, devname);
|
||||||
sprintf(usbnet_adapter, "%s", netcard);
|
sprintf(usbnet_adapter, "%s", netcard);
|
||||||
sprintf(qmichannel, "/dev/%s", devname);
|
sprintf(qmichannel, "/dev/%s", devname);
|
||||||
profile->software_interface = software_interface;
|
profile->software_interface = software_interface;
|
||||||
find = 1;
|
find = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(pDir);
|
closedir(pDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
return find;
|
return find;
|
||||||
}
|
}
|
||||||
|
|
||||||
int atdevice_detect(char *atchannel, char *usbnet_adapter, PROFILE_T *profile) {
|
int atdevice_detect(char *atchannel, char *usbnet_adapter, PROFILE_T *profile) {
|
||||||
if (!access("/sys/class/net/sipa_dummy0", F_OK)) {
|
if (!access("/sys/class/net/sipa_dummy0", F_OK)) {
|
||||||
strcpy(usbnet_adapter, "sipa_dummy0");
|
strcpy(usbnet_adapter, "sipa_dummy0");
|
||||||
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "%s%d", "pcie", profile->pdp - 1);
|
snprintf(profile->qmapnet_adapter, sizeof(profile->qmapnet_adapter), "%s%d", "pcie", profile->pdp - 1);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
dbg_time("atdevice_detect failed");
|
dbg_time("atdevice_detect failed");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -489,65 +523,58 @@ int atdevice_detect(char *atchannel, char *usbnet_adapter, PROFILE_T *profile) {
|
|||||||
if (!access("/dev/stty_nr31", F_OK)) {
|
if (!access("/dev/stty_nr31", F_OK)) {
|
||||||
strcpy(atchannel, "/dev/stty_nr31");
|
strcpy(atchannel, "/dev/stty_nr31");
|
||||||
profile->software_interface = SOFTWARE_ECM_RNDIS_NCM;
|
profile->software_interface = SOFTWARE_ECM_RNDIS_NCM;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
error:
|
error:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int get_driver_type(PROFILE_T *profile)
|
int get_driver_type(PROFILE_T *profile) {
|
||||||
{
|
|
||||||
/* QMI_WWAN */
|
/* QMI_WWAN */
|
||||||
if (profile->usb_intf.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
|
if (profile->usb_intf.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
|
||||||
return SOFTWARE_QMI;
|
return SOFTWARE_QMI;
|
||||||
}
|
} else if (profile->usb_intf.bInterfaceClass == USB_CLASS_COMM) {
|
||||||
else if (profile->usb_intf.bInterfaceClass == USB_CLASS_COMM) {
|
|
||||||
switch (profile->usb_intf.bInterfaceSubClass) {
|
switch (profile->usb_intf.bInterfaceSubClass) {
|
||||||
case USB_CDC_SUBCLASS_MBIM:
|
case USB_CDC_SUBCLASS_MBIM:
|
||||||
return SOFTWARE_MBIM;
|
return SOFTWARE_MBIM;
|
||||||
break;
|
break;
|
||||||
case USB_CDC_SUBCLASS_ETHERNET:
|
case USB_CDC_SUBCLASS_ETHERNET:
|
||||||
case USB_CDC_SUBCLASS_NCM:
|
case USB_CDC_SUBCLASS_NCM:
|
||||||
return SOFTWARE_ECM_RNDIS_NCM;
|
return SOFTWARE_ECM_RNDIS_NCM;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if (profile->usb_intf.bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER) {
|
||||||
else if (profile->usb_intf.bInterfaceClass == USB_CLASS_WIRELESS_CONTROLLER) {
|
|
||||||
if (profile->usb_intf.bInterfaceSubClass == 1 && profile->usb_intf.bInterfaceProtocol == 3)
|
if (profile->usb_intf.bInterfaceSubClass == 1 && profile->usb_intf.bInterfaceProtocol == 3)
|
||||||
return SOFTWARE_ECM_RNDIS_NCM;
|
return SOFTWARE_ECM_RNDIS_NCM;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_time("%s unknow bInterfaceClass=%d, bInterfaceSubClass=%d", __func__,
|
dbg_time("%s unknow bInterfaceClass=%d, bInterfaceSubClass=%d", __func__,
|
||||||
profile->usb_intf.bInterfaceClass, profile->usb_intf.bInterfaceSubClass);
|
profile->usb_intf.bInterfaceClass, profile->usb_intf.bInterfaceSubClass);
|
||||||
return DRV_INVALID;
|
return DRV_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct usbfs_getdriver
|
struct usbfs_getdriver {
|
||||||
{
|
|
||||||
unsigned int interface;
|
unsigned int interface;
|
||||||
char driver[255 + 1];
|
char driver[255 + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct usbfs_ioctl
|
struct usbfs_ioctl {
|
||||||
{
|
|
||||||
int ifno; /* interface 0..N ; negative numbers reserved */
|
int ifno; /* interface 0..N ; negative numbers reserved */
|
||||||
int ioctl_code; /* MUST encode size + direction of data so the
|
int ioctl_code; /* MUST encode size + direction of data so the
|
||||||
* macros in <asm/ioctl.h> give correct values */
|
* macros in <asm/ioctl.h> give correct values */
|
||||||
void *data; /* param buffer (in, or out) */
|
void *data; /* param buffer (in, or out) */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IOCTL_USBFS_DISCONNECT _IO('U', 22)
|
#define IOCTL_USBFS_DISCONNECT _IO('U', 22)
|
||||||
#define IOCTL_USBFS_CONNECT _IO('U', 23)
|
#define IOCTL_USBFS_CONNECT _IO('U', 23)
|
||||||
|
|
||||||
int usbfs_is_kernel_driver_alive(int fd, int ifnum)
|
int usbfs_is_kernel_driver_alive(int fd, int ifnum) {
|
||||||
{
|
|
||||||
struct usbfs_getdriver getdrv;
|
struct usbfs_getdriver getdrv;
|
||||||
getdrv.interface = ifnum;
|
getdrv.interface = ifnum;
|
||||||
if (ioctl(fd, USBDEVFS_GETDRIVER, &getdrv) < 0) {
|
if (ioctl(fd, USBDEVFS_GETDRIVER, &getdrv) < 0) {
|
||||||
@ -558,8 +585,7 @@ int usbfs_is_kernel_driver_alive(int fd, int ifnum)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbfs_detach_kernel_driver(int fd, int ifnum)
|
void usbfs_detach_kernel_driver(int fd, int ifnum) {
|
||||||
{
|
|
||||||
struct usbfs_ioctl operate;
|
struct usbfs_ioctl operate;
|
||||||
operate.data = NULL;
|
operate.data = NULL;
|
||||||
operate.ifno = ifnum;
|
operate.ifno = ifnum;
|
||||||
@ -571,8 +597,7 @@ void usbfs_detach_kernel_driver(int fd, int ifnum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbfs_attach_kernel_driver(int fd, int ifnum)
|
void usbfs_attach_kernel_driver(int fd, int ifnum) {
|
||||||
{
|
|
||||||
struct usbfs_ioctl operate;
|
struct usbfs_ioctl operate;
|
||||||
operate.data = NULL;
|
operate.data = NULL;
|
||||||
operate.ifno = ifnum;
|
operate.ifno = ifnum;
|
||||||
@ -584,15 +609,13 @@ void usbfs_attach_kernel_driver(int fd, int ifnum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int reattach_driver(PROFILE_T *profile)
|
int reattach_driver(PROFILE_T *profile) {
|
||||||
{
|
|
||||||
int ifnum = 4;
|
int ifnum = 4;
|
||||||
int fd;
|
int fd;
|
||||||
char devpath[128] = {'\0'};
|
char devpath[128] = {'\0'};
|
||||||
snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", profile->usb_dev.busnum, profile->usb_dev.devnum);
|
snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", profile->usb_dev.busnum, profile->usb_dev.devnum);
|
||||||
fd = open(devpath, O_RDWR | O_NOCTTY);
|
fd = open(devpath, O_RDWR | O_NOCTTY);
|
||||||
if (fd < 0)
|
if (fd < 0) {
|
||||||
{
|
|
||||||
dbg_time("%s fail to open %s", __func__, devpath);
|
dbg_time("%s fail to open %s", __func__, devpath);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -603,11 +626,11 @@ int reattach_driver(PROFILE_T *profile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define SIOCETHTOOL 0x8946
|
#define SIOCETHTOOL 0x8946
|
||||||
int ql_get_netcard_driver_info(const char *devname)
|
|
||||||
{
|
int ql_get_netcard_driver_info(const char *devname) {
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
struct ethtool_drvinfo drvinfo;
|
struct ethtool_drvinfo drvinfo;
|
||||||
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
|
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
strcpy(ifr.ifr_name, devname);
|
strcpy(ifr.ifr_name, devname);
|
||||||
@ -619,7 +642,7 @@ int ql_get_netcard_driver_info(const char *devname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
drvinfo.cmd = ETHTOOL_GDRVINFO;
|
drvinfo.cmd = ETHTOOL_GDRVINFO;
|
||||||
ifr.ifr_data = (void *)&drvinfo;
|
ifr.ifr_data = (void *) &drvinfo;
|
||||||
|
|
||||||
if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
|
if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
|
||||||
dbg_time("ioctl() error: errno(%d)(%s)", errno, strerror(errno));
|
dbg_time("ioctl() error: errno(%d)(%s)", errno, strerror(errno));
|
||||||
@ -634,11 +657,10 @@ int ql_get_netcard_driver_info(const char *devname)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ql_get_netcard_carrier_state(const char *devname)
|
int ql_get_netcard_carrier_state(const char *devname) {
|
||||||
{
|
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
struct ethtool_value edata;
|
struct ethtool_value edata;
|
||||||
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
|
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
|
||||||
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
strcpy(ifr.ifr_name, devname);
|
strcpy(ifr.ifr_name, devname);
|
||||||
@ -651,7 +673,7 @@ int ql_get_netcard_carrier_state(const char *devname)
|
|||||||
|
|
||||||
edata.cmd = ETHTOOL_GLINK;
|
edata.cmd = ETHTOOL_GLINK;
|
||||||
edata.data = 0;
|
edata.data = 0;
|
||||||
ifr.ifr_data = (void *)&edata;
|
ifr.ifr_data = (void *) &edata;
|
||||||
|
|
||||||
if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
|
if (ioctl(fd, SIOCETHTOOL, &ifr) < 0) {
|
||||||
dbg_time("ioctl('%s') error: errno(%d)(%s)", devname, errno, strerror(errno));
|
dbg_time("ioctl('%s') error: errno(%d)(%s)", devname, errno, strerror(errno));
|
||||||
@ -666,17 +688,16 @@ int ql_get_netcard_carrier_state(const char *devname)
|
|||||||
return edata.data;
|
return edata.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *catch_log(void *arg)
|
static void *catch_log(void *arg) {
|
||||||
{
|
PROFILE_T *profile = (PROFILE_T *) arg;
|
||||||
PROFILE_T *profile = (PROFILE_T *)arg;
|
|
||||||
int nreads = 0;
|
int nreads = 0;
|
||||||
char tbuff[256+32];
|
char tbuff[256 + 32];
|
||||||
char filter[32];
|
char filter[32];
|
||||||
size_t tsize = strlen(get_time()) + 1;
|
size_t tsize = strlen(get_time()) + 1;
|
||||||
|
|
||||||
snprintf(filter, sizeof(filter), ":%d:%03d:", profile->usb_dev.busnum, profile->usb_dev.devnum);
|
snprintf(filter, sizeof(filter), ":%d:%03d:", profile->usb_dev.busnum, profile->usb_dev.devnum);
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
nreads = read(profile->usbmon_fd, tbuff + tsize, sizeof(tbuff) - tsize - 1);
|
nreads = read(profile->usbmon_fd, tbuff + tsize, sizeof(tbuff) - tsize - 1);
|
||||||
if (nreads <= 0) {
|
if (nreads <= 0) {
|
||||||
if (nreads == -1 && errno == EINTR)
|
if (nreads == -1 && errno == EINTR)
|
||||||
@ -684,13 +705,13 @@ static void *catch_log(void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tbuff[tsize+nreads] = '\0'; // printf("%s", buff);
|
tbuff[tsize + nreads] = '\0'; // printf("%s", buff);
|
||||||
|
|
||||||
if (!strstr(tbuff+tsize, filter))
|
if (!strstr(tbuff + tsize, filter))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(tbuff, sizeof(tbuff), "%s", get_time());
|
snprintf(tbuff, sizeof(tbuff), "%s", get_time());
|
||||||
tbuff[tsize-1] = ' ';
|
tbuff[tsize - 1] = ' ';
|
||||||
|
|
||||||
fwrite(tbuff, strlen(tbuff), 1, profile->usbmon_logfile_fp);
|
fwrite(tbuff, strlen(tbuff), 1, profile->usbmon_logfile_fp);
|
||||||
}
|
}
|
||||||
@ -698,8 +719,7 @@ static void *catch_log(void *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ql_capture_usbmon_log(PROFILE_T *profile, const char *log_path)
|
int ql_capture_usbmon_log(PROFILE_T *profile, const char *log_path) {
|
||||||
{
|
|
||||||
char usbmon_path[256];
|
char usbmon_path[256];
|
||||||
pthread_t pt;
|
pthread_t pt;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
@ -726,16 +746,16 @@ int ql_capture_usbmon_log(PROFILE_T *profile, const char *log_path)
|
|||||||
|
|
||||||
profile->usbmon_logfile_fp = fopen(log_path, "wb");
|
profile->usbmon_logfile_fp = fopen(log_path, "wb");
|
||||||
if (!profile->usbmon_logfile_fp) {
|
if (!profile->usbmon_logfile_fp) {
|
||||||
dbg_time("open %s error(%d) (%s)", log_path, errno, strerror(errno));
|
dbg_time("open %s error(%d) (%s)", log_path, errno, strerror(errno));
|
||||||
close(profile->usbmon_fd);
|
close(profile->usbmon_fd);
|
||||||
profile->usbmon_fd = -1;
|
profile->usbmon_fd = -1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
|
||||||
pthread_create(&pt, &attr, catch_log, (void *)profile);
|
pthread_create(&pt, &attr, catch_log, (void *) profile);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 -2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 -2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -58,10 +58,8 @@ static int check_ipv4_address(PROFILE_T *profile) {
|
|||||||
|
|
||||||
if (profile->request_ops == &mbim_request_ops)
|
if (profile->request_ops == &mbim_request_ops)
|
||||||
return 1; //we will get a new ipv6 address per requestGetIPAddress()
|
return 1; //we will get a new ipv6 address per requestGetIPAddress()
|
||||||
if (profile->request_ops == &atc_request_ops) {
|
if (profile->request_ops == &atc_request_ops)
|
||||||
if (!profile->udhcpc_ip) return 1;
|
return 1; //TODO
|
||||||
oldAddress = profile->udhcpc_ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile->request_ops->requestGetIPAddress(profile, IpFamilyV4) == 0) {
|
if (profile->request_ops->requestGetIPAddress(profile, IpFamilyV4) == 0) {
|
||||||
if (profile->ipv4.Address != oldAddress || debug_qmi) {
|
if (profile->ipv4.Address != oldAddress || debug_qmi) {
|
||||||
@ -250,7 +248,6 @@ static int usage(const char *progname) {
|
|||||||
dbg_time("-m iface-idx Bind QMI data call to wwan0_<iface idx> when QMAP used. E.g '-n 7 -m 1' bind pdn-7 data call to wwan0_1");
|
dbg_time("-m iface-idx Bind QMI data call to wwan0_<iface idx> when QMAP used. E.g '-n 7 -m 1' bind pdn-7 data call to wwan0_1");
|
||||||
dbg_time("-b Enable network interface bridge function (default 0)");
|
dbg_time("-b Enable network interface bridge function (default 0)");
|
||||||
dbg_time("-v Verbose log mode, for debug purpose.");
|
dbg_time("-v Verbose log mode, for debug purpose.");
|
||||||
dbg_time("-d Obtain the IP address and dns through qmi");
|
|
||||||
dbg_time("[Examples]");
|
dbg_time("[Examples]");
|
||||||
dbg_time("Example 1: %s ", progname);
|
dbg_time("Example 1: %s ", progname);
|
||||||
dbg_time("Example 2: %s -s 3gnet ", progname);
|
dbg_time("Example 2: %s -s 3gnet ", progname);
|
||||||
@ -370,15 +367,6 @@ static int qmi_main(PROFILE_T *profile)
|
|||||||
request_ops->requestRegisterQos(profile);
|
request_ops->requestRegisterQos(profile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1 //USB disconnnect and re-connect, but not reboot modem, will get this bug
|
|
||||||
if (profile->enable_ipv4
|
|
||||||
&& profile->request_ops == &atc_request_ops
|
|
||||||
&& !request_ops->requestQueryDataCall(&IPv4ConnectionStatus, IpFamilyV4)
|
|
||||||
&& IPv4ConnectionStatus == QWDS_PKT_DATA_CONNECTED) {
|
|
||||||
request_ops->requestDeactivateDefaultPDP(profile, IpFamilyV4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
send_signo_to_main(SIG_EVENT_CHECK);
|
send_signo_to_main(SIG_EVENT_CHECK);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -728,11 +716,6 @@ static int quectel_CM(PROFILE_T *profile)
|
|||||||
dbg_time("Modem works in MBIM mode");
|
dbg_time("Modem works in MBIM mode");
|
||||||
profile->request_ops = &mbim_request_ops;
|
profile->request_ops = &mbim_request_ops;
|
||||||
profile->qmi_ops = &mbim_dev_ops;
|
profile->qmi_ops = &mbim_dev_ops;
|
||||||
if (!profile->apn || !profile->apn[0]) {
|
|
||||||
//see FAE-51804 FAE-59811
|
|
||||||
dbg_time("When MBIM mode, must specify APN with '-s', or setup data call may fail!");
|
|
||||||
exit(-404); //if no such issue on your side, please comment this
|
|
||||||
}
|
|
||||||
ret = qmi_main(profile);
|
ret = qmi_main(profile);
|
||||||
}
|
}
|
||||||
else if (profile->software_interface == SOFTWARE_QMI) {
|
else if (profile->software_interface == SOFTWARE_QMI) {
|
||||||
@ -774,7 +757,6 @@ static int parse_user_input(int argc, char **argv, PROFILE_T *profile) {
|
|||||||
int opt = 1;
|
int opt = 1;
|
||||||
|
|
||||||
profile->pdp = CONFIG_DEFAULT_PDP;
|
profile->pdp = CONFIG_DEFAULT_PDP;
|
||||||
profile->profile_index = CONFIG_DEFAULT_PDP;
|
|
||||||
|
|
||||||
if (!strcmp(argv[argc-1], "&"))
|
if (!strcmp(argv[argc-1], "&"))
|
||||||
argc--;
|
argc--;
|
||||||
@ -883,10 +865,6 @@ static int parse_user_input(int argc, char **argv, PROFILE_T *profile) {
|
|||||||
profile->enable_ipv6 = 1;
|
profile->enable_ipv6 = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
|
||||||
profile->no_dhcp = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
if (has_more_argv()) {
|
if (has_more_argv()) {
|
||||||
profile->usblogfile = argv[opt++];
|
profile->usblogfile = argv[opt++];
|
||||||
@ -921,7 +899,7 @@ int main(int argc, char *argv[])
|
|||||||
int ret;
|
int ret;
|
||||||
PROFILE_T *ctx = &s_profile;
|
PROFILE_T *ctx = &s_profile;
|
||||||
|
|
||||||
dbg_time("QConnectManager_Linux_V1.6.5.1");
|
dbg_time("QConnectManager_Linux_V1.6.4");
|
||||||
|
|
||||||
ret = parse_user_input(argc, argv, ctx);
|
ret = parse_user_input(argc, argv, ctx);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -34,9 +34,9 @@
|
|||||||
|
|
||||||
#include "qendian.h"
|
#include "qendian.h"
|
||||||
#include "qlist.h"
|
#include "qlist.h"
|
||||||
#include "QCQMI.h"
|
#include "MPQMI.h"
|
||||||
#include "QCQCTL.h"
|
#include "MPQCTL.h"
|
||||||
#include "QCQMUX.h"
|
#include "MPQMUX.h"
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN(a, b) ((a) < (b)? (a): (b))
|
#define MIN(a, b) ((a) < (b)? (a): (b))
|
||||||
@ -117,8 +117,6 @@ static int modem_reset_flag = 0;
|
|||||||
static int qmi_sync_done = 0;
|
static int qmi_sync_done = 0;
|
||||||
static uint8_t qmi_buf[4096];
|
static uint8_t qmi_buf[4096];
|
||||||
|
|
||||||
static int send_qmi_to_cdc_wdm(PQCQMIMSG pQMI);
|
|
||||||
|
|
||||||
#ifdef QUECTEL_QMI_MERGE
|
#ifdef QUECTEL_QMI_MERGE
|
||||||
static int merge_qmi_rsp_packet(void *buf, ssize_t *src_size) {
|
static int merge_qmi_rsp_packet(void *buf, ssize_t *src_size) {
|
||||||
static QMI_MSG_PACKET s_QMIPacket;
|
static QMI_MSG_PACKET s_QMIPacket;
|
||||||
@ -170,8 +168,8 @@ static int create_local_server(const char *name) {
|
|||||||
alen = strlen(name) + offsetof(struct sockaddr_un, sun_path) + 1;
|
alen = strlen(name) + offsetof(struct sockaddr_un, sun_path) + 1;
|
||||||
SYSCHECK(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,sizeof(reuse_addr)));
|
SYSCHECK(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,sizeof(reuse_addr)));
|
||||||
if(bind(sockfd, (struct sockaddr *)&sockaddr, alen) < 0) {
|
if(bind(sockfd, (struct sockaddr *)&sockaddr, alen) < 0) {
|
||||||
dprintf("bind %s errno: %d (%s)\n", name, errno, strerror(errno));
|
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
|
dprintf("bind %s errno: %d (%s)\n", name, errno, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +201,7 @@ static void accept_qmi_connection(int serverfd) {
|
|||||||
cfmakenoblock(clientfd);
|
cfmakenoblock(clientfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup_qmi_connection(int clientfd, int clientDisconnect) {
|
static void cleanup_qmi_connection(int clientfd) {
|
||||||
struct qlistnode *con_node, *qmi_node;
|
struct qlistnode *con_node, *qmi_node;
|
||||||
|
|
||||||
qlist_for_each(con_node, &qmi_proxy_connection) {
|
qlist_for_each(con_node, &qmi_proxy_connection) {
|
||||||
@ -213,33 +211,8 @@ static void cleanup_qmi_connection(int clientfd, int clientDisconnect) {
|
|||||||
while (!qlist_empty(&qmi_con->client_qnode)) {
|
while (!qlist_empty(&qmi_con->client_qnode)) {
|
||||||
QMI_PROXY_CLINET *qmi_client = qnode_to_item(qlist_head(&qmi_con->client_qnode), QMI_PROXY_CLINET, qnode);
|
QMI_PROXY_CLINET *qmi_client = qnode_to_item(qlist_head(&qmi_con->client_qnode), QMI_PROXY_CLINET, qnode);
|
||||||
|
|
||||||
if (clientDisconnect) {
|
dprintf("xxx ClientFd=%d QMIType=%d ClientId=%d\n", qmi_con->ClientFd, qmi_client->QMIType, qmi_client->ClientId);
|
||||||
int size = 17;
|
|
||||||
QMI_PROXY_MSG *qmi_msg = malloc(sizeof(QMI_PROXY_MSG) + size);
|
|
||||||
PQCQMIMSG pQMI = &qmi_msg->qmi[0];
|
|
||||||
|
|
||||||
dprintf("xxx ClientFd=%d QMIType=%d ClientId=%d\n", qmi_con->ClientFd, qmi_client->QMIType, qmi_client->ClientId);
|
|
||||||
qlist_init(&qmi_msg->qnode);
|
|
||||||
qmi_msg->ClientFd = qmi_proxy_server_fd;
|
|
||||||
pQMI->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
|
|
||||||
pQMI->QMIHdr.Length = htole16(16);
|
|
||||||
pQMI->QMIHdr.CtlFlags = 0x00;
|
|
||||||
pQMI->QMIHdr.QMIType = QMUX_TYPE_CTL;
|
|
||||||
pQMI->QMIHdr.ClientId= 0x00;
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.CtlFlags = QMICTL_FLAG_REQUEST;
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.TransactionId = 255;
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.QMICTLType = htole16(QMICTL_RELEASE_CLIENT_ID_REQ);
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.Length = htole16(5);
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER;
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.TLVLength = htole16(2);
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.QMIType = qmi_client->QMIType;
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdReq.ClientId = qmi_client->ClientId;
|
|
||||||
|
|
||||||
if (qlist_empty(&qmi_proxy_ctl_msg))
|
|
||||||
send_qmi_to_cdc_wdm(pQMI);
|
|
||||||
qlist_add_tail(&qmi_proxy_ctl_msg, &qmi_msg->qnode);
|
|
||||||
}
|
|
||||||
|
|
||||||
qlist_remove(&qmi_client->qnode);
|
qlist_remove(&qmi_client->qnode);
|
||||||
free(qmi_client);
|
free(qmi_client);
|
||||||
}
|
}
|
||||||
@ -300,13 +273,12 @@ static void dump_qmi(PQCQMIMSG pQMI, int fd, const char flag)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned size = le16toh(pQMI->QMIHdr.Length) + 1;
|
unsigned size = le16toh(pQMI->QMIHdr.Length) + 1;
|
||||||
char buf[128];
|
printf("%c %d %u: ", flag, fd, size);
|
||||||
int cnt = 0;
|
if (size > 16)
|
||||||
|
size = 16;
|
||||||
cnt += snprintf(buf + cnt, sizeof(buf) - cnt, "%c %d %u: ", flag, fd, size);
|
for (i = 0; i < size; i++)
|
||||||
for (i = 0; i < size && i < 24; i++)
|
printf("%02x ", ((uint8_t *)pQMI)[i]);
|
||||||
cnt += snprintf(buf + cnt, sizeof(buf) - cnt, "%02x ", ((uint8_t *)pQMI)[i]);
|
printf("\n");
|
||||||
dprintf("%s\n", buf)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,51 +327,40 @@ static void recv_qmi_from_dev(PQCQMIMSG pQMI) {
|
|||||||
if (!qlist_empty(&qmi_proxy_ctl_msg)) {
|
if (!qlist_empty(&qmi_proxy_ctl_msg)) {
|
||||||
QMI_PROXY_MSG *qmi_msg = qnode_to_item(qlist_head(&qmi_proxy_ctl_msg), QMI_PROXY_MSG, qnode);
|
QMI_PROXY_MSG *qmi_msg = qnode_to_item(qlist_head(&qmi_proxy_ctl_msg), QMI_PROXY_MSG, qnode);
|
||||||
|
|
||||||
if (qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.TransactionId != pQMI->CTLMsg.QMICTLMsgHdrRsp.TransactionId
|
qlist_for_each(con_node, &qmi_proxy_connection) {
|
||||||
|| qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.QMICTLType != pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) {
|
QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(con_node, QMI_PROXY_CONNECTION, qnode);
|
||||||
dprintf("ERROR: ctl rsp tid:%d, type:%d - ctl req %d, %d\n",
|
|
||||||
pQMI->CTLMsg.QMICTLMsgHdrRsp.TransactionId, pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType,
|
|
||||||
qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.TransactionId, qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.QMICTLType);
|
|
||||||
}
|
|
||||||
else if (qmi_msg->ClientFd == qmi_proxy_server_fd) {
|
|
||||||
if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_RESP) {
|
|
||||||
dprintf("--- ClientFd=%d QMIType=%d ClientId=%d\n", qmi_proxy_server_fd,
|
|
||||||
pQMI->CTLMsg.ReleaseClientIdRsp.QMIType, pQMI->CTLMsg.ReleaseClientIdRsp.ClientId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
qlist_for_each(con_node, &qmi_proxy_connection) {
|
|
||||||
QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(con_node, QMI_PROXY_CONNECTION, qnode);
|
|
||||||
|
|
||||||
if (qmi_con->ClientFd == qmi_msg->ClientFd) {
|
if (qmi_con->ClientFd == qmi_msg->ClientFd) {
|
||||||
send_qmi_to_client(pQMI, qmi_msg->ClientFd);
|
send_qmi_to_client(pQMI, qmi_msg->ClientFd);
|
||||||
|
|
||||||
if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_GET_CLIENT_ID_RESP) {
|
if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_GET_CLIENT_ID_RESP)
|
||||||
get_client_id(qmi_con, &pQMI->CTLMsg.GetClientIdRsp);
|
get_client_id(qmi_con, &pQMI->CTLMsg.GetClientIdRsp);
|
||||||
}
|
else if ((le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_RESP) ||
|
||||||
else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_RESP) {
|
(le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_REVOKE_CLIENT_ID_IND)) {
|
||||||
release_client_id(qmi_con, &pQMI->CTLMsg.ReleaseClientIdRsp);
|
release_client_id(qmi_con, &pQMI->CTLMsg.ReleaseClientIdRsp);
|
||||||
}
|
if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_REVOKE_CLIENT_ID_IND)
|
||||||
else {
|
modem_reset_flag = 1;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qlist_remove(&qmi_msg->qnode);
|
qlist_remove(&qmi_msg->qnode);
|
||||||
free(qmi_msg);
|
free(qmi_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!qlist_empty(&qmi_proxy_ctl_msg)) {
|
if (!qlist_empty(&qmi_proxy_ctl_msg)) {
|
||||||
QMI_PROXY_MSG *qmi_msg = qnode_to_item(qlist_head(&qmi_proxy_ctl_msg), QMI_PROXY_MSG, qnode);
|
QMI_PROXY_MSG *qmi_msg = qnode_to_item(qlist_head(&qmi_proxy_ctl_msg), QMI_PROXY_MSG, qnode);
|
||||||
|
|
||||||
|
qlist_for_each(con_node, &qmi_proxy_connection) {
|
||||||
|
QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(con_node, QMI_PROXY_CONNECTION, qnode);
|
||||||
|
|
||||||
|
if (qmi_con->ClientFd == qmi_msg->ClientFd) {
|
||||||
send_qmi_to_cdc_wdm(qmi_msg->qmi);
|
send_qmi_to_cdc_wdm(qmi_msg->qmi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (pQMI->QMIHdr.QMIType == QMICTL_CTL_FLAG_IND) {
|
|
||||||
if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_REVOKE_CLIENT_ID_IND) {
|
|
||||||
modem_reset_flag = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -419,10 +380,10 @@ static void recv_qmi_from_dev(PQCQMIMSG pQMI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int recv_qmi_from_client(PQCQMIMSG pQMI, unsigned size, int clientfd) {
|
static int recv_qmi_from_client(PQCQMIMSG pQMI, unsigned size, int clientfd) {
|
||||||
if (qmi_proxy_server_fd == -1)
|
if (qmi_proxy_server_fd <= 0) {
|
||||||
return -1;
|
send_qmi_to_cdc_wdm(pQMI);
|
||||||
|
}
|
||||||
if (pQMI->QMIHdr.QMIType == QMUX_TYPE_CTL) {
|
else if (pQMI->QMIHdr.QMIType == QMUX_TYPE_CTL) {
|
||||||
QMI_PROXY_MSG *qmi_msg;
|
QMI_PROXY_MSG *qmi_msg;
|
||||||
|
|
||||||
if (pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType == QMICTL_SYNC_REQ) {
|
if (pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType == QMICTL_SYNC_REQ) {
|
||||||
@ -430,13 +391,13 @@ static int recv_qmi_from_client(PQCQMIMSG pQMI, unsigned size, int clientfd) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qlist_empty(&qmi_proxy_ctl_msg))
|
||||||
|
send_qmi_to_cdc_wdm(pQMI);
|
||||||
|
|
||||||
qmi_msg = malloc(sizeof(QMI_PROXY_MSG) + size);
|
qmi_msg = malloc(sizeof(QMI_PROXY_MSG) + size);
|
||||||
qlist_init(&qmi_msg->qnode);
|
qlist_init(&qmi_msg->qnode);
|
||||||
qmi_msg->ClientFd = clientfd;
|
qmi_msg->ClientFd = clientfd;
|
||||||
memcpy(qmi_msg->qmi, pQMI, size);
|
memcpy(qmi_msg->qmi, pQMI, size);
|
||||||
|
|
||||||
if (qlist_empty(&qmi_proxy_ctl_msg))
|
|
||||||
send_qmi_to_cdc_wdm(pQMI);
|
|
||||||
qlist_add_tail(&qmi_proxy_ctl_msg, &qmi_msg->qnode);
|
qlist_add_tail(&qmi_proxy_ctl_msg, &qmi_msg->qnode);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -446,7 +407,7 @@ static int recv_qmi_from_client(PQCQMIMSG pQMI, unsigned size, int clientfd) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qmi_proxy_init(unsigned retry) {
|
static int qmi_proxy_init(void) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
QCQMIMSG _QMI;
|
QCQMIMSG _QMI;
|
||||||
PQCQMIMSG pQMI = &_QMI;
|
PQCQMIMSG pQMI = &_QMI;
|
||||||
@ -461,10 +422,10 @@ static int qmi_proxy_init(unsigned retry) {
|
|||||||
pQMI->CTLMsg.QMICTLMsgHdr.CtlFlags = QMICTL_FLAG_REQUEST;
|
pQMI->CTLMsg.QMICTLMsgHdr.CtlFlags = QMICTL_FLAG_REQUEST;
|
||||||
|
|
||||||
qmi_sync_done = 0;
|
qmi_sync_done = 0;
|
||||||
for (i = 0; i < retry; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
pQMI->CTLMsg.SyncReq.TransactionId = i+1;
|
pQMI->CTLMsg.SyncReq.TransactionId = i+1;
|
||||||
pQMI->CTLMsg.SyncReq.QMICTLType = htole16(QMICTL_SYNC_REQ);
|
pQMI->CTLMsg.SyncReq.QMICTLType = QMICTL_SYNC_REQ;
|
||||||
pQMI->CTLMsg.SyncReq.Length = htole16(0);
|
pQMI->CTLMsg.SyncReq.Length = 0;
|
||||||
|
|
||||||
pQMI->QMIHdr.Length =
|
pQMI->QMIHdr.Length =
|
||||||
htole16(le16toh(pQMI->CTLMsg.QMICTLMsgHdr.Length) + sizeof(QCQMI_HDR) + sizeof(QCQMICTL_MSG_HDR) - 1);
|
htole16(le16toh(pQMI->CTLMsg.QMICTLMsgHdr.Length) + sizeof(QCQMI_HDR) + sizeof(QCQMICTL_MSG_HDR) - 1);
|
||||||
@ -481,6 +442,22 @@ static int qmi_proxy_init(unsigned retry) {
|
|||||||
return qmi_sync_done ? 0 : -1;
|
return qmi_sync_done ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qmi_start_server(const char* servername) {
|
||||||
|
qmi_proxy_server_fd = create_local_server(servername);
|
||||||
|
dprintf("qmi_proxy_server_fd = %d\n", qmi_proxy_server_fd);
|
||||||
|
if (qmi_proxy_server_fd == -1) {
|
||||||
|
dprintf("Failed to create %s, errno: %d (%s)\n", servername, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void qmi_close_server(const char* servername) {
|
||||||
|
if (qmi_proxy_server_fd != -1) {
|
||||||
|
dprintf("%s %s close server\n", __func__, servername);
|
||||||
|
close(qmi_proxy_server_fd);
|
||||||
|
qmi_proxy_server_fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void *qmi_proxy_loop(void *param)
|
static void *qmi_proxy_loop(void *param)
|
||||||
{
|
{
|
||||||
PQCQMIMSG pQMI = (PQCQMIMSG)qmi_buf;
|
PQCQMIMSG pQMI = (PQCQMIMSG)qmi_buf;
|
||||||
@ -533,7 +510,7 @@ static void *qmi_proxy_loop(void *param)
|
|||||||
do {
|
do {
|
||||||
//ret = poll(pollfds, nevents, -1);
|
//ret = poll(pollfds, nevents, -1);
|
||||||
ret = poll(pollfds, nevents, (qmi_proxy_server_fd > 0) ? -1 : 200);
|
ret = poll(pollfds, nevents, (qmi_proxy_server_fd > 0) ? -1 : 200);
|
||||||
} while (ret == -1 && errno == EINTR && qmi_proxy_quit == 0);
|
} while (ret == -1 && errno == EINTR && qmi_proxy_quit == 0);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dprintf("%s poll=%d, errno: %d (%s)\n", __func__, ret, errno, strerror(errno));
|
dprintf("%s poll=%d, errno: %d (%s)\n", __func__, ret, errno, strerror(errno));
|
||||||
@ -551,7 +528,7 @@ static void *qmi_proxy_loop(void *param)
|
|||||||
} else if(fd == qmi_proxy_server_fd) {
|
} else if(fd == qmi_proxy_server_fd) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cleanup_qmi_connection(fd, 1);
|
cleanup_qmi_connection(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -589,7 +566,7 @@ static void *qmi_proxy_loop(void *param)
|
|||||||
|
|
||||||
if (nreads <= 0) {
|
if (nreads <= 0) {
|
||||||
dprintf("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
dprintf("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno));
|
||||||
cleanup_qmi_connection(fd, 1);
|
cleanup_qmi_connection(fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +585,7 @@ qmi_proxy_loop_exit:
|
|||||||
while (!qlist_empty(&qmi_proxy_connection)) {
|
while (!qlist_empty(&qmi_proxy_connection)) {
|
||||||
QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(qlist_head(&qmi_proxy_connection), QMI_PROXY_CONNECTION, qnode);
|
QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(qlist_head(&qmi_proxy_connection), QMI_PROXY_CONNECTION, qnode);
|
||||||
|
|
||||||
cleanup_qmi_connection(qmi_con->ClientFd, 0);
|
cleanup_qmi_connection(qmi_con->ClientFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintf("%s exit, thread_id %p\n", __func__, (void *)pthread_self());
|
dprintf("%s exit, thread_id %p\n", __func__, (void *)pthread_self());
|
||||||
@ -624,7 +601,8 @@ static void usage(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void sig_action(int sig) {
|
static void sig_action(int sig) {
|
||||||
if (qmi_proxy_quit++ == 0) {
|
if (qmi_proxy_quit == 0) {
|
||||||
|
qmi_proxy_quit = 1;
|
||||||
if (thread_id)
|
if (thread_id)
|
||||||
pthread_kill(thread_id, sig);
|
pthread_kill(thread_id, sig);
|
||||||
}
|
}
|
||||||
@ -633,6 +611,7 @@ static void sig_action(int sig) {
|
|||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int opt;
|
int opt;
|
||||||
char cdc_wdm[32+1] = "/dev/cdc-wdm0";
|
char cdc_wdm[32+1] = "/dev/cdc-wdm0";
|
||||||
|
int retry_times = 0;
|
||||||
char servername[64] = {0};
|
char servername[64] = {0};
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
@ -653,47 +632,62 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (access(cdc_wdm, R_OK | W_OK)) {
|
||||||
|
dprintf("Fail to access %s, errno: %d (%s). break\n", cdc_wdm, errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(servername, "quectel-qmi-proxy%c", cdc_wdm[strlen(cdc_wdm)-1]);
|
sprintf(servername, "quectel-qmi-proxy%c", cdc_wdm[strlen(cdc_wdm)-1]);
|
||||||
dprintf("Will use cdc-wdm='%s', proxy='%s'\n", cdc_wdm, servername);
|
dprintf("Will use cdc-wdm='%s', proxy='%s'\n", cdc_wdm, servername);
|
||||||
|
|
||||||
while (qmi_proxy_quit == 0) {
|
while (qmi_proxy_quit == 0) {
|
||||||
cdc_wdm_fd = open(cdc_wdm, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
if (access(cdc_wdm, R_OK | W_OK)) {
|
||||||
if (cdc_wdm_fd == -1) {
|
dprintf("Fail to access %s, errno: %d (%s). continue\n", cdc_wdm, errno, strerror(errno));
|
||||||
dprintf("Failed to open %s, errno: %d (%s)\n", cdc_wdm, errno, strerror(errno));
|
// wait device
|
||||||
sleep(3);
|
sleep(3);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cdc_wdm_fd = open(cdc_wdm, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||||
|
if (cdc_wdm_fd == -1) {
|
||||||
|
dprintf("Failed to open %s, errno: %d (%s). break\n", cdc_wdm, errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
cfmakenoblock(cdc_wdm_fd);
|
cfmakenoblock(cdc_wdm_fd);
|
||||||
|
|
||||||
/* no qmi_proxy_loop lives, create one */
|
/* no qmi_proxy_loop lives, create one */
|
||||||
pthread_create(&thread_id, NULL, qmi_proxy_loop, NULL);
|
pthread_create(&thread_id, NULL, qmi_proxy_loop, NULL);
|
||||||
|
/* try to redo init if failed, init function must be successfully */
|
||||||
if (qmi_proxy_init(60) == 0) {
|
while (qmi_proxy_init() != 0) {
|
||||||
qmi_proxy_server_fd = create_local_server(servername);
|
if (retry_times < 5) {
|
||||||
dprintf("qmi_proxy_server_fd = %d\n", qmi_proxy_server_fd);
|
dprintf("fail to init proxy, try again in 2 seconds.\n");
|
||||||
if (qmi_proxy_server_fd == -1) {
|
sleep(2);
|
||||||
dprintf("Failed to create %s, errno: %d (%s)\n", servername, errno, strerror(errno));
|
retry_times++;
|
||||||
pthread_cancel(thread_id);
|
} else {
|
||||||
|
dprintf("has failed too much times, restart the modem and have a try...\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
/* break loop if modem is detached */
|
||||||
|
if (access(cdc_wdm, F_OK|R_OK|W_OK))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
retry_times = 0;
|
||||||
pthread_cancel(thread_id);
|
qmi_start_server(servername);
|
||||||
}
|
if (qmi_proxy_server_fd == -1)
|
||||||
|
pthread_cancel(thread_id);
|
||||||
pthread_join(thread_id, NULL);
|
pthread_join(thread_id, NULL);
|
||||||
thread_id = 0;
|
|
||||||
|
|
||||||
if (qmi_proxy_server_fd != -1) {
|
/* close local server at last */
|
||||||
dprintf("close server %s\n", servername);
|
qmi_close_server(servername);
|
||||||
close(qmi_proxy_server_fd);
|
|
||||||
qmi_proxy_server_fd = -1;
|
|
||||||
}
|
|
||||||
close(cdc_wdm_fd);
|
close(cdc_wdm_fd);
|
||||||
cdc_wdm_fd = -1;
|
/* DO RESTART IN 20s IF MODEM RESET ITSELF */
|
||||||
|
if (modem_reset_flag) {
|
||||||
if (qmi_proxy_quit == 0)
|
unsigned int time_to_wait = 20;
|
||||||
sleep(modem_reset_flag ? 30 : 3);
|
while (time_to_wait) {
|
||||||
modem_reset_flag = 0;
|
time_to_wait = sleep(time_to_wait);
|
||||||
|
}
|
||||||
|
modem_reset_flag = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -36,9 +36,9 @@
|
|||||||
|
|
||||||
#include "qendian.h"
|
#include "qendian.h"
|
||||||
#include "qlist.h"
|
#include "qlist.h"
|
||||||
#include "QCQMI.h"
|
#include "MPQMI.h"
|
||||||
#include "QCQCTL.h"
|
#include "MPQCTL.h"
|
||||||
#include "QCQMUX.h"
|
#include "MPQMUX.h"
|
||||||
|
|
||||||
static const char * get_time(void) {
|
static const char * get_time(void) {
|
||||||
static char time_buf[128];
|
static char time_buf[128];
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@ -105,17 +105,6 @@ static short ifc_get_flags(const char *ifname)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ifc_set_state(const char *ifname, int state) {
|
|
||||||
char shell_cmd[128];
|
|
||||||
|
|
||||||
if (!access("/sbin/ip", X_OK)) {
|
|
||||||
snprintf(shell_cmd, sizeof(shell_cmd), "ip link set dev %s %s", ifname, state ? "up" : "down");
|
|
||||||
} else {
|
|
||||||
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s %s", ifname, state ? "up" : "down");
|
|
||||||
}
|
|
||||||
ql_system(shell_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ql_netcard_ipv4_address_check(const char *ifname, in_addr_t ip) {
|
static int ql_netcard_ipv4_address_check(const char *ifname, in_addr_t ip) {
|
||||||
in_addr_t addr = 0;
|
in_addr_t addr = 0;
|
||||||
|
|
||||||
@ -126,6 +115,7 @@ static int ql_netcard_ipv4_address_check(const char *ifname, in_addr_t ip) {
|
|||||||
static int ql_raw_ip_mode_check(const char *ifname, uint32_t ip) {
|
static int ql_raw_ip_mode_check(const char *ifname, uint32_t ip) {
|
||||||
int fd;
|
int fd;
|
||||||
char raw_ip[128];
|
char raw_ip[128];
|
||||||
|
char shell_cmd[128];
|
||||||
char mode[2] = "X";
|
char mode[2] = "X";
|
||||||
int mode_change = 0;
|
int mode_change = 0;
|
||||||
|
|
||||||
@ -145,12 +135,14 @@ static int ql_raw_ip_mode_check(const char *ifname, uint32_t ip) {
|
|||||||
if (read(fd, mode, 2) == -1) {};
|
if (read(fd, mode, 2) == -1) {};
|
||||||
if (mode[0] == '0' || mode[0] == 'N') {
|
if (mode[0] == '0' || mode[0] == 'N') {
|
||||||
dbg_time("File:%s Line:%d udhcpc fail to get ip address, try next:", __func__, __LINE__);
|
dbg_time("File:%s Line:%d udhcpc fail to get ip address, try next:", __func__, __LINE__);
|
||||||
ifc_set_state(ifname, 0);
|
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s down", ifname);
|
||||||
|
ql_system(shell_cmd);
|
||||||
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
|
dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname);
|
||||||
mode[0] = 'Y';
|
mode[0] = 'Y';
|
||||||
if (write(fd, mode, 2) == -1) {};
|
if (write(fd, mode, 2) == -1) {};
|
||||||
mode_change = 1;
|
mode_change = 1;
|
||||||
ifc_set_state(ifname, 1);
|
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s up", ifname);
|
||||||
|
ql_system(shell_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -219,7 +211,8 @@ void ql_set_driver_link_state(PROFILE_T *profile, int link_state) {
|
|||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
rc = read(fd, link_file, sizeof(link_file));
|
rc = read(fd, link_file, sizeof(link_file));
|
||||||
if (rc > 1 && (!strncasecmp(link_file, "0\n", 2) || !strncasecmp(link_file, "0x0\n", 4))) {
|
if (rc > 1 && (!strncasecmp(link_file, "0\n", 2) || !strncasecmp(link_file, "0x0\n", 4))) {
|
||||||
ifc_set_state(profile->usbnet_adapter, 0);
|
snprintf(link_file, sizeof(link_file), "ifconfig %s down", profile->usbnet_adapter);
|
||||||
|
ql_system(link_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,6 +470,7 @@ static void ql_openwrt_setup_wan6(const char *ifname, const IPV6_T *ipv6) {
|
|||||||
|
|
||||||
void udhcpc_start(PROFILE_T *profile) {
|
void udhcpc_start(PROFILE_T *profile) {
|
||||||
char *ifname = profile->usbnet_adapter;
|
char *ifname = profile->usbnet_adapter;
|
||||||
|
char shell_cmd[128];
|
||||||
|
|
||||||
ql_set_driver_link_state(profile, 1);
|
ql_set_driver_link_state(profile, 1);
|
||||||
|
|
||||||
@ -489,13 +483,17 @@ void udhcpc_start(PROFILE_T *profile) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(ifname, profile->usbnet_adapter)) {
|
if (strcmp(ifname, profile->usbnet_adapter)) {
|
||||||
ifc_set_state(profile->usbnet_adapter, 1);
|
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s up", profile->usbnet_adapter);
|
||||||
|
ql_system(shell_cmd);
|
||||||
if (ifc_get_flags(ifname)&IFF_UP) {
|
if (ifc_get_flags(ifname)&IFF_UP) {
|
||||||
ifc_set_state(ifname, 0);
|
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s down", ifname);
|
||||||
|
ql_system(shell_cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ifc_set_state(ifname, 1);
|
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s up", ifname);
|
||||||
|
ql_system(shell_cmd);
|
||||||
|
|
||||||
if (profile->ipv4.Address) {
|
if (profile->ipv4.Address) {
|
||||||
if (profile->PCSCFIpv4Addr1)
|
if (profile->PCSCFIpv4Addr1)
|
||||||
dbg_time("pcscf1: %s", ipv4Str(profile->PCSCFIpv4Addr1));
|
dbg_time("pcscf1: %s", ipv4Str(profile->PCSCFIpv4Addr1));
|
||||||
@ -530,7 +528,7 @@ void udhcpc_start(PROFILE_T *profile) {
|
|||||||
if (profile->ipv4.Address == 0)
|
if (profile->ipv4.Address == 0)
|
||||||
goto set_ipv6;
|
goto set_ipv6;
|
||||||
|
|
||||||
if (profile->no_dhcp || profile->request_ops == &mbim_request_ops) { //lots of mbim modem do not support DHCP
|
if (profile->request_ops == &mbim_request_ops) { //lots of mbim modem do not support DHCP
|
||||||
update_ip_address_by_qmi(ifname, &profile->ipv4, NULL);
|
update_ip_address_by_qmi(ifname, &profile->ipv4, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -581,16 +579,9 @@ void udhcpc_start(PROFILE_T *profile) {
|
|||||||
pthread_create(&udhcpc_thread_id, NULL, udhcpc_thread_function, (void*)strdup(udhcpc_cmd));
|
pthread_create(&udhcpc_thread_id, NULL, udhcpc_thread_function, (void*)strdup(udhcpc_cmd));
|
||||||
pthread_join(udhcpc_thread_id, NULL);
|
pthread_join(udhcpc_thread_id, NULL);
|
||||||
|
|
||||||
if (profile->request_ops == &atc_request_ops) {
|
if (profile->request_ops == &atc_request_ops
|
||||||
profile->udhcpc_ip = 0;
|
&& !ql_netcard_ipv4_address_check(ifname, qmi2addr(profile->ipv4.Address))) {
|
||||||
ifc_get_addr(ifname, &profile->udhcpc_ip);
|
ql_get_netcard_carrier_state(ifname);
|
||||||
if (profile->udhcpc_ip != profile->ipv4.Address) {
|
|
||||||
unsigned char *l = (unsigned char *)&profile->udhcpc_ip;
|
|
||||||
unsigned char *r = (unsigned char *)&profile->ipv4.Address;
|
|
||||||
dbg_time("ERROR: IP from udhcpc (%d.%d.%d.%d) is different to IP from ATC (%d.%d.%d.%d)!",
|
|
||||||
l[0], l[1], l[2], l[3], r[0], r[1], r[2], r[3]);
|
|
||||||
ql_get_netcard_carrier_state(ifname); //miss udhcpc default.script or modem not report usb-net-cdc-linkup
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile->request_ops != &qmi_request_ops) { //only QMI modem support next fixup!
|
if (profile->request_ops != &qmi_request_ops) { //only QMI modem support next fixup!
|
||||||
@ -729,14 +720,11 @@ void udhcpc_stop(PROFILE_T *profile) {
|
|||||||
dibbler_client_alive = 0;
|
dibbler_client_alive = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile->udhcpc_ip = 0;
|
|
||||||
//it seems when call netif_carrier_on(), and netcard 's IP is "0.0.0.0", will cause netif_queue_stopped()
|
//it seems when call netif_carrier_on(), and netcard 's IP is "0.0.0.0", will cause netif_queue_stopped()
|
||||||
if (!access("/sbin/ip", X_OK))
|
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s 0.0.0.0", ifname);
|
||||||
snprintf(shell_cmd, sizeof(shell_cmd), "ip addr flush dev %s", ifname);
|
ql_system(shell_cmd);
|
||||||
else
|
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s down", ifname);
|
||||||
snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s 0.0.0.0", ifname);
|
|
||||||
ql_system(shell_cmd);
|
ql_system(shell_cmd);
|
||||||
ifc_set_state(ifname, 0);
|
|
||||||
|
|
||||||
#ifdef QL_OPENWER_NETWORK_SETUP
|
#ifdef QL_OPENWER_NETWORK_SETUP
|
||||||
ql_openwrt_setup_wan(ifname, NULL);
|
ql_openwrt_setup_wan(ifname, NULL);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
None.
|
None.
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
|
||||||
Quectel Wireless Solution Proprietary and Confidential.
|
Quectel Wireless Solution Proprietary and Confidential.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user