diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2014-02-04 11:15:39 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-02-04 11:15:39 -0800 |
| commit | 301d4e49a7b202c26c4709eb82f7453da855c0f1 (patch) | |
| tree | 709739ad07ea3f248a85b2ecdabbcccaf73910fe | |
| parent | 9585e853b3a7fb6849698663d285f4887684b24e (diff) | |
| parent | c49714b4513d5dcb5dcb84c28feae7565f3be579 (diff) | |
Merge "Merge remote-tracking branch 'origin/caf/caf-wlan/master'"
| -rw-r--r-- | CORE/MAC/inc/qwlan_version.h | 4 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limAIDmgmt.c | 8 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limAssocUtils.c | 2 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMessageQueue.c | 2 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limSendManagementFrames.c | 2 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limSession.c | 4 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/adf/adf_os_lock.h | 3 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h | 23 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/copy_engine.c | 27 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/hif_pci.c | 19 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 49 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 130 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.h | 4 | ||||
| -rw-r--r-- | CORE/SERVICES/WMI/wmi_unified.c | 2 | ||||
| -rw-r--r-- | CORE/SME/src/csr/csrApiRoam.c | 34 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_api.h | 26 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_api.c | 35 | ||||
| -rw-r--r-- | CORE/VOSS/src/vos_nvitem.c | 9 |
18 files changed, 302 insertions, 81 deletions
diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 66657230ecaa..694cf83aaa89 100644 --- a/CORE/MAC/inc/qwlan_version.h +++ b/CORE/MAC/inc/qwlan_version.h @@ -42,9 +42,9 @@ BRIEF DESCRIPTION: #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 27 +#define QWLAN_VERSION_BUILD 28 -#define QWLAN_VERSIONSTR "1.0.0.27" +#define QWLAN_VERSIONSTR "1.0.0.28" #ifdef QCA_WIFI_2_0 diff --git a/CORE/MAC/src/pe/lim/limAIDmgmt.c b/CORE/MAC/src/pe/lim/limAIDmgmt.c index aa1e55e05e83..814df1dee01e 100644 --- a/CORE/MAC/src/pe/lim/limAIDmgmt.c +++ b/CORE/MAC/src/pe/lim/limAIDmgmt.c @@ -86,6 +86,14 @@ limInitPeerIdxpool(tpAniSirGlobal pMac,tpPESession pSessionEntry) } else #endif +#ifdef QCA_IBSS_SUPPORT + if (pSessionEntry->limSystemRole == eLIM_STA_IN_IBSS_ROLE) + { + pSessionEntry->freePeerIdxHead=LIM_START_PEER_IDX; + maxAssocSta = pMac->lim.gLimIbssStaLimit; + } + else +#endif { pSessionEntry->freePeerIdxHead=LIM_START_PEER_IDX; } diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c index cf1c486c1b7d..c77a4ff32ffc 100644 --- a/CORE/MAC/src/pe/lim/limAssocUtils.c +++ b/CORE/MAC/src/pe/lim/limAssocUtils.c @@ -3246,7 +3246,7 @@ limDeleteDphHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_U16 staId,t pStaDs = dphLookupHashEntry(pMac, staAddr, &aid, &psessionEntry->dph.dphHashTable); if (pStaDs != NULL) { - PELOGW(limLog(pMac, LOGW, FL("Deleting DPH Hash entry for STAID: %X\n "), staId);) + PELOGW(limLog(pMac, LOGW, FL("Deleting DPH Hash entry for STAID: %X"), staId);) // update the station count and perform associated actions // do this before deleting the dph hash entry limUtilCountStaDel(pMac, pStaDs, psessionEntry); diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index 5330438943fc..60aec34419f6 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -1467,7 +1467,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) tpPESession psessionEntry = &pMac->lim.gpSession[0]; tANI_U8 i; - limLog(pMac, LOGW, FL("Received message Noa_ATTR %x"), limMsg->type); + limLog(pMac, LOG1, FL("Received message Noa_ATTR %x"), limMsg->type); for(i=0; i < pMac->lim.maxBssId; i++) { psessionEntry = &pMac->lim.gpSession[i]; diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c index d7bda27323e9..ca984e801fb1 100644 --- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c +++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c @@ -623,7 +623,7 @@ limSendProbeRspMgmtFrame(tpAniSirGlobal pMac, #ifdef WLAN_FEATURE_11AC if(psessionEntry->vhtCapability) { - limLog( pMac, LOGW, FL("Populate VHT IE in Probe Response")); + limLog( pMac, LOG1, FL("Populate VHT IE in Probe Response")); PopulateDot11fVHTCaps( pMac, psessionEntry, &pFrm->VHTCaps ); PopulateDot11fVHTOperation( pMac, &pFrm->VHTOperation ); // we do not support multi users yet diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c index 73097af80832..642407e4b765 100644 --- a/CORE/MAC/src/pe/lim/limSession.c +++ b/CORE/MAC/src/pe/lim/limSession.c @@ -348,7 +348,7 @@ void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry) tANI_U16 n; TX_TIMER *timer_ptr; - limLog(pMac, LOGW, FL("Trying to delete a session %d.\n "), psessionEntry->peSessionId); + limLog(pMac, LOGW, FL("Trying to delete a session %d"), psessionEntry->peSessionId); for (n = 0; n < pMac->lim.maxStation; n++) { @@ -477,7 +477,7 @@ void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry) != eHAL_STATUS_SUCCESS) { limLog(pMac, LOGE, - FL("Failed to close ps offload for pe session %x\n"), + FL("Failed to close ps offload for pe session %x"), psessionEntry->peSessionId); } } diff --git a/CORE/SERVICES/COMMON/adf/adf_os_lock.h b/CORE/SERVICES/COMMON/adf/adf_os_lock.h index 16f58dc5d539..24ca01849019 100644 --- a/CORE/SERVICES/COMMON/adf/adf_os_lock.h +++ b/CORE/SERVICES/COMMON/adf/adf_os_lock.h @@ -114,6 +114,9 @@ adf_os_spinlock_destroy(adf_os_spinlock_t *lock) #define adf_os_spin_lock( _lock) __adf_os_spin_lock(_lock) #define adf_os_spin_unlock( _lock ) __adf_os_spin_unlock(_lock) +#define adf_os_spin_lock_irqsave( _lock) __adf_os_spin_lock_irqsave(_lock) +#define adf_os_spin_unlock_irqrestore( _lock ) \ + __adf_os_spin_unlock_irqrestore(_lock) /** * @brief locks the spinlock mutex in soft irq context diff --git a/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h b/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h index 5bf81af170d1..e5e96065f149 100644 --- a/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h +++ b/CORE/SERVICES/COMMON/adf/linux/adf_os_lock_pvt.h @@ -41,6 +41,7 @@ typedef struct __adf_os_linux_spinlock { spinlock_t spinlock; unsigned int flags; + unsigned long _flags; } adf_os_linux_spinlock_t; /* define for flag */ @@ -118,6 +119,28 @@ __adf_os_spin_unlock(__adf_os_spinlock_t *lock) spin_unlock(&lock->spinlock); } +/** + * @brief Acquire a Spinlock (SMP) & disable Preemption (Preemptive) + * Disable IRQs + * @param lock (Lock object) + */ +static inline void +__adf_os_spin_lock_irqsave(__adf_os_spinlock_t *lock) +{ + spin_lock_irqsave(&lock->spinlock, lock->_flags); +} + +/** + * @brief Unlock the spinlock and enables the Preemption + * Enable IRQ + * @param lock (Lock object) + */ +static inline void +__adf_os_spin_unlock_irqrestore(__adf_os_spinlock_t *lock) +{ + spin_unlock_irqrestore(&lock->spinlock, lock->_flags); +} + /** * @brief Acquire the spinlock and disable bottom halves * diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine.c b/CORE/SERVICES/HIF/PCIe/copy_engine.c index 526314c8f46a..78995a7a3cc3 100644 --- a/CORE/SERVICES/HIF/PCIe/copy_engine.c +++ b/CORE/SERVICES/HIF/PCIe/copy_engine.c @@ -842,6 +842,17 @@ CE_per_engine_servicereap(struct hif_pci_softc *sc, unsigned int CE_id) } #endif /*ATH_11AC_TXCOMPACT*/ + +/* + * Number of times to check for any pending tx/rx completion on + * a copy engine, this count should be big enough. Once we hit + * this threashold we'll not check for any Tx/Rx comlpetion in same + * interrupt handling. Note that this threashold is only used for + * Rx interrupt processing, this can be used tor Tx as well if we + * suspect any infinite loop in checking for pending Tx completion. + */ +#define CE_TXRX_COMP_CHECK_THRESHOLD 20 + /* * Guts of interrupt handler for per-engine interrupts on a particular CE. * @@ -861,15 +872,17 @@ CE_per_engine_service(struct hif_pci_softc *sc, unsigned int CE_id) unsigned int id; unsigned int flags; u_int32_t CE_int_status; + unsigned int more_comp_cnt = 0; A_TARGET_ACCESS_BEGIN(targid); adf_os_spin_lock(&sc->target_lock); + /* Clear force_break flag and re-initialize receive_count to 0 */ + sc->receive_count = 0; + sc->force_break = 0; more_completions: if (CE_state->recv_cb) { - /* Clear force_break flag and re-initialize receive_count to 0 */ - sc->receive_count = 0; /* Pop completed recv buffers and call the registered recv callback for each */ while (CE_completed_recv_next_nolock(CE_state, &CE_context, &transfer_context, @@ -965,7 +978,15 @@ more_watermarks: * we find no more events to process. */ if (CE_state->recv_cb && CE_recv_entries_done_nolock(sc, CE_state)) { - goto more_completions; + if (more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) { + goto more_completions; + } else { + adf_os_print("%s:Potential infinite loop detected during Rx processing" + "nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x\n", + __func__, CE_state->dest_ring->nentries_mask, + CE_state->dest_ring->sw_index, + CE_DEST_RING_READ_IDX_GET(targid, CE_state->ctrl_addr)); + } } if (CE_state->send_cb && CE_send_entries_done_nolock(sc, CE_state)) { diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c index 74cb50f52d4d..6d7e799dc633 100644 --- a/CORE/SERVICES/HIF/PCIe/hif_pci.c +++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c @@ -52,6 +52,7 @@ #define ATH_MODULE_NAME hif #include <a_debug.h> #include "hif_pci.h" +#include "vos_trace.h" /* use credit flow control over HTC */ unsigned int htc_credit_flow = 1; @@ -1965,7 +1966,7 @@ HIF_sleep_entry(void *arg) struct hif_pci_softc *sc = hif_state->sc; u_int32_t idle_ms; - adf_os_spin_lock(&hif_state->keep_awake_lock); + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); if (hif_state->verified_awake == FALSE) { idle_ms = adf_os_ticks_to_msecs(adf_os_ticks() - hif_state->sleep_ticks); @@ -1981,7 +1982,7 @@ HIF_sleep_entry(void *arg) adf_os_timer_start(&hif_state->sleep_timer, HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS); } - adf_os_spin_unlock(&hif_state->keep_awake_lock); + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); } void @@ -1991,7 +1992,7 @@ HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device) A_target_id_t pci_addr = TARGID_TO_PCI_ADDR(hif_state->targid); struct hif_pci_softc *sc = hif_state->sc; - adf_os_spin_lock(&hif_state->keep_awake_lock); + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); /* * If the deferred sleep timer is running cancel it * and put the soc into sleep. @@ -2004,7 +2005,7 @@ HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device) } hif_state->fake_sleep = FALSE; } - adf_os_spin_unlock(&hif_state->keep_awake_lock); + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); } /* @@ -2323,7 +2324,7 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, if (sleep_ok) { - adf_os_spin_lock(&hif_state->keep_awake_lock); + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); hif_state->keep_awake_count--; if (hif_state->keep_awake_count == 0) { /* Allow sleep */ @@ -2339,9 +2340,9 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, adf_os_timer_start(&hif_state->sleep_timer, HIF_SLEEP_INACTIVITY_TIMER_PERIOD_MS); } - adf_os_spin_unlock(&hif_state->keep_awake_lock); + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); } else { - adf_os_spin_lock(&hif_state->keep_awake_lock); + adf_os_spin_lock_irqsave(&hif_state->keep_awake_lock); if (hif_state->fake_sleep) { hif_state->verified_awake = TRUE; @@ -2353,7 +2354,7 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, } } hif_state->keep_awake_count++; - adf_os_spin_unlock(&hif_state->keep_awake_lock); + adf_os_spin_unlock_irqrestore(&hif_state->keep_awake_lock); if (wait_for_it && !hif_state->verified_awake) { #define PCIE_WAKE_TIMEOUT 5000 /* 5Ms */ @@ -2374,7 +2375,7 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, printk("%s: keep_awake_count %d PCIE_SOC_WAKE_ADDRESS = %x\n",__func__, hif_state->keep_awake_count, A_PCI_READ32(pci_addr + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS)); - ASSERT(0); + VOS_BUG(0); } OS_DELAY(curr_delay); diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 6de3a42c984c..37cbb090dbaf 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -31,6 +31,8 @@ #include <linux/interrupt.h> #include <linux/if_arp.h> #include "if_pci.h" +#include "hif_msg_based.h" +#include "hif_pci.h" #include "copy_engine_api.h" #include "bmi_msg.h" /* TARGET_TYPE_ */ #include "regtable.h" @@ -97,9 +99,13 @@ static irqreturn_t hif_pci_interrupt_handler(int irq, void *arg) { struct hif_pci_softc *sc = (struct hif_pci_softc *) arg; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; volatile int tmp; if (LEGACY_INTERRUPTS(sc)) { + A_TARGET_ACCESS_BEGIN(targid); + /* Clear Legacy PCI line interrupts */ /* IMPORTANT: INTR_CLR regiser has to be set after INTR_ENABLE is set to 0, */ /* otherwise interrupt can not be really cleared */ @@ -107,6 +113,13 @@ hif_pci_interrupt_handler(int irq, void *arg) A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_CLR_ADDRESS), PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */ tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)); + + if (tmp == 0xdeadbeef) { + printk(KERN_ERR "BUG(%s): SoC returns 0xdeadbeef!!\n", __func__); + VOS_BUG(0); + } + + A_TARGET_ACCESS_END(targid); } /* TBDXXX: Add support for WMAC */ @@ -392,6 +405,8 @@ static void wlan_tasklet(unsigned long data) { struct hif_pci_softc *sc = (struct hif_pci_softc *) data; + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; volatile int tmp; if (sc->hif_init_done == FALSE) { @@ -412,11 +427,15 @@ wlan_tasklet(unsigned long data) } irq_handled: if (LEGACY_INTERRUPTS(sc)) { + A_TARGET_ACCESS_BEGIN(targid); + /* Enable Legacy PCI line interrupts */ A_PCI_WRITE32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS), PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); /* IMPORTANT: this extra read transaction is required to flush the posted write buffer */ tmp = A_PCI_READ32(sc->mem+(SOC_CORE_BASE_ADDRESS | PCIE_INTR_ENABLE_ADDRESS)); + + A_TARGET_ACCESS_END(targid); } } @@ -1371,6 +1390,8 @@ hif_pci_suspend(struct pci_dev *pdev, pm_message_t state) struct hif_pci_softc *sc = pci_get_drvdata(pdev); void *vos = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); ol_txrx_pdev_handle txrx_pdev = vos_get_context(VOS_MODULE_ID_TXRX, vos); + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; u32 tx_drain_wait_cnt = 0; u32 val; v_VOID_t * temp_module; @@ -1381,18 +1402,9 @@ hif_pci_suspend(struct pci_dev *pdev, pm_message_t state) msleep(3*1000); /* 3 sec */ #endif -#if CONFIG_ATH_PCIE_MAX_PERF - /* Max performance path so no need to wake/poll target */ - A_PCI_WRITE32(sc->mem + FW_INDICATOR_ADDRESS, (state.event << 16)); -#else - /* Make sure to wake Target before accessing Target memory */ - A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); - while (!hif_pci_targ_is_awake(sc, sc->mem)) { - ; - } + A_TARGET_ACCESS_BEGIN(targid); A_PCI_WRITE32(sc->mem + FW_INDICATOR_ADDRESS, (state.event << 16)); - A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); -#endif + A_TARGET_ACCESS_END(targid); if (!txrx_pdev) { printk("%s: txrx_pdev is NULL\n", __func__); @@ -1439,6 +1451,8 @@ hif_pci_resume(struct pci_dev *pdev) { struct hif_pci_softc *sc = pci_get_drvdata(pdev); void *vos_context = vos_get_global_context(VOS_MODULE_ID_HIF, NULL); + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + A_target_id_t targid = hif_state->targid; u32 val; int err; v_VOID_t * temp_module; @@ -1464,18 +1478,9 @@ hif_pci_resume(struct pci_dev *pdev) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); } -#if CONFIG_ATH_PCIE_MAX_PERF - /* Max performance patch so no need to wake/poll target */ + A_TARGET_ACCESS_BEGIN(targid); val = A_PCI_READ32(sc->mem + FW_INDICATOR_ADDRESS) >> 16; -#else - /* Make sure to wake Target before accessing Target memory */ - A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); - while (!hif_pci_targ_is_awake(sc, sc->mem)) { - ; - } - val = A_PCI_READ32(sc->mem + FW_INDICATOR_ADDRESS) >> 16; - A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); -#endif + A_TARGET_ACCESS_END(targid); /* No need to send WMI_PDEV_RESUME_CMDID to FW if WOW is enabled */ temp_module = vos_get_context(VOS_MODULE_ID_WDA, vos_context); diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 4630ed4a7699..7e3fc61298b5 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -162,6 +162,9 @@ */ #define WMA_MAXNUM_PERIODIC_TX_PTRNS 6 +/* default latency in us */ +#define WMA_PM_QOS_DEFAULT_LATENCY 20000 + static void wma_send_msg(tp_wma_handle wma_handle, u_int16_t msg_type, void *body_ptr, u_int32_t body_val); @@ -435,7 +438,7 @@ static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma, __func__, vdev_id, type); return NULL; } - WMA_LOGD("%s: target request found for vdev id: %d type %d msg %d\n", + WMA_LOGD("%s: target request found for vdev id: %d type %d msg %d", __func__, vdev_id, type, req_msg->msg_type); return req_msg; } @@ -466,7 +469,7 @@ static void wma_vdev_start_rsp(tp_wma_handle wma, #endif #ifdef QCA_IBSS_SUPPORT - WMA_LOGD("%s: vdev start response received for %s mode\n", __func__, + WMA_LOGD("%s: vdev start response received for %s mode", __func__, add_bss->operMode == BSS_OPERATIONAL_MODE_IBSS ? "IBSS" : "non-IBSS"); #endif @@ -502,6 +505,11 @@ static void wma_vdev_start_rsp(tp_wma_handle wma, } bcn->seq_no = MIN_SW_SEQ; adf_os_spinlock_init(&bcn->lock); + adf_os_atomic_set(&wma->interfaces[resp_event->vdev_id].bss_status, + WMA_BSS_STATUS_STARTED); + WMA_LOGD("%s: AP mode (type %d subtype %d) BSS is started", __func__, + wma->interfaces[resp_event->vdev_id].type, + wma->interfaces[resp_event->vdev_id].sub_type); WMA_LOGD("%s: Allocated beacon struct %p, template memory %p\n", __func__, bcn, bcn->buf); @@ -512,7 +520,7 @@ static void wma_vdev_start_rsp(tp_wma_handle wma, add_bss->chainMask = resp_event->chain_mask; add_bss->smpsMode = host_map_smps_mode(resp_event->smps_mode); send_fail_resp: - WMA_LOGD("%s: Sending add bss rsp to umac(vdev %d status %d)\n", + WMA_LOGD("%s: Sending add bss rsp to umac(vdev %d status %d)", __func__, resp_event->vdev_id, add_bss->status); wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)add_bss, 0); } @@ -742,7 +750,7 @@ static int32_t wmi_unified_peer_delete_send(wmi_unified_t wmi, adf_nbuf_free(buf); return -EIO; } - WMA_LOGD("%s: peer_addr %pM vdev_id %d\n", __func__, peer_addr, vdev_id); + WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); return 0; } @@ -775,7 +783,7 @@ static int32_t wmi_unified_peer_flush_tids_send(wmi_unified_t wmi, adf_nbuf_free(buf); return -EIO; } - WMA_LOGD("%s: peer_addr %pM vdev_id %d\n", __func__, peer_addr, vdev_id); + WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); return 0; } @@ -789,7 +797,7 @@ static void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid, ol_txrx_peer_detach(peer); wma->peer_count--; - WMA_LOGD("%s: bssid %pM vdevid %d peer_count %d\n", __func__, + WMA_LOGD("%s: bssid %pM vdevid %d peer_count %d", __func__, bssid, vdev_id, wma->peer_count); /* Flush all TIDs except MGMT TID for this peer in Target */ peer_tid_bitmap &= ~(0x1 << WMI_MGMT_TID); @@ -888,7 +896,7 @@ static int wmi_unified_vdev_down_send(wmi_unified_t wmi, u_int8_t vdev_id) adf_nbuf_free(buf); return -EIO; } - WMA_LOGD("%s: vdev_id %d\n", __func__, vdev_id); + WMA_LOGI("%s: vdev_id %d", __func__, vdev_id); return 0; } @@ -947,12 +955,11 @@ static int wma_vdev_stop_resp_handler(void *handle, u_int8_t *cmd_param_info, wma->interfaces[resp_event->vdev_id].vdev_up = FALSE; } iface = &wma->interfaces[resp_event->vdev_id]; - if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) { - WMA_LOGD("%s: P2P BSS is stopped", __func__); - iface->bss_status = WMA_BSS_STATUS_STOPPED; - } ol_txrx_vdev_flush(iface->handle); wdi_in_vdev_unpause(iface->handle); + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); + WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", + __func__, iface->type, iface->sub_type); #ifndef QCA_WIFI_ISOC bcn = wma->interfaces[resp_event->vdev_id].beacon; @@ -2232,6 +2239,8 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, WMA_LOGP("Memory allocation failed for dfs_ic"); } + vos_wake_lock_init(&wma_handle->pm_qos_lock, "pm_qos_wakelock"); + #if defined(QCA_WIFI_FTM) && !defined(QCA_WIFI_ISOC) if (vos_get_conparam() == VOS_FTM_MODE) wma_utf_attach(wma_handle); @@ -2636,6 +2645,15 @@ void wma_vdev_detach_callback(void *ctx) wma_send_msg(wma, WDA_DEL_STA_SELF_RSP, (void *)param, 0); } +static void wma_reset_pm_qos(tp_wma_handle wma) +{ + if (wma->ap_client_cnt) { + wma->ap_client_cnt = 0; + vos_wake_lock_release(&wma->pm_qos_lock); + vos_remove_pm_qos(); + } +} + /* function : wma_vdev_detach * Descriptin : * Args : @@ -2653,6 +2671,9 @@ static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle, struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; struct wma_target_req *msg; + if (wma_is_vdev_in_ap_mode(wma_handle, vdev_id)) + wma_reset_pm_qos(wma_handle); + if ((iface->type == WMI_VDEV_TYPE_AP) && (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) { @@ -2678,9 +2699,8 @@ static VOS_STATUS wma_vdev_detach(tp_wma_handle wma_handle, pdel_sta_self_req_param->selfMacAddr, vdev_id, peer); } - if ((iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) && - (iface->bss_status == WMA_BSS_STATUS_STARTED)) { - WMA_LOGD("P2P BSS is not yet stopped. Defering vdev deletion"); + if (adf_os_atomic_read(&iface->bss_status) == WMA_BSS_STATUS_STARTED) { + WMA_LOGA("BSS is not yet stopped. Defering vdev deletion"); iface->del_staself_req = pdel_sta_self_req_param; return status; } @@ -2755,7 +2775,7 @@ static int wmi_unified_peer_create_send(wmi_unified_t wmi, adf_nbuf_free(buf); return -EIO; } - WMA_LOGD("%s: peer_addr %pM vdev_id %d\n", __func__, peer_addr, vdev_id); + WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); return 0; } @@ -2765,7 +2785,7 @@ static VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, { ol_txrx_peer_handle peer; - WMA_LOGD("%s: peer_addr %pM vdev_id %d\n", __func__, peer_addr, vdev_id); + WMA_LOGD("%s: peer_addr %pM vdev_id %d", __func__, peer_addr, vdev_id); if (++wma->peer_count > wma->wlan_resource_config.num_peers) { WMA_LOGP("%s, the peer count exceeds the limit %d\n", __func__, wma->peer_count - 1); @@ -3302,6 +3322,8 @@ static ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle, self_sta_req->type; wma_handle->interfaces[self_sta_req->sessionId].sub_type = self_sta_req->subType; + adf_os_atomic_init(&wma_handle->interfaces + [self_sta_req->sessionId].bss_status); if ((self_sta_req->type == WMI_VDEV_TYPE_AP) && (self_sta_req->subType == @@ -3951,6 +3973,8 @@ VOS_STATUS wma_update_channel_list(WMA_HANDLE handle, WMI_SET_CHANNEL_REG_POWER(chan_info, chan_list->chanParam[i].pwr); + WMA_LOGD("Channel TX power[%d] = %u: %d", i, chan_info->mhz, + chan_list->chanParam[i].pwr); /*TODO: Set WMI_SET_CHANNEL_MIN_POWER */ /*TODO: Set WMI_SET_CHANNEL_ANTENNA_MAX */ /*TODO: WMI_SET_CHANNEL_REG_CLASSID*/ @@ -5515,12 +5539,11 @@ void wma_vdev_resp_timer(void *data) } else { wma->interfaces[tgt_req->vdev_id].vdev_up = FALSE; } - if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) { - WMA_LOGD("%s: P2P BSS is stopped", __func__); - iface->bss_status = WMA_BSS_STATUS_STOPPED; - } ol_txrx_vdev_flush(iface->handle); wdi_in_vdev_unpause(iface->handle); + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED); + WMA_LOGD("%s: (type %d subtype %d) BSS is stopped", + __func__, iface->type, iface->sub_type); #ifdef QCA_IBSS_SUPPORT if (wma_is_vdev_in_ibss_mode(wma, params->sessionId)) { del_sta_param.sessionId = params->sessionId; @@ -5549,6 +5572,12 @@ void wma_vdev_resp_timer(void *data) if(iface->addBssStaContext) adf_os_mem_free(iface->addBssStaContext); vos_mem_zero(iface, sizeof(*iface)); + } else if (tgt_req->msg_type == WDA_ADD_BSS_REQ) { + tpAddBssParams params = (tpAddBssParams)tgt_req->user_data; + + params->status = VOS_STATUS_E_TIMEOUT; + WMA_LOGA("%s: WDA_ADD_BSS_REQ timedout", __func__); + wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)params, 0); } vos_timer_destroy(&tgt_req->event_timeout); vos_mem_free(tgt_req); @@ -5567,7 +5596,7 @@ static struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, u_int8_t vdev return NULL; } - WMA_LOGD("%s: vdev_id %d msg %d\n", __func__, vdev_id, msg_type); + WMA_LOGD("%s: vdev_id %d msg %d", __func__, vdev_id, msg_type); req->vdev_id = vdev_id; req->msg_type = msg_type; req->type = type; @@ -8357,10 +8386,9 @@ static void wma_add_sta_req_sta_mode(tp_wma_handle wma, tpAddStaParams params) wma->interfaces[params->smesessionId].vdev_up = TRUE; } - if (iface->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT) { - WMA_LOGD("%s: P2P BSS is started", __func__); - iface->bss_status = WMA_BSS_STATUS_STARTED; - } + adf_os_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STARTED); + WMA_LOGD("%s: STA mode (type %d subtype %d) BSS is started", + __func__, iface->type, iface->sub_type); /* Sta is now associated, configure various params */ /* SM power save, configure the h/w as configured @@ -8393,6 +8421,24 @@ out: wma_send_msg(wma, WDA_ADD_STA_RSP, (void *)params, 0); } +static void wma_request_pm_qos(tp_wma_handle wma) +{ + wma->ap_client_cnt++; + if (1 == wma->ap_client_cnt) { + vos_wake_lock_acquire(&wma->pm_qos_lock); + vos_request_pm_qos(WMA_PM_QOS_DEFAULT_LATENCY); + } +} + +static void wma_remove_pm_qos(tp_wma_handle wma) +{ + wma->ap_client_cnt--; + if (0 == wma->ap_client_cnt) { + vos_wake_lock_release(&wma->pm_qos_lock); + vos_remove_pm_qos(); + } +} + static void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) { tANI_U8 oper_mode = BSS_OPERATIONAL_MODE_STA; @@ -8402,8 +8448,10 @@ static void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) add_sta->bssId[0], add_sta->bssId[1], add_sta->bssId[2], add_sta->bssId[3], add_sta->bssId[4], add_sta->bssId[5]); - if (wma_is_vdev_in_ap_mode(wma, add_sta->smesessionId)) + if (wma_is_vdev_in_ap_mode(wma, add_sta->smesessionId)) { + wma_request_pm_qos(wma); oper_mode = BSS_OPERATIONAL_MODE_AP; + } #ifdef QCA_IBSS_SUPPORT else if (wma_is_vdev_in_ibss_mode(wma, add_sta->smesessionId)) oper_mode = BSS_OPERATIONAL_MODE_IBSS; @@ -8921,9 +8969,11 @@ static void wma_delete_sta_req_ap_mode(tp_wma_handle wma, del_sta->status = VOS_STATUS_SUCCESS; send_del_rsp: - WMA_LOGD("%s: Sending del rsp to umac (status: %d)\n", - __func__, del_sta->status); - wma_send_msg(wma, WDA_DELETE_STA_RSP, (void *)del_sta, 0); + if (del_sta->respReqd) { + WMA_LOGD("%s: Sending del rsp to umac (status: %d)\n", + __func__, del_sta->status); + wma_send_msg(wma, WDA_DELETE_STA_RSP, (void *)del_sta, 0); + } } #ifdef FEATURE_WLAN_TDLS @@ -9009,7 +9059,7 @@ static void wma_delete_sta_req_sta_mode(tp_wma_handle wma, #endif wma_roam_scan_offload_end_connect(wma); params->status = status; - WMA_LOGD("%s: vdev_id %d status %d\n", __func__, params->smesessionId, status); + WMA_LOGD("%s: vdev_id %d status %d", __func__, params->smesessionId, status); wma_send_msg(wma, WDA_DELETE_STA_RSP, (void *)params, 0); } @@ -9017,8 +9067,10 @@ static void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) { tANI_U8 oper_mode = BSS_OPERATIONAL_MODE_STA; - if (wma_is_vdev_in_ap_mode(wma, del_sta->smesessionId)) + if (wma_is_vdev_in_ap_mode(wma, del_sta->smesessionId)) { + wma_remove_pm_qos(wma); oper_mode = BSS_OPERATIONAL_MODE_AP; + } #ifdef QCA_IBSS_SUPPORT if (wma_is_vdev_in_ibss_mode(wma, del_sta->smesessionId)) { oper_mode = BSS_OPERATIONAL_MODE_IBSS; @@ -9133,7 +9185,7 @@ static void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) status = VOS_STATUS_E_FAILURE; goto detach_peer; } - WMA_LOGD("%s: bssid %pM vdev_id %d\n", + WMA_LOGD("%s: bssid %pM vdev_id %d", __func__, params->bssid, params->smesessionId); return; detach_peer: @@ -9150,7 +9202,7 @@ static void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params) ol_txrx_peer_handle peer; u_int8_t vdev_id, peer_id; - WMA_LOGD("%s: state %d selfmac %pM\n", __func__, + WMA_LOGD("%s: state %d selfmac %pM", __func__, params->state, params->selfMacAddr); if ((params->state != eSIR_LINK_PREASSOC_STATE) && (params->state != eSIR_LINK_DOWN_STATE)) { @@ -14824,13 +14876,13 @@ static int wma_mcc_vdev_tx_pause_evt_handler(void *handle, u_int8_t *event, } else { - WMA_LOGD("Found vdev %d\n", vdev_id); + WMA_LOGI("Found vdev %d", vdev_id); break; } } - WMA_LOGD("vdev_id %d, vdev_map 0x%x, tid_map 0x%x," - " pause_type 0x%x, action 0x%x, peer_id 0x%x\n", + WMA_LOGI("vdev_id %d, vdev_map 0x%x, tid_map 0x%x," + " pause_type 0x%x, action 0x%x, peer_id 0x%x", vdev_id, wmi_event->vdev_map, wmi_event->tid_map, wmi_event->pause_type, wmi_event->action, wmi_event->peer_id); @@ -15595,6 +15647,8 @@ VOS_STATUS wma_stop(v_VOID_t *vos_ctx, tANI_U8 reason) goto end; } + wma_reset_pm_qos(wma_handle); + end: WMA_LOGD("%s: Exit", __func__); return vos_status; @@ -15661,6 +15715,8 @@ VOS_STATUS wma_close(v_VOID_t *vos_ctx) if(vos_status != VOS_STATUS_SUCCESS) WMA_LOGP("dbglog_deinit failed"); + vos_wake_lock_destroy(&wma_handle->pm_qos_lock); + /* close the vos events */ vos_event_destroy(&wma_handle->wma_ready_event); vos_event_destroy(&wma_handle->target_suspend); @@ -16895,7 +16951,7 @@ int wma_suspend_target(WMA_HANDLE handle, int disable_target_intr) if (vos_wait_single_event(&wma_handle->target_suspend, WMA_TGT_SUSPEND_COMPLETE_TIMEOUT) != VOS_STATUS_SUCCESS) { - WMA_LOGE("Failed to suspend target"); + WMA_LOGE("Failed to get ACK from firmware for pdev suspend"); return -1; } diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 88cc390e85f1..dcc8759e663d 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -425,7 +425,7 @@ struct wma_txrx_node { tAniGetPEStatsRsp *stats_rsp; tANI_U8 fw_stats_set; void *del_staself_req; - tANI_U8 bss_status; + adf_os_atomic_t bss_status; tANI_U8 rate_flags; tANI_U8 nss; v_BOOL_t is_channel_switch; @@ -566,6 +566,8 @@ typedef struct { vos_wake_lock_t pno_wake_lock; #endif vos_wake_lock_t wow_wake_lock; + vos_wake_lock_t pm_qos_lock; + u_int32_t ap_client_cnt; vos_timer_t wma_scan_comp_timer; scan_timer_info wma_scan_timer_info; diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index 04847f6fa317..6e406bf6504a 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -538,7 +538,7 @@ int wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf, int len, SET_HTC_PACKET_NET_BUF_CONTEXT(pkt, buf); - WMA_LOGD("Send WMI command:%s command_id:%d\n", + WMA_LOGD("Send WMI command:%s command_id:%d", get_wmi_cmd_string(cmd_id), cmd_id); status = HTCSendPkt(wmi_handle->htc_handle, pkt); diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index a39fbc5269cf..5799425a3d32 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -60,6 +60,7 @@ #include "csrApi.h" #include "pmc.h" #include "vos_nvitem.h" +#include "wlan_hdd_main.h" #ifdef WLAN_FEATURE_NEIGHBOR_ROAMING #include "csrNeighborRoam.h" #endif /* WLAN_FEATURE_NEIGHBOR_ROAMING */ @@ -14132,6 +14133,36 @@ eHalStatus csrProcessAddStaSessionCommand( tpAniSirGlobal pMac, tSmeCmd *pComman &pCommand->u.addStaSessionCmd, pCommand->sessionId); } + +/* Function: csr_check_max_interfaces + * Return: 0 - Success, 1 - Failure + */ +tANI_U8 csr_check_max_interfaces(tpAniSirGlobal pMac,tANI_U32 i) +{ + hdd_context_t *pHddCtx; + v_CONTEXT_t vosContext; + + vosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL ); + if (NULL == vosContext) { + smsLog(pMac, LOGE, "%s: Failed to get vos context", __func__); + return 1; + } + + pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, vosContext); + if (NULL == pHddCtx) { + smsLog(pMac, LOGE, "%s: Failed to get hdd context", __func__); + return 1; + } + + if ((v_U8_t)i >= pHddCtx->max_intf_count){ + smsLog(pMac, LOGE, "%s: Max interfaces! Session creation will fail", __func__); + return 1; + } + else { + return 0; + } +} + eHalStatus csrRoamOpenSession(tpAniSirGlobal pMac, csrRoamCompleteCallback callback, void *pContext, @@ -14149,6 +14180,9 @@ eHalStatus csrRoamOpenSession(tpAniSirGlobal pMac, for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) { + if (csr_check_max_interfaces( pMac, i)) + break; + if( !CSR_IS_SESSION_VALID( pMac, i ) ) { pSession = CSR_GET_SESSION( pMac, i ); diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h index a6f037873fa2..f4eba6a638e8 100644 --- a/CORE/VOSS/inc/vos_api.h +++ b/CORE/VOSS/inc/vos_api.h @@ -328,4 +328,28 @@ v_VOID_t vos_fwDumpReq(tANI_U32 cmd, tANI_U32 arg1, tANI_U32 arg2, v_VOID_t vos_flush_work(v_VOID_t *work); v_VOID_t vos_flush_delayed_work(v_VOID_t *dwork); -#endif // if !defined __VOS_NVITEM_H +/** + @brief vos_request_pm_qos() + + This function will vote for QoS latency + + @param + qos_val - QoS latency in us + @return + NONE +*/ +v_VOID_t vos_request_pm_qos(v_U32_t qos_val); + +/** + @brief vos_remove_pm_qos() + + This function will remove QoS latency + that requested by vos_request_pm_qos() + + @param + NONE + @return + NONE +*/ +v_VOID_t vos_remove_pm_qos(v_VOID_t); +#endif // if !defined __VOS_API_H diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index 38c2c1f5598f..6ddfeb552e44 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -2520,3 +2520,38 @@ v_VOID_t vos_flush_delayed_work(v_VOID_t *dwork) cancel_delayed_work_sync(dwork); #endif } + +/** + @brief vos_request_pm_qos() + + This function will vote for QoS latency + + @param + qos_val - QoS latency in us + @return + NONE +*/ +v_VOID_t vos_request_pm_qos(v_U32_t qos_val) +{ +#if defined (CONFIG_CNSS) + cnss_request_pm_qos(qos_val); +#endif +} + +/** + @brief vos_remove_pm_qos() + + This function will remove QoS latency + that requested by vos_request_pm_qos(). + + @param + NONE +@return + NONE +*/ +v_VOID_t vos_remove_pm_qos(v_VOID_t) +{ +#if defined (CONFIG_CNSS) + cnss_remove_pm_qos(); +#endif +} diff --git a/CORE/VOSS/src/vos_nvitem.c b/CORE/VOSS/src/vos_nvitem.c index ea2599edea0f..6f5f85e0bbad 100644 --- a/CORE/VOSS/src/vos_nvitem.c +++ b/CORE/VOSS/src/vos_nvitem.c @@ -3319,6 +3319,15 @@ int wlan_hdd_linux_reg_notifier(struct wiphy *wiphy, #endif } + if (pHddCtx->isLoadUnloadInProgress) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + "%s: Unloading/Loading in Progress, Ignore!!!", __func__); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)) + return; +#else + return 0; +#endif + } /* first check if this callback is in response to the driver callback */ |
