/*----------------------------------------------------------------------------*/ 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 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 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; }
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; }