/*----------------------------------------------------------------------------*/ static int procTxStatisticsWrite(struct file *file, const char *buffer, unsigned long count, void *data) { P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; /* + 1 for "\0" */ UINT_32 u4CopySize; UINT_32 u4ClearCounter; GLUE_SPIN_LOCK_DECLARATION(); ASSERT(data); u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1); copy_from_user(acBuf, buffer, u4CopySize); acBuf[u4CopySize] = '\0'; if (sscanf(acBuf, "%ld", &u4ClearCounter) == 1) { if (u4ClearCounter == 1) { GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); } } return count; } /* end of procTxStatisticsWrite() */
/*----------------------------------------------------------------------------*/ static int procDrvStatusRead(char *page, char **start, off_t off, int count, int *eof, void *data) { P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; char *p = page; UINT_32 u4Count; GLUE_SPIN_LOCK_DECLARATION(); ASSERT(data); /* Kevin: Apply PROC read method 1. */ if (off != 0) return 0; /* To indicate end of file. */ SPRINTF(p, ("GLUE LAYER STATUS:")); SPRINTF(p, ("\n==================")); SPRINTF(p, ("\n* Number of Pending Frames: %ld\n", prGlueInfo->u4TxPendingFrameNum)); GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); u4Count += (UINT_32) (p - page); *eof = 1; return (int)u4Count; } /* end of procDrvStatusRead() */
/*----------------------------------------------------------------------------*/ static int procTxStatisticsRead(char *page, char **start, off_t off, int count, int *eof, void *data) { P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv; char *p = page; UINT_32 u4Count; GLUE_SPIN_LOCK_DECLARATION(); ASSERT(data); /* Kevin: Apply PROC read method 1. */ if (off != 0) return 0; /* To indicate end of file. */ SPRINTF(p, ("TX STATISTICS (Write 1 to clear):")); SPRINTF(p, ("\n=================================\n")); GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM); u4Count += (UINT_32) (p - page); *eof = 1; return (int)u4Count; } /* end of procTxStatisticsRead() */
/*----------------------------------------------------------------------------*/ BOOL kalDevPortWrite ( IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Port, IN UINT_32 u4Len, IN PUINT_8 pucBuf, IN UINT_32 u4ValidInBufSize ) { ASSERT(u4Len); #if DBG if (((unsigned long)pucBuf & 0x03) || (u4Len & 0x03)) { DBGLOG(HAL, ERROR, ("kalDevPortWrite error, address: 0x%p, len:%d!\n", pucBuf, u4Len)); return FALSE; } #endif GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); SpiReadWriteData32(SPI_FUN_WR, u4Port, pucBuf, u4Len); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); return TRUE; } /* kalDevPortWrite */
/*----------------------------------------------------------------------------*/ BOOL kalDevWriteWithSdioCmd52 ( IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Addr, IN UINT_8 ucData ) { UINT_32 u4RegValue; BOOLEAN bRet; GLUE_SPIN_LOCK_DECLARATION(); ASSERT(prGlueInfo); /* 0. acquire spinlock */ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); /* 1. there is no single byte access support for eHPI, use 4-bytes write-after-read approach instead */ if(kalDevRegRead_impl(prGlueInfo, u4Addr, &u4RegValue) == TRUE) { u4RegValue &= 0x00; u4RegValue |= ucData; bRet = kalDevRegWrite_impl(prGlueInfo, u4Addr, u4RegValue); } else { bRet = FALSE; } /* 2. release spin lock */ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); return bRet; }
/*----------------------------------------------------------------------------*/ BOOL kalDevPortRead ( IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Port, IN UINT_32 u4Len, OUT PUINT_8 pucBuf, IN UINT_32 u4ValidOutBufSize ) { ASSERT(u4Len); #if DBG if (IS_NOT_ALIGN_4((UINT_32)pucBuf) || (u4Len & 0x03)) { DBGLOG(HAL, ERROR, ("kalDevPortRead error, address: 0x%p, len:%d!\n", pucBuf, u4Len)); return FALSE; } #endif GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); SpiReadWriteData32(SPI_FUN_RD, u4Port, pucBuf, u4Len); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); return TRUE; } /* kalDevPortRead */
/*----------------------------------------------------------------------------*/ BOOL DllEntry(HANDLE hDLL, DWORD u4Reason, LPVOID lpReserved) { DEBUGFUNC("DllEntry"); switch (u4Reason) { case DLL_PROCESS_ATTACH: CREATE_LOG_FILE(); INITLOG(("MT6620: DLL_PROCESS_ATTACH\n")); DisableThreadLibraryCalls((HMODULE) hDLL); break; case DLL_PROCESS_DETACH: INITLOG(("MT6620: DLL_PROCESS_DETTACH\n")); break; default: INITLOG(("MT6620: Fail\n")); break; } return TRUE; } /* DllEntry */ LINT_EXT_HEADER_END /*----------------------------------------------------------------------------*/ /*! * \brief This routine is used to read a 32 bit register value from device. * * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure. * \param[in] u4Register the register offset. * \param[out] pu4Value Pointer to the 32-bit value of the register been read. * * \retval TRUE * \retval FALSE */ /*----------------------------------------------------------------------------*/ BOOL kalDevRegRead ( IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, OUT PUINT_32 pu4Value ) { GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); SpiSendCmd32(SPI_FUN_RD, u4Register, pu4Value); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); return TRUE; } /* kalDevRegRead */
/*----------------------------------------------------------------------------*/ BOOL kalDevPortWrite( P_GLUE_INFO_T prGlueInfo, IN UINT_16 u2Port, IN UINT_16 u2Len, IN PUINT_8 pucBuf, IN UINT_16 u2ValidInBufSize ) { UINT_32 i; GLUE_SPIN_LOCK_DECLARATION(); ASSERT(prGlueInfo); /* 0. acquire spinlock */ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); /* 1. indicate correct length to HIFSYS if larger than 4-bytes */ if(u2Len > 4) { kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, ALIGN_4(u2Len)); } /* 2. address cycle */ #if EHPI16 writew(u2Port, prGlueInfo->rHifInfo.mcr_addr_base); #elif EHPI8 writew((u2Port & 0xFF), prGlueInfo->rHifInfo.mcr_addr_base); writew(((u2Port & 0xFF00) >> 8), prGlueInfo->rHifInfo.mcr_addr_base); #endif /* 3. data cycle */ for(i = 0 ; i < ALIGN_4(u2Len) ; i += 4) { #if EHPI16 writew((UINT_32)(*((PUINT_16) &(pucBuf[i]))), prGlueInfo->rHifInfo.mcr_data_base); writew((UINT_32)(*((PUINT_16) &(pucBuf[i+2]))), prGlueInfo->rHifInfo.mcr_data_base); #elif EHPI8 writew((UINT_32)(*((PUINT_8) &(pucBuf[i]))), prGlueInfo->rHifInfo.mcr_data_base); writew((UINT_32)(*((PUINT_8) &(pucBuf[i+1]))), prGlueInfo->rHifInfo.mcr_data_base); writew((UINT_32)(*((PUINT_8) &(pucBuf[i+2]))), prGlueInfo->rHifInfo.mcr_data_base); writew((UINT_32)(*((PUINT_8) &(pucBuf[i+3]))), prGlueInfo->rHifInfo.mcr_data_base); #endif } /* 4. restore length to 4 if necessary */ if(u2Len > 4) { kalDevRegWrite_impl(prGlueInfo, MCR_EHTCR, 4); } /* 5. release spin lock */ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); return TRUE; }
/*----------------------------------------------------------------------------*/ BOOL kalDevRegWrite ( IN P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value ) { GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); SpiSendCmd32(SPI_FUN_WR, u4Register, (PUINT_32)&u4Value); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_SPI_ACCESS); return TRUE; } /* kalDevRegWrite */
VOID kalP2PIndicateScanDone ( IN P_GLUE_INFO_T prGlueInfo, IN BOOLEAN fgIsAbort ) { P_GL_P2P_INFO_T prGlueP2pInfo = (P_GL_P2P_INFO_T)NULL; struct cfg80211_scan_request *prScanRequest = NULL; GLUE_SPIN_LOCK_DECLARATION(); do { if (prGlueInfo == NULL) { ASSERT(FALSE); break; } prGlueP2pInfo = prGlueInfo->prP2PInfo; if (prGlueP2pInfo == NULL) { ASSERT(FALSE); break; } DBGLOG(INIT, TRACE, ("[p2p] scan complete %p\n", prGlueP2pInfo->prScanRequest)); GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); if(prGlueP2pInfo->prScanRequest != NULL) { prScanRequest = prGlueP2pInfo->prScanRequest; prGlueP2pInfo->prScanRequest = NULL; } GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_NET_DEV); /* 2. then CFG80211 Indication */ if(prScanRequest != NULL) { /* report all queued beacon/probe response frames to upper layer */ scanReportBss2Cfg80211(prGlueInfo->prAdapter,BSS_TYPE_P2P_DEVICE,NULL); DBGLOG(INIT, TRACE, ("DBG:p2p_cfg_scan_done\n")); cfg80211_scan_done(prScanRequest, fgIsAbort); } } while (FALSE); } /* kalP2PIndicateScanDone */
/*----------------------------------------------------------------------------*/ BOOL kalDevRegWrite(P_GLUE_INFO_T prGlueInfo, IN UINT_32 u4Register, IN UINT_32 u4Value) { GLUE_SPIN_LOCK_DECLARATION(); ASSERT(prGlueInfo); /* 0. acquire spinlock */ GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); /* 1. I/O stuff */ kalDevRegWrite_impl(prGlueInfo, u4Register, u4Value); /* 2. release spin lock */ GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_EHPI_BUS); return TRUE; }
/*----------------------------------------------------------------------------*/ static int bowHardStartXmit(IN struct sk_buff *prSkb, IN struct net_device *prDev) { P_GLUE_INFO_T prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(prDev)); P_QUE_ENTRY_T prQueueEntry = NULL; P_QUE_T prTxQueue = NULL; UINT_16 u2QueueIdx = 0; UINT_8 ucDSAP, ucSSAP, ucControl; UINT_8 aucOUI[3]; PUINT_8 aucLookAheadBuf = NULL; UINT_8 ucBssIndex; GLUE_SPIN_LOCK_DECLARATION(); ASSERT(prSkb); ASSERT(prDev); ASSERT(prGlueInfo); aucLookAheadBuf = prSkb->data; ucDSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET]; ucSSAP = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 1]; ucControl = *(PUINT_8) &aucLookAheadBuf[ETH_LLC_OFFSET + 2]; aucOUI[0] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET]; aucOUI[1] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 1]; aucOUI[2] = *(PUINT_8) &aucLookAheadBuf[ETH_SNAP_OFFSET + 2]; if (!(ucDSAP == ETH_LLC_DSAP_SNAP && ucSSAP == ETH_LLC_SSAP_SNAP && ucControl == ETH_LLC_CONTROL_UNNUMBERED_INFORMATION && aucOUI[0] == ETH_SNAP_BT_SIG_OUI_0 && aucOUI[1] == ETH_SNAP_BT_SIG_OUI_1 && aucOUI[2] == ETH_SNAP_BT_SIG_OUI_2) || (prSkb->len > 1514)) { dev_kfree_skb(prSkb); return NETDEV_TX_OK; } if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) { DBGLOG(BOW, TRACE, ("GLUE_FLAG_HALT skip tx\n")); dev_kfree_skb(prSkb); return NETDEV_TX_OK; } GLUE_SET_PKT_FLAG_PAL(prSkb); ucBssIndex = wlanGetBssIdxByNetInterface(prGlueInfo, NET_DEV_BOW_IDX); GLUE_SET_PKT_BSS_IDX(prSkb, ucBssIndex); prQueueEntry = (P_QUE_ENTRY_T) GLUE_GET_PKT_QUEUE_ENTRY(prSkb); prTxQueue = &prGlueInfo->rTxQueue; if (wlanProcessSecurityFrame(prGlueInfo->prAdapter, (P_NATIVE_PACKET) prSkb) == FALSE) { GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); QUEUE_INSERT_TAIL(prTxQueue, prQueueEntry); GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_TX_QUE); GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingFrameNum); GLUE_INC_REF_CNT(prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx]); if (prGlueInfo->ai4TxPendingFrameNumPerQueue[ucBssIndex][u2QueueIdx] >= CFG_TX_STOP_NETIF_PER_QUEUE_THRESHOLD) { netif_stop_subqueue(prDev, u2QueueIdx); } } else { GLUE_INC_REF_CNT(prGlueInfo->i4TxPendingSecurityFrameNum); } kalSetEvent(prGlueInfo); /* For Linux, we'll always return OK FLAG, because we'll free this skb by ourself */ return NETDEV_TX_OK; }