/* ======================================================================== Routine Description: For each out-going packet, check the upper layer protocol type if need to handled by our APCLI convert engine. If yes, call corresponding handler to handle it. Arguments: pAd =>Pointer to our adapter pPkt =>pointer to the 802.11 header of outgoing packet ifIdx =>Interface Index want to dispatch to. Return Value: Success => TRUE Mapped mac address if found, else return specific default mac address depends on the upper layer protocol type. Error => FALSE. Note: 1.the pPktHdr must be a 802.3 packet. 2.Maybe we need a TxD arguments? 3.We check every packet here including group mac address becasue we need to handle DHCP packet. ======================================================================== */ PUCHAR MATEngineTxHandle( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPkt, IN UINT ifIdx, IN UCHAR OpMode) { PUCHAR pLayerHdr = NULL, pPktHdr = NULL, pMacAddr = NULL; UINT16 protoType, protoType_ori; int i; struct _MATProtoOps *pHandle = NULL; PUCHAR retSkb = NULL; BOOLEAN bVLANPkt = FALSE; if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED) return NULL; pPktHdr = GET_OS_PKT_DATAPTR(pPkt); if (!pPktHdr) return NULL; protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12)); /* Get the upper layer protocol type of this 802.3 pkt. */ protoType = OS_NTOHS(protoType_ori); /* handle 802.1q enabled packet. Skip the VLAN tag field to get the protocol type. */ if (protoType == 0x8100) { protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12 + 4)); protoType = OS_NTOHS(protoType_ori); bVLANPkt = TRUE; } /* For differnet protocol, dispatch to specific handler */ for (i=0; i < MAX_MAT_SUPPORT_PROTO_NUM; i++) { if (protoType == MATProtoTb[i].protocol) { pHandle = MATProtoTb[i].pHandle; /* the pHandle must not be null! */ pLayerHdr = bVLANPkt ? (pPktHdr + MAT_VLAN_ETH_HDR_LEN) : (pPktHdr + MAT_ETHER_HDR_LEN); #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) pMacAddr = &pAd->ApCfg.ApCliTab[ifIdx].CurrentAddress[0]; #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ if (pHandle->tx!=NULL) retSkb = pHandle->tx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, pMacAddr); return retSkb; } } return retSkb; }
/* Delayed TCP Ack */ BOOLEAN delay_tcp_ack(RTMP_ADAPTER *pAd, UCHAR wcid, PNDIS_PACKET pPacket) { PUCHAR pSrcBuf; UINT32 pktLen, qlen; PMAC_TABLE_ENTRY pEntry; BOOLEAN bDelay = FALSE; pEntry = &pAd->MacTab.Content[wcid]; pSrcBuf = GET_OS_PKT_DATAPTR(pPacket); pktLen = GET_OS_PKT_LEN(pPacket); if (pAd->CommonCfg.ACKQEN == 1) { /* get Ethernet protocol field*/ USHORT TypeLen = OS_NTOHS(*((UINT16 *)(pSrcBuf + 12))); /* bypass VALN 802.1Q field */ if(TypeLen == 0x8100) pSrcBuf += 4; else if ((TypeLen==0x9100) || (TypeLen==0x9200) || (TypeLen==0x9300)) pSrcBuf += 8; if ((TypeLen == 0x0800) /* Type: IP (0x0800) */ && (pSrcBuf[23] == 0x06) /* Protocol: TCP (0x06) */ && (pktLen >= 48) && ((pSrcBuf[47]&0x10) == 0x10)) /* Flags: Ack bit is set */ { skb_queue_tail(&pEntry->ack_queue, pPacket); qlen = skb_queue_len(&pEntry->ack_queue); bDelay = TRUE; if (qlen == 1) { if (pEntry->QueueAckTimerRunning == FALSE) { DBGPRINT(RT_DEBUG_LOUD, ("found tcp ack..\n")); RTMPSetTimer(&pEntry->QueueAckTimer, pAd->CommonCfg.AckWaitTime); pEntry->QueueAckTimerRunning = TRUE; } } else if ((qlen >= pAd->CommonCfg.Acklen) || ((pSrcBuf[47]&0x03) != 0) /* Flags: FIN(bit0) or SYN(bit1) is set */ || (pktLen > 66)) /* TCP ACK with other payload in IPv4 format */ { pAd->CommonCfg.AckNOTimeout += flush_tcp_ack_queue(pAd, pEntry, TRUE); } } } else { flush_tcp_ack_queue(pAd, pEntry, TRUE); } return bDelay; }
/* ======================================================================== Routine Description: Depends on the Received packet, check the upper layer protocol type and search for specific mapping table to find out the real destination MAC address. Arguments: pAd =>Pointer to our adapter pPkt =>pointer to the 802.11 header of receviced packet infIdx =>Interface Index want to dispatch to. Return Value: Success => Mapped mac address if found, else return specific default mac address depends on the upper layer protocol type. Error => NULL Note: ======================================================================== */ PUCHAR MATEngineRxHandle( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPkt, IN UINT infIdx) { PUCHAR pMacAddr = NULL; PUCHAR pLayerHdr = NULL, pPktHdr = NULL; UINT16 protoType; int i =0; struct _MATProtoOps *pHandle = NULL; if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED) return NULL; pPktHdr = GET_OS_PKT_DATAPTR(pPkt); if (!pPktHdr) return NULL; /* If it's a multicast/broadcast packet, we do nothing. */ if (IS_GROUP_MAC(pPktHdr)) return NULL; /* Get the upper layer protocol type of this 802.3 pkt and dispatch to specific handler */ protoType = OS_NTOHS(get_unaligned((PUINT16)(pPktHdr + 12))); for (i=0; i<MAX_MAT_SUPPORT_PROTO_NUM; i++) { if (protoType == MATProtoTb[i].protocol) { pHandle = MATProtoTb[i].pHandle; /* the pHandle must not be null! */ pLayerHdr = (pPktHdr + MAT_ETHER_HDR_LEN); /* RTMP_SEM_LOCK(&MATDBLock); */ if(pHandle->rx!=NULL) pMacAddr = pHandle->rx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, NULL); /* RTMP_SEM_UNLOCK(&MATDBLock); */ break; } } if (pMacAddr) NdisMoveMemory(pPktHdr, pMacAddr, MAC_ADDR_LEN); return NULL; }
/* ======================================================================== Routine Description: For each out-going packet, check the upper layer protocol type if need to handled by our APCLI convert engine. If yes, call corresponding handler to handle it. Arguments: pAd =>Pointer to our adapter pPkt =>pointer to the 802.11 header of outgoing packet ifIdx =>Interface Index want to dispatch to. Return Value: Success => TRUE Mapped mac address if found, else return specific default mac address depends on the upper layer protocol type. Error => FALSE. Note: 1.the pPktHdr must be a 802.3 packet. 2.Maybe we need a TxD arguments? 3.We check every packet here including group mac address becasue we need to handle DHCP packet. ======================================================================== */ PUCHAR MATEngineTxHandle( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPkt, IN UINT ifIdx, IN UCHAR OpMode) { PUCHAR pLayerHdr = NULL, pPktHdr = NULL, pMacAddr = NULL; UINT16 protoType, protoType_ori; INT i; struct _MATProtoOps *pHandle = NULL; PUCHAR retSkb = NULL; BOOLEAN bVLANPkt = FALSE; if(pAd->MatCfg.status != MAT_ENGINE_STAT_INITED) return NULL; pPktHdr = GET_OS_PKT_DATAPTR(pPkt); if (!pPktHdr) return NULL; protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12)); /* Get the upper layer protocol type of this 802.3 pkt. */ protoType = OS_NTOHS(protoType_ori); /* handle 802.1q enabled packet. Skip the VLAN tag field to get the protocol type. */ if (protoType == 0x8100) { protoType_ori = get_unaligned((PUINT16)(pPktHdr + 12 + 4)); protoType = OS_NTOHS(protoType_ori); bVLANPkt = TRUE; } #ifdef RELEASE_EXCLUDE DBGPRINT(RT_DEBUG_INFO,("%s(): protoType=0x%04x\n", __FUNCTION__, protoType)); #endif /* RELEASE_EXCLUDE */ /* For differnet protocol, dispatch to specific handler */ for (i=0; i < MAX_MAT_SUPPORT_PROTO_NUM; i++) { if (protoType == MATProtoTb[i].protocol) { pHandle = MATProtoTb[i].pHandle; /* the pHandle must not be null! */ pLayerHdr = bVLANPkt ? (pPktHdr + MAT_VLAN_ETH_HDR_LEN) : (pPktHdr + MAT_ETHER_HDR_LEN); #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef MAC_REPEATER_SUPPORT UCHAR tempIdx = ifIdx; UCHAR CliIdx = 0xFF; if (tempIdx >= 64) { CliIdx = ((tempIdx - 64) % 16); tempIdx = ((tempIdx - 64) / 16); pMacAddr = &pAd->ApCfg.ApCliTab[tempIdx].RepeaterCli[CliIdx].CurrentAddress[0]; } else #endif /* MAC_REPEATER_SUPPORT */ pMacAddr = &pAd->ApCfg.ApCliTab[ifIdx].wdev.if_addr[0]; } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT #ifdef ETH_CONVERT_SUPPORT #ifdef P2P_SUPPORT if (OpMode == OPMODE_STA) pMacAddr = &pAd->CurrentAddress[0]; #ifdef APCLI_SUPPORT else pMacAddr = &pAd->ApCfg.ApCliTab[ifIdx].wdev.if_addr[0]; #endif /* APCLI_SUPPORT */ #else IF_DEV_CONFIG_OPMODE_ON_STA(pAd) pMacAddr = &pAd->CurrentAddress[0]; #endif /* P2P_SUPPORT */ #endif /* ETH_CONVERT_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ if (pHandle->tx!=NULL) retSkb = pHandle->tx((PVOID)&pAd->MatCfg, RTPKT_TO_OSPKT(pPkt), pLayerHdr, pMacAddr); return retSkb; } }