📄 intprismwdsend.c
字号:
if (netClBlkJoin (pClBlk, (char*)pRxPacket, pWlanDev->clDescTbl.clSize, NULL, 0, 0, 0) == NULL) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismWDSReceive: Error in" " netClBlkJoin\n")); return ERROR; } if (netMblkClJoin (pMBlk, pClBlk) == NULL) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismWDSReceive: Error in" " netMblkClJoin\n")); return ERROR; } pMBlk->mBlkHdr.mData = (char *)(pRxPacket->pData + sizeof(WLAN_RX_FRAME) - WLAN_EH_SIZE); pMBlk->mBlkHdr.mLen = datalen - sizeof(WLAN_RX_FRAME) + WLAN_EH_SIZE; pMBlk->mBlkHdr.mFlags |= M_PKTHDR; pMBlk->mBlkPktHdr.len = datalen - sizeof(WLAN_RX_FRAME) + WLAN_EH_SIZE; END_ERR_ADD (pEnd, MIB2_IN_UCAST, +1); END_RCV_RTN_CALL((END_OBJ *)pIntPrWdsDev, pMBlk); return OK; }/***************************************************************************** intPrismWDSSend - END function to send a packet across the WDS link** Formats a packet as a WDS packet and sends it out the physical interface** RETURNS: OK, ERROR, or END_ERR_BLOCK if a recoverable error occurs before the* MBLK is freed.** ERRNO: N/A*/STATUS intPrismWDSSend ( END_OBJ * pDrvCtrl, /* Device handle for this card */ M_BLK_ID pMblk /* MBLK contianing the packet to be sent */ ) { UINT8 txBuf[WLAN_EH_SIZE + WLAN_SNAP_HDR_LEN + ETHERMTU + WLAN_ETHER_CRC_LEN]; INTPRWDS_DEV * pIntPrWdsDev = (INTPRWDS_DEV *) pDrvCtrl; WLAN_DEV * pWlanDev; int length; WLAN_FRAME txFrame; UINT16 txFID; int i; int intLevel; if ((pIntPrWdsDev == NULL) || (pMblk == NULL)) { WLAN_DEBUG(DEBUG_FATAL, ("intPrismSend: Null device ptr or MBLK\n")); return ERROR; } pWlanDev = pIntPrWdsDev->pWlanDev; /* No point going further if we're blocked */ if (pWlanDev->txBlocked) { return END_ERR_BLOCK; } if (semTake(pWlanDev->txPool[pWlanDev->curTx].empty,sysClkRateGet()/2) != OK) { /* This just means the card hasn't released the buffer yet. Move on */ if ((++pWlanDev->curTx) >= WLAN_MAX_TX_BUF) pWlanDev->curTx = 0; if (semTake(pWlanDev->txPool[pWlanDev->curTx].empty, sysClkRateGet()/2) != OK) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismSend: TX SEM ERROR\n")); pWlanDev->txBlocked = TRUE; return END_ERR_BLOCK; } } txFID = pWlanDev->txPool[pWlanDev->curTx].fid; if ((++pWlanDev->curTx) >= WLAN_MAX_TX_BUF) pWlanDev->curTx = 0; /* Take the END semaphore */ END_TX_SEM_TAKE(&pWlanDev->endObj, WAIT_FOREVER); if((length = netMblkToBufCopy(pMblk, (char *) txBuf, NULL)) == 0) { WLAN_DEBUG(DEBUG_ERROR, ("intPrismSend: Error copying MBUF\n")); END_TX_SEM_GIVE(&pWlanDev->endObj); return ERROR; } netMblkClChainFree(pMblk); /* Set up the transmit frame for WDS transmission*/ txFrame.tx_ctl = WLAN_TXCTL_802_11 | (pIntPrWdsDev->macPort << 8); txFrame.frame_ctl = WLAN_FCTL_TO_DS | WLAN_FCTL_FROM_DS | WLAN_FTYPE_DATA | WLAN_STYPE_DATA; txFrame.rsvd3 = pIntPrWdsDev->txRate << 8; txFrame.dat_len = length - WLAN_EH_SIZE + WLAN_SNAP_HDR_LEN; txFrame.dat[0] = htons(WLAN_SNAP_WORD0); txFrame.dat[1] = htons(WLAN_SNAP_WORD1); txFrame.dat[2] = 0x0000; txFrame.len = htons(length - WLAN_EH_SIZE + WLAN_SNAP_HDR_LEN); txFrame.type = *((UINT16*)(txBuf + (WLAN_ENET_ADDR_LEN << 1) )); /* Set up the four address fields for a WDS packet */ bcopyswap((UINT8 *) pIntPrWdsDev->dstMacAddr, (UINT8 *) txFrame.addr1, WLAN_ENET_ADDR_LEN); bcopyswap((UINT8 *) pWlanDev->MACAddr, (UINT8 *) txFrame.addr2, WLAN_ENET_ADDR_LEN); bcopyswap((UINT8 *) &txBuf[0], (UINT8 *) txFrame.addr3, WLAN_ENET_ADDR_LEN); bcopyswap((UINT8 *) &txBuf[6], (UINT8 *) txFrame.addr4, WLAN_ENET_ADDR_LEN); /* Check if this is an 802.1x packet. If so, it should be sent non- encrypted */ if (pWlanDev->oneXMode == ONEX_MODE_ENABLED) { if (txFrame.type == htons(ONEX_PROTOCOL)) { /* Disable WEP temporarily */ intPrismRIDWordWrite(pWlanDev, INTERSIL_RID_WEP_FLAGS, 0x0000); WLAN_DEBUG(DEBUG_INFO, ("intPrismSend: Sending EAPOL " "unencrypted\n")); } else { WLAN_DEBUG(DEBUG_FLOOD, ("intPrismSend: Sending %04x encrypted\n", txFrame.type)); } } /* Check to see if we are supposed to use a different WEP key for unicast and broadcast packets. If so, check if this is a broadcast packet and swap to a different key slot if so (the default key is kept at the unicast key) */ if (pWlanDev->broadcastKey != pWlanDev->defaultKey) { /* Check if this is a broadcast packet */ if (MULTICAST_MAC(txFrame.dst_addr)) { if (pWlanDev->cardType == WLAN_CARDTYPE_WAVELAN) { intPrismRIDWordWrite(pWlanDev, WVLAN_RID_TX_CRYPT_KEY, pWlanDev->broadcastKey); } else { intPrismRIDWordWrite(pWlanDev, INTERSIL_RID_WEP_DEFAULT_KEY_ID, pWlanDev->broadcastKey); } } } if(semTake(pWlanDev->BAP1Sem, sysClkRateGet()) != OK) { WLAN_DEBUG(DEBUG_ERROR,("intPrismSend: Timed out waiting for " "BAP\n")); return ERROR; } /* Fix for SPR 73754 : If we're interrupted while writing to BAP 1, and the interrupt uses BAP0 (As in an RX itnerrupt) we lock the card up. The solution to this is to lock out interrupts while we transfer data to bap1*/ WLAN_INT_LOCK; /* Reserve the BAP1 so that nobody else can use it while we're transferring data */ if (intPrismBAP1Offset(pWlanDev, txFID, 0) == ERROR) { WLAN_INT_UNLOCK; WLAN_DEBUG(DEBUG_ERROR, ("intPrismSend: Error Opening BAP1\n")); END_TX_SEM_GIVE(&pWlanDev->endObj); return ERROR; } /* Transfer the Intersil packet frame */ for (i=0; i< (WLAN_802_3_OFFSET)/2; i++) { WLAN_OUT_16(WLAN_BASE_ADDR + WLAN_DATA1, *(((UINT16*)&txFrame)+i)); } /* Transfer the ethernet header using native encoding, to ensure correct endianess */ for (i=0; i< (WLAN_EH_SIZE + WLAN_SNAP_HDR_LEN)/2; i++) { WLAN_OUT_16_ENDIAN(WLAN_BASE_ADDR + WLAN_DATA1, *(((UINT16*)&txFrame.dst_addr[0])+i)); } /* Transfer the packet data using native encoding too */ for (i=0; i< (length - WLAN_EH_SIZE + 1)/2; i++) { WLAN_OUT_16_ENDIAN(WLAN_BASE_ADDR + WLAN_DATA1, *(((UINT16*)&txBuf[WLAN_EH_SIZE])+i)); } WLAN_INT_UNLOCK; semGive(pWlanDev->BAP1Sem); /* Now that the data is transferred onto the card, give the send command */ if (intPrismCommandAsync(pWlanDev, WLAN_CMD_TX | WLAN_RECLAIM, txFID,0,0) != OK) { WLAN_DEBUG (DEBUG_INFO, ("intPrismSend: ERROR in transmit\n")); END_TX_SEM_GIVE(&pWlanDev->endObj); return ERROR; } END_TX_SEM_GIVE(&pWlanDev->endObj);#if (CPU==XSCALE) || (CPU==STRONGARM) || (CPU==ARMARCH4) i = intLock(); if ((WLAN_IN_16(WLAN_BASE_ADDR + WLAN_EVENT_STAT) & pWlanDev->intMask)!= 0) intPrismInt(pWlanDev); intUnlock(i);#endif if ((pWlanDev->oneXMode == ONEX_MODE_ENABLED) && (txFrame.type == htons(ONEX_PROTOCOL)) ) { /* Restore WEP */ intPrismRIDWordWrite(pWlanDev, INTERSIL_RID_WEP_FLAGS, 0x0001); } if (pWlanDev->broadcastKey != pWlanDev->defaultKey) { /* Check if this is a broadcast packet */ if ((txFrame.dst_addr[0] & 0x01) == 0x01) { /* If so, we need to reset the key to the unicast key */ if (pWlanDev->cardType == WLAN_CARDTYPE_WAVELAN) { intPrismRIDWordWrite(pWlanDev, WVLAN_RID_TX_CRYPT_KEY, pWlanDev->defaultKey); } else { intPrismRIDWordWrite(pWlanDev, INTERSIL_RID_WEP_DEFAULT_KEY_ID, pWlanDev->defaultKey); } } } return OK; }/****************************************************************************** NOMANUAL* intPrismWDSPollSend - Sends a packet in polled mode** This function is not relevent to the WDS virtual END driver. Use this * feature of the real END driver for the desired effect.** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL STATUS intPrismWDSPollSend ( END_OBJ* pDrvCtrl, /* Pointer to device handle */ M_BLK_ID pMblk /* Buffer containing data to write */ ) { return ERROR; }/****************************************************************************** NOMANUAL* intPrismWDSPollRcv - Receives a packet in polled mode** This function is not relevent to the WDS virtual END driver. Use this * feature of the real END driver for the desired effect.** ERRNO: N/A*/LOCAL STATUS intPrismWDSPollRcv ( END_OBJ* pDrvCtrl, /* Pointer to device handle */ M_BLK_ID pMblk /* Pre-allocated MBLK to store data */ ) { return (ERROR); }/****************************************************************************** NOMANUAL* intPrismWDSMCastAdd - Add an entry to the multicast table** This function is not relevent to the WDS virtual END driver. Use this * feature of the real END driver for the desired effect.** ERRNO: N/A*/LOCAL STATUS intPrismWDSMCastAdd (END_OBJ * pDrvCtrl, char * pAddress) { return ERROR; }/****************************************************************************** NOMANUAL* intPrismWDSMcastDel - Delete an entry in the multicast table** This function is not relevent to the WDS virtual END driver. Use this * feature of the real END driver for the desired effect.** ERRNO: N/A*/LOCAL STATUS intPrismWDSMCastDel (END_OBJ * pDrvCtrl, char * pAddress) { return ERROR; }/****************************************************************************** NOMANUAL* intPrismWDSMCastGet - Get the multicast table** This function is not relevent to the WDS virtual END driver. Use this * feature of the real END driver for the desired effect.** ERRNO: N/A*/LOCAL STATUS intPrismWDSMCastGet (END_OBJ * pDrvCtrl,MULTI_TABLE * pTable) { return ERROR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -