📄 rtmp_data.c
字号:
/*
***************************************************************************
* Ralink Tech Inc.
* 4F, No. 2 Technology 5th Rd.
* Science-based Industrial Park
* Hsin-chu, Taiwan, R.O.C.
*
* (c) Copyright 2002-2005, Ralink Technology, Inc.
*
* All rights reserved. Ralink's source code is an unpublished work and the
* use of a copyright notice does not imply otherwise. This source code
* contains confidential trade secret material of Ralink Tech. Any attempt
* or participation in deciphering, decoding, reverse engineering or in any
* way altering the source code is stricitly prohibited, unless the prior
* written consent of Ralink Technology, Inc. is obtained.
***************************************************************************
Module Name:
rtmp_data.c
Abstract:
Data path subroutines
Revision History:
Who When What
-------- ---------- ----------------------------------------------
John Aug/17/04 major modification for RT2561/2661
*/
#include "rt_config.h"
#ifdef RTL865X_SOC
static inline BOOLEAN RTMPBridgeToWdsAndWirelessSta(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR pHeader802_3,
IN UINT HdrLen,
IN PUCHAR pData,
IN UINT DataLen,
IN UINT FromWhichBSSID);
static inline BOOLEAN RTMPCheckDHCPFrame(
IN PRTMP_ADAPTER pAd,
IN struct sk_buff *pSkb);
static inline NDIS_STATUS RTMPCloneNdisPacket(
IN PRTMP_ADAPTER pAdapter,
IN struct sk_buff *pInSkb,
OUT struct sk_buff **ppOutSkb);
static void rtl865x_rx(PRTMP_ADAPTER pAd, struct sk_buff *skb);
//#define netif_rx rtl865x_rx
#endif /* RTL865X_SOC */
UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
// Add Cisco Aironet SNAP heade for CCX2 support
UCHAR SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
UCHAR EAPOL[] = {0x88, 0x8E};
UCHAR IPX[] = {0x81, 0x37};
UCHAR APPLE_TALK[] = {0x80, 0xF3};
//static UCHAR TPID[] = {0x81, 0x00};
static UCHAR RateIdToPlcpSignal[12] = {
0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
// Macro for rx indication
VOID REPORT_ETHERNET_FRAME_TO_LLC(
IN PRTMP_ADAPTER pAd,
IN PUCHAR p8023hdr,
IN PUCHAR pData,
IN ULONG DataSize,
IN struct net_device *net_dev)
{
struct sk_buff *pSkb;
if ((pSkb = __dev_alloc_skb(DataSize + LENGTH_802_3 + 2, MEM_ALLOC_FLAG)) != NULL)
{
pSkb->dev = net_dev;
skb_reserve(pSkb, 2); // 16 byte align the IP header
memcpy(skb_put(pSkb, LENGTH_802_3), p8023hdr, LENGTH_802_3);
memcpy(skb_put(pSkb, DataSize), pData, DataSize);
#ifdef APCLI_SUPPORT
UWRMacConverterForRxPkt(pAd, pSkb, net_dev);
#endif
pSkb->protocol = eth_type_trans(pSkb, net_dev);
#ifdef RTL865X_SOC
skb_push(pSkb, net_dev->hard_header_len);
rtl865x_rx(pAd, pSkb);
#else
netif_rx(pSkb);
#endif
pAd->net_dev->last_rx = jiffies;
pAd->stats.rx_packets++;
}
}
#ifdef RTL865X_SOC
// Macro for rx indication
VOID REPORT_ETHERNET_FRAME_TO_LLC_RTL865X(
IN PRTMP_ADAPTER pAd,
IN PUCHAR p8023hdr,
IN PUCHAR pData,
IN ULONG DataSize,
IN struct net_device *net_dev)
{
struct sk_buff *pSkb;
if ((pSkb = __dev_alloc_skb(DataSize + LENGTH_802_3 + 2, MEM_ALLOC_FLAG)) != NULL)
{
pSkb->dev = net_dev;
skb_reserve(pSkb, 2); // 16 byte align the IP header
memcpy(skb_put(pSkb, LENGTH_802_3), p8023hdr, LENGTH_802_3);
memcpy(skb_put(pSkb, DataSize), pData, DataSize);
#ifdef APCLI_SUPPORT
UWRMacConverterForRxPkt(pAd, pSkb, net_dev);
#endif
pSkb->protocol = eth_type_trans(pSkb, net_dev);
netif_rx(pSkb);
pAd->net_dev->last_rx = jiffies;
pAd->stats.rx_packets++;
}
}
#endif
// Macro for rx indication
VOID REPORT_ETHERNET_FRAME_TO_LLC_WITH_NON_COPY(
IN PRTMP_ADAPTER pAd,
IN PUCHAR p8023hdr,
IN PUCHAR pData,
IN ULONG DataSize,
IN struct net_device *net_dev)
{
#ifdef NONCOPY_RX
// PRXD_STRUC pRxD;
struct sk_buff *pRxSkb = pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.pSkb;
struct sk_buff *pSkb = NULL;
// allocate a new one and update RxD
if ((pSkb = __dev_alloc_skb(RX_DMA_BUFFER_SIZE, MEM_ALLOC_FLAG)) != NULL)
{
pRxSkb->dev = net_dev;
pRxSkb->data = pData;
pRxSkb->len = DataSize;
pRxSkb->tail = pRxSkb->data + pRxSkb->len;
memcpy(skb_push(pRxSkb, LENGTH_802_3), p8023hdr, LENGTH_802_3);
#ifdef APCLI_SUPPORT
UWRMacConverterForRxPkt(pAd, pRxSkb, net_dev);
#endif
pRxSkb->protocol = eth_type_trans(pRxSkb, net_dev);
#ifdef RTL865X_SOC
skb_push(pRxSkb, net_dev->hard_header_len);
rtl865x_rx(pAd, pRxSkb);
#else
netif_rx(pRxSkb);
#endif
pAd->net_dev->last_rx = jiffies;
pAd->stats.rx_packets++;
RTMP_SET_PACKET_SOURCE(pSkb, PKTSRC_DRIVER);
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize = RX_DMA_BUFFER_SIZE;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.pSkb = pSkb;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa = pSkb->data;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa = pci_map_single(pAd->pPci_Dev, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
// Write RxD buffer address & allocated buffer length
//pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
//pRxD->BufPhyAddr = pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa;
} else {
RTMP_SET_PACKET_SOURCE(pRxSkb, PKTSRC_DRIVER);
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize = RX_DMA_BUFFER_SIZE;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.pSkb = pRxSkb;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa = pRxSkb->data;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa = pci_map_single(pAd->pPci_Dev, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
// Write RxD buffer address & allocated buffer length
//pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
//pRxD->BufPhyAddr = pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa;
}
#else
struct sk_buff *pSkb;
if ((pSkb = __dev_alloc_skb(DataSize + LENGTH_802_3 + 2, MEM_ALLOC_FLAG)) != NULL)
{
pSkb->dev = net_dev;
skb_reserve(pSkb, 2); // 16 byte align the IP header
memcpy(skb_put(pSkb, LENGTH_802_3), p8023hdr, LENGTH_802_3);
memcpy(skb_put(pSkb, DataSize), pData, DataSize);
#ifdef APCLI_SUPPORT
UWRMacConverterForRxPkt(pAd, pSkb, net_dev);
#endif
pSkb->protocol = eth_type_trans(pSkb, net_dev);
#ifdef RTL865X_SOC
skb_push(pSkb, net_dev->hard_header_len);
rtl865x_rx(pAd, pSkb);
#else
netif_rx(pSkb);
#endif
pAd->net_dev->last_rx = jiffies;
pAd->stats.rx_packets++;
}
#endif
}
// Macro for rx indication
VOID REPORT_AGGREGATE_ETHERNET_FRAME_TO_LLC_WITH_NON_COPY(
IN PRTMP_ADAPTER pAd,
IN PUCHAR p8023hdr,
IN PUCHAR pData,
IN ULONG DataSize1,
IN ULONG DataSize2,
IN struct net_device *net_dev)
{
struct sk_buff *pRxSkb = pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.pSkb;
struct sk_buff *pSkb1 = NULL;
struct sk_buff *pSkb2 = NULL;
PUCHAR pData2;
PUCHAR phdr;
pData2 = pData + DataSize1 + LENGTH_802_3;
phdr = pData + DataSize1;
if ((pSkb2 = __dev_alloc_skb(DataSize2 + LENGTH_802_3 + 2, MEM_ALLOC_FLAG)) != NULL)
{
pSkb2->dev = net_dev;
skb_reserve(pSkb2, 2); // 16 byte align the IP header
memcpy(skb_put(pSkb2, LENGTH_802_3), phdr, LENGTH_802_3);
memcpy(skb_put(pSkb2, DataSize2), pData2, DataSize2);
#ifdef APCLI_SUPPORT
UWRMacConverterForRxPkt(pAd, pSkb2, net_dev);
#endif
pSkb2->protocol = eth_type_trans(pSkb2, net_dev);
} else {
return;
}
// allocate a new one and update RxD
if ((pSkb1 = __dev_alloc_skb(RX_DMA_BUFFER_SIZE, MEM_ALLOC_FLAG)) != NULL)
{
pRxSkb->dev = net_dev;
pRxSkb->data = pData;
pRxSkb->len = DataSize1;
pRxSkb->tail = pRxSkb->data + pRxSkb->len;
memcpy(skb_push(pRxSkb, LENGTH_802_3), p8023hdr, LENGTH_802_3);
#ifdef APCLI_SUPPORT
UWRMacConverterForRxPkt(pAd, pRxSkb, net_dev);
#endif
pRxSkb->protocol = eth_type_trans(pRxSkb, net_dev);
#ifdef RTL865X_SOC
skb_push(pRxSkb, net_dev->hard_header_len);
rtl865x_rx(pAd, pRxSkb);
skb_push(pSkb2, net_dev->hard_header_len);
rtl865x_rx(pAd, pSkb2);
#else
netif_rx(pRxSkb);
netif_rx(pSkb2);
#endif
pAd->net_dev->last_rx = jiffies;
pAd->stats.rx_packets += 2;
RTMP_SET_PACKET_SOURCE(pSkb1, PKTSRC_DRIVER);
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize = RX_DMA_BUFFER_SIZE;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.pSkb = pSkb1;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa = pSkb1->data;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa = pci_map_single(pAd->pPci_Dev, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
// Write RxD buffer address & allocated buffer length
//pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
//pRxD->BufPhyAddr = pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa;
} else {
RTMP_SET_PACKET_SOURCE(pRxSkb, PKTSRC_DRIVER);
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize = RX_DMA_BUFFER_SIZE;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.pSkb = pRxSkb;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa = pRxSkb->data;
pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa = pci_map_single(pAd->pPci_Dev, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocVa, pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(pSkb2);
return;
// Write RxD buffer address & allocated buffer length
//pRxD = (PRXD_STRUC) pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].AllocVa;
//pRxD->BufPhyAddr = pAd->RxRing.Cell[pAd->RxRing.CurRxIndex].DmaBuf.AllocPa;
}
}
// Enqueue this frame to MLME engine
// We need to enqueue the whole frame because MLME need to pass data type
// information from 802.11 header
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -