diff options
author | Roman Yeryomin <roman@advem.lv> | 2012-09-13 00:40:35 +0300 |
---|---|---|
committer | Roman Yeryomin <roman@advem.lv> | 2012-12-03 00:13:21 +0200 |
commit | 5deb3317cb51ac52de922bb55f8492624018906d (patch) | |
tree | c2fbe6346699d9bb0f2100490c3029519bb8fde8 /target/linux/realtek/files/drivers/net/rtl819x/common | |
parent | 0239d37124f9184b478a42de8a7fa1bc85a6a6fe (diff) |
Add realtek target files
Signed-off-by: Roman Yeryomin <roman@advem.lv>
Diffstat (limited to 'target/linux/realtek/files/drivers/net/rtl819x/common')
12 files changed, 8468 insertions, 0 deletions
diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/Makefile b/target/linux/realtek/files/drivers/net/rtl819x/common/Makefile new file mode 100644 index 000000000..5414e6faf --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/Makefile @@ -0,0 +1,47 @@ +# +# Makefile for the Tulip ethernet driver +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +#Add mips16 Support + +DIR_RTLASIC = $(TOPDIR)/drivers/net/rtl819x/ + +ifeq ($(CONFIG_RTK_IPTABLES_FAST_PATH),m) +EXTRA_CFLAGS += -DCONFIG_FAST_PATH_MODULE +endif +ifdef CONFIG_RTL865X_KERNEL_MIPS16_LAYERDRIVER + CFLAGS_rtl_utils.o = -mips16 + CFLAGS_rtl865xC_tblDrvPatch.o = -mips16 + CFLAGS_rtl865x_vlan.o = -mips16 + CFLAGS_rtl865x_netif.o = -mips16 + CFLAGS_rtl865x_eventMgr.o = -mips16 +endif + ifeq ($(CONFIG_RTL_LAYERED_ASIC_DRIVER),y) + obj-y := rtl865x_vlan.o rtl865x_netif.o rtl865x_eventMgr.o + else + obj-y := rtl865xC_tblDrvPatch.o rtl865x_vlan.o rtl865x_netif.o rtl865x_eventMgr.o + endif + +ifeq ($(CONFIG_RTL_PROC_DEBUG), y) + obj-y += rtl_utils.o +endif + + +EXTRA_CFLAGS += -O1 -DRTL_TBLDRV -D__linux__ -mno-memcpy -DRTL865X_OVER_KERNEL -DRTL865X_OVER_LINUX -Werror +EXTRA_CFLAGS += -I$(DIR_RTLASIC) + +ifeq ($(CONFIG_RTL865X_MODULE_ROMEDRV),y) + EXTRA_CFLAGS += -D__KERNEL__ + EXTRA_CFLAGS += -G 0 + EXTRA_CFLAGS += -DMODULE + EXTRA_CFLAGS += -mlong-calls + EXTRA_CFLAGS += -DEXPORT_SYMTAB + EXTRA_CFLAGS += -DCONFIG_RTL865X_MODULE_INTERNAL +endif + +EXTRA_AFLAGS += $(EXTRA_CFLAGS) diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/mbuf.h b/target/linux/realtek/files/drivers/net/rtl819x/common/mbuf.h new file mode 100644 index 000000000..dfe886b71 --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/mbuf.h @@ -0,0 +1,1254 @@ + +/* +* Copyright c Realtek Semiconductor Corporation, 2002 +* All rights reserved. +* +* Program : The mbuf module header file +* Abstract : +* Author : David Chun-Feng Liu (cfliu@realtek.com.tw) +* +*/ +#ifndef _MBUF_H_ +#define _MBUF_H_ + +/********************************************************************************* + SECTION 1: mbuf module default settings +**********************************************************************************/ +#define PKT_MBUF_CLUSTER_LEN 1650 + +#define PKT_BUF_SZ PKT_MBUF_CLUSTER_LEN /* Size of each temporary Rx buffer.*/ + +/********************************************************************************* + SECTION 2: mbuf module data structure definitions +**********************************************************************************/ +#define BUF_FREE 0x00 /* Buffer is Free */ +#define BUF_USED 0x80 /* Buffer is occupied */ +#define BUF_ASICHOLD 0x80 /* Buffer is hold by ASIC */ +#define BUF_DRIVERHOLD 0xc0 /* Buffer is hold by driver */ + +#define MBUFTYPE_DATA 0x01 //not in use now. Keep for backward compatablity. + +/*@struct m_buf | The mbuf header associated with each cluster */ + +struct rtl_mBuf +{ + struct rtl_mBuf *m_next; + struct rtl_pktHdr *m_pkthdr; /* Points to the pkthdr structure */ + uint16 m_len; /* data bytes used in this cluster */ + int8 m_flags; /* mbuf flags; see below */ +#define MBUF_FREE BUF_FREE /* Free. Not occupied. should be on free list */ +#define MBUF_USED BUF_USED /* Buffer is occupied */ +#define MBUF_EXT 0x10 /* has associated with an external cluster, this is always set. */ +#define MBUF_PKTHDR 0x08 /* is the 1st mbuf of this packet */ +#define MBUF_EOR 0x04 /* is the last mbuf of this packet. Set only by ASIC*/ + uint8 *m_data; /* location of data in the cluster */ + uint8 *m_extbuf; /* start of buffer*/ + uint16 m_extsize; /* sizeof the cluster */ + int8 m_reserved[2]; /* padding */ + void *skb; +}; + +/*@struct rtl_pktHdr | pkthdr records packet specific information. Each pkthdr is exactly 32 bytes. + first 20 bytes are for ASIC, the rest 12 bytes are for driver and software usage. + */ +struct rtl_pktHdr +{ + union + { + struct rtl_pktHdr *pkthdr_next; /* next pkthdr in free list */ + struct rtl_mBuf *mbuf_first; /* 1st mbuf of this pkt */ + }PKTHDRNXT; +#define ph_nextfree PKTHDRNXT.pkthdr_next +#define ph_mbuf PKTHDRNXT.mbuf_first + uint16 ph_len; /* total packet length */ + uint16 ph_reserved1: 1; /* reserved */ + uint16 ph_queueId: 3; /* bit 2~0: Queue ID */ + uint16 ph_extPortList: 4; /* dest extension port list. must be 0 for TX */ + /* for ph_extPortList */ + #define PKTHDR_EXTPORT_MAGIC 0xA530 + #define PKTHDR_EXTPORT_MAGIC2 0xA531 + #define PKTHDR_EXTPORT_P1 6 + #define PKTHDR_EXTPORT_P2 7 + #define PKTHDR_EXTPORT_P3 8 + + #define PKTHDR_EXTPORT_LIST_P0 0 + #define PKTHDR_EXTPORT_LIST_P1 1 + #define PKTHDR_EXTPORT_LIST_P2 2 + #define PKTHDR_EXTPORT_LIST_CPU 3 + #define PKTHDR_EXTPORTMASK_P0 (0x1 << (PKTHDR_EXTPORT_LIST_P0)) + #define PKTHDR_EXTPORTMASK_P1 (0x1 << (PKTHDR_EXTPORT_LIST_P1)) + #define PKTHDR_EXTPORTMASK_P2 (0x1 << (PKTHDR_EXTPORT_LIST_P2)) + #define PKTHDR_EXTPORTMASK_CPU (0x1 << (PKTHDR_EXTPORT_LIST_CPU)) + #define PKTHDR_EXTPORTMASK_ALL ( PKTHDR_EXTPORTMASK_P0 |\ + PKTHDR_EXTPORTMASK_P1 |\ + PKTHDR_EXTPORTMASK_P2 |\ + PKTHDR_EXTPORTMASK_CPU \ + ) + + uint16 ph_reserved2: 3; /* reserved */ + uint16 ph_hwFwd: 1; /* hwFwd - copy from HSA bit 200 */ + uint16 ph_isOriginal: 1; /* isOriginal - DP included cpu port or more than one ext port */ + uint16 ph_l2Trans: 1; /* l2Trans - copy from HSA bit 129 */ + uint16 ph_srcExtPortNum: 2; /* Both in RX & TX. Source extension port number. */ + + uint16 ph_type: 3; +#define ph_proto ph_type +#define PKTHDR_ETHERNET 0 +#define PKTHDR_IP 2 +#define PKTHDR_ICMP 3 +#define PKTHDR_IGMP 4 +#define PKTHDR_TCP 5 +#define PKTHDR_UDP 6 + uint16 ph_vlanTagged: 1; /* the tag status after ALE */ + uint16 ph_LLCTagged: 1; /* the tag status after ALE */ + uint16 ph_pppeTagged: 1; /* the tag status after ALE */ + uint16 ph_pppoeIdx: 3; + uint16 ph_linkID: 7; /* for WLAN WDS multiple tunnel */ + uint16 ph_reason; /* indicates wht the packet is received by CPU */ + + uint16 ph_flags; /* NEW:Packet header status bits */ +#define PKTHDR_FREE (BUF_FREE << 8) /* Free. Not occupied. should be on free list */ +#define PKTHDR_USED (BUF_USED << 8) +#define PKTHDR_ASICHOLD (BUF_ASICHOLD<<8) /* Hold by ASIC */ +#define PKTHDR_DRIVERHOLD (BUF_DRIVERHOLD<<8) /* Hold by driver */ +#define PKTHDR_CPU_OWNED 0x4000 +#define PKT_INCOMING 0x1000 /* Incoming: packet is incoming */ +#define PKT_OUTGOING 0x0800 /* Outgoing: packet is outgoing */ +#define PKT_BCAST 0x0100 /*send/received as link-level broadcast */ +#define PKT_MCAST 0x0080 /*send/received as link-level multicast */ +#define PKTHDR_BRIDGING 0x0040 /* when PKTHDR_HWLOOKUP is on. 1: Hardware assist to do L2 bridging only, 0:hardware assist to do NAPT*/ +#define PKTHDR_HWLOOKUP 0x0020 /* valid when ph_extPortList!=0. 1:Hardware table lookup assistance*/ +#define PKTHDR_PPPOE_AUTOADD 0x0004 /* PPPoE header auto-add */ +#define CSUM_TCPUDP_OK 0x0001 /*Incoming:TCP or UDP cksum checked */ +#define CSUM_IP_OK 0x0002 /* Incoming: IP header cksum has checked */ +#define CSUM_TCPUDP 0x0001 /*Outgoing:TCP or UDP cksum offload to ASIC*/ +#define CSUM_IP 0x0002 /* Outgoing: IP header cksum offload to ASIC*/ + + uint8 ph_orgtos; /* RX: original TOS of IP header's value before remarking, TX: undefined */ + uint8 ph_portlist; /* RX: source port number, TX: destination portmask */ + + uint16 ph_vlanId_resv: 1; + uint16 ph_txPriority: 3; + uint16 ph_vlanId: 12; + // uint16 ph_flags2; + union + { + uint16 _flags2; /* RX: bit 15: Reserved, bit14~12: Original Priority, bit 11~0: Original VLAN ID */ + /* TX: bit 15~6: Reserved, bit 5~0: Per Port Tag mask setting for TX(bit 5:MII, bit 4~0: Physical Port) */ + struct + { + /* RX: bit 15: Reserved, bit14~12: Original Priority, bit 11~0: Original VLAN ID */ + uint16 _reserved:1; + uint16 _rxPktPriority:3; /* Rx packet's original priority */ + uint16 _svlanId:12; /* Source (Original) VLAN ID */ + } _rx; + + struct + { + /* TX: bit 15~6: Reserved, bit 5~0: Per Port Tag mask setting for TX(bit 5:MII, bit 4~0: Physical Port) */ + uint16 _reserved:10; + uint16 _txCVlanTagAutoAdd:6; /* BitMask to indicate the port which would need to add VLAN tag */ + } _tx; + } _flags2; + #define ph_dvlanId ph_vlanId + #define ph_rxPriority ph_txPriority + + #define PKTHDR_TXPRIORITY_MIN 0 + #define PKTHDR_TXPRIORITY_MAX 7 + + #define ph_flags2 _flags2._flags2 + #define ph_svlanId _flags2._rx._svlanId + #define ph_rxPktPriority _flags2._rx._rxPktPriority + #define ph_txCVlanTagAutoAdd _flags2._tx._txCVlanTagAutoAdd + + #define PKTHDR_TXCVID(vid) (vid & 0xfff) + #define PKTHDR_VLAN_P0_AUTOADD (0x0001<<0) + #define PKTHDR_VLAN_P1_AUTOADD (0x0001<<1) + #define PKTHDR_VLAN_P2_AUTOADD (0x0001<<2) + #define PKTHDR_VLAN_P3_AUTOADD (0x0001<<3) + #define PKTHDR_VLAN_P4_AUTOADD (0x0001<<4) + #define PKTHDR_VLAN_P5_AUTOADD (0x0001<<5) + #define PKTHDR_VLAN_AUTOADD ( (PKTHDR_VLAN_P0_AUTOADD)| \ + (PKTHDR_VLAN_P1_AUTOADD)| \ + (PKTHDR_VLAN_P2_AUTOADD)| \ + (PKTHDR_VLAN_P3_AUTOADD)| \ + (PKTHDR_VLAN_P4_AUTOADD)| \ + (PKTHDR_VLAN_P5_AUTOADD) ) + +}; + + //property for ph_unnumber : cw_du + #define PHUNNUMBER_SRCGLOBEIP 0x01 + #define PHUNNUMBER_DIRECTION 0x02 // 1 : WAN->LAN; 0: LAN->WAN + #define PHUNNUMBER_UNNUMBEREDSRCIP 0x04 + #define PHUNNUMBER_ADVRTMATCHED 0x08 + + + #define PHUNNUMBER_ALLBITS 0xff + + + #define PKTHDR_PHUNNUMBER_SET(pkthdrPtr, property) \ + do{\ + assert(pkthdrPtr);\ + pkthdrPtr->ph_unnumber |=property;\ + }while(0) + + #define PKTHDR_PHUNNUMBER_CLR(pkthdrPtr, property) \ + do{\ + assert(pkthdrPtr);\ + pkthdrPtr->ph_unnumber &= ~property;\ + }while(0) + + #define PKTHDR_PHUNNUMBER_TEST(pkthdrPtr, property) ((pkthdrPtr->ph_unnumber & property) ? 1: 0) + + + + + + +struct rtl_mBufStatus +{ + uint32 m_totalmbufs; //Total mbufs allocated during initialization + uint32 m_totalclusters; //Total clusters allocated during initialization + uint32 m_totalpkthdrs; //Total pkthdrs allocated during initialization + uint32 m_freembufs; /* free mbufs in pool now*/ + uint32 m_freeclusters; /* free clusters in pool now*/ + uint32 m_freepkthdrs; /* free pkthdrs in pool now*/ + uint32 m_msize; /* length of an mbuf */ + uint32 m_mclbytes; /* length of an mbuf cluster */ + uint32 m_pkthdrsize; /* length of an pkthdr */ + + uint32 m_wait; /* times waited for space, includes mbuf, pkthdr and cluster */ +}; + + +/********************************************************************************* + SECTION 3: mbuf module exported variables, symbols and macros +**********************************************************************************/ +#define MBUF_COPYALL 1000000000 /* length for m_copy to copy all */ +#define MBUF_WAITOK 0x01 +#define MBUF_DONTWAIT 0x02 /* Don't wait if there is no buffer available */ +#define MBUF_ONLY 0x04 /* Don't allocate a cluster in mBuf_get */ +#define MBUF_ALLOCPKTHDR 0x08 /* Allocate a packet header with mbuf chain in mBuf_getm, mBuf_cloneMbufChain, mBuf_dupMbufChain*/ +#define MBUF_GETNEWMBUF 0x10 /* In mBuf_prepend, alloate new mbufs directly */ +#define MBUF_CHECKPKTHDR(m) ((m)&&(ISSET((m)->m_flags, MBUF_USED) && ((m)->m_pkthdr))?1:0) +#define MBUF_GETPKTHDRFIELD16(field) (*((uint16 *)(field))) +#define MBUF_SETPKTHDRFIELD16(field, value) *((uint16 *)(field)) = (value) + +//The size of each cluster. +extern int32 m_clusterSize; + +/********************************************************************************* + SECTION 4: mbuf module exported API prototype +**********************************************************************************/ + +/* mbuf module exported APIs */ + +/* @doc MBUF_API + + @module mbuf.h - Mbuf module API documentation | + This document illustrates the API interface of the mbuf module. + @normal Chun-Feng Liu (cfliu@realtek.com.tw) <date> + + Copyright <cp>2001 Realtek<tm> Semiconductor Cooperation, All Rights Reserved. + + @head3 List of Symbols | + Here is a list of all functions and variables in this module. + + @index | MBUF_API +*/ +extern int32 mBuf_init(uint32, uint32, uint32, uint32, uint32); //was tunable_mbinit() +#if defined(RTL865X_TEST)||defined(RTL865X_MODEL_USER) +extern int32 mBuf_Reinit(void); +#endif /* RTL865X_TEST */ +/* +@func void | mBuf_init | mbuf module initialization +@parm uint32 | mbufs | Number of mbufs +@parm uint32 | clusters | Number of clusters +@parm uint32 | pkthdrs | Number of packet headers +@parm uint32 | clusterSize | Size of each cluster. must be power of 2 +@parm uint32 | msgLogId | Debuging message log list id +@rdesc None +@rvalue SUCCESS | The mbuf module and its memory pool is initiated as requested +@rvalue FAILED | Failed to initialize the mbuf module. +@comm mbuf module initialization. Allocate mbuf and related structure pools. Value for <p clusterSize> must be power of 2. +If <p clusters> is 0, clusters would be allocated externally through registered OS buffer allocation glue function. If clusters +are allocated this way, MBUF_WAITOK flag can't be used for mBuf_get, mBuf_getm, mBuf_dupMbufChain, mBuf_dupPacket since +mbuf module knows nothing about external cluter pool managed by OS hence doesn't know when to wakeup waiting threads. + */ + + +extern int32 mBuf_getBufStat(struct rtl_mBufStatus *mbs); +/* +@func int32 | mBuf_getBufStat | Returns current status of the mbuf module +@parm struct rtl_mBufStatus * | mbs | A pointer to the mbstat structure for mBuf_getBufStat() to fill in +@rdesc Returns current status of the mbuf module +@rvalue <p FAILED> | Failed to get mbuf module status. Maybe mbs is NULL or mbuf module not yet initiated. +@rvalue <p SUCCESS> | Mbuf module status is returned with the mbstat structure given. + */ + + + +extern int32 mBuf_leadingSpace(struct rtl_mBuf *m); + +/* +@func int32 | mBuf_leadingSpace | Calculate the number of leading free data bytes. +@parm struct rtl_mBuf * | m | Pointer to the mbuf chain. +@rdesc Returns the number of free leading space +@rvalue n | The number of free leading data bytes in cluster. +@comm +Calculate the number of leading free data bytes. +@xref <c mBuf_trailingSpace> + + */ + + +extern int32 mBuf_trailingSpace(struct rtl_mBuf *m); + +/* +@func int32 | mBuf_trailingSpace | Calculate the number of trailing free data bytes. +@parm struct rtl_mBuf * | m | Pointer to the mbuf chain. +@rdesc Returns the number of free trailing space +@rvalue n | The number of free trailing data bytes in cluster. +@comm +Calculate the number of trailing free data bytes. +@xref <c mBuf_leadingSpace> + + */ + + +extern int32 mBuf_clusterIsWritable(struct rtl_mBuf *m); + +/* +@func int32 | mBuf_clusterIsWritable | Determine whether <p m>'s cluster is writable or not. +@parm struct rtl_mBuf * | m | Pointer to an mbuf. +@rdesc Returns TRUE or FALSE +@rvalue TRUE | The cluster is writable. +@rvalue FALSE | The cluster is not writable. +@comm +Determine whether <p m>'s cluster is writable or not. New mbufs allocated due to mBuf_clonePacket, mBuf_split, mBuf_cloneMbufChain +should not modify its cluster becoz it is not the owner of these clusters. This function always return TRUE if the 'clusters' parameter +during mBuf_init() was initialized to 0. + + */ + +extern uint32 mBuf_getPktlen(struct rtl_mBuf *m); +/* +@func uint32 | mBuf_getPktlen | Get total number of data bytes in the packet which <p m> belongs to +@parm struct rtl_mBuf * |m | Indicate the packet +@rdesc Returns data length of the packet +@rvalue -1 | Failed. +@rvalue <p length>| The actual length of packet +@comm +Get total number of data bytes in the packet which <p m> belongs to +@xref <c MBUF_GETLEN> +*/ + +extern struct rtl_mBuf *mBuf_data2Mbuf(int8 * x); //was dtom + +/* +@func struct rtl_mBuf * | mBuf_data2Mbuf | Given data address <p x>, return mbuf address <p m> +@parm int8 * |x | Data address +@rdesc Returns mbuf address <p m> which owns the cluster block where <p x> resides. +@rvalue <p NULL> | Can't find the address. The data address <p x> given might be within a zombie cluster whose owning mbuf has already been freed. +@rvalue <p m> | The address of owning mbuf +@comm +Finds the mbuf address of given data address <p x> +This function can't be called if the 'clusters' parameter during mBuf_init() was initialized to 0. +@devnote Original BSD code define this as a dtom macro. In our implmentation, we make it a function. +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + + n = mBuf_data2Mbuf(x); + if (n != NULL) { + printf("There are %d bytes in the cluster", n->m_len); + } + @xref <c MBUF2DATAPTR> +*/ + + + +extern struct rtl_mBuf *mBuf_get(int32 how, int32 unused, uint32 Nbuf); + +/* +@func struct rtl_mBuf * | mBuf_get | mbuf space allocation routines. +@parm int32 | how | <p MBUF_WAITOK>, <p MBUF_DONTWAIT>, and/or <p MBUF_ONLY> +@parm int32 | unused | unused now. Keep for backward compatibility. +@parm uint32 | Nbuf | The number of mbufs requesting. + +@rdesc Returns the address of allocated mbuf head +@rvalue <p NULL> | Can't allocate all <p Nbuf>s at once. +@rvalue <p n> | The address of first mbuf allocated. All <p Nbuf>s have been linked together. +@comm +Get <p Nbuf> mbufs and clusters. All mbufs are chained via the <p m_next> pointer inside each mbuf. Note that memory content in all allocated clusters are NOT initialized. + +If <p how> has MBUF_DONTWAIT bit set, and we can't get all <p Nbuf>s immediately, return NULL. + +If <p how> has MBUF_WAITOK bit set, and we can't get all <p Nbuf>s right away, block waiting until our request is satisfied + +If <p how> has MBUF_ONLY bit set, then no clusters would be allocated. Only mbufs are allocated. Can be used with MBUF_DONTWAIT or MBUF_WAITOK + +@devnote +1.Side effect: <p mBuf_get> wakes up any sleeping threads if they are block waiting for free mbufs or clusters. +2. If the 'clusters' parameter during mBuf_init() was initialized to 0, mBuf_get doesn't accept MBUF_ONLY flag + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *m; + m= mBuf_get( MBUF_DONTWAIT, 0, 5); //allocate 5 mbufs and clusters without blocking. + if (!m) + return NULL; + + @xref + <c mBuf_getCleared> , <c mBuf_getm>, <c mBuf_driverGet> + */ + + +extern struct rtl_mBuf *mBuf_getCleared(int32 how, int32 unused, uint32 Nbuf); + +/* +@func struct rtl_mBuf * | mBuf_getCleared| Same as mBuf_get, but initialize all clusters to zero. +@parm int32 |how | <p MBUF_WAIT>, <p MBUF_DONTWAIT> and/or <p MBUF_ONLY> +@parm int32 |unused | unused now. Keep for backward compatibility. +@parm uint32 | Nbuf | The number of mbufs requesting. + +@rdesc Returns the address of allocated mbuf head +@rvalue <p NULL> | Can't allocate all <p Nbuf>s at once. +@rvalue <p n> | The address of first mbuf allocated. All <p Nbuf>s have been linked together and cleared to 0. +@comm +Same as <p mget>(). However, content in all mbufs and clusters have been cleared to 0. +@ex The following example demonstrates how to use this function | + register struct rtl_mBuf *m; + m= mBuf_getCleared(MBUF_DONTWAIT | MBUF_ONLY, 0, 5); //allocate 5 mbufs without blocking. + if (!m) + return NULL; + + @xref + <c mBuf_get>, <c mBuf_getm>, <c mBuf_driverGet> + */ + + +extern uint32 mBuf_driverGet(uint32 Nmbuf,struct rtl_mBuf **ppFirstMbuf, struct rtl_mBuf **ppLastMbuf); +/* +@func uint32 | mBuf_driverGet| Driver specific. Get multiple mbufs without blocking +@parm uint32 |Nmbuf | Number of mbufs requesting +@parm struct rtl_mBuf ** |ppFirstMbuf | Returns a pointer which points to the first mbuf allocated. +@parm struct rtl_mBuf ** | ppLastMbuf | Returns a pointer which points to the last mbuf allocated. +@rdesc Returns number of mbufs successfully allocated. +@comm +An optimized mBuf_get() for driver. <p ppFirstMbuf> and <p ppLastMbuf> should not be NULL!! +mbuf and cluster not initialized to zero. Only required fields in mBuf_driverGet have been properly filled. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf * localTempMbufHead, * localTempMbufTail; + int32 allocated; + requested = 5; + allocated= mBuf_driverGet(requested, &localTempMbufHead, &localTempMbufTail); + if (allocated!=requested) + printf("Can't allocate all 5 mbufs in driver\n") + + @xref + <c mBuf_get>, <c mBuf_getm>, <c mBuf_getCleared> + */ + +extern struct rtl_mBuf *mBuf_getm(struct rtl_mBuf *m, uint32 len, int32 how, int32 unused); + +/* +@func struct rtl_mBuf * | mBuf_getm| allocate <p len>-worth of mbuf clusters and return a pointer to the top +of the allocated chain. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. Could be NULL. +@parm uint32 |len | Number of data bytes requesting. +@parm int32 |how | <p MBUF_WAIT> or <p MBUF_DONTWAIT> and/or <p M_ALLOCPKTHDR>. +@parm int32 |unused | unused now. Keep for backward compatibility. +@rdesc Returns return a pointer to the head of the allocated chain. +@rvalue <p NULL> | Allocation failed. +@rvalue <p n> | The memory address of first mbuf allocated. +@comm +If <p m> is non-null, then it is an mbuf chain to which we want <p len> bytes worth of clusters and their associating mbufs be attached, and so +if allocation is successful, a pointer to m is returned. i.e <p n> = <p m>) + +If <p m> is null, <p len> bytes worth of clusters and their associating mbufs would be allocated. + +If <p how> has M_ALLOCPKTHDR bit set, <p mBuf_getm> also allocates a pkthdr with the mbuf chain. +If <p how> has MBUF_DONTWAIT bit set, and we can't get a pkthdr immediately, return NULL. +If <p how> has MBUF_WAITOK bit set, and we can't get a pkthdr right away, block waiting until our request is satisfied. + +M_BUFONLY can't be used with mBuf_getm, in this case, you should use mBuf_get() and calculate how many mbufs you need on your own. + +@ex The following example demonstrates how to use this function | + m = mBuf_getm(m, size, MBUF_WAITOK, 0); + if (m == NULL) + return ENOBUFS; + + @xref + <c mBuf_get> , <c mBuf_driverGet>, <c mBuf_getCleared> + */ + + +extern struct rtl_mBuf *mBuf_getPkthdr(struct rtl_mBuf *m, int32 how); +/* +@func struct rtl_mBuf * | mBuf_getPkthdr| Allocate a packet header for mbuf chain <p m> +@parm struct rtl_mBuf * | m | Pointer to the mbuf chain. +@parm int32 |how | <p MBUF_WAIT> or <p MBUF_DONTWAIT> + +@rdesc Returns the address of mbuf <p m> that holds a packet header. +@rvalue <p NULL> | Can't allocate a pkthdr for mbuf <p m>. +@rvalue <p m> | A pkthdr is allocated to mbuf <p m>. +@comm + +Given an mbuf <p m>, allocate a packet header (pkthdr) structure for <p m> and makes <p m> the owner of this pkthdr. +If there is already a pkthdr owned by some mbuf after m on the same mbuf chain, m becomes the owner of that pkthdr without getting a new one. Corresponding pkthdr fields are modified accordingly. + +If <p how> has MBUF_DONTWAIT bit set, and we can't get a pkthdr immediately, return NULL. +If <p how> has MBUF_WAITOK bit set, and we can't get a pkthdr right away, block waiting until our request is satisfied. + + + mBuf_getPkthdr may wake up other sleeping threads waiting for pkthdrs if any + +@ex The following example demonstrates how to use this function | + if (!mBuf_getPkthdr(pNewMbuf, MBUF_DONTWAIT)) //get a pkthdr + goto nospace; + @xref + <c mBuf_driverGetPkthdr> + */ + +extern uint32 mBuf_driverGetPkthdr(uint32 Npkthdr,struct rtl_pktHdr **ppHeadPkthdr, struct rtl_pktHdr **ppTailPkthdr); +/* +@func uint32 | mBuf_driverGetPkthdr| Driver specific. Get multiple pkthdrs without blocking +@parm uint32 |Npkthdr | Number of pkthdrs requesting +@parm struct rtl_pktHdr ** |ppHeadPkthdr | Returns a pointer which points to the first pkthdr allocated. +@parm struct rtl_pktHdr ** | ppTailPkthdr | Returns a pointer which points to the last pkthdr allocated. +@rdesc Returns number of pkthdrs successfully allocated. +@comm +This function is dedicated for driver. <p ppHeadPkthdr> and <p ppTailPkthdr> should not be NULL!! + +@ex The following example demonstrates how to use this function | + struct rtl_pktHdr * localTempPkthdrHead, * localTempPkthdrTail; + int32 allocated; + requested = 5; + allocated= mBuf_driverGetPkthdr(requested, &localTempPkthdrHead, &localTempPkthdrTail); + if (allocated!=requested) + printf("Can't allocate all 5 mbufs in driver\n") + + @xref + <c mBuf_getPkthdr> + */ + + +extern void mBuf_freeMbuf(struct rtl_mBuf *m); +/* +@func struct rtl_mBuf * | mBuf_freeMbuf | Free a single mbuf <p m>.. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@rdesc None +@comm + Free a single mbuf. Leave assocated pkthdr or cluster, if any, intact. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + mBuf_freeMbuf(m); +@xref + <c mBuf_freeMbufChain> , <c mBuf_driverFreeMbufChain>, <c mBuf_freePkthdr>, <c mBuf_driverFreePkthdr> + */ + + +extern int32 mBuf_attachCluster(struct rtl_mBuf *m, void *buffer, uint32 id, uint32 size, uint16 datalen, uint16 align); +/* +@func struct rtl_mBuf * | mBuf_attachCluster | Attach a cluster to mbuf <p m> +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm void * | buffer | Address of cluster to be associated with mbuf <p m>. +@parm uint32 | id | Identifier of cluster to be associated with mbuf <p m>. +@parm uint32 | size | Size of cluster to be associated with mbuf <p m>. +@parm uint32 | datalen | Byte count of data already in packet. +@parm uint16 | align | byte offset of first data byte in cluster <p buffer>,if any,from which <p m> attaches to. Default is 0. +@rvalue <p SUCCESS> | cluster has been successfully attached with mbuf <p m>. +@rvalue <p FAILED> | Failed to attach cluster with mbuf <p m> +@comm +Attach a cluster to mbuf <p m>. If there is already a cluster attached with mbuf <p m>, return FAILED. +If <p align> is non-zero, mbuf <p m> sets it's data pointer from which <p m>'s data pointer attaches. +@xref + <c mBuf_get> , <c mBuf_driverGetMbufChain>, <c mBuf_GetPkthdr>, <c mBuf_getm> + */ + + +extern int32 mBuf_freeOneMbufPkthdr(struct rtl_mBuf *m, void **buffer, uint32 *id, uint16 *size); +/* +@func struct int32 | mBuf_freeOneMbufPkthdr | Free a single mbuf <p m> and associated pkthdr, if any. Returns information of cluster associated. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm void * | buffer | placeholder for address of cluster associated on return. +@parm void * | id | placeholder of identifier of cluster associated on return. +@parm uint16 * | size | placeholder of size of cluster associated on return. +@rdesc Returns number of mbufs being freed +@rvalue <p n> | number of mbufs being freed +@comm + Free a single mbuf and associated pkthdr, if any. Place the successor, if any, in <p n>. + Note that this function DOES NOT free the associated cluster. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + void *buffer ; + uint32 size, id; + n = mBuf_freeOne(m,&buffer,&id, &size); + +@xref + <c mBuf_freeMbufChain> , <c mBuf_driverFreeMbufChain>, <c mBuf_freePkthdr>, <c mBuf_driverFreePkthdr>, <c mBuf_freeOne> + */ + + +extern struct rtl_mBuf *mBuf_freeOne(struct rtl_mBuf *m); + +/* +@func struct rtl_mBuf * | mBuf_freeOne | Free a single mbuf <p m> and associated cluster storage. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@rdesc Returns address of next mbuf if any +@rvalue <p NULL> | <p m> has been freed and there isn't any successing mbufs. +@rvalue <p n> | The address of next mbuf after <p m>. +@comm + Free a single mbuf and associated external storage. Place the successor, if any, in <p n>. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + n = mBuf_freeOne(m); + +@xref + <c mBuf_freeMbufChain> , <c mBuf_driverFreeMbufChain>, <c mBuf_freePkthdr>, <c mBuf_driverFreePkthdr> + */ + +extern uint32 mBuf_freeMbufChain(register struct rtl_mBuf *m); + +/* +@func struct rtl_mBuf * | mBuf_freeMbufChain| Free the whole mbuf chain started from <p m> +@parm struct rtl_mBuf * | m | Pointer to the mbuf chain. +@rdesc Returns number of mbufs being freed in mbuf chain <p m>. +@rvalue <p n> | The number of mbufs being freed. If <p n> is 0, <p m> is not freed. +@comm + Free the whole mbuf chain starting from <p m>. + +@devnote Return type changed from void to int32 to provide more information. +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *m; + int32 n; + m = mBuf_get(MBUF_DONTWAIT, 0, 5); + n = mBuf_freeMbufChain(m); + if (n!=5){ + //Do error handling... + } +@xref + <c mBuf_freeOne> , <c mBuf_driverFreeMbufChain>, <c mBuf_freePkthdr>, <c mBuf_driverFreePkthdr> + */ + +extern uint32 mBuf_driverFreeMbufChain(struct rtl_mBuf *pFirstMbuf); +/* +@func uint32 | mBuf_driverFreeMbufChain| Free the whole mbuf chain started from <p m> +@parm struct rtl_mBuf * | m | Pointer to the mbuf chain. +@rdesc Returns number of mbufs being freed in mbuf chain <p m>. +@rvalue <p n> | The number of mbufs being freed. If <p n> is 0, <p m> is not freed. +@comm + Free the whole mbuf chain starting from <p m>. To be used only in driver. +@ex The following example demonstrates how to use this function | + struct rtl_mBuf * localTempMbufHead, * localTempMbufTail; + int32 allocated; + requested = 5; + allocated= mBuf_driverGet(requested, &localTempMbufHead, &localTempMbufTail); + if (allocated==requested){ + n = mBuf_driverFreeMbufChain(localTempMbufHead); + if(n==allocated) + printf("All mbufs successfully freed in driver\n"); + } +@xref + <c mBuf_freeOne> , <c mBuf_driverFreeMbufChain>, <c mBuf_freePkthdr>, <c mBuf_driverFreePkthdr> + */ + + + +extern void mBuf_freePkthdr(struct rtl_pktHdr *ph); +/* +@func struct rtl_pktHdr * | mBuf_freePkthdr| Free a pkthdr alone. +@parm struct rtl_pktHdr * |ph | The pkthdr to be freed. +@rdesc No return value +@comm Free a pkthdr alone. Callers should be aware that this is NOT the normal way to free a pkthdr with mbufs attached. +You should use <p mBuf_freeOne> or <p mBuf_freeMbufChain> to free pkthdrs attached with mbuf chains. This function is usd once only in TCP module. +@devnote +Caller of this function should remove the links between mbufs and pkthdrs on their own before <p mBuf_freePkthdr> is called. +@xref <c mBuf_freeOne> , <c mBuf_freeMbufChain>, <c mBuf_driverFreeMbufChain>, <c mBuf_driverFreePkthdr> + */ + +uint32 mBuf_driverFreePkthdr(struct rtl_pktHdr *ph, uint32 Npkthdr, struct rtl_pktHdr **ppHeadPkthdr); +/* +@func uint32 | mBuf_driverFreePkthdr| Driver specific. Free multiple pkthdrs without blocking +@parm struct rtl_pktHdr * |ph | The first pkthdr to be freed +@parm uint32 |Npkthdr | Number of pkthdrs to be freed +@parm struct rtl_pktHdr ** |ppHeadPkthdr | Returns next un-freed pkthdr, if any. +@rdesc Returns number of pkthdrs successfully freed. +@comm +This function is dedicated for driver. <p ph> should not be NULL!! + + @xref + <c mBuf_freeOne> , <c mBuf_freeMbufChain>, <c mBuf_driverFreeMbufChain>, <c mBuf_freePkthdr> + */ + +extern struct rtl_mBuf *mBuf_adjHead(struct rtl_mBuf *, uint32 req_len); +/* +@func struct rtl_mBuf * | mBuf_adjHead | Remove <p req_len> bytes of data from head the mbuf chain pointed to by <p m>. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. <p m> doesn't need to be the first mbuf in chain. +@parm int32 | req_len | Number of data bytes to be removed +@rdesc m_adj returns the address of first mbuf after trimming data. +@rvalue <p NULL> | Can't adjust length of mbuf. <p m> might 1)be NULL 2)have no clusters. +@rvalue <p m> | When success, the first mbuf <p m> where user can read/write data is returned. +@comm +Remove <p req_len> bytes of data from the head of mbuf chain <p m>. If user removed all +data bytes in the whole packet, <p m> is returned. + +@devnote If any clusters, after m_adj, is totally unused (ie. m_len=0), +the m_data pointer would be reset to m_extbuf and the mbuf would NOT be freed. + +@xref + <c mBuf_adjTail>, <c mBuf_trimHead>, <c mBuf_trimTail> + */ + +extern struct rtl_mBuf *mBuf_adjTail(struct rtl_mBuf *, uint32 req_len); +/* +@func struct rtl_mBuf * | mBuf_adjTail | Remove <p req_len> bytes of data from tail of the mbuf chain pointed to by <p m>. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. <p m> doesn't need to be the first mbuf in chain. +@parm int32 | req_len | Number of data bytes to be removed +@rdesc m_adj returns the address of mbuf which contains the last data byte. +@rvalue <p NULL> | Can't adjust length of mbuf. <p m> might 1)be NULL 2)have no clusters or <p req_len> is 0 +@rvalue <p m> | When success, the address of the mbuf which hold the last data byte is returned. +@comm +Remove <p req_len> bytes of data from the tail of mbuf chain <p m>. If user removed all +data bytes in the whole packet, <p m> is returned. + +@devnote If any clusters, after m_adj, is totally unused (ie. m_len=0), +the m_data pointer would be reset to m_extbuf and the mbuf would NOT be freed. + +@xref + <c mBuf_adjHead>, <c mBuf_trimHead>, <c mBuf_trimTail> + */ + +extern struct rtl_mBuf *mBuf_trimHead(struct rtl_mBuf *, uint32 req_len); +/* +@func struct rtl_mBuf * | mBuf_trimHead | Same as mBuf_adjHead, but also frees unused mbufs and clusters +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. <p m> doesn't need to be the first mbuf in chain. +@parm int32 | req_len | Number of data bytes to be trimmed from head. +@rdesc mBuf_trimHead returns the address of first mbuf after trimming. +@rvalue <p NULL> | Can't adjust length of mbuf or the whole mbuf chain is trimmed and freed. +@rvalue <p m> | When success, the first mbuf <p m> where user can read/write data is returned. +@comm +Same as mBuf_adjHead, but also frees unused mbufs and clusters + +@devnote mBuf_trimHead is implemented with mBuf_split and mBuf_freeMbufChain. It first splits the mbuf +to two mbuf chains from indicated position and frees the first one. +There is a possible risk that mBuf_trimHead may fail when the mbuf chain <p m> consumes all mbufs and no free mbufs +is available for mBuf_split to work correctly. + +@xref + <c mBuf_adjHead>, <c mBuf_adjTail>, <c mBuf_trimTail> + */ + +extern struct rtl_mBuf *mBuf_trimTail(struct rtl_mBuf *, uint32 req_len); +/* +@func struct rtl_mBuf * | mBuf_trimTail | Same as mBuf_adjTail, but also frees unused mbufs and clusters +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. <p m> doesn't need to be the first mbuf in chain. +@parm int32 | req_len | Number of data bytes to be trimmed from tail. +@rdesc mBuf_trimTail returns the address <p m>. +@rvalue <p NULL> | Can't adjust length of mbuf or the whole mbuf chain is trimmed and freed. +@rvalue <p m> | When success, returns the first mbuf <p m> with data. +@comm +Same as mBuf_adjTail, but also frees unused mbufs and clusters + +@devnote mBuf_trimTail is implemented with mBuf_split and mBuf_freeMbufChain. It first splits the mbuf +to two mbuf chains from indicated position and frees the latter one. +There is a possible risk that mBuf_trimTail may fail when the mbuf chain <p m> consumes all mbufs and no free mbufs +is available for mBuf_split to work correctly. + +@xref + <c mBuf_adjHead>, <c mBuf_adjTail>, <c mBuf_trimTail> +*/ + + + +extern int32 mBuf_copyToMbuf(struct rtl_mBuf *, uint32 offset, uint32 len, int8 *cp); + +/* +@func int32 | mBuf_copyToMbuf | Copy <p len> bytes of data from user's buffer <p cp> to mbuf chain <p m>, started form offset <p offset>. +@parm struct rtl_mBuf * | m | Address of the mbuf chain. +@parm uint32 |offset | Starting byte to be copied in mbuf chain <p m>. Start from 0 +@parm uint32 |len | Number of bytes to be copied from <p cp> +@parm int8 * |cp | Address of user's buffer. +@rdesc Returns number of bytes successfully copied +@rvalue <p -1> | Failed. +@rvalue <p n> | <p n> bytes have been copied from <p cp> into indicated mbuf chain <p m> +@comm +Copy <p len> bytes from user's buffer <p cp>, to the indicated mbuf chain +<p m> beginning from the <p offset>-th data byte in mbuf chain. +If there aren't at least 'offset' bytes in mbuf chain, -1 is returned. +mBuf_copyToMbuf() extends mbuf chain if neccessary. +@comm +Be careful, when clusters are allocated externally by OS, mbuf module doesn't know which mbuf +is the first referee and owns the write priviledge to cluster. Therefore, write priviledge +is granted to ALL cluster referees. + +@ex The following example demonstrates how to use this function | + #define SIZE 100 + int32 i; + int8 my_buffer[SIZE]; + for(i=0; i<SIZE; i++) + my_buffer[i] = i; + if (100!=mBuf_copyToMbuf(m, 10, 100, my_buffer)) //copy 100 bytes from my_buffer to mbuf m, started from the 10th bytes in mbuf + printf("Can't copy all data!"); + @xref + <c mBuf_copyToUserBuffer> + */ + + + +extern int32 mBuf_copyToUserBuffer(struct rtl_mBuf *m, uint32 off, uint32 len, int8 * cp); + +/* +@func int32 | mBuf_copyToUserBuffer | Copy some data from an mbuf chain <p m> to user's buffer <p cp>. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm uint32 |offset | The number of starting data byte in mbuf chain <p m>. Start from 0. +@parm uint32 |len | The number of data bytes to be copied. If <p len>=M_COPYALL, then copy all data till the end of mbuf chain. +@parm int8 * |cp | User specified buffer address. +@rdesc Returns number of bytes successfully received and copied to user's buffer +@rvalue <p -1> | Failed. +@rvalue <p n> | <p n> bytes have been copied from <p m> into indicated buffer <p cp> successfully. +@comm +Copy data from an mbuf chain starting from the <p offset>-th data byte, +continuing for <p len> bytes, into the indicated buffer <p cp>. User should be sure that there is enough free space in +the specified buffer <p cp>. + +@ex The following example demonstrates how to use this function | + int8 my_buffer[100]; + mBuf_copyToUserBuffer(m, 10, 100, my_buffer); //copy 100 bytes from the 10-th byte in mbuf to user's cp buffer. + + @xref + <c mBuf_copyToMbuf> + */ + +extern struct rtl_mBuf *mBuf_cloneMbufChain(struct rtl_mBuf *pThisMbuf, int32 iOffset, + int32 iLength, int32 iWait); + +/* +@func struct rtl_mBuf * | mBuf_cloneMbufChain | Clone a part of mbuf chain <p m> +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm int32 |offset | The number of starting data byte in mbuf chain <p m>. Start from 0 +@parm int32 |len | The number of data bytes to be cloned. If <p len>=M_COPYALL, then clone all data till the end of mbuf chain. +@parm int32 |how | <p MBUF_WAIT> or <p MBUF_DONTWAIT> and/or <p M_ALLOCPKTHDR> +@rdesc Returns address of the new, cloned mbuf chain <p n>. +@rvalue <p NULL> | Can't clone mbuf chain <p m>. +@rvalue <p n> | The address of cloned mbuf chain <p n>. Data in <p n> is read only. +@comm +Make a clone of an mbuf chain starting from <p offset>-th byte from the beginning, +continuing for <p len> bytes. If <p len> is M_COPYALL, then clone to end of the whole mbuf chain. (You may choose to use the optimized mBuf_clonePacket() in this case) +The <p how> parameter is a choice of MBUF_WAIT or MBUF_DONTWAIT and/or M_ALLOCPKTHDR by the caller. +If M_ALLOCPKTHDR flag is given, a new pkthdr would be allocated for duplicated packet. + +Note that the clone is read-only, The new mbuf chain <p n> only shares cluster data with <p m>. +<p n> can only read cluster data, but not write. <p m> still owns write priviledge. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + + n = mBuf_cloneMbufChain(m, 20, M_COPYALL, MBUF_WAIT); + if (n != NULL) { + // do following processing + } + @xref + <c mBuf_clonePacket>, <c mBuf_dupPacket>, <c mBuf_cloneMbufChain> + */ + +extern struct rtl_mBuf *mBuf_dupMbufChain(struct rtl_mBuf *pMbufChain, int32 iOffset, int32 iLength, int32 flag); + +/* +@func struct rtl_mBuf * | mBuf_dupMbufChain | Duplicate a part of mbuf chain <p m> +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm int32 |offset | The number of starting data byte in mbuf chain <p m>. Start from 0 +@parm int32 |len | The number of data bytes to be cloned. If <p len>=M_COPYALL, then duplicate all data till the end of mbuf chain. +@parm int32 |how | <p MBUF_WAIT> or <p MBUF_DONTWAIT> and/or <p M_ALLOCPKTHDR> +@rdesc Returns address of the new, duplicated mbuf chain <p n>. +@rvalue <p NULL> | Can't duplicate mbuf chain <p m>. +@rvalue <p n> | The address of duplicated mbuf chain <p n>. Data in <p n> is writable. +@comm +Duplicate an mbuf chain starting from <p offset>-th byte from the beginning, +continuing for <p len> bytes. If <p len> is M_COPYALL, then duplicate to end of the whole mbuf chain. (You may choose to use the optimized mBuf_dupPacket() in this case) +The <p how> parameter is a choice of MBUF_WAIT or MBUF_DONTWAIT and/or M_ALLOCPKTHDR by the caller. +If M_ALLOCPKTHDR flag is given, a new pkthdr would be allocated for duplicated packet. + +Note that the duplicated mbuf is writable.. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + + n = mBuf_dupMbufChain(m, 20, M_COPYALL, MBUF_WAIT); + if (n != NULL) { + // do following processing + } + @xref + <c mBuf_clonePacket>, <c mBuf_dupPacket>, <c mBuf_cloneMbufChain> + */ + + + +extern struct rtl_mBuf *mBuf_clonePacket(struct rtl_mBuf *pMbuf, int32 iHow); + +/* +@func struct rtl_mBuf * | mBuf_clonePacket | Clone the entire packet <p m> +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm int32 |how | <p MBUF_WAIT> or <p MBUF_DONTWAIT> +@rdesc Returns address of the new mbuf chain <p n>. +@rvalue <p NULL> | Can't clone mbuf chain <p m>. +@rvalue <p n> | The address of copied mbuf chain <p n>. Data in <p n> is read only. +@comm +Clone an entire mbuf chain <p m>, including the packet header (which must be present). +An optimization of the common case `mBuf_cloneMbufChain(m, 0, M_COPYALL, how)'. +The new cloned packet always allocates a new pkthdr. +Note that the copy is read-only, because clusters are not copied, only their reference counts are incremented. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + n = mBuf_clonePacket(m, MBUF_WAIT); + if (n != NULL) { + // do following processing + } + @xref + <c mBuf_dupPacket>, <c mBuf_cloneMbufChain>, <c mBuf_dupMbufChain> + */ + +extern struct rtl_mBuf *mBuf_dupPacket(struct rtl_mBuf *pMbuf, int32 iHow); + +/* +@func struct rtl_mBuf * | mBuf_dupPacket | Duplicate an mbuf chain <p m>, including its data, into a completely new chain <p n> +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm int32 |how | <p MBUF_WAIT> or <p MBUF_DONTWAIT> +@rdesc Returns address of the new mbuf chain <p n>. +@rvalue <p NULL> | Can't duplicate mbuf chain <p m>. +@rvalue <p n> | The address of copied mbuf chain <p n>. Data in <p n> is writable. +@comm +Duplicate an mbuf chain <p m> into a completely new chain <p n>, including +copying data in any <p m>'s mbuf clusters. +The new duplicated packet always allocates a new pkthdr. +Use this instead of mBuf_clonePacket() when you need a writable copy of an mbuf chain. + +@ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + n = mBuf_dupPacket(m, MBUF_WAIT); + if (n != NULL) { + // do following processing + } + @xref + <c mBuf_clonePacket> , <c mBuf_copyToUserBuffer>, <c mBuf_cloneMbufChain> + */ + + + + + +extern struct rtl_mBuf *mBuf_prepend(struct rtl_mBuf *m, uint32 plen, int32 how); + +/* +@func struct rtl_mBuf * | mBuf_prepend | Arrange to prepend space of size <p plen> to mbuf <p m>. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm uint32 |plen | Number of bytes to be prepended before <p m> +@parm int32 |how | <p MBUF_WAIT>, <p MBUF_DONTWAIT>, <p M_GETNEWMBUF> +@rdesc Returns address of the first mbuf. +@rvalue <p NULL> | Can't allocate memory or parameter problem. +@rvalue <p n> | The address of first mbuf after prepending. +@comm +Arrange to prepend space of size <p plen> to mbuf <p m>. + If new mbufs must be allocated, <p how> specifies whether to wait or not. When user calls mBuf_prepend, the + data length recorded in mbufs and pkthdr is incremented accordingly. + +By default, mBuf_prepend uses any leading free space before allocating any new clusters. +But if <p M_GETNEWMBUF> is set, mBuf_prepend allocates new mbufs directly and leaves any leading free buffer space as is. + +If <p how> has MBUF_DONTWAIT bit set, and we can't get all buffers immediately, return NULL. +If <p how> has MBUF_WAITOK bit set, and we can't get all buffers right away, block waiting until our request is satisfied. + +M_BUFONLY can't be used with mBuf_prepend. + +@ex The following example demonstrates how to use this function | + m0 = mBuf_prepend(m0, PPP_HDRLEN, MBUF_DONTWAIT | M_GETNEWMBUF); + if (m0 == 0) { + error = ENOBUFS; + goto bad; + } + @xref <c mBuf_cat>, <c mBuf_padding> + + */ + +extern struct rtl_mBuf *mBuf_padding(struct rtl_mBuf *m, uint32 plen, int32 how); +/* +@func struct rtl_mBuf * | mBuf_padding | Arrange to append space of size <p plen> to mbuf <p m>. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm uint32 |plen | Number of bytes to append at <p m> +@parm int32 |how | <p MBUF_WAIT> or <p MBUF_DONTWAIT> +@rdesc Returns address of the last mbuf padded. +@rvalue <p NULL> | Can't allocate memory or parameter problem. +@rvalue <p n> | The address of last mbuf after padding +@comm +Arrange to append space of size <p plen> to mbuf <p m>. + If new mbufs must be allocated, <p how> specifies whether to wait or not. When user calls mBuf_padding, the + data length recorded in mbufs and pkthdr are incremented accordingly. + + M_BUFONLY can't be used with mBuf_padding. +@devnote API CHANGED: If <p how> is MBUF_DONTWAIT and allocation fails, NULL is returned. +Original mbuf <p m> is intact. + +@ex The following example demonstrates how to use this function | + m0 = mBuf_padding(m, (ETHER_MIN_LEN-ETHER_CRC_LEN-len), MBUF_DONTWAIT); + if (m0 == 0) { + error = ENOBUFS; + goto bad; + } +@xref <c mBuf_split>, <c mBuf_cat>, <c mBuf_getm>, <c mBuf_prepend>, <c mBuf_split> + + + */ + + +extern struct rtl_mBuf *mBuf_cat(struct rtl_mBuf *m, struct rtl_mBuf *n); + +/* +@func struct rtl_mBuf * | mBuf_cat | Concatenate mbuf chain <p n> to <p m>. +@parm struct rtl_mBuf * | m | mbuf chain to be appended. +@parm struct rtl_mBuf * | n | mbuf chain to be appended after <p m> +@rdesc Returns the address of <p m> or NULL if failed. +@rvalue <p NULL> | Can't concatenate two mbuf chain +@rvalue <p m> | When success, the address of <p m> is returned.. +@comm +Concatenate mbuf chain <p n> to <p m>. +Total packet length of <p m> would be adjusted accordingly. However, <p n>'s control header, if any, would be freed +@xref <c mBuf_split>, <c mBuf_padding>, <p mBuf_getm> + + */ + + +extern int32 mBuf_pullup(struct rtl_mBuf *, int32); + +/* +@func int32 | mBuf_pullup| Rearange an mbuf chain so that <p len> bytes are contiguous + in <p m>'s first cluster. +@parm struct rtl_mBuf * | m | Pointer to an mbuf chain. +@parm int32 |len | The number of databytes requested to put in <p m>'s first cluster. <p len> should not exceed the size of a cluster buffer (256 bytes). +@rdesc Returns total data bytes in the first mbuf cluster. +@rvalue <p n> | The number of data bytes in <p m>'s first cluster. If <p n> is less than <p len>, + that means <p mBuf_pullup> can't pull up all <p len> bytes requested because there isn't + so much data in mbuf chain. +@comm Original BSD4.4 note: Rearange an mbuf chain so that <p len> bytes are contiguous and in <p m>'s cluster. +Successing mbufs are adjusted accordingly. If the return value <p n> is smaller than requested <p len>, +maybe there isn't enough data bytes in the mbuf chain <p m>, or maybe the requested value <p len> exceeds +the maximum capacity for a single cluster. + +Our implementation note: +(cfliu 2002.02.19)This function is important in traditional BSD networking stack because +original mbuf can't do dtom() if data is saved in cluster. This is not the +case here since we offer a back pointer from cluster to mbuf via cltag_mbuf field. +However, this function is still useful if we want to collect continous databytes from later clusters +to the specified mbuf's cluster. The maximum number of <p len> should be less than a cluster +can hold (ie. len less than or equal to m_clusterSIze) + +(2002.08.11) If 1) requested length <p len> is smaller than m_clusterSize, and 2) there are enough data in this mbuf chain. However, the +trailing space in <p m> is not large enough, <p mBuf_pullup> will move m's data upward first and then copy requested data from latter clusters + +@devnote This function is different from traditional BSD mbuf code. When pull up fails, the mbuf chain will not be freed, +and the return value has been changed to an integer instead of a pointer to mbuf structure. + +@ex The following example demonstrates how to use this function | + int32 n; + + n = mBuf_pullup(m, 128); + if (n < 128) { + //There isn't so much data in mbuf chain. + } + @xref + <c m_pulldown> + */ + + +struct rtl_mBuf *mBuf_split(register struct rtl_mBuf *m0, uint32 len0, int32 wait); + +/*@func struct rtl_mBuf * | mBuf_split | Partition an mbuf chain in two pieces. Data is cloned + @parm struct rtl_mBuf * | m | Pointer to an mbuf chain + @parm int32 | len | The number of last data byte to remain in original mbuf chain <p m> + @parm int32 | wait | <p MBUF_DONTWAIT> or <p MBUF_WAIT> + @rdesc Returns a pointer to the splited mbuf chain <p n> + @rvalue NULL | Can't split the mbuf chain + @rvalue <p n> | Success. <p n> is the address of second mbuf chain. It holds all data bytes after the <p len>-th byte in <p m>. + @comm Partition an mbuf chain <p m> into two pieces, returning the tail mbuf chain <p n>. In case of failure, it returns NULL and + attempts to restore the chain to its original state. Data in clusters are NOT copied, but cloned only. + + @ex The following example demonstrates how to use this function | + struct rtl_mBuf *n; + + n = mBuf_split(m, off, MBUF_DONTWAIT); + if (n == NULL) { + goto bad; + } + @xref + <c mBuf_cat>, <c mBuf_padding>, <c mBuf_getm> + + */ +void mBuf_getBMjmpTable(uint8 *pat, uint16 *jump_tbl,uint16 patLen, uint8 caseSensitive); +int32 mBuf_BMpatternMatch(struct rtl_mBuf *m, uint32 len, uint8 *delimiter, uint32 delimitLen, uint16 *jmp_tbl, uint8 caseSensitive); + +#define MBUF_GETLEN(m) ((m)? ((m)->m_len : -1) +/* +@func MACRO | MBUF_GETLEN | Get total number of data bytes in the mbuf <p m> +@parm struct rtl_mBuf * |m | Indicate the packet +@rdesc Returns data length of the mbuf +@rvalue -1 | Failed. +@rvalue <p length>| The actual length of data in <p m> +@comm + Get total number of data bytes in the mbuf <p m> +@xref <c mBuf_getPktlen> +*/ + + + struct rtl_mBuf *mBuf_attachHeader(void *buffer, uint32 id, uint32 bufsize,uint32 datalen, uint16 align); +struct rtl_mBuf *mBuf_attachHeaderJumbo(void *buffer, uint32 id, uint32 bufsize,uint32 datalen); + +int32 mBuf_setNICRxRingSize(uint32 size); +extern int32 mBuf_reserve(struct rtl_mBuf * m, uint16 headroom); + + +#define MBUF_SET_PKTHDRFLAGS(m, Flags) do{\ + assert((m));\ + assert(ISSET((m)->m_flags, MBUF_USED));\ + assert((m)->m_pkthdr);\ + MBUF_SETPKTHDRFIELD16(((memaddr *)&(m)->m_pkthdr->ph_flags), (Flags));\ + }while(0) + + +/* +@func MACRO | MBUF_SET_PKTHDRFLAGS | Set packet specific flags for ASIC processing +@parm struct rtl_mBuf * |m | Indicate the packet +@parm uint32 |Flags | flag to be set +@rdesc None +@comm +Set packet specific flags for ASIC processing. This overwrites original flag value. If you are adding flag bits rather than reseting it, +remember to save its old value first + +@xref <c MBUF_GET_PKTHDRFLAGS> +*/ + + +#define MBUF_GET_PKTHDRFLAGS(m) (MBUF_CHECKPKTHDR((m))? MBUF_GETPKTHDRFIELD16((memaddr *)(&m->m_pkthdr->ph_flags)):-1) +/* +@func MACRO | MBUF_GET_PKTHDRFLAGS | Get packet specific flags set by ASIC +@parm struct rtl_mBuf * |m | Indicate the packet +@rdesc Returns the result of execution +@rvalue -1 | Failed. <p m> might have no pkthdrs. +@rvalue FLAGS | Returns the flags. +@comm +Get packet specific flags set by ASIC + +@xref <c MBUF_SET_PKTHDRFLAGS> +*/ + +#define MBUF_SET_PORTLIST(m,Portlist) do{\ + assert((m));\ + assert(ISSET((m)->m_flags, MBUF_USED));\ + assert((m)->m_pkthdr);\ + (m)->m_pkthdr->ph_portlist = (Portlist);\ +}while(0) + +/* +@func MACRO | MBUF_SET_PORTLIST | Set outgoing port list +@parm struct rtl_mBuf * |m | Indicate the packet +@parm uint32 |Portlist | port list +@rdesc None +@comm Set outgoing port list +@xref <c MBUF_GET_PORTLIST> +*/ + +#define MBUF_GET_PORTLIST(m) (MBUF_CHECKPKTHDR((m))? ((m)->m_pkthdr->ph_portlist):-1) +/* +@func MACRO | MBUF_GET_PORTLIST | get incoming port list +@parm struct rtl_mBuf * |m | Indicate the packet +@rdesc Returns the result of execution +@rvalue 0 | Failed. <p m> might have no pkthdrs. +@rvalue Portlist | Returns incoming portlist. +@comm + get incoming port list + +@xref <c MBUF_SET_PORTLIST> +*/ + + +#define MBUF_SET_TRAPREASON(m, Reason) do{\ + assert((m));\ + assert(ISSET((m)->m_flags, MBUF_USED));\ + assert((m)->m_pkthdr);\ + MBUF_SETPKTHDRFIELD16(((memaddr *)&(m)->m_pkthdr->ph_reason), (Reason));\ +}while(0) + +/* +@func MACRO | MBUF_SET_TRAPREASON | Set packet trapping reason for ASIC processing +@parm struct rtl_mBuf * |m | Indicate the packet +@parm uint16 |Reason | Trapping reason +@rdesc None +@comm +Set packet trapping reason for ASIC processing + +@xref <c MBUF_GET_TRAPREASON> +*/ + +#define MBUF_GET_TRAPREASON(m) (MBUF_CHECKPKTHDR((m))? MBUF_GETPKTHDRFIELD16((memaddr *)(&m->m_pkthdr->ph_reason)):-1) +/* +@func MACRO | MBUF_GET_TRAPREASON | Get packet trapping reason set by ASIC +@parm struct rtl_mBuf * |m | Indicate the packet +@rdesc Returns the result of execution +@rvalue -1 | Failed. <p m> might have no pkthdrs. +@rvalue Reason | Returns trap reason +@comm +Get packet trapping reason set by ASIC + +@xref <c MBUF_SET_TRAPREASON> +*/ + +#define MBUF2DATAPTR(m, t) ((t)((m)->m_data)) +/* +@func MACRO | MBUF2DATAPTR | Given mbuf pointer 'm', returns address of m->m_data, and convert it to type 't' +@parm struct rtl_mBuf * |m | Pointer to an mbuf +@parm TYPE |t | A type to be casted +@rdesc Address of m->m_data +@comm +Given mbuf pointer 'm', returns address of m->m_data, and convert it to type 't' +@xref <c mBuf_data2Mbuf> +*/ + + +#define MBUF_ALIGN(m, len) do { \ + assert((m)->m_len==0);\ + assert(len>0);\ + assert(((m)->m_extsize - (len))>0);\ + (m)->m_data += ( (m)->m_extsize - (len)) & ~(sizeof(memaddr) - 1); \ +} while (0) + +/* +@func MACRO | MBUF_ALIGN | Align the m->m_data pointer from end of the cluster, for 'len' bytes. +@parm struct rtl_mBuf * |m | Pointer to an mbuf +@parm uint32 |len | Size to be aligned. +@rdesc None +@comm +Set the m_data pointer of a NEWLY-allocated cluster to place +an object of the specified size at the end of the mbuf, longword aligned. +@xref <c MBUF_RESERVE> +*/ + + +#define MBUF_RESERVE(m, len) do { \ + assert(len>0);\ + (m)->m_data += ( ((len) > (m)->m_extsize)? (m)->m_extsize : len); \ +} while (0) +/* +@func MACRO | MBUF_RESERVE | Reserve 'len' bytes from the beginning of the newly allocated cluster +@parm struct rtl_mBuf * |m | Pointer to an mbuf +@parm uint32 |len | Size to be aligned. +@rdesc None +@comm +Forward move the m_data pointer of a NEWLY-allocated cluster for 'len' bytes. +m_data won't move beyond m_extbuf + m_extsize, make sure 'len' you give is a reasonable value +@xref <c MBUF_ALIGN> +*/ +#endif /* !_MBUF_H_ */ + diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl8651_tblDrvProto.h b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl8651_tblDrvProto.h new file mode 100644 index 000000000..8dbb8483c --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl8651_tblDrvProto.h @@ -0,0 +1,584 @@ +/* +* Copyright c Realtek Semiconductor Corporation, 2002 +* All rights reserved. +* +* Program : Protocol Header rtl8651_proto.h +* Abstract : +* Author : Chih-Hua Huang (chhuang@realtek.com.tw) +* $Id: rtl8651_tblDrvProto.h,v 1.1 2007-12-21 10:29:52 davidhsu Exp $ +* +*/ + +#ifndef RTL8651_TBLDRV_PROTO_H +#define RTL8651_TBLDRV_PROTO_H + +#include <linux/in.h> +#include <net/rtl/rtl_types.h> + +/*========================================================================================== + * Ethernet Header for MAC ACL lookup + *==========================================================================================*/ +#define ETHER_ADDR_LEN 6 +struct ether_header { + uint8 ether_dhost[ETHER_ADDR_LEN]; + uint8 ether_shost[ETHER_ADDR_LEN]; + uint16 ether_type; +}; + +/* The number of bytes in the type field. */ +#define ETHER_TYPE_LEN 2 + +/* The length of the combined header. */ +#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) +#define ETHER_VLAN_HDR_LEN (ETHER_HDR_LEN+4) + + +#ifndef UTILITY_H /* pktproc/utility.h also defined this structure. */ +struct ether_addr { + uint8 octet[ETHER_ADDR_LEN]; +}; +#endif + +typedef struct pppoeHdr_s { + #ifdef _LITTLE_ENDIAN + uint8 type:4, ver:4; + #else + uint8 ver:4, type:4; + #endif + uint8 code; + uint16 sessionId, + length; //Length of the PPPoE payload, does not include Ethernet and PPPoE header + uint16 proto; //PPP protocol field +} pppoeHdr_t; + +typedef struct vlanHdr_s { +#ifdef _LITTLE_ENDIAN + uint16 vidh:4; + uint16 cfi:1; + uint16 priority:3; + uint16 vidl:8; +#else + uint16 priority:3; + uint16 cfi:1; + uint16 vidh:4; + uint16 vidl:8; +#endif + uint16 ether_type; +} vlanHdr_t; + + +/*========================================================================================== + * IP Header for IP ACL lookup + *==========================================================================================*/ +//#ifndef UTILITY_H /* pktproc/utility.h also defined this structure. */ +#if !defined(_LINUX_IN_H) +struct in_addr{ + uint32 s_addr; +}; + +/* AF_INET Supported IP Protocols*/ +#define IPPROTO_ICMP 1 +#define IPPROTO_IGMP 2 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 +#endif + +struct ip { + +#if 0 +union{ + uint8 _vhl; /* version << 4 | header length >> 2 */ +#ifdef _LITTLE_ENDIAN + struct { + uint8 _hl:4, /* header length */ + _ver:4; /* version */ + }s; +#else + struct { + uint8 _ver:4, /* version */ + _hl:4;/* header length */ + }s; +#endif + } vhl; + +#define ip_vhl vhl._vhl +#define ip_hl vhl.s._hl +#define ip_ver vhl.s._ver +#else + /* replace bit field */ + uint8 ip_vhl; +#endif + + uint8 ip_tos; /* type of service */ + uint16 ip_len; /* total length */ + uint16 ip_id; /* identification */ + uint16 ip_off; /* fragment offset field */ + uint8 ip_ttl; /* time to live */ + uint8 ip_p; /* protocol */ + uint16 ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; +typedef struct ip ip_t; + +#define IP_RF 0x8000 /* reserved fragment flag */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + + + +/*========================================================================================== + * IP Header for IP ACL lookup + *==========================================================================================*/ +struct icmp_ra_addr { + uint32 ira_addr; + uint32 ira_preference; +}; + +struct icmp { + uint8 icmp_type; /* type of message, see below */ + uint8 icmp_code; /* type sub code */ + uint16 icmp_cksum; /* ones complement cksum of struct */ + union { + uint8 ih_pptr; /* ICMP_PARAMPROB */ + struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ + struct ih_idseq { + uint16 icd_id; + uint16 icd_seq; + } ih_idseq; + uint32 ih_void; + + /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ + struct ih_pmtu { + uint16 ipm_void; + uint16 ipm_nextmtu; + } ih_pmtu; + + struct ih_rtradv { + uint8 irt_num_addrs; + uint8 irt_wpa; + uint16 irt_lifetime; + } ih_rtradv; + } icmp_hun; +#define icmp_pptr icmp_hun.ih_pptr +#define icmp_gwaddr icmp_hun.ih_gwaddr +#define icmp_id icmp_hun.ih_idseq.icd_id +#define icmp_seq icmp_hun.ih_idseq.icd_seq +#define icmp_void icmp_hun.ih_void +#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void +#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu +#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs +#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa +#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime + union { + struct id_ts { + uint32 its_otime; + uint32 its_rtime; + uint32 its_ttime; + } id_ts; + struct id_ip { + struct ip idi_ip; + /* options and then 64 bits of data */ + } id_ip; + struct icmp_ra_addr id_radv; + uint32 id_mask; + int8 id_data[1]; + } icmp_dun; +#define icmp_otime icmp_dun.id_ts.its_otime +#define icmp_rtime icmp_dun.id_ts.its_rtime +#define icmp_ttime icmp_dun.id_ts.its_ttime +#define icmp_ip icmp_dun.id_ip.idi_ip +#define icmp_radv icmp_dun.id_radv +#define icmp_mask icmp_dun.id_mask +#define icmp_data icmp_dun.id_data +}; + + +/* + * Definition of type and code field values. + */ +#define ICMP_ECHOREPLY 0 /* echo reply */ +#define ICMP_UNREACH 3 /* dest unreachable, codes: */ +#define ICMP_UNREACH_NET 0 /* bad net */ +#define ICMP_UNREACH_HOST 1 /* bad host */ +#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ +#define ICMP_UNREACH_PORT 3 /* bad port */ +#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ +#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ +#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ +#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ +#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ +#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ +#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ +#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ +#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ +#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */ +#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */ +#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */ +#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ +#define ICMP_REDIRECT 5 /* shorter route, codes: */ +#define ICMP_REDIRECT_NET 0 /* for network */ +#define ICMP_REDIRECT_HOST 1 /* for host */ +#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ +#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ +#define ICMP_ECHO 8 /* echo service */ +#define ICMP_ROUTERADVERT 9 /* router advertisement */ +#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ +#define ICMP_TIMXCEED 11 /* time exceeded, code: */ +#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ +#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ +#define ICMP_PARAMPROB 12 /* ip header bad */ +#define ICMP_PARAMPROB_ERRATPTR 0 /* error at param ptr */ +#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ +#define ICMP_PARAMPROB_LENGTH 2 /* bad length */ +#define ICMP_TSTAMP 13 /* timestamp request */ +#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ +#define ICMP_IREQ 15 /* information request */ +#define ICMP_IREQREPLY 16 /* information reply */ +#define ICMP_MASKREQ 17 /* address mask request */ +#define ICMP_MASKREPLY 18 /* address mask reply */ + +#define ICMP_MAXTYPE 18 + +/*========================================================================================== + * IP Header for IP ACL lookup + *==========================================================================================*/ +// igmp v3 group record +struct igmp_gr { + uint8 igmp_gr_rt; /* Record Type */ + uint8 igmp_gr_auxlen; /* aux data length */ + uint16 igmp_gr_nofs; /* number of sources */ + ipaddr_t igmp_gr_group; /* group address being reported */ + ipaddr_t src_list; /* first entry of src list */ + // auxiliary data is unused now + }; +struct igmp { + uint8 igmp_type; /* version & type of IGMP message */ + uint8 igmp_code; /* subtype for routing msgs */ + uint16 igmp_cksum; /* IP-style checksum */ + + union { + struct in_addr group; /* group address being presented (v1/v2/v3 query) */ + struct v3_report{ + uint16 resv; /* reserved */ + uint16 nofg; /* number of group records */ + } v3_report; + } grp; + + union { + struct query { + uint8 rsq; /* 4bit: reserved, 1bit: suppress router-side processing, 3bit: querier's robustness variable*/ +// uint8 resv:4; /* reserved */ +// uint8 s:1; /* suppress router-side processing */ +// uint8 qrv:3; /* querier's robustness variable */ + uint8 qqic; /* querier's query interval code */ + uint16 nofs; /* number of sources */ + ipaddr_t src_list; /* first entry of src list */ + } query; + struct report { + struct igmp_gr gr_list; /* first entry of group record */ + } report; + } un_v3; + + #define igmp_group grp.group + #define igmp_qrsq un_v3.query.rsq +// #define igmp_qresv un_v3.query.resv +// #define igmp_qsflag un_v3.query.s +// #define igmp_qrv un_v3.query.qrv + #define igmp_qqic un_v3.query.qqic + #define igmp_qnofs un_v3.query.nofs + #define igmp_qsrclist un_v3.query.src_list + #define igmp_rnofg grp.v3_report.nofg + #define igmp_rresv grp.v3_report.resv + #define igmp_grlist un_v3.report.gr_list + +}; + +/* IGMP Type */ +#define IGMP_QUERY 0x11 /* igmp group membership query */ +#define IGMP_V1_REPORT 0x12 /* igmp v1 membership report */ +#define IGMP_DVMRP 0x13 /* DVMRP */ +#define IGMP_PIMV1 0x14 /* PIM v1 */ +#define IGMP_CISCOTRACE 0x15 /* CISCO trace messages */ +#define IGMP_V2_REPORT 0x16 /* igmp v2 membership report */ +#define IGMP_V2_LEAVE 0x17 /* igmp v2 leave group message */ +#define IGMP_MTRACE_RESPONSE 0x1e /* multicast traceroute response */ +#define IGMP_MTRACE 0x1f /* multicast traceroute */ +#define IGMP_V3_REPORT 0x22 /* igmp v3 membership report */ +#define IGMP_MROUTER_ADV 0x24 /* igmp multicast router advertisement */ +#define IGMP_MROUTER_SOL 0x25 /* igmp multicast router solicitation */ +#define IGMP_MROUTER_TERM 0x26 /* igmp multicast router termination */ + +/* IGMP v3 Group Record Type */ +#define IGMPV3_MODE_IS_INCLUDE 0x01 +#define IGMPV3_MODE_IS_EXCLUDE 0x02 +#define IGMPV3_CHANGE_TO_INCLUDE_MODE 0x03 +#define IGMPV3_CHANGE_TO_EXCLUDE_MODE 0x04 +#define IGMPV3_ALLOW_NEW_SOURCES 0x05 +#define IGMPV3_BLOCK_OLD_SOURCES 0x06 + +/*========================================================================================== + * IP Header for IP ACL lookup + *==========================================================================================*/ +typedef uint32 tcp_seq; +struct tcphdr { + uint16 th_sport; /* source port */ + uint16 th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ +#if 0 + #ifdef _LITTLE_ENDIAN + uint8 th_x2:4, /* (unused) */ + th_off:4; /* data offset */ + #else + uint8 th_off:4, /* data offset */ + th_x2:4; /* (unused) */ + #endif +#else + /* replace bit field */ + uint8 th_off_x; + +#endif + + uint8 th_flags; + #define TH_FIN 0x01 + #define TH_SYN 0x02 + #define TH_RST 0x04 + #define TH_PUSH 0x08 + #define TH_ACK 0x10 + #define TH_URG 0x20 + #define TH_ECE 0x40 + #define TH_CWR 0x80 + #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) + + uint16 th_win; /* window */ + uint16 th_sum; /* checksum */ + uint16 th_urp; /* urgent pointer */ + + //Optional TCP options. Max: 40 bytes. + #define TCPOPT_EOL 0 + #define TCPOPT_NOP 1 + #define TCPOPT_MAXSEG 2 + #define TCPOLEN_MAXSEG 4 + #define TCPOPT_WINDOW 3 + #define TCPOLEN_WINDOW 3 + #define TCPOPT_SACK_PERMITTED 4 /* Experimental */ + #define TCPOLEN_SACK_PERMITTED 2 + #define TCPOPT_SACK 5 /* Experimental */ + #define TCPOPT_TIMESTAMP 8 + #define TCPOLEN_TIMESTAMP 10 + #define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */ + #define TCPOPT_TSTAMP_HDR \ + (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP) + + #define TCPOPT_CC 11 /* CC options: RFC-1644 */ + #define TCPOPT_CCNEW 12 + #define TCPOPT_CCECHO 13 + #define TCPOLEN_CC 6 + #define TCPOLEN_CC_APPA (TCPOLEN_CC+2) + #define TCPOPT_CC_HDR(ccopt) \ + (TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC) +}; + + +/*========================================================================================== + * IP Header for IP ACL lookup + *==========================================================================================*/ +struct udphdr +{ + uint16 uh_sport; /* source port */ + uint16 uh_dport; /* destination port */ + uint16 uh_ulen; /* udp length */ + uint16 uh_sum; /* udp checksum */ +}; + +/*========================================================================================== + * TFTP header for RRQ/WRQ + *==========================================================================================*/ + +struct tftpRequest { + uint16 opcode; + char *string; +}; + +#define TFTP_RRQ 0x01 +#define TFTP_WRQ 0x02 +#define TFTP_DATA 0x03 +#define TFTP_ACK 0x04 +#define TFTP_ERR 0x05 + +/*========================================================================================== + * AH Header + *==========================================================================================*/ +#define AH_AUTHLEN 12 /* authenticator length of 96bits */ +#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi and the ah_hl, says how many bytes after that to cover. */ +typedef struct ahHdr_s /* Generic AH header */ +{ + uint8 ah_nh; /* Next header (protocol) */ + uint8 ah_hl; /* AH length, in 32-bit words */ + uint16 ah_rv; /* reserved, must be 0 */ + uint32 ah_spi; /* Security Parameters Index */ + uint32 ah_rpl; /* Replay prevention */ + uint8 ah_data[AH_AUTHLEN]; /* Authentication hash */ +} ahHdr_t; + +/*========================================================================================== + * ESP Header + *==========================================================================================*/ +typedef struct espHdr_s +{ + uint32 spi; + uint32 seq; +} espHdr_t; + +typedef struct cbcHdr64_s +{ + uint32 iv[2]; +} cbcHdr64_t; + +typedef struct cbcHdr128_s +{ + uint32 iv[4]; +} cbcHdr128_t; + + +#if 0 +#define ntohs(x) (x) +#define ntohl(x) (x) +#define htons(x) (x) +#define htonl(x) (x) + +#define NTOHL(d) +#define NTOHS(d) +#define HTONL(d) +#define HTONS(d) +#endif + +#if !defined(_LINUX_IN_H) +/* + * Protocols (RFC 1700) + */ +#define IPPROTO_IP 0 /* dummy for IP */ +#define IPPROTO_HOPOPTS 0 /* IP6 hop-by-hop options */ +#define IPPROTO_ICMP 1 /* control message protocol */ +#define IPPROTO_IGMP 2 /* group mgmt protocol */ +#define IPPROTO_GGP 3 /* gateway^2 (deprecated) */ +#define IPPROTO_IPV4 4 /* IPv4 encapsulation */ +#define IPPROTO_IPIP IPPROTO_IPV4 /* for compatibility */ +#define IPPROTO_TCP 6 /* tcp */ +#define IPPROTO_ST 7 /* Stream protocol II */ +#define IPPROTO_EGP 8 /* exterior gateway protocol */ +#define IPPROTO_PIGP 9 /* private interior gateway */ +#define IPPROTO_RCCMON 10 /* BBN RCC Monitoring */ +#define IPPROTO_NVPII 11 /* network voice protocol*/ +#define IPPROTO_PUP 12 /* pup */ +#define IPPROTO_ARGUS 13 /* Argus */ +#define IPPROTO_EMCON 14 /* EMCON */ +#define IPPROTO_XNET 15 /* Cross Net Debugger */ +#define IPPROTO_CHAOS 16 /* Chaos*/ +#define IPPROTO_UDP 17 /* user datagram protocol */ +#define IPPROTO_MUX 18 /* Multiplexing */ +#define IPPROTO_MEAS 19 /* DCN Measurement Subsystems */ +#define IPPROTO_HMP 20 /* Host Monitoring */ +#define IPPROTO_PRM 21 /* Packet Radio Measurement */ +#define IPPROTO_IDP 22 /* xns idp */ +#define IPPROTO_TRUNK1 23 /* Trunk-1 */ +#define IPPROTO_TRUNK2 24 /* Trunk-2 */ +#define IPPROTO_LEAF1 25 /* Leaf-1 */ +#define IPPROTO_LEAF2 26 /* Leaf-2 */ +#define IPPROTO_RDP 27 /* Reliable Data */ +#define IPPROTO_IRTP 28 /* Reliable Transaction */ +#define IPPROTO_TP 29 /* tp-4 w/ class negotiation */ +#define IPPROTO_BLT 30 /* Bulk Data Transfer */ +#define IPPROTO_NSP 31 /* Network Services */ +#define IPPROTO_INP 32 /* Merit Internodal */ +#define IPPROTO_SEP 33 /* Sequential Exchange */ +#define IPPROTO_3PC 34 /* Third Party Connect */ +#define IPPROTO_IDPR 35 /* InterDomain Policy Routing */ +#define IPPROTO_XTP 36 /* XTP */ +#define IPPROTO_DDP 37 /* Datagram Delivery */ +#define IPPROTO_CMTP 38 /* Control Message Transport */ +#define IPPROTO_TPXX 39 /* TP++ Transport */ +#define IPPROTO_IL 40 /* IL transport protocol */ +#define IPPROTO_IPV6 41 /* IP6 header */ +#define IPPROTO_SDRP 42 /* Source Demand Routing */ +#define IPPROTO_ROUTING 43 /* IP6 routing header */ +#define IPPROTO_FRAGMENT 44 /* IP6 fragmentation header */ +#define IPPROTO_IDRP 45 /* InterDomain Routing*/ +#define IPPROTO_RSVP 46 /* resource reservation */ +#define IPPROTO_GRE 47 /* General Routing Encap. */ +#define IPPROTO_MHRP 48 /* Mobile Host Routing */ +#define IPPROTO_BHA 49 /* BHA */ +#define IPPROTO_ESP 50 /* IP6 Encap Sec. Payload */ +#define IPPROTO_AH 51 /* IP6 Auth Header */ +#define IPPROTO_INLSP 52 /* Integ. Net Layer Security */ +#define IPPROTO_SWIPE 53 /* IP with encryption */ +#define IPPROTO_NHRP 54 /* Next Hop Resolution */ +/* 55-57: Unassigned */ +#define IPPROTO_ICMPV6 58 /* ICMP6 */ +#define IPPROTO_NONE 59 /* IP6 no next header */ +#define IPPROTO_DSTOPTS 60 /* IP6 destination option */ +#define IPPROTO_AHIP 61 /* any host internal protocol */ +#define IPPROTO_CFTP 62 /* CFTP */ +#define IPPROTO_HELLO 63 /* "hello" routing protocol */ +#define IPPROTO_SATEXPAK 64 /* SATNET/Backroom EXPAK */ +#define IPPROTO_KRYPTOLAN 65 /* Kryptolan */ +#define IPPROTO_RVD 66 /* Remote Virtual Disk */ +#define IPPROTO_IPPC 67 /* Pluribus Packet Core */ +#define IPPROTO_ADFS 68 /* Any distributed FS */ +#define IPPROTO_SATMON 69 /* Satnet Monitoring */ +#define IPPROTO_VISA 70 /* VISA Protocol */ +#define IPPROTO_IPCV 71 /* Packet Core Utility */ +#define IPPROTO_CPNX 72 /* Comp. Prot. Net. Executive */ +#define IPPROTO_CPHB 73 /* Comp. Prot. HeartBeat */ +#define IPPROTO_WSN 74 /* Wang Span Network */ +#define IPPROTO_PVP 75 /* Packet Video Protocol */ +#define IPPROTO_BRSATMON 76 /* BackRoom SATNET Monitoring */ +#define IPPROTO_ND 77 /* Sun net disk proto (temp.) */ +#define IPPROTO_WBMON 78 /* WIDEBAND Monitoring */ +#define IPPROTO_WBEXPAK 79 /* WIDEBAND EXPAK */ +#define IPPROTO_EON 80 /* ISO cnlp */ +#define IPPROTO_VMTP 81 /* VMTP */ +#define IPPROTO_SVMTP 82 /* Secure VMTP */ +#define IPPROTO_VINES 83 /* Banyon VINES */ +#define IPPROTO_TTP 84 /* TTP */ +#define IPPROTO_IGP 85 /* NSFNET-IGP */ +#define IPPROTO_DGP 86 /* dissimilar gateway prot. */ +#define IPPROTO_TCF 87 /* TCF */ +#define IPPROTO_IGRP 88 /* Cisco/GXS IGRP */ +#define IPPROTO_OSPFIGP 89 /* OSPFIGP */ +#define IPPROTO_SRPC 90 /* Strite RPC protocol */ +#define IPPROTO_LARP 91 /* Locus Address Resoloution */ +#define IPPROTO_MTP 92 /* Multicast Transport */ +#define IPPROTO_AX25 93 /* AX.25 Frames */ +#define IPPROTO_IPEIP 94 /* IP encapsulated in IP */ +#define IPPROTO_MICP 95 /* Mobile Int.ing control */ +#define IPPROTO_SCCSP 96 /* Semaphore Comm. security */ +#define IPPROTO_ETHERIP 97 /* Ethernet IP encapsulation */ +#define IPPROTO_ENCAP 98 /* encapsulation header */ +#define IPPROTO_APES 99 /* any private encr. scheme */ +#define IPPROTO_GMTP 100 /* GMTP*/ +#define IPPROTO_IPCOMP 108 /* payload compression (IPComp) */ +/* 101-254: Partly Unassigned */ +#define IPPROTO_PIM 103 /* Protocol Independent Mcast */ +#define IPPROTO_PGM 113 /* PGM */ +/* 255: Reserved */ +/* BSD Private, local use, namespace incursion */ +#define IPPROTO_RAW 255 /* raw IP packet */ +#define IPPROTO_MAX 256 + +/* last return value of *_input(), meaning "all job for this pkt is done". */ +#define IPPROTO_DONE 257 +#endif + +/* + * Ports < IPPORT_RESERVED are reserved for + * privileged processes (e.g. root). (IP_PORTRANGE_LOW) + * Ports > IPPORT_USERRESERVED are reserved + * for servers, not necessarily privileged. (IP_PORTRANGE_DEFAULT) + */ +#define IPPORT_RESERVED 1024 +#define IPPORT_USERRESERVED 5000 + +#endif /* RTL8651_TBLDRV_PROTO_H */ + diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_eventMgr.c b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_eventMgr.c new file mode 100644 index 000000000..8d6950ba6 --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_eventMgr.c @@ -0,0 +1,530 @@ +/*
+* Copyright c Realtek Semiconductor Corporation, 2008
+* All rights reserved.
+* Abstract :
+* Author : hyking (hyking_liu@realsil.com.cn)
+*/
+#include <net/rtl/rtl_types.h> +#include <net/rtl/rtl_glue.h> +#include "rtl_errno.h"
+//#include "rtl_utils.h"
+#include "rtl865x_eventMgr.h"
+#include "rtl865x_vlan.h"
+
+/*record the allocated memory pool pointer,
+it can be used when event management module destroyed*/
+static char eventMgrInitFlag=FALSE;
+static rtl865x_event_t *eventPool;
+static rtl865x_eventLayerList_t *eventLayerListPool;
+static struct rtl865x_eventTables_s eventsTables;
+static rtl865x_eventMgr_param_t eventMgrParam;
+
+int32 rtl865x_initEventMgr(rtl865x_eventMgr_param_t *param)
+{
+ int32 i;
+ memset(&eventMgrParam,0,sizeof(rtl865x_eventMgr_param_t));
+
+ if(param==NULL)
+ {
+ eventMgrParam.eventCnt=DEFAULT_EVENT_CNT;
+ eventMgrParam.eventListCnt=DEFAULT_EVENT_LIST_CNT;
+ }
+ else
+ {
+ if(param->eventCnt>MAX_EVENT_CNT)
+ {
+ eventMgrParam.eventCnt=MAX_EVENT_CNT;
+ }
+ else if(param->eventCnt==0)
+ {
+ eventMgrParam.eventCnt=DEFAULT_EVENT_CNT;
+ }
+ else
+ {
+ eventMgrParam.eventCnt=param->eventCnt;
+ }
+
+
+ if(param->eventListCnt>MAX_EVENT_LIST_CNT)
+ {
+ eventMgrParam.eventListCnt=MAX_EVENT_LIST_CNT;
+ }
+ else if(param->eventListCnt==0)
+ {
+ eventMgrParam.eventListCnt=DEFAULT_EVENT_LIST_CNT;
+ }
+ else
+ {
+ eventMgrParam.eventListCnt=param->eventListCnt;
+ }
+ }
+
+ CTAILQ_INIT(&eventsTables.freeList.eventHead);
+ CTAILQ_INIT(&eventsTables.freeList.eventLayerListHead);
+ CTAILQ_INIT(&eventsTables.inuseList.eventLayerListHead);
+
+ //#ifdef __KERNEL__
+
+ TBL_MEM_ALLOC(eventPool, rtl865x_event_t, eventMgrParam.eventCnt);
+ //#else
+ //eventPool= (rtl865x_event_t *)malloc(eventMgrParam.eventCnt * sizeof(rtl865x_event_t));
+ //#endif
+ if(eventPool!=NULL)
+ {
+ memset( eventPool, 0, eventMgrParam.eventCnt * sizeof(rtl865x_event_t));
+ }
+ else
+ {
+ return FAILED;
+ }
+
+
+ //#ifdef __KERNEL__
+ TBL_MEM_ALLOC(eventLayerListPool, rtl865x_eventLayerList_t, eventMgrParam.eventListCnt);
+ //#else
+ //eventLayerListPool=(rtl865x_eventLayerList_t *)malloc(eventMgrParam.eventListCnt * sizeof(rtl865x_eventLayerList_t));
+ //#endif
+ if(eventLayerListPool!=NULL)
+ {
+ memset( eventLayerListPool, 0, eventMgrParam.eventListCnt * sizeof(rtl865x_eventLayerList_t));
+ }
+ else
+ {
+ return FAILED;
+ }
+
+ for(i = 0; i<eventMgrParam.eventCnt;i++)
+ {
+ CTAILQ_INSERT_HEAD(&eventsTables.freeList.eventHead, &eventPool[i], next);
+ }
+
+ for(i = 0; i<eventMgrParam.eventListCnt;i++)
+ {
+ CTAILQ_INSERT_HEAD(&eventsTables.freeList.eventLayerListHead, &eventLayerListPool[i], next);
+ }
+
+ eventMgrInitFlag=TRUE;
+ return SUCCESS;
+}
+
+
+static int32 rtl865x_flushEventLayerList(rtl865x_eventLayerList_t *eventLayerList)
+{
+ rtl865x_event_t *event;
+ rtl865x_event_t *nextEvent;
+
+ if(eventLayerList==NULL)
+ {
+ return SUCCESS;
+ }
+
+ event = CTAILQ_FIRST(&eventLayerList->eventHead);
+ while(event)
+ {
+ nextEvent = CTAILQ_NEXT( event, next );
+ event->eventId=0;
+ event->eventPriority=0;
+ event->event_action_fn=NULL;
+ CTAILQ_REMOVE(&eventLayerList->eventHead, event, next);
+ CTAILQ_INSERT_HEAD(&eventsTables.freeList.eventHead, event, next);
+ event = nextEvent;
+ }
+ return SUCCESS;
+}
+
+int32 rtl865x_reInitEventMgr(void)
+{
+ rtl865x_eventLayerList_t *eventLayerList;
+ rtl865x_eventLayerList_t *nextEventLayerList;
+
+ if(eventMgrInitFlag==FALSE)
+ {
+ return FAILED;
+ }
+
+ eventLayerList = TAILQ_FIRST(&eventsTables.inuseList.eventLayerListHead);
+
+ for (;eventLayerList!=NULL;eventLayerList=nextEventLayerList)
+ {
+ nextEventLayerList=TAILQ_NEXT(eventLayerList, next);
+ rtl865x_flushEventLayerList(eventLayerList);
+
+ CTAILQ_REMOVE(&eventsTables.inuseList.eventLayerListHead, eventLayerList, next);
+ eventLayerList->eventLayerId=0;
+ CTAILQ_INIT(&eventLayerList->eventHead);
+ CTAILQ_INSERT_HEAD(&eventsTables.freeList.eventLayerListHead, eventLayerList, next);
+ }
+ return SUCCESS;
+}
+
+int32 rtl865x_destroyEventMgr(void)
+{
+
+ if(eventMgrInitFlag==FALSE)
+ {
+ return FAILED;
+ }
+
+ rtl865x_reInitEventMgr();
+ #ifdef __KERNEL__
+ if(eventPool!=NULL)
+ {
+ kfree(eventPool);
+ eventPool=NULL;
+ }
+
+ if(eventLayerListPool!=NULL)
+ {
+ kfree(eventLayerListPool);
+ eventLayerListPool=NULL;
+ }
+ #else
+ if(eventPool!=NULL)
+ {
+ free(eventPool);
+ eventPool=NULL;
+ }
+
+ if(eventLayerListPool!=NULL)
+ {
+ free(eventLayerListPool);
+ eventLayerListPool=NULL;
+ }
+ #endif
+
+ eventMgrInitFlag=FALSE;
+
+ return SUCCESS;
+}
+
+static rtl865x_eventLayerList_t * rtl865x_searchEventLayerList(rtl865x_event_Param_t *eventParam)
+{
+ rtl865x_eventLayerList_t *eventLayerList;
+ CTAILQ_FOREACH(eventLayerList, &eventsTables.inuseList.eventLayerListHead, next)
+ {
+ if(eventLayerList->eventLayerId==eventParam->eventLayerId)
+ {
+ return eventLayerList;
+ }
+ }
+
+ return NULL;
+}
+
+static rtl865x_event_t * rtl865x_searchEvent(rtl865x_eventLayerList_t *eventList,rtl865x_event_Param_t *eventParam)
+{
+ rtl865x_event_t *event=NULL;
+
+ if(eventParam==NULL)
+ {
+ return NULL;
+ }
+
+ CTAILQ_FOREACH(event, &eventList->eventHead, next)
+ {
+ if( (event->eventId==eventParam->eventId)
+ &&(event->eventPriority==eventParam->eventPriority)
+ &&(event->event_action_fn== eventParam->event_action_fn))
+ {
+ return event;
+ }
+ }
+
+ return NULL;
+}
+
+static void rtl865x_insertEventLayerList(rtl865x_eventLayerList_t *eventLayerList)
+{
+ rtl865x_eventLayerList_t *tmpEventLayerList=NULL;
+ if(eventLayerList==NULL)
+ {
+ return;
+ }
+
+ CTAILQ_FOREACH(tmpEventLayerList, &eventsTables.inuseList.eventLayerListHead, next)
+ {
+ if(tmpEventLayerList->eventLayerId>=eventLayerList->eventLayerId)
+ {
+ CTAILQ_INSERT_BEFORE(&eventsTables.inuseList.eventLayerListHead,tmpEventLayerList,eventLayerList,next);
+ break;
+ }
+ }
+
+ if(tmpEventLayerList==NULL)
+ {
+ CTAILQ_INSERT_TAIL(&eventsTables.inuseList.eventLayerListHead,eventLayerList,next);
+ }
+ return;
+
+}
+
+static void rtl8651_insertEvent(rtl865x_eventLayerList_t *eventLayerList,rtl865x_event_t *event)
+{
+ rtl865x_event_t *tmpEvent=NULL;
+ if( (eventLayerList==NULL) ||(event==NULL))
+ {
+ return ;
+ }
+
+ CTAILQ_FOREACH(tmpEvent, &eventLayerList->eventHead, next)
+ {
+
+ if((tmpEvent->eventId>event->eventId)||
+ ((tmpEvent->eventId== event->eventId) && (tmpEvent->eventPriority>=event->eventPriority)))
+ {
+ CTAILQ_INSERT_BEFORE(&eventLayerList->eventHead,tmpEvent,event,next);
+ break;
+ }
+ }
+
+ if(tmpEvent==NULL)
+ {
+ CTAILQ_INSERT_TAIL(&eventLayerList->eventHead,event,next);
+ }
+ return ;
+
+}
+
+int32 rtl865x_registerEvent(rtl865x_event_Param_t *eventParam)
+{
+ rtl865x_eventLayerList_t *eventLayerList=NULL;
+ rtl865x_event_t *event=NULL;
+
+ if(eventMgrInitFlag==FALSE)
+ {
+ return FAILED;
+ }
+
+ if(eventParam==NULL)
+ {
+ return RTL_EINVALIDINPUT;
+ }
+
+ if(eventParam->eventLayerId==0)
+ {
+ return RTL_EINVALIDINPUT;
+ }
+
+ eventLayerList=rtl865x_searchEventLayerList(eventParam);
+ if(eventLayerList==NULL)
+ {
+ eventLayerList = CTAILQ_FIRST(&eventsTables.freeList.eventLayerListHead);
+ if(eventLayerList==NULL)
+ {
+ return RTL_ENOFREEBUFFER;
+ }
+ CTAILQ_REMOVE(&eventsTables.freeList.eventLayerListHead, eventLayerList, next);
+ CTAILQ_INIT(&eventLayerList->eventHead);
+ eventLayerList->eventLayerId=eventParam->eventLayerId;
+ rtl865x_insertEventLayerList(eventLayerList);
+ }
+
+ if( (eventParam->eventId< 0) ||
+ (eventParam->eventId >MAX_SYSTEM_EVENT_ID) ||
+ (eventParam->event_action_fn == NULL))
+ return RTL_EINVALIDINPUT;
+
+
+ /*check duplicate entry*/
+ event=rtl865x_searchEvent(eventLayerList,eventParam);
+ if(event!=NULL)
+ {
+ return RTL_EENTRYALREADYEXIST;
+ }
+ else
+ {
+
+ event = CTAILQ_FIRST(&eventsTables.freeList.eventHead);
+ if(event==NULL)
+ {
+ return RTL_ENOFREEBUFFER;
+ }
+ CTAILQ_REMOVE( &eventsTables.freeList.eventHead, event, next);
+ event->eventId= eventParam->eventId;
+ event->eventPriority = eventParam->eventPriority;
+ event->event_action_fn = eventParam->event_action_fn;
+
+ rtl8651_insertEvent(eventLayerList,event);
+ }
+
+ return SUCCESS;
+
+}
+
+int32 rtl865x_unRegisterEvent(rtl865x_event_Param_t *eventParam)
+{
+ rtl865x_eventLayerList_t *eventLayerList=NULL;
+ rtl865x_event_t *event=NULL;
+
+ if(eventMgrInitFlag==FALSE)
+ {
+ return FAILED;
+ }
+
+ if(eventParam==NULL)
+ {
+ return RTL_EINVALIDINPUT;
+ }
+
+ eventLayerList=rtl865x_searchEventLayerList(eventParam);
+ if(eventLayerList==NULL)
+ {
+ return RTL_EINVALIDINPUT;
+ }
+
+ if( (eventParam->eventId< 0) ||
+ (eventParam->eventId >MAX_SYSTEM_EVENT_ID) ||
+ (eventParam->event_action_fn == NULL))
+ return RTL_EINVALIDINPUT;
+
+
+ event=rtl865x_searchEvent(eventLayerList,eventParam);
+ if(event!=NULL)
+ {
+ event->eventId = 0;
+ event->eventPriority = 0;
+ event->event_action_fn = NULL;
+ CTAILQ_REMOVE(&eventLayerList->eventHead, event, next);
+ CTAILQ_INSERT_HEAD(&eventsTables.freeList.eventHead, event, next);
+
+ if(CTAILQ_EMPTY(&eventLayerList->eventHead))
+ {
+ CTAILQ_REMOVE(&eventsTables.inuseList.eventLayerListHead, eventLayerList, next);
+ eventLayerList->eventLayerId=0;
+ CTAILQ_INIT(&eventLayerList->eventHead);
+ CTAILQ_INSERT_HEAD(&eventsTables.freeList.eventLayerListHead, eventLayerList, next);
+ }
+
+ return SUCCESS;
+ }
+ else
+ {
+ return RTL_EINVALIDINPUT;
+ }
+
+ return SUCCESS;
+
+}
+
+
+int32 rtl865x_raiseEvent(int32 eventId,void *actionParam)
+{
+ rtl865x_eventLayerList_t *eventLayerList;
+ rtl865x_event_t *event;
+ int retValue;
+
+ if(eventMgrInitFlag==FALSE)
+ {
+ return FAILED;
+ }
+
+ CTAILQ_FOREACH(eventLayerList, &eventsTables.inuseList.eventLayerListHead, next)
+ {
+ CTAILQ_FOREACH(event, &eventLayerList->eventHead, next)
+ {
+ if((event->eventId==eventId))
+ {
+ if(event->event_action_fn!=NULL)
+ {
+ do
+ {
+ retValue=event->event_action_fn(actionParam);
+ }while(retValue==EVENT_RE_EXECUTE);
+
+ switch(retValue)
+ {
+
+ case EVENT_STOP_EXECUTE:
+ return SUCCESS;
+
+ case EVENT_CONTINUE_EXECUTE:
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ return SUCCESS;
+}
+
+void rtl865x_dumpAllEventLayerListInfo(void)
+{
+
+ rtl865x_eventLayerList_t *eventLayerList;
+ rtl865x_event_t *event;
+ int eventListCnt=0;
+ int eventCnt=0;
+ CTAILQ_FOREACH(eventLayerList, &eventsTables.inuseList.eventLayerListHead, next)
+ {
+ eventListCnt++;
+ eventCnt=0;
+ rtl865x_debug_printf(" No.%d eventLayerList:eventLayerId:%d \n",eventListCnt,eventLayerList->eventLayerId);
+ CTAILQ_FOREACH(event, &eventLayerList->eventHead, next)
+ {
+ eventCnt++;
+ rtl865x_debug_printf(" \tNo.%d event:eventId:%d,priority:%d,action_fn is 0x%x\n",eventCnt,event->eventId, event->eventPriority,(unsigned int)(event->event_action_fn));
+ }
+
+ }
+
+ return;
+}
+
+
+#ifdef CONFIG_RTL865X_EVENT_PROC_DEBUG
+int32 rtl865x_event_proc_read( char *page, char **start, off_t off, int count, int *eof, void *data )
+{
+ int len=0;
+ rtl865x_eventLayerList_t *eventLayerList;
+ rtl865x_event_t *event;
+ int eventListCnt=0;
+ int eventCnt=0;
+
+ len = sprintf(page, "%s\n", "realtek event management Table:");
+
+ CTAILQ_FOREACH(eventLayerList, &eventsTables.inuseList.eventLayerListHead, next)
+ {
+ eventListCnt++;
+ eventCnt=0;
+ len += sprintf(page+len, " No.%d eventLayerList:eventLayerId:0x%x \n",eventListCnt,eventLayerList->eventLayerId);
+ CTAILQ_FOREACH(event, &eventLayerList->eventHead, next)
+ {
+ eventCnt++;
+ len += sprintf(page+len, " \tNo.%d event:eventId:0x%x,priority:%d,action_fn is 0x%x\n",eventCnt,event->eventId, event->eventPriority,(unsigned int)(event->event_action_fn));
+ }
+
+ }
+
+ if (len <= off+count)
+ {
+ *eof = 1;
+ }
+
+ *start = page + off; + len -= off;
+
+ if (len>count)
+ {
+ len = count;
+ }
+
+ if (len<0)
+ {
+ len = 0;
+ }
+ + return len; +} + +int32 rtl865x_event_proc_write( struct file *filp, const char *buff,unsigned long len, void *data )
+{
+ return len; +}
+#endif
+
+
diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_eventMgr.h b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_eventMgr.h new file mode 100644 index 000000000..6bb6d29ed --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_eventMgr.h @@ -0,0 +1,215 @@ +/* +* Copyright c Realtek Semiconductor Corporation, 2008 +* All rights reserved. +* +* Abstract : +* Author : hyking (hyking_liu@realsil.com.cn) +*/ + +#ifndef RTL865X_EVENT_MANAGEMENT_H +#define RTL865X_EVENT_MANAGEMENT_H + +#include <net/rtl/rtl_queue.h> +#if 0 +#define COMMON_MAX_EVENT_CNT 16 /*number of event*/ +#define MAX_NODE_PER_EVENT 4 /*max event node per event*/ +#define MAX_TOTAL_EVENT_NODE COMMON_MAX_EVENT_CNT * MAX_NODE_PER_EVENT /*total event node count*/ + +#define EV_DEL_VLAN 0 +#define EV_CHG_VLANFID 1 +#define EV_DEL_NETIF 2 + + +typedef struct action_param_s +{ + void *org; /*old information*/ + void *now; /*new information*/ + void *flag; +}action_param_t; + +typedef struct event_node_s +{ + uint32 valid; + int32 priority; /*priority: minimal value indicate high priority*/ + void (*event_action)(void *param); + struct event_node_s *pre,*next; +}event_node_t; + +typedef struct event_s +{ + uint32 count; + event_node_t *head; + /*need a lock?*/ +}event_t; + + +int32 rtl865x_initEventMgr(void); +int32 rtl865x_registEvent(int32 event, int32 priority, void (*event_action_fn)(void *param)); +int32 rtl865x_unRegistEvent(int32 event, int32 priority, void (*event_action_fn)(void *param)); +int32 do_eventAction(int32 event,void *param); +#else + +#ifdef CONFIG_PROC_FS +#define CONFIG_RTL865X_EVENT_PROC_DEBUG +#endif +#define DEFAULT_EVENT_LIST_CNT 4 +#define DEFAULT_EVENT_CNT 100 + +#define MAX_EVENT_LIST_CNT 20 +#define MAX_EVENT_CNT 200 + + +#define DEFAULT_COMMON_EVENT_LIST_ID 0x10000000 +#define DEFAULT_LAYER2_EVENT_LIST_ID 0x20000000 +#define DEFAULT_LAYER3_EVENT_LIST_ID 0x30000000 +#define DEFAULT_LAYER4_EVENT_LIST_ID 0x40000000 + +#define RTL865X_EVENT_PROC_DIR "reasilEvent" + +/*common layer event definition, common event range 0x10000000~0x1FFFFFFF*/ +#define MIN_COMM_EVENT_ID 0x10000000 +#define MAX_COMM_EVENT_ID 0x1FFFFFFF + +#define EVENT_ADD_VLAN 0x10000001 +#define EVENT_DEL_VLAN 0x10000002 +#define EVENT_CHANGE_VLANFID 0x10000003 +#define EVENT_ADD_NETIF 0x10000004 +#define EVENT_DEL_NETIF 0x10000005 +#define EVENT_ADD_ACL 0x10000006 +#define EVENT_DEL_ACL 0x10000007 + +/*layer2 event definition, layer 2 event range 0x20000000~0x2FFFFFFF*/ +#define MIN_LAYER2_EVENT_ID 0x20000000 +#define MAX_LAYER2_EVENT_ID 0x2FFFFFFF + +#define EVENT_ADD_FDB 0x20000001 +#define EVENT_DEL_FDB 0x20000002 +#define EVENT_ADD_AUTHED_FDB 0x20000004 +#define EVENT_DEL_AUTHED_FDB 0x20000008 + +#define EVENT_CHANGE_QOSRULE 0x20001001 +#define EVENT_FLUSH_QOSRULE 0x20001002 + + +/*layer3 event definition, layer3 event range 0x30000000~0x3FFFFFFF*/ +#define MIN_LAYER3_EVENT_ID 0x30000000 +#define MAX_LAYER3_EVENT_ID 0x3FFFFFFF + +#define EVENT_ADD_ROUTE 0x30000001 +#define EVENT_DEL_ROUTE 0x30000001 +#define EVENT_ADD_NEXTHOP 0x30000003 +#define EVENT_DEL_NEXTHOP 0x30000004 +#define EVENT_ADD_IP 0x30000005 +#define EVENT_DEL_IP 0x30000006 +#define EVENT_ADD_ARP 0x30000007 +#define EVENT_DEL_ARP 0x30000008 +#define EVENT_ADD_PPP 0x30000009 +#define EVENT_DEL_PPP 0x30000010 + +/*macro for ip multicast usage*/ +#define EVENT_UPDATE_MCAST 0x30000011 +#define EVENT_ADD_MCAST 0x30000012 +#define EVENT_DEL_MCAST 0x30000013 +#define EVENT_ADD_GROUP 0x30000014 +#define EVENT_DEL_GROUP 0x30000015 +#define EVENT_ADD_MEMBER 0x30000016 +#define EVENT_DEL_MEMBER 0x30000017 +#define EVENT_ADD_SOURCE 0x30000018 +#define EVENT_DEL_SOURCE 0x30000019 + +/*layer4 event definition, layer4 event range 0x40000000~0x4FFFFFFF*/ +#define MIN_LAYER4_EVENT_ID 0x40000000 +#define MAX_LAYER4_EVENT_ID 0x4FFFFFFF + +#define EVENT_ADD_NAPT 0x40000001 +#define EVENT_DELETE_NAPT 0x40000002 + +#define MAX_SYSTEM_EVENT_ID 0x4FFFFFFF + +#define HIGHEST_EVENT_PRIORITY 1 +#define LOWEST_EVENT_PRIORITY 65535 + +/*callback function return vlue definition*/ +#define EVENT_CONTINUE_EXECUTE SUCCESS +#define EVENT_STOP_EXECUTE FAILED +#define EVENT_RE_EXECUTE (FAILED-1) + + +#ifdef __KERNEL__ + #define rtl865x_debug_printf printk +#else + #define rtl865x_debug_printf printf +#endif + +/*data structure definition*/ +typedef struct rtl865x_eventMgr_param_s +{ + uint32 eventListCnt; + uint32 eventCnt; +}rtl865x_eventMgr_param_t; + +typedef struct rtl865x_event_Param_s +{ + int32 eventLayerId; + int32 eventId; + int32 eventPriority; + int32 (*event_action_fn)(void *param); +}rtl865x_event_Param_t; + + +typedef struct action_param_s +{ + void *org; /*old information*/ + void *now; /*new information*/ + void *flag; +}action_param_t; + + +typedef struct rtl865x_event_s +{ + int32 eventId; + int32 eventPriority; /*priority: less value indicate higher priority*/ + int32 (*event_action_fn)(void *param); + CTAILQ_ENTRY(rtl865x_event_s) next; +}rtl865x_event_t; + + +typedef CTAILQ_HEAD(_event_head_s, rtl865x_event_s) rtl865x_event_Head_t; + +typedef struct rtl865x_eventLayerList_s +{ + int32 eventLayerId; + rtl865x_event_Head_t eventHead; + CTAILQ_ENTRY(rtl865x_eventLayerList_s) next; +}rtl865x_eventLayerList_t; + +typedef CTAILQ_HEAD(_eventLayerList_head_s, rtl865x_eventLayerList_s) rtl865x_eventLayerList_Head_t; + +struct rtl865x_eventTables_s { + struct freeEntryList_s { + rtl865x_event_Head_t eventHead; + rtl865x_eventLayerList_Head_t eventLayerListHead; + } freeList; + + struct inuseEntryList_s { + rtl865x_eventLayerList_Head_t eventLayerListHead; + } inuseList; + +}; + +int32 rtl865x_initEventMgr(rtl865x_eventMgr_param_t *param); +int32 rtl865x_reInitEventMgr(void); +int32 rtl865x_registerEvent(rtl865x_event_Param_t *eventParam); +int32 rtl865x_unRegisterEvent(rtl865x_event_Param_t *eventParam); +int32 rtl865x_raiseEvent(int32 eventId,void *actionParam); +void rtl865x_dumpAllEventLayerListInfo(void); +int32 rtl865x_destroyEventMgr(void); + +#ifdef CONFIG_RTL865X_EVENT_PROC_DEBUG +int32 rtl865x_event_proc_read( char *page, char **start, off_t off, int count, int *eof, void *data ); +int32 rtl865x_event_proc_write( struct file *filp, const char *buff,unsigned long len, void *data ); +#endif + +#endif +#endif + diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_netif.c b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_netif.c new file mode 100644 index 000000000..1fe0f0db8 --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_netif.c @@ -0,0 +1,4048 @@ +/* +* Copyright c Realtek Semiconductor Corporation, 2008 +* All rights reserved. +* +* Program : network interface driver +* Abstract : +* Author : hyking (hyking_liu@realsil.com.cn) +*/ + +/* @doc RTL_LAYEREDDRV_API + + @module rtl865x_netif.c - RTL865x Home gateway controller Layered driver API documentation | + This document explains the API interface of the table driver module. Functions with rtl865x prefix + are external functions. + @normal Hyking Liu (Hyking_liu@realsil.com.cn) <date> + + Copyright <cp>2008 Realtek<tm> Semiconductor Cooperation, All Rights Reserved. + + @head3 List of Symbols | + Here is a list of all functions and variables in this module. + + @index | RTL_LAYEREDDRV_API +*/ +#include <net/rtl/rtl_types.h> +#include <net/rtl/rtl_glue.h> +#include "rtl_errno.h" +//#include "rtl_utils.h" +//#include "rtl_glue.h" +#include <net/rtl/rtl865x_netif.h> +#include "rtl865x_netif_local.h" +#include "rtl865x_vlan.h" /*reference vlan*/ +#include "rtl865x_eventMgr.h" /*call back function....*/ +#ifdef CONFIG_RTL_LAYERED_ASIC_DRIVER +#include "AsicDriver/rtl865x_asicBasic.h" +#include "AsicDriver/rtl865x_asicCom.h" +#include "AsicDriver/rtl865x_asicL2.h" +#else +#include "AsicDriver/rtl865xC_tblAsicDrv.h" +#endif + +#if defined (CONFIG_RTL_LOCAL_PUBLIC) +//#include "rtl865x_localPublic.h" +#endif + +static rtl865x_netif_local_t *netifTbl; +static RTL_DECLARE_MUTEX(netif_sem); +#if defined (CONFIG_RTL_LOCAL_PUBLIC) +static rtl865x_netif_local_t virtualNetIf; +#endif + +static int (*rtl_get_drv_netifName_by_psName)(const char *psName,char *netifName); +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL +static rtl865x_aclBuf_t freeAclList; +static rtl865x_acl_chain_t *freeChainHead; + +#if defined(CONFIG_RTK_VLAN_SUPPORT) +static uint32 rtl865x_acl_enable = 1; //default enable +#endif + +static int32 _rtl865x_regist_aclChain(char *netifName, int32 priority,uint32 flag); +static int32 _rtl865x_unRegister_all_aclChain(char *netifName); +#endif + +static int32 _rtl865x_delNetif(char *name); +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL +int32 rtl865x_show_allAclChains(void) +{ + rtl865x_netif_local_t *netif = NULL; + rtl865x_acl_chain_t *chain; + rtl865x_AclRule_t *rule; + int32 i,j; + int8 *actionT[] = { "permit", "redirect to ether", "drop", "to cpu", "legacy drop", + "drop for log", "mirror", "redirect to pppoe", "default redirect", "mirror keep match", + "drop rate exceed pps", "log rate exceed pps", "drop rate exceed bps", "log rate exceed bps","priority " + }; + + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid == 1) + { + netif = &netifTbl[i]; + for(j = RTL865X_ACL_INGRESS; j<= RTL865X_ACL_EGRESS;j++) + { + printk("netif(%s),isEgress(%d):\n",netif->name,j); + chain = netif->chainListHead[j]; + while(chain) + { + printk("\tchain:priority(%d),rulecnt(%d)\n",chain->priority,chain->ruleCnt); + printk("===========================\n"); + rule = chain->head; + while(rule) + { + switch(rule->ruleType_) + { + case RTL865X_ACL_MAC: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Ethernet", actionT[rule->actionType_]); + printk("\tether type: %x ether type mask: %x\n", rule->typeLen_, rule->typeLenMask_); + printk("\tDMAC: %x:%x:%x:%x:%x:%x DMACM: %x:%x:%x:%x:%x:%x\n", + rule->dstMac_.octet[0], rule->dstMac_.octet[1], rule->dstMac_.octet[2], + rule->dstMac_.octet[3], rule->dstMac_.octet[4], rule->dstMac_.octet[5], + rule->dstMacMask_.octet[0], rule->dstMacMask_.octet[1], rule->dstMacMask_.octet[2], + rule->dstMacMask_.octet[3], rule->dstMacMask_.octet[4], rule->dstMacMask_.octet[5] + ); + + printk( "\tSMAC: %x:%x:%x:%x:%x:%x SMACM: %x:%x:%x:%x:%x:%x\n", + rule->srcMac_.octet[0], rule->srcMac_.octet[1], rule->srcMac_.octet[2], + rule->srcMac_.octet[3], rule->srcMac_.octet[4], rule->srcMac_.octet[5], + rule->srcMacMask_.octet[0], rule->srcMacMask_.octet[1], rule->srcMacMask_.octet[2], + rule->srcMacMask_.octet[3], rule->srcMacMask_.octet[4], rule->srcMacMask_.octet[5] + ); + break; + + case RTL865X_ACL_IP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IP", actionT[rule->actionType_]); + printk( "\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x ipProto: %x ipProtoM: %x ipFlag: %x ipFlagM: %x\n", + rule->tos_, rule->tosMask_, rule->ipProto_, rule->ipProtoMask_, rule->ipFlag_, rule->ipFlagMask_ + ); + + printk("\t<FOP:%x> <FOM:%x> <http:%x> <httpM:%x> <IdentSdip:%x> <IdentSdipM:%x> \n", + rule->ipFOP_, rule->ipFOM_, rule->ipHttpFilter_, rule->ipHttpFilterM_, rule->ipIdentSrcDstIp_, + rule->ipIdentSrcDstIpM_ + ); + printk( "\t<DF:%x> <MF:%x>\n", rule->ipDF_, rule->ipMF_); + break; + + case RTL865X_ACL_IP_RANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IP Range", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x ipProto: %x ipProtoM: %x ipFlag: %x ipFlagM: %x\n", + rule->tos_, rule->tosMask_, rule->ipProto_, rule->ipProtoMask_, rule->ipFlag_, rule->ipFlagMask_ + ); + printk("\t<FOP:%x> <FOM:%x> <http:%x> <httpM:%x> <IdentSdip:%x> <IdentSdipM:%x> \n", + rule->ipFOP_, rule->ipFOM_, rule->ipHttpFilter_, rule->ipHttpFilterM_, rule->ipIdentSrcDstIp_, + rule->ipIdentSrcDstIpM_ + ); + printk("\t<DF:%x> <MF:%x>\n", rule->ipDF_, rule->ipMF_); + break; + case RTL865X_ACL_ICMP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "ICMP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x code: %x codeM: %x\n", + rule->tos_, rule->tosMask_, rule->icmpType_, rule->icmpTypeMask_, + rule->icmpCode_, rule->icmpCodeMask_); + break; + case RTL865X_ACL_ICMP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "ICMP IP RANGE", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x code: %x codeM: %x\n", + rule->tos_, rule->tosMask_, rule->icmpType_, rule->icmpTypeMask_, + rule->icmpCode_, rule->icmpCodeMask_); + break; + case RTL865X_ACL_IGMP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IGMP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x\n", rule->tos_, rule->tosMask_, + rule->igmpType_, rule->igmpTypeMask_ + ); + break; + + + case RTL865X_ACL_IGMP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IGMP IP RANGE", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x\n", rule->tos_, rule->tosMask_, + rule->igmpType_, rule->igmpTypeMask_ + ); + break; + + case RTL865X_ACL_TCP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "TCP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->tcpSrcPortLB_, rule->tcpSrcPortUB_, + rule->tcpDstPortLB_, rule->tcpDstPortUB_ + ); + printk("\tflag: %x flagM: %x <URG:%x> <ACK:%x> <PSH:%x> <RST:%x> <SYN:%x> <FIN:%x>\n", + rule->tcpFlag_, rule->tcpFlagMask_, rule->tcpURG_, rule->tcpACK_, + rule->tcpPSH_, rule->tcpRST_, rule->tcpSYN_, rule->tcpFIN_ + ); + break; + case RTL865X_ACL_TCP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "TCP IP RANGE", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->tcpSrcPortLB_, rule->tcpSrcPortUB_, + rule->tcpDstPortLB_, rule->tcpDstPortUB_ + ); + printk("\tflag: %x flagM: %x <URG:%x> <ACK:%x> <PSH:%x> <RST:%x> <SYN:%x> <FIN:%x>\n", + rule->tcpFlag_, rule->tcpFlagMask_, rule->tcpURG_, rule->tcpACK_, + rule->tcpPSH_, rule->tcpRST_, rule->tcpSYN_, rule->tcpFIN_ + ); + break; + + case RTL865X_ACL_UDP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx,"UDP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->udpSrcPortLB_, rule->udpSrcPortUB_, + rule->udpDstPortLB_, rule->udpDstPortUB_ + ); + break; + case RTL865X_ACL_UDP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "UDP IP RANGE", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->udpSrcPortLB_, rule->udpSrcPortUB_, + rule->udpDstPortLB_, rule->udpDstPortUB_ + ); + break; + + + case RTL865X_ACL_SRCFILTER: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Source Filter", actionT[rule->actionType_]); + printk("\tSMAC: %x:%x:%x:%x:%x:%x SMACM: %x:%x:%x:%x:%x:%x\n", + rule->srcFilterMac_.octet[0], rule->srcFilterMac_.octet[1], rule->srcFilterMac_.octet[2], + rule->srcFilterMac_.octet[3], rule->srcFilterMac_.octet[4], rule->srcFilterMac_.octet[5], + rule->srcFilterMacMask_.octet[0], rule->srcFilterMacMask_.octet[1], rule->srcFilterMacMask_.octet[2], + rule->srcFilterMacMask_.octet[3], rule->srcFilterMacMask_.octet[4], rule->srcFilterMacMask_.octet[5] + ); + printk("\tsvidx: %d svidxM: %x sport: %d sportM: %x ProtoType: %x\n", + rule->srcFilterVlanIdx_, rule->srcFilterVlanIdxMask_, rule->srcFilterPort_, rule->srcFilterPortMask_, + (rule->srcFilterIgnoreL3L4_==TRUE? 2: (rule->srcFilterIgnoreL4_ == 1? 1: 0)) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcFilterIpAddr_>>24), + ((rule->srcFilterIpAddr_&0x00ff0000)>>16), ((rule->srcFilterIpAddr_&0x0000ff00)>>8), + (rule->srcFilterIpAddr_&0xff), (rule->srcFilterIpAddrMask_>>24), + ((rule->srcFilterIpAddrMask_&0x00ff0000)>>16), ((rule->srcFilterIpAddrMask_&0x0000ff00)>>8), + (rule->srcFilterIpAddrMask_&0xff) + ); + printk("\tsportL: %d sportU: %d\n", rule->srcFilterPortLowerBound_, rule->srcFilterPortUpperBound_); + break; + + case RTL865X_ACL_SRCFILTER_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Source Filter(IP RANGE)", actionT[rule->actionType_]); + printk("\tSMAC: %x:%x:%x:%x:%x:%x SMACM: %x:%x:%x:%x:%x:%x\n", + rule->srcFilterMac_.octet[0], rule->srcFilterMac_.octet[1], rule->srcFilterMac_.octet[2], + rule->srcFilterMac_.octet[3], rule->srcFilterMac_.octet[4], rule->srcFilterMac_.octet[5], + rule->srcFilterMacMask_.octet[0], rule->srcFilterMacMask_.octet[1], rule->srcFilterMacMask_.octet[2], + rule->srcFilterMacMask_.octet[3], rule->srcFilterMacMask_.octet[4], rule->srcFilterMacMask_.octet[5] + ); + printk("\tsvidx: %d svidxM: %x sport: %d sportM: %x ProtoType: %x\n", + rule->srcFilterVlanIdx_, rule->srcFilterVlanIdxMask_, rule->srcFilterPort_, rule->srcFilterPortMask_, + (rule->srcFilterIgnoreL3L4_==TRUE? 2: (rule->srcFilterIgnoreL4_ == 1? 1: 0)) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcFilterIpAddr_>>24), + ((rule->srcFilterIpAddr_&0x00ff0000)>>16), ((rule->srcFilterIpAddr_&0x0000ff00)>>8), + (rule->srcFilterIpAddr_&0xff), (rule->srcFilterIpAddrMask_>>24), + ((rule->srcFilterIpAddrMask_&0x00ff0000)>>16), ((rule->srcFilterIpAddrMask_&0x0000ff00)>>8), + (rule->srcFilterIpAddrMask_&0xff) + ); + printk("\tsportL: %d sportU: %d\n", rule->srcFilterPortLowerBound_, rule->srcFilterPortUpperBound_); + break; + + case RTL865X_ACL_DSTFILTER: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Deatination Filter", actionT[rule->actionType_]); + printk("\tDMAC: %x:%x:%x:%x:%x:%x DMACM: %x:%x:%x:%x:%x:%x\n", + rule->dstFilterMac_.octet[0], rule->dstFilterMac_.octet[1], rule->dstFilterMac_.octet[2], + rule->dstFilterMac_.octet[3], rule->dstFilterMac_.octet[4], rule->dstFilterMac_.octet[5], + rule->dstFilterMacMask_.octet[0], rule->dstFilterMacMask_.octet[1], rule->dstFilterMacMask_.octet[2], + rule->dstFilterMacMask_.octet[3], rule->dstFilterMacMask_.octet[4], rule->dstFilterMacMask_.octet[5] + ); + printk("\tdvidx: %d dvidxM: %x ProtoType: %x dportL: %d dportU: %d\n", + rule->dstFilterVlanIdx_, rule->dstFilterVlanIdxMask_, + (rule->dstFilterIgnoreL3L4_==TRUE? 2: (rule->dstFilterIgnoreL4_ == 1? 1: 0)), + rule->dstFilterPortLowerBound_, rule->dstFilterPortUpperBound_ + ); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstFilterIpAddr_>>24), + ((rule->dstFilterIpAddr_&0x00ff0000)>>16), ((rule->dstFilterIpAddr_&0x0000ff00)>>8), + (rule->dstFilterIpAddr_&0xff), (rule->dstFilterIpAddrMask_>>24), + ((rule->dstFilterIpAddrMask_&0x00ff0000)>>16), ((rule->dstFilterIpAddrMask_&0x0000ff00)>>8), + (rule->dstFilterIpAddrMask_&0xff) + ); + break; + case RTL865X_ACL_DSTFILTER_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Deatination Filter(IP Range)", actionT[rule->actionType_]); + printk("\tDMAC: %x:%x:%x:%x:%x:%x DMACM: %x:%x:%x:%x:%x:%x\n", + rule->dstFilterMac_.octet[0], rule->dstFilterMac_.octet[1], rule->dstFilterMac_.octet[2], + rule->dstFilterMac_.octet[3], rule->dstFilterMac_.octet[4], rule->dstFilterMac_.octet[5], + rule->dstFilterMacMask_.octet[0], rule->dstFilterMacMask_.octet[1], rule->dstFilterMacMask_.octet[2], + rule->dstFilterMacMask_.octet[3], rule->dstFilterMacMask_.octet[4], rule->dstFilterMacMask_.octet[5] + ); + printk("\tdvidx: %d dvidxM: %x ProtoType: %x dportL: %d dportU: %d\n", + rule->dstFilterVlanIdx_, rule->dstFilterVlanIdxMask_, + (rule->dstFilterIgnoreL3L4_==TRUE? 2: (rule->dstFilterIgnoreL4_ == 1? 1: 0)), + rule->dstFilterPortLowerBound_, rule->dstFilterPortUpperBound_ + ); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstFilterIpAddr_>>24), + ((rule->dstFilterIpAddr_&0x00ff0000)>>16), ((rule->dstFilterIpAddr_&0x0000ff00)>>8), + (rule->dstFilterIpAddr_&0xff), (rule->dstFilterIpAddrMask_>>24), + ((rule->dstFilterIpAddrMask_&0x00ff0000)>>16), ((rule->dstFilterIpAddrMask_&0x0000ff00)>>8), + (rule->dstFilterIpAddrMask_&0xff) + ); + break; + + default: + printk("rule->ruleType_(0x%x)\n", rule->ruleType_); + + } + + switch (rule->actionType_) + { + case RTL865X_ACL_PERMIT: + case RTL865X_ACL_REDIRECT_ETHER: + case RTL865X_ACL_DROP: + case RTL865X_ACL_TOCPU: + case RTL865X_ACL_LEGACY_DROP: + case RTL865X_ACL_DROPCPU_LOG: + case RTL865X_ACL_MIRROR: + case RTL865X_ACL_REDIRECT_PPPOE: + case RTL865X_ACL_MIRROR_KEEP_MATCH: + printk("\tnetifIdx: %d pppoeIdx: %d l2Idx:%d ", rule->netifIdx_, rule->pppoeIdx_, rule->L2Idx_); + break; + + case RTL865X_ACL_PRIORITY: + printk("\tprioirty: %d ", rule->priority_) ; + break; + + case RTL865X_ACL_DEFAULT_REDIRECT: + printk("\tnextHop:%d ", rule->nexthopIdx_); + break; + + case RTL865X_ACL_DROP_RATE_EXCEED_PPS: + case RTL865X_ACL_LOG_RATE_EXCEED_PPS: + case RTL865X_ACL_DROP_RATE_EXCEED_BPS: + case RTL865X_ACL_LOG_RATE_EXCEED_BPS: + printk("\tratelimitIdx: %d ", rule->ratelimtIdx_); + break; + default: + ; + + } + printk("pktOpApp: %d\n", rule->pktOpApp_); + + rule = rule->next; + } + printk("===========================\n"); + chain = chain->nextChain; + } + printk("--------------------------------\n\n"); + } + + } + } + +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + { + if(virtualNetIf.valid == 1) + { + netif = &virtualNetIf; + for(j = RTL865X_ACL_INGRESS; j<= RTL865X_ACL_EGRESS;j++) + { + printk("netif(%s),isEgress(%d):\n",netif->name,j); + chain = netif->chainListHead[j]; + while(chain) + { + printk("\tchain:priority(%d),rulecnt(%d)\n",chain->priority,chain->ruleCnt); + printk("===========================\n"); + rule = chain->head; + while(rule) + { + switch(rule->ruleType_) + { + case RTL865X_ACL_MAC: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Ethernet", actionT[rule->actionType_]); + printk("\tether type: %x ether type mask: %x\n", rule->typeLen_, rule->typeLenMask_); + printk("\tDMAC: %x:%x:%x:%x:%x:%x DMACM: %x:%x:%x:%x:%x:%x\n", + rule->dstMac_.octet[0], rule->dstMac_.octet[1], rule->dstMac_.octet[2], + rule->dstMac_.octet[3], rule->dstMac_.octet[4], rule->dstMac_.octet[5], + rule->dstMacMask_.octet[0], rule->dstMacMask_.octet[1], rule->dstMacMask_.octet[2], + rule->dstMacMask_.octet[3], rule->dstMacMask_.octet[4], rule->dstMacMask_.octet[5] + ); + + printk( "\tSMAC: %x:%x:%x:%x:%x:%x SMACM: %x:%x:%x:%x:%x:%x\n", + rule->srcMac_.octet[0], rule->srcMac_.octet[1], rule->srcMac_.octet[2], + rule->srcMac_.octet[3], rule->srcMac_.octet[4], rule->srcMac_.octet[5], + rule->srcMacMask_.octet[0], rule->srcMacMask_.octet[1], rule->srcMacMask_.octet[2], + rule->srcMacMask_.octet[3], rule->srcMacMask_.octet[4], rule->srcMacMask_.octet[5] + ); + break; + + case RTL865X_ACL_IP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IP", actionT[rule->actionType_]); + printk( "\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x ipProto: %x ipProtoM: %x ipFlag: %x ipFlagM: %x\n", + rule->tos_, rule->tosMask_, rule->ipProto_, rule->ipProtoMask_, rule->ipFlag_, rule->ipFlagMask_ + ); + + printk("\t<FOP:%x> <FOM:%x> <http:%x> <httpM:%x> <IdentSdip:%x> <IdentSdipM:%x> \n", + rule->ipFOP_, rule->ipFOM_, rule->ipHttpFilter_, rule->ipHttpFilterM_, rule->ipIdentSrcDstIp_, + rule->ipIdentSrcDstIpM_ + ); + printk( "\t<DF:%x> <MF:%x>\n", rule->ipDF_, rule->ipMF_); + break; + + case RTL865X_ACL_IP_RANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IP Range", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x ipProto: %x ipProtoM: %x ipFlag: %x ipFlagM: %x\n", + rule->tos_, rule->tosMask_, rule->ipProto_, rule->ipProtoMask_, rule->ipFlag_, rule->ipFlagMask_ + ); + printk("\t<FOP:%x> <FOM:%x> <http:%x> <httpM:%x> <IdentSdip:%x> <IdentSdipM:%x> \n", + rule->ipFOP_, rule->ipFOM_, rule->ipHttpFilter_, rule->ipHttpFilterM_, rule->ipIdentSrcDstIp_, + rule->ipIdentSrcDstIpM_ + ); + printk("\t<DF:%x> <MF:%x>\n", rule->ipDF_, rule->ipMF_); + break; + case RTL865X_ACL_ICMP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "ICMP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x code: %x codeM: %x\n", + rule->tos_, rule->tosMask_, rule->icmpType_, rule->icmpTypeMask_, + rule->icmpCode_, rule->icmpCodeMask_); + break; + case RTL865X_ACL_ICMP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "ICMP IP RANGE", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x code: %x codeM: %x\n", + rule->tos_, rule->tosMask_, rule->icmpType_, rule->icmpTypeMask_, + rule->icmpCode_, rule->icmpCodeMask_); + break; + case RTL865X_ACL_IGMP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IGMP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x\n", rule->tos_, rule->tosMask_, + rule->igmpType_, rule->igmpTypeMask_ + ); + break; + + + case RTL865X_ACL_IGMP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "IGMP IP RANGE", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos: %x TosM: %x type: %x typeM: %x\n", rule->tos_, rule->tosMask_, + rule->igmpType_, rule->igmpTypeMask_ + ); + break; + + case RTL865X_ACL_TCP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "TCP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->tcpSrcPortLB_, rule->tcpSrcPortUB_, + rule->tcpDstPortLB_, rule->tcpDstPortUB_ + ); + printk("\tflag: %x flagM: %x <URG:%x> <ACK:%x> <PSH:%x> <RST:%x> <SYN:%x> <FIN:%x>\n", + rule->tcpFlag_, rule->tcpFlagMask_, rule->tcpURG_, rule->tcpACK_, + rule->tcpPSH_, rule->tcpRST_, rule->tcpSYN_, rule->tcpFIN_ + ); + break; + case RTL865X_ACL_TCP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "TCP IP RANGE", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->tcpSrcPortLB_, rule->tcpSrcPortUB_, + rule->tcpDstPortLB_, rule->tcpDstPortUB_ + ); + printk("\tflag: %x flagM: %x <URG:%x> <ACK:%x> <PSH:%x> <RST:%x> <SYN:%x> <FIN:%x>\n", + rule->tcpFlag_, rule->tcpFlagMask_, rule->tcpURG_, rule->tcpACK_, + rule->tcpPSH_, rule->tcpRST_, rule->tcpSYN_, rule->tcpFIN_ + ); + break; + + case RTL865X_ACL_UDP: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx,"UDP", actionT[rule->actionType_]); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->udpSrcPortLB_, rule->udpSrcPortUB_, + rule->udpDstPortLB_, rule->udpDstPortUB_ + ); + break; + case RTL865X_ACL_UDP_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "UDP IP RANGE", actionT[rule->actionType_]); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstIpAddr_>>24), + ((rule->dstIpAddr_&0x00ff0000)>>16), ((rule->dstIpAddr_&0x0000ff00)>>8), + (rule->dstIpAddr_&0xff), (rule->dstIpAddrMask_>>24), ((rule->dstIpAddrMask_&0x00ff0000)>>16), + ((rule->dstIpAddrMask_&0x0000ff00)>>8), (rule->dstIpAddrMask_&0xff) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcIpAddr_>>24), + ((rule->srcIpAddr_&0x00ff0000)>>16), ((rule->srcIpAddr_&0x0000ff00)>>8), + (rule->srcIpAddr_&0xff), (rule->srcIpAddrMask_>>24), ((rule->srcIpAddrMask_&0x00ff0000)>>16), + ((rule->srcIpAddrMask_&0x0000ff00)>>8), (rule->srcIpAddrMask_&0xff) + ); + printk("\tTos:%x TosM:%x sportL:%d sportU:%d dportL:%d dportU:%d\n", + rule->tos_, rule->tosMask_, rule->udpSrcPortLB_, rule->udpSrcPortUB_, + rule->udpDstPortLB_, rule->udpDstPortUB_ + ); + break; + + + case RTL865X_ACL_SRCFILTER: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Source Filter", actionT[rule->actionType_]); + printk("\tSMAC: %x:%x:%x:%x:%x:%x SMACM: %x:%x:%x:%x:%x:%x\n", + rule->srcFilterMac_.octet[0], rule->srcFilterMac_.octet[1], rule->srcFilterMac_.octet[2], + rule->srcFilterMac_.octet[3], rule->srcFilterMac_.octet[4], rule->srcFilterMac_.octet[5], + rule->srcFilterMacMask_.octet[0], rule->srcFilterMacMask_.octet[1], rule->srcFilterMacMask_.octet[2], + rule->srcFilterMacMask_.octet[3], rule->srcFilterMacMask_.octet[4], rule->srcFilterMacMask_.octet[5] + ); + printk("\tsvidx: %d svidxM: %x sport: %d sportM: %x ProtoType: %x\n", + rule->srcFilterVlanIdx_, rule->srcFilterVlanIdxMask_, rule->srcFilterPort_, rule->srcFilterPortMask_, + (rule->srcFilterIgnoreL3L4_==TRUE? 2: (rule->srcFilterIgnoreL4_ == 1? 1: 0)) + ); + printk("\tsip: %d.%d.%d.%d sipM: %d.%d.%d.%d\n", (rule->srcFilterIpAddr_>>24), + ((rule->srcFilterIpAddr_&0x00ff0000)>>16), ((rule->srcFilterIpAddr_&0x0000ff00)>>8), + (rule->srcFilterIpAddr_&0xff), (rule->srcFilterIpAddrMask_>>24), + ((rule->srcFilterIpAddrMask_&0x00ff0000)>>16), ((rule->srcFilterIpAddrMask_&0x0000ff00)>>8), + (rule->srcFilterIpAddrMask_&0xff) + ); + printk("\tsportL: %d sportU: %d\n", rule->srcFilterPortLowerBound_, rule->srcFilterPortUpperBound_); + break; + + case RTL865X_ACL_SRCFILTER_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Source Filter(IP RANGE)", actionT[rule->actionType_]); + printk("\tSMAC: %x:%x:%x:%x:%x:%x SMACM: %x:%x:%x:%x:%x:%x\n", + rule->srcFilterMac_.octet[0], rule->srcFilterMac_.octet[1], rule->srcFilterMac_.octet[2], + rule->srcFilterMac_.octet[3], rule->srcFilterMac_.octet[4], rule->srcFilterMac_.octet[5], + rule->srcFilterMacMask_.octet[0], rule->srcFilterMacMask_.octet[1], rule->srcFilterMacMask_.octet[2], + rule->srcFilterMacMask_.octet[3], rule->srcFilterMacMask_.octet[4], rule->srcFilterMacMask_.octet[5] + ); + printk("\tsvidx: %d svidxM: %x sport: %d sportM: %x ProtoType: %x\n", + rule->srcFilterVlanIdx_, rule->srcFilterVlanIdxMask_, rule->srcFilterPort_, rule->srcFilterPortMask_, + (rule->srcFilterIgnoreL3L4_==TRUE? 2: (rule->srcFilterIgnoreL4_ == 1? 1: 0)) + ); + printk("\tsipU: %d.%d.%d.%d sipL: %d.%d.%d.%d\n", (rule->srcFilterIpAddr_>>24), + ((rule->srcFilterIpAddr_&0x00ff0000)>>16), ((rule->srcFilterIpAddr_&0x0000ff00)>>8), + (rule->srcFilterIpAddr_&0xff), (rule->srcFilterIpAddrMask_>>24), + ((rule->srcFilterIpAddrMask_&0x00ff0000)>>16), ((rule->srcFilterIpAddrMask_&0x0000ff00)>>8), + (rule->srcFilterIpAddrMask_&0xff) + ); + printk("\tsportL: %d sportU: %d\n", rule->srcFilterPortLowerBound_, rule->srcFilterPortUpperBound_); + break; + + case RTL865X_ACL_DSTFILTER: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Deatination Filter", actionT[rule->actionType_]); + printk("\tDMAC: %x:%x:%x:%x:%x:%x DMACM: %x:%x:%x:%x:%x:%x\n", + rule->dstFilterMac_.octet[0], rule->dstFilterMac_.octet[1], rule->dstFilterMac_.octet[2], + rule->dstFilterMac_.octet[3], rule->dstFilterMac_.octet[4], rule->dstFilterMac_.octet[5], + rule->dstFilterMacMask_.octet[0], rule->dstFilterMacMask_.octet[1], rule->dstFilterMacMask_.octet[2], + rule->dstFilterMacMask_.octet[3], rule->dstFilterMacMask_.octet[4], rule->dstFilterMacMask_.octet[5] + ); + printk("\tdvidx: %d dvidxM: %x ProtoType: %x dportL: %d dportU: %d\n", + rule->dstFilterVlanIdx_, rule->dstFilterVlanIdxMask_, + (rule->dstFilterIgnoreL3L4_==TRUE? 2: (rule->dstFilterIgnoreL4_ == 1? 1: 0)), + rule->dstFilterPortLowerBound_, rule->dstFilterPortUpperBound_ + ); + printk("\tdip: %d.%d.%d.%d dipM: %d.%d.%d.%d\n", (rule->dstFilterIpAddr_>>24), + ((rule->dstFilterIpAddr_&0x00ff0000)>>16), ((rule->dstFilterIpAddr_&0x0000ff00)>>8), + (rule->dstFilterIpAddr_&0xff), (rule->dstFilterIpAddrMask_>>24), + ((rule->dstFilterIpAddrMask_&0x00ff0000)>>16), ((rule->dstFilterIpAddrMask_&0x0000ff00)>>8), + (rule->dstFilterIpAddrMask_&0xff) + ); + break; + case RTL865X_ACL_DSTFILTER_IPRANGE: + printk(" [%d] rule type: %s rule action: %s\n", rule->aclIdx, "Deatination Filter(IP Range)", actionT[rule->actionType_]); + printk("\tDMAC: %x:%x:%x:%x:%x:%x DMACM: %x:%x:%x:%x:%x:%x\n", + rule->dstFilterMac_.octet[0], rule->dstFilterMac_.octet[1], rule->dstFilterMac_.octet[2], + rule->dstFilterMac_.octet[3], rule->dstFilterMac_.octet[4], rule->dstFilterMac_.octet[5], + rule->dstFilterMacMask_.octet[0], rule->dstFilterMacMask_.octet[1], rule->dstFilterMacMask_.octet[2], + rule->dstFilterMacMask_.octet[3], rule->dstFilterMacMask_.octet[4], rule->dstFilterMacMask_.octet[5] + ); + printk("\tdvidx: %d dvidxM: %x ProtoType: %x dportL: %d dportU: %d\n", + rule->dstFilterVlanIdx_, rule->dstFilterVlanIdxMask_, + (rule->dstFilterIgnoreL3L4_==TRUE? 2: (rule->dstFilterIgnoreL4_ == 1? 1: 0)), + rule->dstFilterPortLowerBound_, rule->dstFilterPortUpperBound_ + ); + printk("\tdipU: %d.%d.%d.%d dipL: %d.%d.%d.%d\n", (rule->dstFilterIpAddr_>>24), + ((rule->dstFilterIpAddr_&0x00ff0000)>>16), ((rule->dstFilterIpAddr_&0x0000ff00)>>8), + (rule->dstFilterIpAddr_&0xff), (rule->dstFilterIpAddrMask_>>24), + ((rule->dstFilterIpAddrMask_&0x00ff0000)>>16), ((rule->dstFilterIpAddrMask_&0x0000ff00)>>8), + (rule->dstFilterIpAddrMask_&0xff) + ); + break; + + default: + printk("rule->ruleType_(0x%x)\n", rule->ruleType_); + + } + + switch (rule->actionType_) + { + case RTL865X_ACL_PERMIT: + case RTL865X_ACL_REDIRECT_ETHER: + case RTL865X_ACL_DROP: + case RTL865X_ACL_TOCPU: + case RTL865X_ACL_LEGACY_DROP: + case RTL865X_ACL_DROPCPU_LOG: + case RTL865X_ACL_MIRROR: + case RTL865X_ACL_REDIRECT_PPPOE: + case RTL865X_ACL_MIRROR_KEEP_MATCH: + printk("\tnetifIdx: %d pppoeIdx: %d l2Idx:%d ", rule->netifIdx_, rule->pppoeIdx_, rule->L2Idx_); + break; + + case RTL865X_ACL_PRIORITY: + printk("\tprioirty: %d ", rule->priority_) ; + break; + + case RTL865X_ACL_DEFAULT_REDIRECT: + printk("\tnextHop:%d ", rule->nexthopIdx_); + break; + + case RTL865X_ACL_DROP_RATE_EXCEED_PPS: + case RTL865X_ACL_LOG_RATE_EXCEED_PPS: + case RTL865X_ACL_DROP_RATE_EXCEED_BPS: + case RTL865X_ACL_LOG_RATE_EXCEED_BPS: + printk("\tratelimitIdx: %d ", rule->ratelimtIdx_); + break; + default: + ; + + } + printk("pktOpApp: %d\n", rule->pktOpApp_); + + rule = rule->next; + } + printk("===========================\n"); + chain = chain->nextChain; + } + printk("--------------------------------\n\n"); + } + + } + } +#endif + return SUCCESS; + +} + + +#if RTL_LAYERED_DRIVER_DEBUG + +static int32 _rtl865x_print_allChain_allAcl(rtl865x_netif_local_t *netif) +{ + rtl865x_acl_chain_t *chain; + rtl865x_AclRule_t *rule; + int32 i; + + for(i = RTL865X_ACL_INGRESS; i<= RTL865X_ACL_EGRESS;i++) + { + printk("netif(%s),isEgress(%d):\n",netif->name,i); + chain = netif->chainListHead[i]; + while(chain) + { + printk("\tchain:priority(%d),rulecnt(%d)\n",chain->priority,chain->ruleCnt); + printk("===========================\n"); + rule = chain->head; + while(rule) + { + printk("\tIdx%d: aclIdx(%d),ruleType(%d),action(%d),direction(%d),pktOpApp(%d)\n", rule->aclIdx,rule->aclIdx,rule->ruleType_,rule->actionType_,rule->direction_,rule->pktOpApp_); + rule = rule->next; + } + printk("===========================\n"); + chain = chain->nextChain; + } + printk("--------------------------------\n\n"); + } + return SUCCESS; + +} + + +static int32 _rtl865x_print_freeChainNum(void) +{ + rtl865x_acl_chain_t *entry; + rtl865x_AclRule_t *acl; + int32 freeCnt = 0; + + entry = freeChainHead; + while(entry) + { + freeCnt++; + entry = entry->nextChain; + } + printk("the free chain number is: %d\n",freeCnt); + + acl = freeAclList.freeHead; + freeCnt = 0; + while(acl) + { + freeCnt++; + acl = acl->next; + } + printk("freeAclList total(%d),free(%d),in fact free(%d)\n",freeAclList.totalCnt,freeAclList.freeCnt,freeCnt); + return SUCCESS; +} + +#endif + +#endif //CONFIG_RTL_LAYERED_DRIVER_ACL +static int32 _rtl865x_setAsicNetif(rtl865x_netif_local_t *entry) +{ + int32 retval = FAILED; + rtl865x_tblAsicDrv_intfParam_t asicEntry; + + if(entry->is_slave == 1) + return retval; +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + if(entry==(&virtualNetIf)) + { + return FAILED; + } +#endif + memset(&asicEntry,0,sizeof(rtl865x_tblAsicDrv_intfParam_t)); + asicEntry.enableRoute = entry->enableRoute; + asicEntry.inAclStart = entry->inAclStart; + asicEntry.inAclEnd = entry->inAclEnd; + asicEntry.outAclStart = entry->outAclStart; + asicEntry.outAclEnd = entry->outAclEnd; + //asicEntry.macAddr = entry->macAddr; + memcpy(asicEntry.macAddr.octet,entry->macAddr.octet,ETHER_ADDR_LEN); + asicEntry.macAddrNumber = entry->macAddrNumber; + asicEntry.mtu = entry->mtu; + asicEntry.vid = entry->vid; + asicEntry.valid = entry->valid; + + + + retval = rtl8651_setAsicNetInterface( entry->asicIdx, &asicEntry); + return retval; + +} + +rtl865x_netif_local_t *_rtl865x_getSWNetifByName(char *name) +{ + int32 i; + rtl865x_netif_local_t *netif = NULL; + + if(name == NULL) + return NULL; + + for(i = 0; i < NETIF_NUMBER; i++) + { + //printk("%s:%d,i(%d),valid(%d),ifname(%s),strlen of name(%d), netifTbl(0x%p),netifTblName(%s)\n",__FUNCTION__,__LINE__,i,netifTbl[i].valid,name,strlen(name),&netifTbl[i],netifTbl[i].name); + if(netifTbl[i].valid == 1 && strlen(name) == strlen(netifTbl[i].name) && memcmp(netifTbl[i].name,name,strlen(name)) == 0) + { + netif = &netifTbl[i]; + break; + } + } + + #if defined (CONFIG_RTL_LOCAL_PUBLIC) + if(virtualNetIf.valid == 1 && strlen(name) == strlen(virtualNetIf.name) && memcmp(virtualNetIf.name,name,strlen(name)) == 0) + { + netif = &virtualNetIf; + + } + #endif + + return netif; +} + +rtl865x_netif_local_t *_rtl865x_getNetifByName(char *name) +{ + int32 i; + rtl865x_netif_local_t *netif = NULL; + + if(name == NULL) + return NULL; + + for(i = 0; i < NETIF_NUMBER; i++) + { + //printk("i(%d),ifname(%s),netifTbl(0x%p),netifTblName(%s)\n",i,name,&netifTbl[i],netifTbl[i].name); + if(netifTbl[i].valid == 1 && strlen(name) == strlen(netifTbl[i].name) && memcmp(netifTbl[i].name,name,strlen(name)) == 0) + { + if(netifTbl[i].is_slave == 0) + netif = &netifTbl[i]; + else + { + netif = netifTbl[i].master; + } + break; + } + } + #if defined (CONFIG_RTL_LOCAL_PUBLIC) + if(virtualNetIf.valid == 1 && strlen(name) == strlen(virtualNetIf.name) && memcmp(virtualNetIf.name,name,strlen(name)) == 0) + { + netif = &virtualNetIf; + + } + #endif + return netif; +} + +rtl865x_netif_local_t *_rtl865x_getDefaultWanNetif(void) +{ + int32 i; + rtl865x_netif_local_t *firstWan, *defNetif; + firstWan = defNetif = NULL; + + for(i = 0; i < NETIF_NUMBER; i++) + { + //printk("i(%d),netifTbl(0x%p)\n",i,&netifTbl[i]); + if(netifTbl[i].valid == 1 && netifTbl[i].is_wan == 1 && firstWan == NULL) + firstWan = &netifTbl[i]; + + if(netifTbl[i].valid == 1 && netifTbl[i].is_defaultWan == 1) + { + defNetif = &netifTbl[i]; + break; + } + } + + /*if not found default wan, return wan interface first found*/ + if(defNetif == NULL) + { + defNetif = firstWan; + } + + return defNetif; + +} + +int32 _rtl865x_setDefaultWanNetif(char *name) +{ + rtl865x_netif_local_t *entry; + entry = _rtl865x_getSWNetifByName(name); + + //printk("set default wan interface....(%s)\n",name); + if(entry) + entry->is_defaultWan = 1; + + return SUCCESS; +} + +int32 _rtl865x_clearDefaultWanNetif(char *name) +{ + rtl865x_netif_local_t *entry; + entry = _rtl865x_getSWNetifByName(name); + + //printk("set default wan interface....(%s)\n",name); + if(entry) + entry->is_defaultWan = 0; + + return SUCCESS; +} + +static int32 _rtl865x_attachMasterNetif(char *slave, char *master) +{ + rtl865x_netif_local_t *slave_netif, *master_netif; + + slave_netif = _rtl865x_getSWNetifByName(slave); + master_netif = _rtl865x_getNetifByName(master); + + if(slave_netif == NULL || master_netif == NULL) + return RTL_EENTRYNOTFOUND; + + //printk("===%s(%d),slave(%s),master(%s),slave_netif->master(0x%p)\n",__FUNCTION__,__LINE__,slave,master,slave_netif->master); + if(slave_netif->master != NULL) + return RTL_EENTRYALREADYEXIST; + + slave_netif ->master = master_netif; + + return SUCCESS; + +} + +static int32 _rtl865x_detachMasterNetif(char *slave) +{ + rtl865x_netif_local_t *slave_netif; + + slave_netif = _rtl865x_getSWNetifByName(slave); + + if(slave_netif == NULL) + return RTL_EENTRYNOTFOUND; + + slave_netif ->master = NULL; + + return SUCCESS; +} + +int32 _rtl865x_addNetif(rtl865x_netif_t *netif) +{ + rtl865x_netif_local_t *entry; + int32 retval = FAILED; + int32 i; +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + int asicIdx; + rtl865xc_tblAsic_netifTable_t asicEntry; +#endif + if(netif == NULL) + return RTL_EINVALIDINPUT; + + /*duplicate entry....*/ + entry = _rtl865x_getSWNetifByName(netif->name); + if(entry) + return RTL_EENTRYALREADYEXIST; + + /*get netif buffer*/ + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid == 0) + break; + } + +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + for (asicIdx=0;asicIdx<RTL865XC_NETIFTBL_SIZE;asicIdx++) + { + _rtl8651_readAsicEntry(TYPE_NETINTERFACE_TABLE, asicIdx, &asicEntry); + if (asicEntry.valid==0) + { + break; + } + } + if(netif->forMacBasedMCast==TRUE) + { + asicIdx=RTL865XC_NETIFTBL_SIZE-1; + } +#endif + + if(i == NETIF_NUMBER) + return RTL_ENOFREEBUFFER; + + /*add new entry*/ + entry = &netifTbl[i]; + + #if defined (CONFIG_RTL_LOCAL_PUBLIC) + memset(entry, 0, sizeof(rtl865x_netif_local_t)); + #endif + + entry->valid = 1; + entry->mtu = netif->mtu; + entry->if_type = netif->if_type; + entry->macAddr = netif->macAddr; + entry->vid = netif->vid; + entry->is_wan = netif->is_wan; + entry->dmz = netif->dmz; + entry->is_slave = netif->is_slave; + memcpy(entry->name,netif->name,MAX_IFNAMESIZE); + + /*private number...*/ +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + entry->asicIdx=asicIdx; +#else + entry->asicIdx = i; +#endif + entry->enableRoute = netif->enableRoute; + entry->macAddrNumber = 1; + entry->inAclEnd = entry->inAclStart = entry->outAclEnd = entry->outAclStart = RTL865X_ACLTBL_PERMIT_ALL; /*default permit...*/ + entry->refCnt = 1; + entry->master = NULL; + +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL + //ingress acl chains head + entry->chainListHead[RTL865X_ACL_INGRESS] = NULL; + + //init egress acl + entry->chainListHead[RTL865X_ACL_EGRESS] = NULL; +#endif + + /*only write master interface into ASIC*/ + if(entry->is_slave == 0) + { + retval = _rtl865x_setAsicNetif(entry); + if(retval == SUCCESS) + rtl865x_referVlan(entry->vid); + +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL + /*register 2 ingress chains: system/user*/ + retval = rtl865x_regist_aclChain(netif->name, RTL865X_ACL_SYSTEM_USED, RTL865X_ACL_INGRESS); +#if RTL_LAYERED_DRIVER_DEBUG + printk("register system acl chain, return %d\n",retval); + _rtl865x_print_freeChainNum(); +#endif + retval = rtl865x_regist_aclChain(netif->name, RTL865X_ACL_USER_USED, RTL865X_ACL_INGRESS); + retval = rtl865x_regist_aclChain(netif->name, RTL865X_ACL_USER_USED, RTL865X_ACL_EGRESS); + +#if RTL_LAYERED_DRIVER_DEBUG + printk("register user acl chain, return %d\n",retval); + _rtl865x_print_freeChainNum(); +#endif + +#if defined(CONFIG_RTL_HW_QOS_SUPPORT) + retval = rtl865x_regist_aclChain(netif->name, RTL865X_ACL_QOS_USED0, RTL865X_ACL_INGRESS); + retval = rtl865x_regist_aclChain(netif->name, RTL865X_ACL_QOS_USED1, RTL865X_ACL_INGRESS); +#endif +#endif //CONFIG_RTL_LAYERED_DRIVER_ACL + } + + + return SUCCESS; +} + +static int32 _rtl865x_delNetif(char *name) +{ + rtl865x_netif_local_t *entry; + int32 retval = FAILED; + + /*FIXME:hyking, get swNetif entry.....*/ + entry = _rtl865x_getSWNetifByName(name); + if(entry == NULL) + return RTL_EENTRYNOTFOUND; + + if(entry->refCnt > 1) + { + printk("name(%s),refcnt(%d)\n",name,entry->refCnt); + return RTL_EREFERENCEDBYOTHER; + } + + if(entry->is_slave == 0) + { +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL + retval = _rtl865x_unRegister_all_aclChain(name); +#endif + + retval = rtl865x_delNetInterfaceByVid(entry->vid); + if(retval == SUCCESS) + { + rtl865x_deReferVlan(entry->vid); + + /*flush acl*/ + #if 0 + do_eventAction(EV_DEL_NETIF, (void*)entry); + #else + rtl865x_raiseEvent(EVENT_DEL_NETIF, (void*)entry); + #endif + } + + /*now delete all slave interface whose master is the deleting master interface*/ + { + int32 i ; + + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid == 1 && netifTbl[i].is_slave == 1 && netifTbl[i].master == entry) + netifTbl[i].master = NULL; + } + } +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL +#if RTL_LAYERED_DRIVER_DEBUG + printk("unregist all acl chain, return %d\n",retval); + _rtl865x_print_freeChainNum(); +#endif +#endif + } + + //entry->valid = 0; + memset(entry,0,sizeof(rtl865x_netif_local_t)); + retval = SUCCESS; + + return retval; +} + +static int32 _rtl865x_referNetif(char *ifName) +{ + rtl865x_netif_local_t *entry; + if(ifName == NULL) + return FAILED; + + entry = _rtl865x_getSWNetifByName(ifName); + if(entry == NULL) + return RTL_EENTRYNOTFOUND; + + entry->refCnt++; + return SUCCESS; +} + +static int32 _rtl865x_deReferNetif(char *ifName) +{ + rtl865x_netif_local_t *entry; + if(ifName == NULL) + return FAILED; + + entry = _rtl865x_getSWNetifByName(ifName); + if(entry == NULL) + return RTL_EENTRYNOTFOUND; + + entry->refCnt--; + + return SUCCESS; +} + +static int32 _rtl865x_setNetifVid(char *name, uint16 vid) +{ + rtl865x_netif_local_t *entry; + + if(name == NULL || vid < 1 ||vid > 4095) + return RTL_EINVALIDINPUT; + + entry = _rtl865x_getSWNetifByName(name); + + if(entry == NULL) + return RTL_EENTRYNOTFOUND; + + if(entry->vid > 0 && entry->vid <= 4095) + rtl865x_deReferVlan(entry->vid); + + entry->vid = vid; + + /*update asic table*/ + if (entry->is_slave) + return SUCCESS; + else + return _rtl865x_setAsicNetif(entry); +} + + +static int32 _rtl865x_setNetifType(char *name, uint32 ifType) +{ + rtl865x_netif_local_t *entry; + + if(name == NULL || ifType <= IF_NONE ||ifType > IF_L2TP) + return RTL_EINVALIDINPUT; + + entry = _rtl865x_getSWNetifByName(name); + + if(entry == NULL) + return RTL_EENTRYNOTFOUND; + + entry->if_type = ifType; + + return SUCCESS; +} + +int32 _rtl865x_setNetifMac(rtl865x_netif_t *netif) +{ + int32 retval = FAILED; + rtl865x_netif_local_t *entry; + + if(netif == NULL) + return RTL_EINVALIDINPUT; + entry = _rtl865x_getNetifByName(netif->name); + + if(entry == NULL) + return RTL_EENTRYNOTFOUND; + + entry->macAddr = netif->macAddr; + + /*update asic table*/ + retval = _rtl865x_setAsicNetif(entry); + + return retval; + +} + +int32 _rtl865x_setNetifMtu(rtl865x_netif_t *netif) +{ + int32 retval = FAILED; + rtl865x_netif_local_t *entry; + entry = _rtl865x_getNetifByName(netif->name); + + if(entry == NULL) + return RTL_EENTRYNOTFOUND; + + entry->mtu = netif->mtu; + + /*update asic table*/ + retval = _rtl865x_setAsicNetif(entry); + + return retval; + +} + +int32 _rtl865x_getNetifIdxByVid(uint16 vid) +{ + int32 i; + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid == 1 && netifTbl[i].vid == vid) + break; + } + + if(i == NETIF_NUMBER) + return -1; + + return i; +} + +int32 _rtl865x_getNetifIdxByName(uint8 *name) +{ + int32 i; + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid == 1 && memcmp(netifTbl[i].name,name,strlen(name)) == 0) + break; + } + + if(i == NETIF_NUMBER) + return -1; + + return i; +} + +int32 _rtl865x_getNetifIdxByNameExt(uint8 *name) +{ + int32 i; + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid == 1 && memcmp(netifTbl[i].name,name,strlen(name)) == 0) + { + if (netifTbl[i].is_slave==TRUE) + { + if(netifTbl[i].master) + return _rtl865x_getNetifIdxByNameExt(netifTbl[i].master->name); + else + return -1; + } + else + return i; + } + } + + return -1; +} + +int32 _rtl865x_getAclFromAsic(int32 index, rtl865x_AclRule_t *rule) +{ + rtl865xc_tblAsic_aclTable_t entry; + + if(index >= RTL865X_ACL_MAX_NUMBER + RTL865X_ACL_RESERVED_NUMBER || rule == NULL) + return FAILED; + _rtl8651_readAsicEntry(TYPE_ACL_RULE_TABLE, index, &entry); + bzero(rule, sizeof(rtl865x_AclRule_t)); + + switch(entry.ruleType) { + + case RTL865X_ACL_MAC: /* Ethernet rule type */ + rule->dstMac_.octet[0] = entry.is.ETHERNET.dMacP47_32 >> 8; + rule->dstMac_.octet[1] = entry.is.ETHERNET.dMacP47_32 & 0xff; + rule->dstMac_.octet[2] = entry.is.ETHERNET.dMacP31_16 >> 8; + rule->dstMac_.octet[3] = entry.is.ETHERNET.dMacP31_16 & 0xff; + rule->dstMac_.octet[4] = entry.is.ETHERNET.dMacP15_0 >> 8; + rule->dstMac_.octet[5] = entry.is.ETHERNET.dMacP15_0 & 0xff; + rule->dstMacMask_.octet[0] = entry.is.ETHERNET.dMacM47_32 >> 8; + rule->dstMacMask_.octet[1] = entry.is.ETHERNET.dMacM47_32 & 0xff; + rule->dstMacMask_.octet[2] = entry.is.ETHERNET.dMacM31_16 >> 8; + rule->dstMacMask_.octet[3] = entry.is.ETHERNET.dMacM31_16 & 0xff; + rule->dstMacMask_.octet[4] = entry.is.ETHERNET.dMacM15_0 >> 8; + rule->dstMacMask_.octet[5] = entry.is.ETHERNET.dMacM15_0 & 0xff; + rule->srcMac_.octet[0] = entry.is.ETHERNET.sMacP47_32 >> 8; + rule->srcMac_.octet[1] = entry.is.ETHERNET.sMacP47_32 & 0xff; + rule->srcMac_.octet[2] = entry.is.ETHERNET.sMacP31_16 >> 8; + rule->srcMac_.octet[3] = entry.is.ETHERNET.sMacP31_16 & 0xff; + rule->srcMac_.octet[4] = entry.is.ETHERNET.sMacP15_0 >> 8; + rule->srcMac_.octet[5] = entry.is.ETHERNET.sMacP15_0 & 0xff; + rule->srcMacMask_.octet[0] = entry.is.ETHERNET.sMacM47_32 >> 8; + rule->srcMacMask_.octet[1] = entry.is.ETHERNET.sMacM47_32 & 0xff; + rule->srcMacMask_.octet[2] = entry.is.ETHERNET.sMacM31_16 >> 8; + rule->srcMacMask_.octet[3] = entry.is.ETHERNET.sMacM31_16 & 0xff; + rule->srcMacMask_.octet[4] = entry.is.ETHERNET.sMacM15_0 >> 8; + rule->srcMacMask_.octet[5] = entry.is.ETHERNET.sMacM15_0 & 0xff; + rule->typeLen_ = entry.is.ETHERNET.ethTypeP; + rule->typeLenMask_ = entry.is.ETHERNET.ethTypeM; + rule->ruleType_ = entry.ruleType; + break; + + case RTL865X_ACL_IP: /* IP mask rule type */ + case RTL865X_ACL_IP_RANGE: /* IP range rule type*/ + rule->tos_ = entry.is.L3L4.is.IP.IPTOSP; + rule->tosMask_ = entry.is.L3L4.is.IP.IPTOSM; + rule->ipProto_ = entry.is.L3L4.is.IP.IPProtoP; + rule->ipProtoMask_ = entry.is.L3L4.is.IP.IPProtoM; + rule->ipFlag_ = entry.is.L3L4.is.IP.IPFlagP; + rule->ipFlagMask_ = entry.is.L3L4.is.IP.IPFlagM; + rule->ipFOP_ = entry.is.L3L4.is.IP.FOP; + rule->ipFOM_ = entry.is.L3L4.is.IP.FOM; + rule->ipHttpFilterM_ = entry.is.L3L4.is.IP.HTTPM; + rule->ipHttpFilter_ = entry.is.L3L4.is.IP.HTTPP; + rule->ipIdentSrcDstIp_ = entry.is.L3L4.is.IP.identSDIPM; + rule->ruleType_= entry.ruleType; + goto l3l4_shared; + + case RTL865X_ACL_ICMP: /* ICMP (ip is mask) rule type */ + case RTL865X_ACL_ICMP_IPRANGE: /* ICMP (ip is range) rule type */ + rule->tos_ = entry.is.L3L4.is.ICMP.IPTOSP; + rule->tosMask_ = entry.is.L3L4.is.ICMP.IPTOSM; + rule->icmpType_ = entry.is.L3L4.is.ICMP.ICMPTypeP; + rule->icmpTypeMask_ = entry.is.L3L4.is.ICMP.ICMPTypeM; + rule->icmpCode_ = entry.is.L3L4.is.ICMP.ICMPCodeP; + rule->icmpCodeMask_ = entry.is.L3L4.is.ICMP.ICMPCodeM; + rule->ruleType_ = entry.ruleType; + goto l3l4_shared; + + case RTL865X_ACL_IGMP: /* IGMP (ip is mask) rule type */ + case RTL865X_ACL_IGMP_IPRANGE: /* IGMP (ip is range) rule type */ + rule->tos_ = entry.is.L3L4.is.IGMP.IPTOSP; + rule->tosMask_ = entry.is.L3L4.is.IGMP.IPTOSM; + rule->igmpType_ = entry.is.L3L4.is.IGMP.IGMPTypeP; + rule->igmpTypeMask_ = entry.is.L3L4.is.IGMP.IGMPTypeM; + rule->ruleType_ = entry.ruleType; + goto l3l4_shared; + + case RTL865X_ACL_TCP: /* TCP rule type */ + case RTL865X_ACL_TCP_IPRANGE: + rule->tos_ = entry.is.L3L4.is.TCP.IPTOSP; + rule->tosMask_ = entry.is.L3L4.is.TCP.IPTOSM; + rule->tcpFlag_ = entry.is.L3L4.is.TCP.TCPFlagP; + rule->tcpFlagMask_ = entry.is.L3L4.is.TCP.TCPFlagM; + rule->tcpSrcPortUB_ = entry.is.L3L4.is.TCP.TCPSPUB; + rule->tcpSrcPortLB_ = entry.is.L3L4.is.TCP.TCPSPLB; + rule->tcpDstPortUB_ = entry.is.L3L4.is.TCP.TCPDPUB; + rule->tcpDstPortLB_ = entry.is.L3L4.is.TCP.TCPDPLB; + rule->ruleType_ = entry.ruleType; + goto l3l4_shared; + + case RTL865X_ACL_UDP: /* UDP rule type */ + case RTL865X_ACL_UDP_IPRANGE: + rule->tos_ = entry.is.L3L4.is.UDP.IPTOSP; + rule->tosMask_ = entry.is.L3L4.is.UDP.IPTOSM; + rule->udpSrcPortUB_ = entry.is.L3L4.is.UDP.UDPSPUB; + rule->udpSrcPortLB_ = entry.is.L3L4.is.UDP.UDPSPLB; + rule->udpDstPortUB_ = entry.is.L3L4.is.UDP.UDPDPUB; + rule->udpDstPortLB_ = entry.is.L3L4.is.UDP.UDPDPLB; + rule->ruleType_ = entry.ruleType; +l3l4_shared: + rule->srcIpAddr_ = entry.is.L3L4.sIPP; + rule->srcIpAddrMask_ = entry.is.L3L4.sIPM; + rule->dstIpAddr_ = entry.is.L3L4.dIPP; + rule->dstIpAddrMask_ = entry.is.L3L4.dIPM; + break; + + case RTL865X_ACL_SRCFILTER: /* Source Filter */ + case RTL865X_ACL_SRCFILTER_IPRANGE: + rule->srcFilterMac_.octet[0] = entry.is.SRC_FILTER.sMacP47_32 >> 8; + rule->srcFilterMac_.octet[1] = entry.is.SRC_FILTER.sMacP47_32 & 0xff; + rule->srcFilterMac_.octet[2] = entry.is.SRC_FILTER.sMacP31_16 >> 8; + rule->srcFilterMac_.octet[3] = entry.is.SRC_FILTER.sMacP31_16 & 0xff; + rule->srcFilterMac_.octet[4] = entry.is.SRC_FILTER.sMacP15_0 >> 8; + rule->srcFilterMac_.octet[5] = entry.is.SRC_FILTER.sMacP15_0 & 0xff; + if ( entry.is.SRC_FILTER.sMacM3_0&0x8) + { + rule->srcFilterMacMask_.octet[0] = 0xff; + rule->srcFilterMacMask_.octet[1] = 0xff; + rule->srcFilterMacMask_.octet[2] = 0xff; + rule->srcFilterMacMask_.octet[3] = 0xff; + rule->srcFilterMacMask_.octet[4] = 0xff; + rule->srcFilterMacMask_.octet[5] = 0xF0|entry.is.SRC_FILTER.sMacM3_0; + } + else + { + rule->srcFilterMacMask_.octet[0] = 0x0; + rule->srcFilterMacMask_.octet[1] = 0x0; + rule->srcFilterMacMask_.octet[2] = 0x0; + rule->srcFilterMacMask_.octet[3] = 0x0; + rule->srcFilterMacMask_.octet[4] = 0x0; + rule->srcFilterMacMask_.octet[5] = entry.is.SRC_FILTER.sMacM3_0; + } + + rule->srcFilterPort_ = entry.is.SRC_FILTER.spaP; + rule->srcFilterVlanIdx_ = entry.is.SRC_FILTER.sVidP; + rule->srcFilterVlanIdxMask_ = entry.is.SRC_FILTER.sVidM; + if(entry.is.SRC_FILTER.protoType == 2) rule->srcFilterIgnoreL4_ = 1; + else if(entry.is.SRC_FILTER.protoType == 1) rule->srcFilterIgnoreL3L4_ = 1; + rule->srcFilterIpAddr_ = entry.is.SRC_FILTER.sIPP; + rule->srcFilterIpAddrMask_ = entry.is.SRC_FILTER.sIPM; + rule->srcFilterPortUpperBound_ = entry.is.SRC_FILTER.SPORTUB; + rule->srcFilterPortLowerBound_ = entry.is.SRC_FILTER.SPORTLB; + rule->ruleType_ = entry.ruleType; + break; + + case RTL865X_ACL_DSTFILTER: /* Destination Filter */ + case RTL865X_ACL_DSTFILTER_IPRANGE: /* Destination Filter(IP range) */ + rule->dstFilterMac_.octet[0] = entry.is.DST_FILTER.dMacP47_32 >> 8; + rule->dstFilterMac_.octet[1] = entry.is.DST_FILTER.dMacP47_32 & 0xff; + rule->dstFilterMac_.octet[2] = entry.is.DST_FILTER.dMacP31_16 >> 8; + rule->dstFilterMac_.octet[3] = entry.is.DST_FILTER.dMacP31_16 & 0xff; + rule->dstFilterMac_.octet[4] = entry.is.DST_FILTER.dMacP15_0 >> 8; + rule->dstFilterMac_.octet[5] = entry.is.DST_FILTER.dMacP15_0 & 0xff; + if ( entry.is.DST_FILTER.dMacM3_0&0x8) + { + rule->dstFilterMacMask_.octet[0] = 0xff; + rule->dstFilterMacMask_.octet[1] = 0xff; + rule->dstFilterMacMask_.octet[2] = 0xff; + rule->dstFilterMacMask_.octet[3] = 0xff; + rule->dstFilterMacMask_.octet[4] = 0xff; + rule->dstFilterMacMask_.octet[5] = 0xF0|entry.is.DST_FILTER.dMacM3_0; + } + else + { + rule->dstFilterMacMask_.octet[0] = 0x0; + rule->dstFilterMacMask_.octet[1] = 0x0; + rule->dstFilterMacMask_.octet[2] = 0x0; + rule->dstFilterMacMask_.octet[3] = 0x0; + rule->dstFilterMacMask_.octet[4] = 0x0; + rule->dstFilterMacMask_.octet[5] = entry.is.DST_FILTER.dMacM3_0; + } + + + rule->dstFilterVlanIdx_ = entry.is.DST_FILTER.vidP; + rule->dstFilterVlanIdxMask_ = entry.is.DST_FILTER.vidM; + if(entry.is.DST_FILTER.protoType == 1) rule->dstFilterIgnoreL3L4_ = 1; + else if(entry.is.DST_FILTER.protoType == 2) rule->dstFilterIgnoreL4_ = 1; + rule->dstFilterIpAddr_ = entry.is.DST_FILTER.dIPP; + rule->dstFilterIpAddrMask_ = entry.is.DST_FILTER.dIPM; + rule->dstFilterPortUpperBound_ = entry.is.DST_FILTER.DPORTUB; + rule->dstFilterPortLowerBound_ = entry.is.DST_FILTER.DPORTLB; + rule->ruleType_ = entry.ruleType; + break; + default: return FAILED; /* Unknown rule type */ + + } + + rule->aclIdx = index; + + switch(entry.actionType) { + + case RTL865X_ACL_PERMIT: + case RTL865X_ACL_REDIRECT_ETHER: + case RTL865X_ACL_DROP: + case RTL865X_ACL_TOCPU: + case RTL865X_ACL_LEGACY_DROP: + case RTL865X_ACL_DROPCPU_LOG: + case RTL865X_ACL_MIRROR: + case RTL865X_ACL_REDIRECT_PPPOE: + case RTL865X_ACL_MIRROR_KEEP_MATCH: + rule->L2Idx_ = entry.nextHop ; + rule->netifIdx_ = entry.vid; + rule->pppoeIdx_ = entry.PPPoEIndex; + break; + + case RTL865X_ACL_DEFAULT_REDIRECT: + rule->nexthopIdx_ = entry.nextHop; + break; + + case RTL865X_ACL_DROP_RATE_EXCEED_PPS: + rule->ratelimtIdx_ = entry.nextHop; + break; + case RTL865X_ACL_LOG_RATE_EXCEED_PPS: + rule->ratelimtIdx_ = entry.nextHop; + break; + case RTL865X_ACL_DROP_RATE_EXCEED_BPS: + rule->ratelimtIdx_ = entry.nextHop; + break; + case RTL865X_ACL_LOG_RATE_EXCEED_BPS: + rule->ratelimtIdx_ = entry.nextHop; + break; + case RTL865X_ACL_PRIORITY: + rule->priority_ = entry.nextHop; + break; + + } + + rule->actionType_ = entry.actionType; + rule->pktOpApp_ = entry.pktOpApp; + + return SUCCESS; + +} + +static int32 _rtl865x_setAclToAsic(int32 startIdx, rtl865x_AclRule_t *rule) +{ + rtl865xc_tblAsic_aclTable_t entry; + + if(rule->aclIdx >= RTL865X_ACL_MAX_NUMBER + RTL865X_ACL_RESERVED_NUMBER || rule == NULL) + return FAILED; + + memset(&entry, 0, sizeof(entry)); + switch(rule->ruleType_) + { + + case RTL865X_ACL_MAC: /* Etnernet type rule: 0x0000 */ + entry.is.ETHERNET.dMacP47_32 = rule->dstMac_.octet[0]<<8 | rule->dstMac_.octet[1]; + entry.is.ETHERNET.dMacP31_16 = rule->dstMac_.octet[2]<<8 | rule->dstMac_.octet[3]; + entry.is.ETHERNET.dMacP15_0 = rule->dstMac_.octet[4]<<8 | rule->dstMac_.octet[5]; + entry.is.ETHERNET.dMacM47_32 = rule->dstMacMask_.octet[0]<<8 | rule->dstMacMask_.octet[1]; + entry.is.ETHERNET.dMacM31_16 = rule->dstMacMask_.octet[2]<<8 | rule->dstMacMask_.octet[3]; + entry.is.ETHERNET.dMacM15_0 = rule->dstMacMask_.octet[4]<<8 | rule->dstMacMask_.octet[5]; + entry.is.ETHERNET.sMacP47_32 = rule->srcMac_.octet[0]<<8 | rule->srcMac_.octet[1]; + entry.is.ETHERNET.sMacP31_16 = rule->srcMac_.octet[2]<<8 | rule->srcMac_.octet[3]; + entry.is.ETHERNET.sMacP15_0 = rule->srcMac_.octet[4]<<8 | rule->srcMac_.octet[5]; + entry.is.ETHERNET.sMacM47_32 = rule->srcMacMask_.octet[0]<<8 | rule->srcMacMask_.octet[1]; + entry.is.ETHERNET.sMacM31_16 = rule->srcMacMask_.octet[2]<<8 | rule->srcMacMask_.octet[3]; + entry.is.ETHERNET.sMacM15_0 = rule->srcMacMask_.octet[4]<<8 | rule->srcMacMask_.octet[5]; + entry.is.ETHERNET.ethTypeP = rule->typeLen_; + entry.is.ETHERNET.ethTypeM = rule->typeLenMask_; + + entry.ruleType = rule->ruleType_; + break; + + case RTL865X_ACL_IP: /* IP Rule Type: 0x0010 */ + case RTL865X_ACL_IP_RANGE: + entry.is.L3L4.is.IP.IPTOSP = rule->tos_; + entry.is.L3L4.is.IP.IPTOSM = rule->tosMask_; + entry.is.L3L4.is.IP.IPProtoP = rule->ipProto_; + entry.is.L3L4.is.IP.IPProtoM = rule->ipProtoMask_; + entry.is.L3L4.is.IP.IPFlagP = rule->ipFlag_; + entry.is.L3L4.is.IP.IPFlagM = rule->ipFlagMask_; + entry.is.L3L4.is.IP.FOP = rule->ipFOP_; + entry.is.L3L4.is.IP.FOM = rule->ipFOM_; + entry.is.L3L4.is.IP.HTTPP = entry.is.L3L4.is.IP.HTTPM = rule->ipHttpFilter_; + entry.is.L3L4.is.IP.identSDIPP = entry.is.L3L4.is.IP.identSDIPM = rule->ipIdentSrcDstIp_; + + goto l3l4_shared; + + case RTL865X_ACL_ICMP: + case RTL865X_ACL_ICMP_IPRANGE: + entry.is.L3L4.is.ICMP.IPTOSP = rule->tos_; + entry.is.L3L4.is.ICMP.IPTOSM = rule->tosMask_; + entry.is.L3L4.is.ICMP.ICMPTypeP = rule->icmpType_; + entry.is.L3L4.is.ICMP.ICMPTypeM = rule->icmpTypeMask_; + entry.is.L3L4.is.ICMP.ICMPCodeP = rule->icmpCode_; + entry.is.L3L4.is.ICMP.ICMPCodeM = rule->icmpCodeMask_; + goto l3l4_shared; + + case RTL865X_ACL_IGMP: + case RTL865X_ACL_IGMP_IPRANGE: + entry.is.L3L4.is.IGMP.IPTOSP = rule->tos_; + entry.is.L3L4.is.IGMP.IPTOSM = rule->tosMask_; + entry.is.L3L4.is.IGMP.IGMPTypeP = rule->igmpType_; + entry.is.L3L4.is.IGMP.IGMPTypeM = rule->igmpTypeMask_; + + goto l3l4_shared; + + case RTL865X_ACL_TCP: + case RTL865X_ACL_TCP_IPRANGE: + entry.is.L3L4.is.TCP.IPTOSP = rule->tos_; + entry.is.L3L4.is.TCP.IPTOSM = rule->tosMask_; + entry.is.L3L4.is.TCP.TCPFlagP = rule->tcpFlag_; + entry.is.L3L4.is.TCP.TCPFlagM = rule->tcpFlagMask_; + entry.is.L3L4.is.TCP.TCPSPUB = rule->tcpSrcPortUB_; + entry.is.L3L4.is.TCP.TCPSPLB = rule->tcpSrcPortLB_; + entry.is.L3L4.is.TCP.TCPDPUB = rule->tcpDstPortUB_; + entry.is.L3L4.is.TCP.TCPDPLB = rule->tcpDstPortLB_; + + goto l3l4_shared; + + case RTL865X_ACL_UDP: + case RTL865X_ACL_UDP_IPRANGE: + entry.is.L3L4.is.UDP.IPTOSP = rule->tos_; + entry.is.L3L4.is.UDP.IPTOSM = rule->tosMask_; + entry.is.L3L4.is.UDP.UDPSPUB = rule->udpSrcPortUB_; + entry.is.L3L4.is.UDP.UDPSPLB = rule->udpSrcPortLB_; + entry.is.L3L4.is.UDP.UDPDPUB = rule->udpDstPortUB_; + entry.is.L3L4.is.UDP.UDPDPLB = rule->udpDstPortLB_; + +l3l4_shared: + entry.ruleType = rule->ruleType_; + entry.is.L3L4.sIPP = rule->srcIpAddr_; + entry.is.L3L4.sIPM = rule->srcIpAddrMask_; + entry.is.L3L4.dIPP = rule->dstIpAddr_; + entry.is.L3L4.dIPM = rule->dstIpAddrMask_; + break; + + case RTL865X_ACL_SRCFILTER: + case RTL865X_ACL_SRCFILTER_IPRANGE: + rule->srcFilterMac_.octet[0] = rule->srcFilterMac_.octet[0] & rule->srcFilterMacMask_.octet[0]; + rule->srcFilterMac_.octet[1] = rule->srcFilterMac_.octet[1] & rule->srcFilterMacMask_.octet[1]; + rule->srcFilterMac_.octet[2] = rule->srcFilterMac_.octet[2] & rule->srcFilterMacMask_.octet[2]; + rule->srcFilterMac_.octet[3] = rule->srcFilterMac_.octet[3] & rule->srcFilterMacMask_.octet[3]; + rule->srcFilterMac_.octet[4] = rule->srcFilterMac_.octet[4] & rule->srcFilterMacMask_.octet[4]; + rule->srcFilterMac_.octet[5] = rule->srcFilterMac_.octet[5] & rule->srcFilterMacMask_.octet[5]; + + entry.is.SRC_FILTER.sMacP47_32 = rule->srcFilterMac_.octet[0]<<8 | rule->srcFilterMac_.octet[1]; + entry.is.SRC_FILTER.sMacP31_16 = rule->srcFilterMac_.octet[2]<<8 | rule->srcFilterMac_.octet[3]; + entry.is.SRC_FILTER.sMacP15_0 = rule->srcFilterMac_.octet[4]<<8 | rule->srcFilterMac_.octet[5]; + entry.is.SRC_FILTER.sMacM3_0 =rule->srcFilterMacMask_.octet[5] &0xf; + + rule->srcFilterVlanId_ = rule->srcFilterVlanId_ & rule->srcFilterVlanIdMask_; + entry.is.SRC_FILTER.spaP = rule->srcFilterPort_; + entry.is.SRC_FILTER.sVidP = rule->srcFilterVlanId_; + entry.is.SRC_FILTER.sVidM = rule->srcFilterVlanIdMask_; + if(rule->srcFilterIgnoreL3L4_) + entry.is.SRC_FILTER.protoType = 1; + else if(rule->srcFilterIgnoreL4_) + entry.is.SRC_FILTER.protoType = 2; + else + entry.is.SRC_FILTER.protoType = 0; + + entry.is.SRC_FILTER.sIPP = rule->srcFilterIpAddr_; + entry.is.SRC_FILTER.sIPM = rule->srcFilterIpAddrMask_; + entry.is.SRC_FILTER.SPORTUB = rule->srcFilterPortUpperBound_; + entry.is.SRC_FILTER.SPORTLB = rule->srcFilterPortLowerBound_; + + entry.ruleType = rule->ruleType_; + break; + + case RTL865X_ACL_DSTFILTER: + case RTL865X_ACL_DSTFILTER_IPRANGE: + entry.is.DST_FILTER.dMacP47_32 = rule->dstFilterMac_.octet[0]<<8 | rule->dstFilterMac_.octet[1]; + entry.is.DST_FILTER.dMacP31_16 = rule->dstFilterMac_.octet[2]<<8 | rule->dstFilterMac_.octet[3]; + entry.is.DST_FILTER.dMacP15_0 = rule->dstFilterMac_.octet[4]<<8 | rule->dstFilterMac_.octet[5]; + entry.is.DST_FILTER.dMacM3_0 = rule->dstFilterMacMask_.octet[5]&0xf; + entry.is.DST_FILTER.vidP = rule->dstFilterVlanIdx_; + entry.is.DST_FILTER.vidM = rule->dstFilterVlanIdxMask_; + if(rule->dstFilterIgnoreL3L4_) + entry.is.DST_FILTER.protoType = 1; + else if(rule->dstFilterIgnoreL4_) + entry.is.DST_FILTER.protoType = 2; + else + entry.is.DST_FILTER.protoType = 0; + entry.is.DST_FILTER.dIPP = rule->dstFilterIpAddr_; + entry.is.DST_FILTER.dIPM = rule->dstFilterIpAddrMask_; + entry.is.DST_FILTER.DPORTUB = rule->dstFilterPortUpperBound_; + entry.is.DST_FILTER.DPORTLB = rule->dstFilterPortLowerBound_; + + entry.ruleType = rule->ruleType_; + break; + + default: return FAILED; /* Unknown rule type */ + + } + + switch(rule->actionType_) + { + case RTL865X_ACL_PERMIT: + case RTL865X_ACL_REDIRECT_ETHER: + case RTL865X_ACL_DROP: + case RTL865X_ACL_TOCPU: + case RTL865X_ACL_LEGACY_DROP: + case RTL865X_ACL_DROPCPU_LOG: + case RTL865X_ACL_MIRROR: + case RTL865X_ACL_REDIRECT_PPPOE: + case RTL865X_ACL_MIRROR_KEEP_MATCH: + entry.nextHop = rule->L2Idx_; + entry.vid = rule->netifIdx_; + entry.PPPoEIndex = rule->pppoeIdx_; + break; + + case RTL865X_ACL_DEFAULT_REDIRECT: + entry.nextHop = rule->nexthopIdx_; + break; + + case RTL865X_ACL_DROP_RATE_EXCEED_PPS: + entry.nextHop = rule->ratelimtIdx_; + break; + case RTL865X_ACL_LOG_RATE_EXCEED_PPS: + entry.nextHop = rule->ratelimtIdx_; + break; + case RTL865X_ACL_DROP_RATE_EXCEED_BPS: + entry.nextHop = rule->ratelimtIdx_; + break; + case RTL865X_ACL_LOG_RATE_EXCEED_BPS: + entry.nextHop = rule->ratelimtIdx_; + break; + case RTL865X_ACL_PRIORITY: + entry.nextHop = rule->priority_; + break; + + } + + entry.actionType = rule->actionType_; + entry.pktOpApp = rule->pktOpApp_; + + + return _rtl8651_forceAddAsicEntry(TYPE_ACL_RULE_TABLE, startIdx + rule->aclIdx -1, &entry); +} + +/*config the reserved acl rules: default permit/drop/toCPU*/ +static int32 _rtl865x_confReservedAcl(void) +{ + rtl865x_AclRule_t defAcl; + + /*default permit*/ + memset(&defAcl,0,sizeof(rtl865x_AclRule_t)); + defAcl.actionType_ = RTL865X_ACL_PERMIT; + defAcl.aclIdx = 1; + defAcl.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + _rtl865x_setAclToAsic(RTL865X_ACLTBL_PERMIT_ALL,&defAcl); + + /*default drop*/ + defAcl.actionType_ = RTL865X_ACL_DROP; + defAcl.aclIdx = 1; + defAcl.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + _rtl865x_setAclToAsic(RTL865X_ACLTBL_DROP_ALL, &defAcl); + + /*default to cpu*/ + defAcl.actionType_ = RTL865X_ACL_TOCPU; + defAcl.aclIdx = 1; + defAcl.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + _rtl865x_setAclToAsic(RTL865X_ACLTBL_ALL_TO_CPU, &defAcl); + + /*hyking:set default permit when network interface decision miss match*/ + #ifdef CONFIG_RTL_LAYERED_ASIC_DRIVER + rtl865x_setDefACLForNetDecisionMiss(RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL); + #endif + + return SUCCESS; + +} + +/* +@func int32 | rtl865x_reinit_acl |memory reinit. +@rvalue SUCCESS | Success. +@comm + this API must be called when system boot. +*/ +int32 rtl865x_reinit_acl(void) +{ + _rtl865x_confReservedAcl(); + return SUCCESS; +} + +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL +/*===================================== +*acl releated function +*======================================*/ +static int32 _rtl865x_setDefACLForAllNetif(uint8 start_ingressAclIdx, uint8 end_ingressAclIdx,uint8 start_egressAclIdx,uint8 end_egressAclIdx) +{ + rtl865x_netif_local_t *netif = NULL; + int32 i; + for(i = 0 ; i < NETIF_NUMBER; i++) + { + netif = &netifTbl[i]; + if(netif->valid == 0 || netif->is_slave == 1) + continue; + + netif->inAclStart = start_ingressAclIdx; + netif->inAclEnd = end_ingressAclIdx; + netif->outAclStart = start_egressAclIdx; + netif->outAclEnd = end_egressAclIdx; + _rtl865x_setAsicNetif(netif); + } +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + rtl865x_setDefACLForNetDecisionMiss(start_ingressAclIdx,end_ingressAclIdx,start_egressAclIdx,end_egressAclIdx); +#endif + + return SUCCESS; +} + +int32 rtl865x_setDefACLForAllNetif(uint8 start_ingressAclIdx, uint8 end_ingressAclIdx,uint8 start_egressAclIdx,uint8 end_egressAclIdx) +{ + _rtl865x_setDefACLForAllNetif(start_ingressAclIdx, end_ingressAclIdx,start_egressAclIdx,end_egressAclIdx); + return SUCCESS; +} + +static int8 _rtl865x_sameAclRule(rtl865x_AclRule_t *rule1, rtl865x_AclRule_t *rule2) +{ + + if (rule1->actionType_ != rule2->actionType_ || rule1->ruleType_ != rule2->ruleType_) + return FALSE; + + switch(rule1->ruleType_) { + case RTL865X_ACL_MAC: + if (rule1->typeLen_ != rule2->typeLen_ || rule1->typeLenMask_ != rule2->typeLenMask_) + return FALSE; + if (memcmp(&rule1->dstMac_, &rule2->dstMac_, sizeof(ether_addr_t)) || + memcmp(&rule1->dstMacMask_, &rule2->dstMacMask_, sizeof(ether_addr_t)) || + memcmp(&rule1->srcMac_, &rule2->srcMac_, sizeof(ether_addr_t)) || + memcmp(&rule1->srcMacMask_, &rule2->srcMacMask_, sizeof(ether_addr_t)) ) + return FALSE; + return TRUE; + case RTL865X_ACL_IP: + case RTL865X_ACL_IP_RANGE: + if (rule1->ipProto_ != rule2->ipProto_ || rule1->ipProtoMask_ != rule2->ipProtoMask_ || + rule1->ipFlag_ != rule2->ipFlag_ || rule1->ipFlagMask_ != rule2->ipFlagMask_) + return FALSE; + break; + + case RTL865X_ACL_ICMP: + case RTL865X_ACL_ICMP_IPRANGE: + if (rule1->icmpType_ != rule2->icmpType_ || rule1->icmpTypeMask_ != rule2->icmpTypeMask_ || + rule1->icmpCode_ != rule2->icmpCode_ || rule1->icmpCodeMask_ != rule2->icmpCodeMask_) + return FALSE; + break; + + case RTL865X_ACL_IGMP: + case RTL865X_ACL_IGMP_IPRANGE: + if(rule1->igmpType_ != rule2->igmpType_ || rule1->igmpTypeMask_ != rule2->igmpTypeMask_) + return FALSE; + break; + case RTL865X_ACL_TCP: + case RTL865X_ACL_TCP_IPRANGE: + if(rule1->tcpFlag_ != rule2->tcpFlag_ || rule1->tcpFlagMask_ != rule2->tcpFlagMask_ || + rule1->tcpSrcPortUB_ != rule2->tcpSrcPortUB_ || rule1->tcpSrcPortLB_ != rule2->tcpSrcPortLB_ || + rule1->tcpDstPortUB_ != rule2->tcpDstPortUB_ || rule1->tcpDstPortLB_ != rule2->tcpDstPortLB_) + return FALSE; + break; + case RTL865X_ACL_UDP: + case RTL865X_ACL_UDP_IPRANGE: + if(rule1->udpSrcPortUB_ != rule2->udpSrcPortUB_ || rule1->udpSrcPortLB_ != rule2->udpSrcPortLB_ || + rule1->udpDstPortUB_ != rule2->udpDstPortUB_ || rule1->udpDstPortLB_ != rule2->udpDstPortLB_) + return FALSE; + break; + + case RTL865X_ACL_SRCFILTER: + case RTL865X_ACL_SRCFILTER_IPRANGE: + if((rule1->srcFilterPort_ != rule2->srcFilterPort_)|| + memcmp(&rule1->srcFilterMac_, &rule2->srcFilterMac_, sizeof(ether_addr_t)) != 0|| + memcmp(&rule1->srcFilterMacMask_, &rule2->srcFilterMacMask_,sizeof(ether_addr_t)) != 0|| + (rule1->srcFilterVlanIdx_ != rule2->srcFilterVlanIdx_)|| + (rule1->srcFilterVlanIdxMask_ != rule2->srcFilterVlanIdxMask_)|| + (rule1->srcFilterIgnoreL3L4_ != rule2->srcFilterIgnoreL3L4_)|| + (rule1->srcFilterIgnoreL4_ != rule2->srcFilterIgnoreL4_)) + { + return FALSE; + } + + if(rule1->srcFilterIgnoreL4_==0 && rule1->srcFilterIgnoreL3L4_==0) + { + if((rule1->srcFilterPortUpperBound_ != rule2->srcFilterPortUpperBound_)|| + (rule1->srcFilterPortLowerBound_ != rule2->srcFilterPortLowerBound_)) + return FALSE; + } + + if(rule1->srcFilterIgnoreL3L4_==0) + { + if((rule1->srcFilterIpAddr_ != rule2->srcFilterIpAddr_)|| + (rule2->srcFilterIpAddrMask_ != rule2->srcFilterIpAddrMask_)) + return FALSE; + } + + break; + + case RTL865X_ACL_DSTFILTER: + case RTL865X_ACL_DSTFILTER_IPRANGE: + if( memcmp(&rule1->dstFilterMac_, &rule2->dstFilterMac_, sizeof(ether_addr_t)) != 0|| + memcmp(&rule1->dstFilterMacMask_, &rule2->dstFilterMacMask_,sizeof(ether_addr_t)) != 0|| + (rule1->dstFilterVlanIdx_ != rule2->dstFilterVlanIdx_)|| + (rule1->dstFilterVlanIdxMask_ != rule2->dstFilterVlanIdxMask_)|| + (rule1->dstFilterIgnoreL3L4_ != rule2->dstFilterIgnoreL3L4_)|| + (rule1->dstFilterIgnoreL4_ != rule2->dstFilterIgnoreL4_)) + { + return FALSE; + } + + if(rule1->dstFilterIgnoreL4_==0 && rule1->dstFilterIgnoreL4_==0) + { + if((rule1->dstFilterPortUpperBound_ != rule2->dstFilterPortUpperBound_)|| + (rule1->dstFilterPortLowerBound_ != rule2->dstFilterPortLowerBound_)) + return FALSE; + } + + if(rule1->dstFilterIgnoreL3L4_==0) + { + if((rule1->dstFilterIpAddr_ != rule2->dstFilterIpAddr_)|| + (rule2->dstFilterIpAddrMask_ != rule2->dstFilterIpAddrMask_)) + return FALSE; + } + + break; + default: return FALSE; /* Unknown rule type */ + + } + /* Compare common part */ + if (rule1->srcIpAddr_ != rule2->srcIpAddr_ || rule1->srcIpAddrMask_ != rule2->srcIpAddrMask_ || + rule1->dstIpAddr_ != rule2->dstIpAddr_ || rule1->dstIpAddrMask_ != rule2->dstIpAddrMask_ || + rule1->tos_ != rule2->tos_ || rule1->tosMask_ != rule2->tosMask_ ) + return FALSE; + return TRUE; +} + + +static int32 _rtl865x_addAclToChain(rtl865x_AclRule_t *rule, rtl865x_AclRule_t **head, rtl865x_AclRule_t **tail) +{ + rtl865x_AclRule_t *addAcl; + rtl865x_AclRule_t *tmpRule; + + if(head == NULL || tail == NULL) + { + return RTL_EINVALIDINPUT; + } + + + if((*head) != NULL) + { + tmpRule = *head; + while(tmpRule) + { + if(_rtl865x_sameAclRule(tmpRule, rule)==TRUE) + { + return RTL_EENTRYALREADYEXIST; + } + tmpRule = tmpRule->next; + } + } + + addAcl = freeAclList.freeHead; + if(addAcl == NULL) + return RTL_ENOFREEBUFFER; + + /*remove acl buffer from freeAclList*/ + freeAclList.freeHead = freeAclList.freeHead->next; + if(freeAclList.freeHead) + freeAclList.freeHead->pre = NULL; + freeAclList.freeCnt--; + + memcpy(addAcl,rule,sizeof(rtl865x_AclRule_t)); + + addAcl->pre = addAcl->next = NULL; + if((*head) == NULL) + { + /*head = null, tail must null*/ + addAcl->aclIdx = 1; + *head = addAcl; + *tail = addAcl; + } + else + { + if(addAcl->aclIdx == 0 || addAcl->aclIdx > (*tail)->aclIdx) + { + /*append this rule to tail*/ + addAcl->aclIdx = (*tail)->aclIdx + 1; + (*tail)->next = addAcl; + addAcl->pre = *tail; + addAcl->next = NULL; + *tail = addAcl; + } + else + { + /*user specified the index, it's means: this rule should be inserted before the rule->aclIdx*/ + + tmpRule = *head; + while(tmpRule) + { + if(tmpRule->aclIdx == addAcl->aclIdx) + { + /*found the rule...*/ + break; + } + + tmpRule = tmpRule->next; + } + + if(tmpRule == NULL) + { + /*not found the correct position, append this rule at the tail??*/ + + + printk("%s(%d): BUG!!!\n",__FUNCTION__,__LINE__); + + addAcl->pre = NULL; + addAcl->next = freeAclList.freeHead; + if(freeAclList.freeHead) + freeAclList.freeHead->pre = addAcl; + freeAclList.freeHead = addAcl; + freeAclList.freeCnt++; + return FAILED; + } + + /*insert new rule before the found rule*/ + if(tmpRule->pre == NULL) + { + /*tmpRule->pre = null, means: tmprule is the head of this chain*/ + addAcl->next = tmpRule; + tmpRule ->pre = addAcl; + *head = addAcl; + addAcl->aclIdx = 1; + } + else + { + tmpRule->pre->next = addAcl; + addAcl->pre = tmpRule->pre; + addAcl->next = tmpRule; + tmpRule->pre = addAcl; + } + + /*update aclIdx...*/ + while(tmpRule) + { + tmpRule->aclIdx++; + tmpRule = tmpRule->next; + } + + } + } + return SUCCESS; +} + +static int32 _rtl865x_delAclFromChain(rtl865x_AclRule_t *rule, rtl865x_AclRule_t **head, rtl865x_AclRule_t **tail) +{ + rtl865x_AclRule_t *delRule,*nextRule; + int8 isSame = FALSE; + + if(head == NULL || tail == NULL) + { + return RTL_EINVALIDINPUT; + } + + delRule = *head; + while(delRule) + { + if(rule->aclIdx != 0) + { + if(rule->aclIdx == delRule->aclIdx) + { + break; + } + } + else + { + isSame = _rtl865x_sameAclRule(delRule,rule); + if(isSame == TRUE) + { + break; + } + } + + delRule = delRule->next; + } + + if(delRule == NULL) + return RTL_EENTRYNOTFOUND; + + /*remove the acl rule from chains to free list*/ + nextRule = delRule->next; + if(delRule->pre) + delRule->pre->next = delRule->next; + if(delRule->next) + delRule->next->pre = delRule->pre; + + if(delRule == *head) + *head = delRule->next; + + if(delRule == *tail) + *tail = delRule->pre; + + /*inser the rule to free list*/ + delRule->pre = NULL; + delRule->next = freeAclList.freeHead; + if(freeAclList.freeHead) + freeAclList.freeHead->pre = delRule; + freeAclList.freeHead = delRule; + freeAclList.freeCnt++; + + /*update acl index whose position is after the delRule*/ + while(nextRule) + { + nextRule->aclIdx--; + nextRule = nextRule->next; + } + return SUCCESS; +} + + +static int32 _rtl865x_synAclwithAsicTbl(void) +{ + rtl865x_netif_local_t *netif = NULL; + rtl865x_acl_chain_t *chain; + rtl865x_AclRule_t *rule; + int32 i,startIdx,addCnt,totalAddCnt; + + //hyking:when rearrange asic acl, permit all first... + _rtl865x_setDefACLForAllNetif(RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL); + startIdx = 0; + for(i = 0; i<NETIF_NUMBER; i++) + { + netif = &netifTbl[i]; + if(netif->valid) + { + chain = netif->chainListHead[RTL865X_ACL_INGRESS]; + totalAddCnt = 0; + netif->inAclStart = startIdx; + while(chain) + { + addCnt = 0; + /*ingress acl*/ + rule = chain->head; + while(rule) + { + _rtl865x_setAclToAsic(startIdx, rule); + addCnt++; + rule = rule->next; + } + /*next chain..*/ + chain = chain->nextChain; + startIdx += addCnt; + totalAddCnt += addCnt; + } + + /*addCnt = 0: default permit??*/ + if(totalAddCnt > 0) + { + netif->inAclEnd = netif->inAclStart + totalAddCnt -1; +// startIdx += addCnt; + } + else + netif->inAclEnd = netif->inAclStart = RTL865X_ACLTBL_PERMIT_ALL; /*default permit...*/ + + /*egress acl*/ + chain = netif->chainListHead[RTL865X_ACL_EGRESS]; + totalAddCnt = 0; + netif->outAclStart = startIdx; + while(chain) + { + addCnt = 0; + rule = chain->head; + while(rule) + { + _rtl865x_setAclToAsic(startIdx, rule); + addCnt++; + rule = rule->next; + } + chain = chain->nextChain; + startIdx += addCnt; + totalAddCnt += addCnt; + } + + if(totalAddCnt > 0) + { + netif->outAclEnd = netif->outAclStart + totalAddCnt -1; +// startIdx += addCnt; + } + else + netif->outAclEnd = netif->outAclStart = RTL865X_ACLTBL_PERMIT_ALL; /*default permit...*/ + + _rtl865x_setAsicNetif(netif); + + } + } + +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + { + + netif = &virtualNetIf; + if(netif->valid) + { + chain = netif->chainListHead[RTL865X_ACL_INGRESS]; + totalAddCnt = 0; + netif->inAclStart = startIdx; + while(chain) + { + addCnt = 0; + /*ingress acl*/ + rule = chain->head; + while(rule) + { + _rtl865x_setAclToAsic(startIdx, rule); + addCnt++; + rule = rule->next; + } + /*next chain..*/ + chain = chain->nextChain; + startIdx += addCnt; + totalAddCnt += addCnt; + } + + /*addCnt = 0: default permit??*/ + if(totalAddCnt > 0) + { + netif->inAclEnd = netif->inAclStart + totalAddCnt -1; +// startIdx += addCnt; + } + else + netif->inAclEnd = netif->inAclStart = RTL865X_ACLTBL_PERMIT_ALL; /*default permit...*/ + + + /*egress acl*/ + chain = netif->chainListHead[RTL865X_ACL_EGRESS]; + totalAddCnt = 0; + netif->outAclStart = startIdx; + while(chain) + { + addCnt = 0; + rule = chain->head; + while(rule) + { + _rtl865x_setAclToAsic(startIdx, rule); + addCnt++; + rule = rule->next; + } + chain = chain->nextChain; + startIdx += addCnt; + totalAddCnt += addCnt; + } + + if(totalAddCnt > 0) + { + netif->outAclEnd = netif->outAclStart + totalAddCnt -1; +// startIdx += addCnt; + } + else + netif->outAclEnd = netif->outAclStart = RTL865X_ACLTBL_PERMIT_ALL; /*default permit...*/ + //printk("netif->inAclStart is %d,netif->inAclEnd is %d,netif->outAclStart is %d, netif->outAclEnd is %d\n",netif->inAclStart,netif->inAclEnd,netif->outAclStart, netif->outAclEnd); + rtl865x_setDefACLForNetDecisionMiss(netif->inAclStart, netif->inAclEnd, netif->outAclStart, netif->outAclEnd); + } + } +#endif + return SUCCESS; +} + + +/*flag, 0: ingress, 1: egress*/ +static int32 _rtl865x_regist_aclChain(char *netifName, int32 priority,uint32 flag) +{ + rtl865x_netif_local_t *netif; + rtl865x_acl_chain_t *addEntry,*chainEntry; + uint32 aclDir = RTL865X_ACL_INGRESS;/*default :RTL865X_ACL_INGRESS*/ + + netif = _rtl865x_getNetifByName(netifName); + + if(netif == NULL) + return RTL_ENETIFINVALID; + + if(flag == RTL865X_ACL_EGRESS) + aclDir = RTL865X_ACL_EGRESS; + + chainEntry = netif->chainListHead[aclDir]; + + + while(chainEntry) + { + if(chainEntry->priority < priority) + chainEntry = chainEntry->nextChain; + else + /*bingo!, find the position*/ + break; + } + + /*duplicate?*/ + if(chainEntry && chainEntry->priority == priority) + return RTL_EENTRYALREADYEXIST; + + addEntry = freeChainHead; + if(addEntry == NULL) + return RTL_ENOFREEBUFFER; + + freeChainHead = addEntry->nextChain; + if(freeChainHead) + freeChainHead->preChain = NULL; + + memset(addEntry,0,sizeof(rtl865x_acl_chain_t)); + addEntry->ruleCnt = 0; + addEntry->priority = priority; + addEntry->head = NULL; + addEntry->tail = NULL; + addEntry->preChain = addEntry->nextChain = NULL; + + if(chainEntry) + { + /*insert addentry before the chainEntry*/ + addEntry->nextChain = chainEntry; + addEntry->preChain = chainEntry->preChain; + + if(chainEntry->preChain) + chainEntry->preChain->nextChain = addEntry; + else + { + /*insert before head???*/ + netif->chainListHead[aclDir] = addEntry; + } + + chainEntry->preChain = addEntry; + } + else + { + if(netif->chainListHead[aclDir] == NULL) + netif->chainListHead[aclDir] = addEntry; + else + { + /*append addEntry to the tail of this list...*/ + chainEntry = netif->chainListHead[aclDir]; + while(chainEntry) + { + if(chainEntry->nextChain == NULL) + break; + + chainEntry = chainEntry->nextChain; + } + + if(chainEntry == NULL) + printk("%s(%d) BUG!!!!\n",__FUNCTION__,__LINE__); + + chainEntry->nextChain = addEntry; + addEntry->preChain = chainEntry; + } + } + + return SUCCESS; + +} + + +static int32 _rtl865x_unRegist_aclChain(char *netifName,int32 priority, uint32 flag) +{ + rtl865x_netif_local_t *netif; + rtl865x_AclRule_t *aclRule; + rtl865x_acl_chain_t *chainEntry; + uint32 aclDir = RTL865X_ACL_INGRESS;/*default :RTL865X_ACL_INGRESS*/ + + netif = _rtl865x_getNetifByName(netifName); + + if(netif == NULL) + return RTL_ENETIFINVALID; + + if(flag == RTL865X_ACL_EGRESS) + aclDir = RTL865X_ACL_EGRESS; + + chainEntry = netif->chainListHead[aclDir]; + + + while(chainEntry) + { + if(chainEntry->priority == priority) + break; + chainEntry = chainEntry->nextChain; + } + + if(chainEntry == NULL) + return RTL_EENTRYNOTFOUND; + + /*remove all aclrule*/ + aclRule = chainEntry->head; + while(aclRule) + { + _rtl865x_delAclFromChain(aclRule, &chainEntry->head, &chainEntry->tail); + aclRule = chainEntry->head; + chainEntry->ruleCnt--; + } + + chainEntry->ruleCnt = 0; + + if(chainEntry->nextChain) + chainEntry->nextChain->preChain = chainEntry->preChain; + + if(chainEntry->preChain) + chainEntry->preChain->nextChain = chainEntry->nextChain; + else + /*remove head???*/ + netif->chainListHead[aclDir] = chainEntry->nextChain; + + + memset(chainEntry,0,sizeof(rtl865x_acl_chain_t)); + + chainEntry->nextChain = freeChainHead; + if (freeChainHead) + freeChainHead->preChain = chainEntry; + freeChainHead = chainEntry; + + _rtl865x_synAclwithAsicTbl(); + + return SUCCESS; +} + +static int32 _rtl865x_flush_allAcl_fromChain(char *netifName,int32 priority, uint32 flag) +{ + rtl865x_netif_local_t *netif; + rtl865x_AclRule_t *aclRule; + rtl865x_acl_chain_t *chainEntry; + uint32 aclDir = RTL865X_ACL_INGRESS;/*default :RTL865X_ACL_INGRESS*/ + + if(flag == RTL865X_ACL_EGRESS) + aclDir = RTL865X_ACL_EGRESS; + + if(netifName && netifName[0] != '\0') + { + netif = _rtl865x_getNetifByName(netifName); + + if(netif == NULL) + return RTL_ENETIFINVALID; + + chainEntry = netif->chainListHead[aclDir]; + while(chainEntry) + { + if(chainEntry->priority == priority) + break; + chainEntry = chainEntry->nextChain; + } + + if(chainEntry == NULL) + return RTL_EENTRYNOTFOUND; + + /*remove all aclrule*/ + aclRule = chainEntry->head; + while(aclRule) + { + _rtl865x_delAclFromChain(aclRule, &chainEntry->head, &chainEntry->tail); + aclRule = chainEntry->head; + chainEntry->ruleCnt--; + } + + chainEntry->ruleCnt = 0; + + } + else + { + /*add this rule to every netif*/ + int32 i; + for(i = 0 ; i < NETIF_NUMBER; i++) + { + netif = &netifTbl[i]; + if(netif->valid) + { + chainEntry = netif->chainListHead[aclDir]; + while(chainEntry) + { + if(chainEntry->priority == priority) + break; + chainEntry = chainEntry->nextChain; + } + + if(chainEntry == NULL) + continue; + + /*remove all aclrule*/ + aclRule = chainEntry->head; + while(aclRule) + { + _rtl865x_delAclFromChain(aclRule, &chainEntry->head, &chainEntry->tail); + aclRule = chainEntry->head; + chainEntry->ruleCnt--; + } + + chainEntry->ruleCnt = 0; + } + } + } + + _rtl865x_synAclwithAsicTbl(); + + return SUCCESS; +} + +static rtl865x_AclRule_t* _rtl865x_matched_layer4_aclChain(char *netifName,int32 priority, uint32 flag, rtl865x_AclRule_t *match) +{ + rtl865x_netif_local_t *netif; + rtl865x_AclRule_t *aclRule; + rtl865x_acl_chain_t *chainEntry; + uint32 isRange; + uint32 aclDir = RTL865X_ACL_INGRESS;/*default :RTL865X_ACL_INGRESS*/ + + if(flag == RTL865X_ACL_EGRESS) + aclDir = RTL865X_ACL_EGRESS; + + if(netifName && netifName[0] != '\0') + { + netif = _rtl865x_getNetifByName(netifName); + + if(netif == NULL) + return NULL; + + chainEntry = netif->chainListHead[aclDir]; + while(chainEntry) + { + if(chainEntry->priority == priority) + break; + chainEntry = chainEntry->nextChain; + } + + if(chainEntry == NULL) + return NULL; + + /*check all aclrule*/ + for(aclRule = chainEntry->head;aclRule;aclRule = aclRule->next) + { + isRange = FALSE; + switch(aclRule->ruleType_) + { + case RTL865X_ACL_TCP_IPRANGE: + isRange = TRUE; + case RTL865X_ACL_TCP: + if ( (aclRule->tcpSrcPortLB_<=match->tcpSrcPortLB_) + &&(aclRule->tcpSrcPortUB_>=match->tcpSrcPortLB_) + &&(aclRule->tcpDstPortLB_<=match->tcpDstPortLB_) + &&(aclRule->tcpDstPortUB_>=match->tcpDstPortLB_) + && (match->ruleType_==RTL865X_ACL_TCP)) + { + break; + } + else + continue; + case RTL865X_ACL_UDP_IPRANGE: + isRange = TRUE; + case RTL865X_ACL_UDP: + if ( (aclRule->udpSrcPortLB_<=match->tcpSrcPortLB_) + &&(aclRule->udpSrcPortUB_>=match->tcpSrcPortLB_) + &&(aclRule->udpDstPortLB_<=match->tcpDstPortLB_) + &&(aclRule->udpDstPortUB_>=match->tcpDstPortLB_) + &&(match->ruleType_==RTL865X_ACL_UDP)) + { + break; + } + else + continue; + case RTL865X_ACL_IP_RANGE: + isRange = TRUE; + case RTL865X_ACL_IP: + if ( ((aclRule->tos_&aclRule->tosMask_)==(match->tos_&aclRule->tosMask_)) + && ((aclRule->ipProto_&aclRule->ipProtoMask_)==(match->ipProto_&aclRule->ipProtoMask_)) + && ((aclRule->ipFlag_&aclRule->ipFlagMask_)==(match->ipFlag_&aclRule->ipFlagMask_))) + { + break; + } + else + continue; + default: + continue; + } + + if (isRange) + { + if ( (aclRule->srcIpAddrStart_<=match->srcIpAddr_) + &&(aclRule->srcIpAddrEnd_>=match->srcIpAddr_) + &&(aclRule->dstIpAddrStart_<=match->dstIpAddr_) + &&(aclRule->dstIpAddrEnd_>=match->dstIpAddr_) ) + { + break; + } + else + continue; + } + else + { + if ( ((aclRule->srcIpAddr_&aclRule->srcIpAddrMask_) + ==(match->srcIpAddr_&aclRule->srcIpAddrMask_)) + &&((aclRule->dstIpAddr_&aclRule->dstIpAddrMask_) + ==(match->dstIpAddr_&aclRule->dstIpAddrMask_)) ) + { + break; + } + else + continue; + } + } + } + else + { + return NULL; + } + + return aclRule; +} + +static inline int _rtl865x_cmpMacAddr(ether_addr_t *mac1, ether_addr_t *mac2, ether_addr_t *mask) +{ + int i; + + for(i=0;i<ETHER_ADDR_LEN;i++) + { + if ((mac1->octet[i]&mask->octet[i])!=(mac2->octet[i]&mask->octet[i])) + return (SUCCESS+i+1); + } + return SUCCESS; +} + +static rtl865x_AclRule_t* _rtl865x_matched_layer2_aclChain(char *netifName,int32 priority, uint32 flag, rtl865x_AclRule_t *match) +{ + rtl865x_netif_local_t *netif; + rtl865x_AclRule_t *aclRule; + rtl865x_acl_chain_t *chainEntry; + uint32 aclDir = RTL865X_ACL_INGRESS;/*default :RTL865X_ACL_INGRESS*/ + + if(flag == RTL865X_ACL_EGRESS) + aclDir = RTL865X_ACL_EGRESS; + + if(netifName && netifName[0] != '\0') + { + netif = _rtl865x_getNetifByName(netifName); + + if(netif == NULL) + return NULL; + + chainEntry = netif->chainListHead[aclDir]; + while(chainEntry) + { + if(chainEntry->priority == priority) + break; + chainEntry = chainEntry->nextChain; + } + + if(chainEntry == NULL) + return NULL; + + /*check all aclrule*/ + for(aclRule = chainEntry->head;aclRule;aclRule = aclRule->next) + { + switch(aclRule->ruleType_) + { + case RTL865X_ACL_MAC: + break; + default: + continue; + } + + { + if ( _rtl865x_cmpMacAddr(&aclRule->srcMac_, &match->srcMac_, &aclRule->srcMacMask_)==SUCCESS + &&_rtl865x_cmpMacAddr(&aclRule->dstMac_, &match->dstMac_, &aclRule->dstMacMask_)==SUCCESS + &&((aclRule->typeLen_&aclRule->typeLenMask_)==(match->typeLen_&aclRule->typeLenMask_)) + && aclRule->ruleType_==match->ruleType_) + { + break; + } + else + continue; + } + } + } + else + { + return NULL; + } + + return aclRule; +} + +static int32 _rtl865x_unRegister_all_aclChain(char *netifName) +{ + rtl865x_netif_local_t *netif; + rtl865x_AclRule_t *aclRule; + rtl865x_acl_chain_t *chainEntry; + uint32 aclDir = RTL865X_ACL_INGRESS; + + netif = _rtl865x_getNetifByName(netifName); + if(netif == NULL) + return RTL_ENETIFINVALID; + + for(aclDir = RTL865X_ACL_INGRESS; aclDir <= RTL865X_ACL_EGRESS; aclDir++) + { + chainEntry = netif->chainListHead[aclDir]; + while(chainEntry) + { + /*remove all aclrule*/ + aclRule = chainEntry->head; + while(aclRule) + { + _rtl865x_delAclFromChain(aclRule, &chainEntry->head, &chainEntry->tail); + aclRule = chainEntry->head; + } + + chainEntry->ruleCnt = 0; + netif->chainListHead[aclDir] = chainEntry->nextChain; + + /*remove to freelist*/ + chainEntry->nextChain = freeChainHead; + if(freeChainHead) + freeChainHead->preChain = chainEntry; + freeChainHead = chainEntry; + + chainEntry = netif->chainListHead[aclDir]; + } + } + + netif->inAclEnd = netif->inAclStart = netif->outAclEnd = netif->outAclStart = RTL865X_ACLTBL_PERMIT_ALL; /*default permit...*/ + _rtl865x_setAsicNetif(netif); + + return SUCCESS; +} + +static rtl865x_acl_chain_t* _rtl865x_find_aclChain_byPriority(rtl865x_acl_chain_t *head, int32 priority) +{ + rtl865x_acl_chain_t *entry; + entry = head; + while(entry) + { + if(entry->priority == priority) + break; + entry = entry->nextChain; + } + + return entry; +} + +static int32 _rtl865x_add_acl(rtl865x_AclRule_t *rule, char *netifName,int32 chainNo) +{ + rtl865x_netif_local_t *netif = NULL; + rtl865x_acl_chain_t *chain = NULL; + int32 isSynAsic = 0; + int32 retval = FAILED; + + if(rule == NULL) + return RTL_EINVALIDINPUT; + + if(netifName && netifName[0] != '\0' && (rule->inv_flag == 0)) + { + netif = _rtl865x_getNetifByName(netifName); + if(netif == NULL) + return RTL_EINVALIDINPUT; + + chain = _rtl865x_find_aclChain_byPriority(netif->chainListHead[rule->direction_],chainNo); + if(chain == NULL) + return RTL_EENTRYNOTFOUND; + + retval = _rtl865x_addAclToChain(rule, &(chain->head), &(chain->tail)); + if(retval == SUCCESS) + { + isSynAsic = 1; + chain->ruleCnt++; + } + } + else + { + /*add this rule to every netif*/ + int32 i; + for(i = 0 ; i < NETIF_NUMBER; i++) + { + netif = &netifTbl[i]; + if(netif->valid == 0) + continue; + + /*inv_flag != 0, means alc should add to the other netifs else netifName*/ + /*now: the inv_flag only should be RTL865X_INVERT_IN_NETIF or RTL865X_INVERT_OUT_NETIF*/ + if(netifName && netifName[0] != '\0' && rule->inv_flag != 0) + { + if(memcmp(netif->name,netifName,strlen(netifName)) == 0) + continue; + } + + /*add rule to netif*/ + { + chain = _rtl865x_find_aclChain_byPriority(netif->chainListHead[rule->direction_],chainNo); + if(chain == NULL) + continue; + + retval = _rtl865x_addAclToChain(rule, &(chain->head), &(chain->tail)); + if(retval == SUCCESS) + { + isSynAsic = 1; + chain->ruleCnt++; + } + } + } + } + + if(isSynAsic == 1) + _rtl865x_synAclwithAsicTbl(); + + return retval; +} + +static int32 _rtl865x_del_acl(rtl865x_AclRule_t *rule, char *netifName,int32 chainNo) +{ + rtl865x_netif_local_t *netif = NULL; + rtl865x_acl_chain_t *chain = NULL; + int32 isSynAsic = 0; + int32 retval = FAILED; + + if(rule == NULL) + return RTL_EINVALIDINPUT; + + if(netifName) + { + netif = _rtl865x_getNetifByName(netifName); + if(netif == NULL) + return RTL_EINVALIDINPUT; + } + + + if(netif != NULL) + { + chain = _rtl865x_find_aclChain_byPriority(netif->chainListHead[rule->direction_],chainNo); + if(chain == NULL) + return RTL_EENTRYNOTFOUND; + + retval = _rtl865x_delAclFromChain(rule, &(chain->head), &(chain->tail)); + if(retval == SUCCESS) + { + isSynAsic = 1; + chain->ruleCnt--; + } + } + else + { + /*remvoe this rule from every netif*/ + int32 i; + for(i = 0 ; i < NETIF_NUMBER; i++) + { + netif = &netifTbl[i]; + if(netif->valid) + { + chain = _rtl865x_find_aclChain_byPriority(netif->chainListHead[rule->direction_],chainNo); + if(chain == NULL) + continue; + retval = _rtl865x_delAclFromChain(rule, &(chain->head), &(chain->tail)); + if(retval == SUCCESS) + { + isSynAsic = 1; + chain->ruleCnt--; + } + } + } + } + + if(isSynAsic == 1) + _rtl865x_synAclwithAsicTbl(); + + return retval; + +} + +/* +@func int32 | rtl865x_regist_aclChain | register an acl chain for a network interface. +@parm char* | netifName | network interface Name. +@parm int32 | priority | priority of this acl chain. +@parm uint32 | flag | flags. it's value should be RTL865X_ACL_EGRESS or RTL865X_ACL_INGRESS. +@rvalue SUCCESS | Success. +@rvalue RTL_ENETIFINVALID | network interface is invalid. +@rvalue RTL_EENTRYALREADYEXIST | acl chain is already exist. +@rvalue RTL_ENOFREEBUFFER | no aclchains buffer. +@comm +In realtek 865x, there are two types acl list in each network interface: Ingress and Egress ACL list. +NOTE 1:the priority of acl chain is the primary key, which should be unique! + 2:priority RTL865X_ACL_USER_USED = 0 is used by system. + 3:acl chain with minimal priority value hold the highest priority. +In order to easily configure the ACL list, acl chains architecture is designed. lots of acl chains are allowed in one network work interface and lots of ACL rules can be attached in an acl chain. +according to the priority of acl chains, ACL engine sequentially scan ACL rules in each chain. +for example: +ingress acl head--->acl chain(priority0)--->acl chain(priority1)--->acl chain(priority2) + | | | + |->acl rule1 |->acl rule1 |->aclrule1 + |->acl rule2 |->acl rule2 |->aclrule2 + |->acl rule3 |->acl rule3 |->aclrule3 + |->acl rule4 |->aclrule4 + |->acl rule5 |->aclrule5 + + +*/ +int32 rtl865x_regist_aclChain(char *netifName, int32 priority, uint32 flag) +{ + return _rtl865x_regist_aclChain(netifName, priority, flag); +} + +/* +@func int32 | rtl865x_unRegist_aclChain | unregister an acl chain from a network interface. +@parm char* | netifName | network interface Name. +@parm int32 | priority | priority of this acl chain. +@parm uint32 | flag | flags. it's value should be RTL865X_ACL_EGRESS or RTL865X_ACL_INGRESS. +@rvalue SUCCESS | Success. +@rvalue RTL_ENETIFINVALID | network interface is invalid. +@rvalue RTL_EENTRYNOTFOUND | Not found the acl chain . +@comm +an acl chain is unregistered, all ACL rules which attach on the acl chain are deleted at the same time. +*/ +int32 rtl865x_unRegist_aclChain(char *netifName, int32 priority, uint32 flag) +{ + //printk("============%s(%d),netif(%s),priority(%d),flag(%d)\n",__FUNCTION__,__LINE__,netifName,priority,flag); + return _rtl865x_unRegist_aclChain(netifName, priority, flag); +} + +/* +@func int32 | rtl865x_flush_allAcl_fromChain | delete all Acl Rules which attach on the acl chain. +@parm char* | netifName | network interface Name. +@parm int32 | priority | priority of this acl chain. +@parm uint32 | flag | flags. it's value should be RTL865X_ACL_EGRESS or RTL865X_ACL_INGRESS. +@rvalue SUCCESS | Success. +@rvalue RTL_ENETIFINVALID | network interface is invalid. +@rvalue RTL_EENTRYNOTFOUND | Not found the acl chain . +@comm + just delete the ACL rules, the acl chain is alive. +*/ +int32 rtl865x_flush_allAcl_fromChain(char *netifName, int32 priority, uint32 flag) +{ + return _rtl865x_flush_allAcl_fromChain(netifName, priority, flag); +} + +rtl865x_AclRule_t* rtl865x_matched_layer4_aclChain(char *netifName,int32 priority, uint32 flag, rtl865x_AclRule_t *match) +{ + return _rtl865x_matched_layer4_aclChain(netifName, priority, flag, match); +} + +rtl865x_AclRule_t* rtl865x_matched_layer2_aclChain(char *netifName,int32 priority, uint32 flag, rtl865x_AclRule_t *match) +{ + return _rtl865x_matched_layer2_aclChain(netifName, priority, flag, match); +} +rtl865x_acl_chain_t* rtl865x_find_aclChain_byPriority(rtl865x_acl_chain_t *head, int32 priority) +{ + rtl865x_acl_chain_t *entry; + entry = head; + while(entry) + { + if(entry->priority == priority) + break; + entry = entry->nextChain; + } + + return entry; +} + +/* +@func int32 | rtl865x_init_acl_chain |memory init for acl chains. +@rvalue SUCCESS | Success. +@comm + this API must be called when system boot. +*/ +int32 rtl865x_init_acl_chain(void) +{ + int32 i; + rtl865x_acl_chain_t *entry; + + freeChainHead = NULL; + + TBL_MEM_ALLOC(entry, rtl865x_acl_chain_t, RTL865X_ACL_CHAIN_NUMBER); + + for(i = 0; i<RTL865X_ACL_CHAIN_NUMBER;i++) + { + memset(&entry[i],0,sizeof(rtl865x_acl_chain_t)); + entry[i].preChain= NULL; + entry[i].nextChain= freeChainHead; + + entry[i].head = NULL; + entry[i].tail = NULL; + if(freeChainHead) + freeChainHead->preChain = &entry[i]; + freeChainHead = &entry[i]; + } + + return SUCCESS; +} + +/* +@func int32 | rtl865x_init_acl |memory init for acl rules. +@rvalue SUCCESS | Success. +@comm + this API must be called when system boot. +*/ +int32 rtl865x_init_acl(void) +{ + int32 i; + rtl865x_AclRule_t *aclEntry; + + freeAclList.freeHead = NULL; + + TBL_MEM_ALLOC(aclEntry, rtl865x_AclRule_t, RTL865X_ACL_MAX_NUMBER); + + for(i = 0; i<RTL865X_ACL_MAX_NUMBER;i++) + { + memset(&aclEntry[i],0,sizeof(rtl865x_AclRule_t)); + aclEntry[i].pre = NULL; + aclEntry[i].next = freeAclList.freeHead; + if(freeAclList.freeHead) + freeAclList.freeHead->pre = &aclEntry[i]; + freeAclList.freeHead = &aclEntry[i]; + + freeAclList.totalCnt++; + freeAclList.freeCnt++; + } + + _rtl865x_confReservedAcl(); + /*init acl chains*/ + rtl865x_init_acl_chain(); + return SUCCESS; +} + + + +/* +@func int32 | rtl865x_add_acl |add an ACL Rule to acl chain. +@parm rtl865x_AclRule_t* | rule | realtek ACL rule +@parm char* | netifName | network interface Name. +@parm int32 | priority | priority of this acl chain. +@rvalue SUCCESS | Success. +@rvalue RTL_EINVALIDINPUT | ACL rule is NULL or netifName is NULL +@rvalue RTL_EENTRYNOTFOUND | acl chain with priority is not found +@rvalue FAILED | Failed +@comm + ACL rule structure: please refer in header file. +*/ +int32 rtl865x_add_acl(rtl865x_AclRule_t *rule, char *netifName,int32 priority) +{ + int32 retval = FAILED; + unsigned long flags; + //printk("********%s(%d)*********,netif(%s),priority(%d)\n",__FUNCTION__,__LINE__,netifName,priority); +#if defined(CONFIG_RTK_VLAN_SUPPORT) + if(rtl865x_acl_enable == 0) + return retval; +#endif + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_add_acl(rule,netifName,priority); + if(retval == RTL_ENOFREEBUFFER){ // acl entries is full. + _rtl865x_setDefACLForAllNetif(RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL); + } + //rtl_up(&netif_sem); + local_irq_restore(flags); + //printk("********%s(%d)*********retval(%d)\n",__FUNCTION__,__LINE__,retval); + return retval; +} + +/* +@func int32 | rtl865x_del_acl |del an ACL Rule from the acl chain. +@parm rtl865x_AclRule_t* | rule | realtek ACL rule +@parm char* | netifName | network interface Name. +@parm int32 | priority | priority of this acl chain. +@rvalue SUCCESS | Success. +@rvalue RTL_EINVALIDINPUT | ACL rule is NULL or netifName is NULL +@rvalue RTL_EENTRYNOTFOUND | acl chain with priority is not found +@rvalue FAILED | Failed +@comm + ACL rule structure: please refer in header file. +*/ +int32 rtl865x_del_acl(rtl865x_AclRule_t *rule, char *netifName,int32 priority) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_del_acl(rule,netifName,priority); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return retval; +} + +#if defined(CONFIG_RTK_VLAN_SUPPORT) +int32 rtl865x_enable_acl(uint32 enable) +{ + if(enable) + { + rtl865x_acl_enable = 1; + _rtl865x_setDefACLForAllNetif(RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL); + } + else + { + rtl865x_acl_enable = 0; + _rtl865x_setDefACLForAllNetif(RTL865X_ACLTBL_ALL_TO_CPU,RTL865X_ACLTBL_ALL_TO_CPU,RTL865X_ACLTBL_PERMIT_ALL,RTL865X_ACLTBL_PERMIT_ALL); + } + return SUCCESS; +} +#endif + + + +int rtl865x_add_pattern_acl_for_contentFilter(rtl865x_AclRule_t *rule,char *netifName) +{ + uint32 i; + //### add by sen_liu 2011.5.4 to get wan prot + rtl865x_netif_local_t *netif; + rtl865x_vlan_entry_t *vlan; + union + { + char pat[4]; + uint32 pattern; + }u; + + if(rule == NULL) + return FAILED; + + rtl865x_add_acl(rule, netifName, RTL865X_ACL_SYSTEM_USED); + netif = _rtl865x_getNetifByName(netifName); + if(netif == NULL) + return FAILED; + vlan = _rtl8651_getVlanTableEntry(netif->vid); + if(vlan == NULL) + return FAILED; + + u.pat[0]='T'; + u.pat[1]='T'; + u.pat[2]='P'; + u.pat[3]='/'; + for(i=0;i<RTL8651_PORT_NUMBER;i++) + { + if (vlan->memberPortMask & 1<<i) { + if(rtl8651_setAsicPortPatternMatch(i, u.pattern, 0xffffffff, 0x2)!=SUCCESS) + return FAILED; + } + + } + + return SUCCESS; +} + +int rtl865x_del_pattern_acl_for_contentFilter(rtl865x_AclRule_t *rule,char *netifName) +{ + union + { + char pat[4]; + uint32 pattern; + }u; + int32 i; + + rtl865x_netif_local_t *netif; + rtl865x_vlan_entry_t *vlan; + + if(rule == NULL) + return FAILED; + + rtl865x_del_acl(rule, netifName, RTL865X_ACL_SYSTEM_USED); + + netif = _rtl865x_getNetifByName(netifName); + if(netif == NULL) + return FAILED; + vlan = _rtl8651_getVlanTableEntry(netif->vid); + if(vlan == NULL) + return FAILED; + + u.pat[0]='T'; + u.pat[1]='T'; + u.pat[2]='P'; + u.pat[3]='/'; + for(i=0;i<RTL8651_PORT_NUMBER;i++) + { + if (vlan->memberPortMask & 1<<i) { + rtl8651_setAsicPortPatternMatch(i, 0, 0, 0x2); + } + } + + return SUCCESS; +} + + + +#ifdef CONFIG_FAST_PATH_MODULE +EXPORT_SYMBOL(rtl865x_del_acl); +EXPORT_SYMBOL(rtl865x_add_acl); +#endif +#endif //CONFIG_RTL_LAYERED_DRIVER_ACL +int32 rtl865x_attachMasterNetif(char *slave, char *master) +{ + return _rtl865x_attachMasterNetif(slave, master); +} + +int32 rtl865x_detachMasterNetif(char *slave) +{ + return _rtl865x_detachMasterNetif(slave); +} + +/* +@func int32 | rtl865x_addNetif |add network interface. +@parm rtl865x_netif_t* | netif | network interface +@rvalue SUCCESS | Success. +@rvalue RTL_EINVALIDINPUT | netif is NULL +@rvalue RTL_EENTRYALREADYEXIST | netif is already exist +@rvalue RTL_ENOFREEBUFFER | no netif to used +@rvalue FAILED | Failed +@comm + rtl865x_netif_t: please refer in header file. +*/ + +int32 rtl865x_addNetif(rtl865x_netif_t *netif) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_addNetif(netif); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return retval; +} + +/* +@func int32 | rtl865x_delNetif |delete network interface. +@parm char* | ifName | network interface name +@rvalue SUCCESS | Success. +@rvalue RTL_EENTRYNOTFOUND | network interface is NOT found +@rvalue RTL_EREFERENCEDBYOTHER | netif is referenced by onter table entry +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_delNetif(char *ifName) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_delNetif(ifName); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return retval; +} +#if defined (CONFIG_RTL_LOCAL_PUBLIC) +int32 rtl865x_addVirtualNetif(rtl865x_netif_t *netif) +{ + + rtl865x_netif_local_t *entry; + int32 retval = FAILED; + if(netif == NULL) + return RTL_EINVALIDINPUT; + + /*duplicate entry....*/ + entry = _rtl865x_getSWNetifByName(netif->name); + if(entry) + return RTL_EENTRYALREADYEXIST; + + + /*add new entry*/ + entry = &virtualNetIf; + + memset(entry, 0, sizeof(rtl865x_netif_local_t)); + + entry->valid = 1; + memcpy(entry->name,netif->name,MAX_IFNAMESIZE); + entry->inAclEnd = entry->inAclStart = entry->outAclEnd = entry->outAclStart = RTL865X_ACLTBL_PERMIT_ALL; /*default permit...*/ + entry->refCnt = 1; + + +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL + entry->chainListHead[RTL865X_ACL_INGRESS] = NULL; + entry->chainListHead[RTL865X_ACL_EGRESS] = NULL; +#endif + + +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL + /*register 2 ingress chains: system/user*/ + retval = rtl865x_regist_aclChain(netif->name, RTL865X_ACL_SYSTEM_USED, RTL865X_ACL_INGRESS); + retval = rtl865x_regist_aclChain(netif->name, RTL865X_ACL_USER_USED, RTL865X_ACL_INGRESS); +#endif //CONFIG_RTL_LAYERED_DRIVER_ACL + + return SUCCESS; +} + +int32 rtl865x_delVirtualNetif(char *ifName) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_delNetif(ifName); + //rtl_up(&netif_sem); + local_irq_restore(flags); + _rtl865x_confReservedAcl(); + return retval; +} +#endif +/* +@func int32 | rtl865x_referNetif |reference network interface entry. +@parm char* | ifName | network interface name +@rvalue SUCCESS | Success. +@rvalue RTL_EENTRYNOTFOUND | network interface is NOT found +@rvalue FAILED | Failed +@comm +when other table entry refer network interface table entry, please call this API. +*/ +int32 rtl865x_referNetif(char *ifName) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_referNetif(ifName); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return retval; +} + +/* +@func int32 | rtl865x_deReferNetif |dereference network interface. +@parm char* | ifName | network interface name +@rvalue SUCCESS | Success. +@rvalue RTL_EENTRYNOTFOUND | network interface is NOT found +@rvalue FAILED | Failed +@comm +this API should be called after rtl865x_referNetif. +*/ +int32 rtl865x_deReferNetif(char *ifName) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_deReferNetif(ifName); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return retval; +} + +/* +@func int32 | rtl865x_setNetifVid |mapping network interface with vlan. +@parm char* | name | network interface name +@parm uint16 | vid | vlan id +@rvalue SUCCESS | Success. +@rvalue RTL_EENTRYNOTFOUND | network interface is NOT found +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_setNetifVid(char *name, uint16 vid) +{ + int32 ret; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + ret = _rtl865x_setNetifVid(name,vid); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return ret; +} + +int32 rtl865x_setPortToNetif(char *name,uint32 port) +{ + int32 ret; + rtl865x_netif_local_t *entry; + entry = _rtl865x_getNetifByName(name); + + if(entry == NULL) + return FAILED; + + ret = rtl8651_setPortToNetif(port, entry->asicIdx); + return ret; +} + +/* +@func int32 | rtl865x_setNetifType |config network interface type. +@parm char* | ifName | network interface name +@parm uint32 | ifType | interface type. IF_ETHER/IF_PPPOE/IF_PPTP/IF_L2TP allowed. +@rvalue SUCCESS | Success. +@rvalue RTL_EENTRYNOTFOUND | network interface is NOT found +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_setNetifType(char *name, uint32 ifType) +{ + int32 ret; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + ret = _rtl865x_setNetifType(name,ifType); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return ret; +} + +/* +@func int32 | rtl865x_setNetifMac |config network interface Mac address. +@parm rtl865x_netif_t* | netif | netif name&MAC address +@rvalue SUCCESS | Success. +@rvalue RTL_EENTRYNOTFOUND | network interface is NOT found +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_setNetifMac(rtl865x_netif_t *netif) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_setNetifMac(netif); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return retval; +} + +/* +@func int32 | rtl865x_setNetifMtu |config network interface MTU. +@parm rtl865x_netif_t* | netif | netif name & MTU +@rvalue SUCCESS | Success. +@rvalue RTL_EENTRYNOTFOUND | network interface is NOT found +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_setNetifMtu(rtl865x_netif_t *netif) +{ + int32 retval = FAILED; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + retval = _rtl865x_setNetifMtu(netif); + //rtl_up(&netif_sem); + local_irq_restore(flags); + return retval; +} + + +/* +@func int32 | rtl865x_initNetifTable | initialize network interface table. +@rvalue SUCCESS | Success. +@rvalue FAILED | Failed,system should be reboot. +*/ +int32 rtl865x_initNetifTable(void) +{ + TBL_MEM_ALLOC(netifTbl, rtl865x_netif_local_t, NETIF_NUMBER); + memset(netifTbl,0,sizeof(rtl865x_netif_local_t)*NETIF_NUMBER); +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL + /*init reserved acl in function init_acl...*/ +#else + _rtl865x_confReservedAcl(); +#endif + +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + memset(&virtualNetIf,0,sizeof(rtl865x_netif_local_t)); +#endif + rtl_get_drv_netifName_by_psName = NULL; + + return SUCCESS; +} + +int32 rtl865x_config_callback_for_get_drv_netifName(int (*fun)(const char *psName,char *netifName)) +{ + rtl_get_drv_netifName_by_psName = fun; + return SUCCESS; +} + +int32 rtl865x_get_drvNetifName_by_psName(const char *psName,char *netifName) +{ + if(strlen(psName) >= MAX_IFNAMESIZE) + return FAILED; + + if(rtl_get_drv_netifName_by_psName) + rtl_get_drv_netifName_by_psName(psName,netifName); + else + { + memcpy(netifName,psName,MAX_IFNAMESIZE); + } + + return SUCCESS; +} + +/* +@func int32 | rtl865x_enableNetifRouting |config network interface operation layer. +@parm rtl865x_netif_local_t* | netif | netif & enableRoute +@rvalue SUCCESS | Success. +@rvalue RTL_EINVALIDINPUT | input is invalid +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_enableNetifRouting(rtl865x_netif_local_t *netif) +{ + int32 retval = FAILED; + + if(netif == NULL) + return RTL_EINVALIDINPUT; + if(netif ->enableRoute == 1) + return SUCCESS; + + netif->enableRoute = 1; + retval = _rtl865x_setAsicNetif(netif); + return retval; +} + +/* +@func int32 | rtl865x_disableNetifRouting |config network interface operation layer. +@parm rtl865x_netif_local_t* | netif | netif & enableRoute +@rvalue SUCCESS | Success. +@rvalue RTL_EINVALIDINPUT | input is invalid +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_disableNetifRouting(rtl865x_netif_local_t *netif) +{ + int32 retval = FAILED; + + if(netif == NULL) + return RTL_EINVALIDINPUT; + + if(netif ->enableRoute == 0) + return SUCCESS; + + netif->enableRoute = 0; + retval = _rtl865x_setAsicNetif(netif); + return retval; +} + +/* +@func int32 | rtl865x_disableNetifRouting |config network interface operation layer. +@parm rtl865x_netif_local_t* | netif | netif & enableRoute +@rvalue SUCCESS | Success. +@rvalue RTL_EINVALIDINPUT | input is invalid +@rvalue FAILED | Failed +@comm +*/ +int32 rtl865x_reinitNetifTable(void) +{ + int32 i; + unsigned long flags; + //rtl_down_interruptible(&netif_sem); + local_irq_save(flags); + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid) + { + _rtl865x_delNetif(netifTbl[i].name); + } + } + //memset(netifTbl,0,sizeof(rtl865x_netif_local_t)*NETIF_NUMBER); + +#if defined (CONFIG_RTL_LOCAL_PUBLIC) + if(virtualNetIf.valid) + { + _rtl865x_delNetif(virtualNetIf.name); + } +#endif + + //rtl_up(&netif_sem); + local_irq_restore(flags); + return SUCCESS; +} + + +#if defined (CONFIG_RTL_HARDWARE_MULTICAST) +uint32 rtl865x_getExternalPortMask(void) +{ + int32 i; + rtl865x_netif_local_t *netif = NULL; + uint32 externalPortMask=0; + + for(i = 0; i < NETIF_NUMBER; i++) + { + netif = &netifTbl[i]; + if((netif->valid == 1) && (netif->is_wan==1)) + { + externalPortMask|=rtl865x_getVlanPortMask(netif->vid); + } + } + + return externalPortMask; +} + +int32 rtl865x_getNetifVid(char *name, uint32 *vid) +{ + rtl865x_netif_local_t *entry; + + if(name == NULL) + { + return FAILED; + } + + entry = _rtl865x_getNetifByName(name); + + if(entry == NULL) + { + return FAILED; + } + + *vid=(uint32)(entry->vid); + return SUCCESS; + +} + +int32 rtl865x_getNetifType(char *name,uint32 *type) +{ + rtl865x_netif_local_t *entry; + + if(name == NULL) + { + return FAILED; + } + + if(type==NULL) + { + return FAILED; + } + + entry = _rtl865x_getNetifByName(name); + + if(entry == NULL) + { + return FAILED; + } + + *type=(uint32)(entry->if_type); + return SUCCESS; + +} +#endif + + +#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL +#if RTL_LAYERED_DRIVER_DEBUG +int32 rtl865x_acl_test(int32 testNo) +{ + int32 retval = 0; + printk("testNo = %d\n",testNo); + switch(testNo) + { + /*add a chain to br0, and delete it...*/ + case 0: + { + rtl865x_acl_chain_t *chain = NULL; + rtl865x_netif_local_t *netif = NULL; + int32 cnt = 0; + retval = _rtl865x_regist_aclChain(RTL_DRV_LAN_NETIF_NAME, -500, RTL865X_ACL_INGRESS); + netif = _rtl865x_getNetifByName(RTL_DRV_LAN_NETIF_NAME); + if(netif == NULL) + { + printk("netif is NULL!!!!\n"); + return FAILED; + } + chain = netif->chainListHead[RTL865X_ACL_INGRESS]; + + printk("chains of netif(%s):\n",netif->name); + while(chain) + { + printk("chain %d:\n",cnt); + printk("chain:priority(%d),ruleCnt(%d)\n",chain->priority,chain->ruleCnt); + cnt++; + chain = chain->nextChain; + } + printk("====================================\n"); + + retval = _rtl865x_unRegist_aclChain(RTL_DRV_LAN_NETIF_NAME, -500, RTL865X_ACL_INGRESS); + + chain = netif->chainListHead[RTL865X_ACL_INGRESS]; + cnt = 0; + printk("=============after unregist the chain================\n"); + printk("chains of netif(%s):\n",netif->name); + while(chain) + { + printk("chain %d:\n",cnt); + printk("chain:priority(%d),ruleCnt(%d)\n",chain->priority,chain->ruleCnt); + cnt++; + chain = chain->nextChain; + } + } + break; + + /*add acls and delete acl....*/ + case 1: + { + rtl865x_acl_chain_t *chain = NULL; + rtl865x_netif_local_t *netif = NULL; + rtl865x_AclRule_t rule,rule1,rule2; + retval = _rtl865x_regist_aclChain(RTL_DRV_LAN_NETIF_NAME, -500, RTL865X_ACL_INGRESS); + + netif = _rtl865x_getNetifByName(RTL_DRV_LAN_NETIF_NAME); + chain = netif->chainListHead[RTL865X_ACL_INGRESS]; + + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + + memset(&rule,0,sizeof(rtl865x_AclRule_t)); + rule.pktOpApp_ = RTL865X_ACL_L2_AND_L3; + rule.actionType_ = RTL865X_ACL_DROP; + + printk("============add 1st acl===========\n"); + rtl865x_add_acl(&rule, RTL_DRV_LAN_NETIF_NAME, -500); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + printk("del the 1st acl\n"); + rtl865x_del_acl(&rule, RTL_DRV_LAN_NETIF_NAME, -500); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + printk("add 2 rule, delete the tail...\n"); + rtl865x_add_acl(&rule,RTL_DRV_LAN_NETIF_NAME, -500); + memset(&rule1,0,sizeof(rtl865x_AclRule_t)); + + rule1.pktOpApp_ = RTL865X_ACL_L3_AND_L4; + rule1.ruleType_ = RTL865X_ACL_IP; + rule1.actionType_ = RTL865X_ACL_DROP; + + rtl865x_add_acl(&rule1,RTL_DRV_LAN_NETIF_NAME,-500); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + printk("del the rule1...\n"); + rtl865x_del_acl(&rule1, RTL_DRV_LAN_NETIF_NAME, -500); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + rtl865x_add_acl(&rule1,RTL_DRV_LAN_NETIF_NAME,-500); + memset(&rule2,0,sizeof(rtl865x_AclRule_t)); + + rule2.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rule2.ruleType_ = RTL865X_ACL_ICMP; + rule2.actionType_ = RTL865X_ACL_TOCPU; + rtl865x_add_acl(&rule2,RTL_DRV_LAN_NETIF_NAME,-500); + + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + printk("del the rule1...\n"); + rtl865x_del_acl(&rule1, RTL_DRV_LAN_NETIF_NAME, -500); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + printk("unregist the chain(-500)\n"); + _rtl865x_unRegist_aclChain(RTL_DRV_LAN_NETIF_NAME,-500,RTL865X_ACL_INGRESS); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + + printk("flush all chain of br0"); + _rtl865x_unRegister_all_aclChain(RTL_DRV_LAN_NETIF_NAME); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + } + break; + + /*add acls....*/ + case 2: + { + rtl865x_acl_chain_t *chain = NULL; + rtl865x_netif_local_t *netif = NULL; + rtl865x_AclRule_t rule; + retval = _rtl865x_regist_aclChain(RTL_DRV_LAN_NETIF_NAME, -500, RTL865X_ACL_INGRESS); + + netif = _rtl865x_getNetifByName(RTL_DRV_LAN_NETIF_NAME); + chain = netif->chainListHead[RTL865X_ACL_INGRESS]; + + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + + memset(&rule,0,sizeof(rtl865x_AclRule_t)); + rule.pktOpApp_ = RTL865X_ACL_L2_AND_L3; + rule.actionType_ = RTL865X_ACL_DROP; + + printk("============add 1st acl===========\n"); + rtl865x_add_acl(&rule, RTL_DRV_LAN_NETIF_NAME, -500); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + } + break; + + /*add acls....*/ + case 3: + { + rtl865x_acl_chain_t *chain = NULL; + rtl865x_netif_local_t *netif = NULL; + rtl865x_AclRule_t rule1; + + netif = _rtl865x_getNetifByName(RTL_DRV_LAN_NETIF_NAME); + chain = netif->chainListHead[RTL865X_ACL_INGRESS]; + + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + + memset(&rule1,0,sizeof(rtl865x_AclRule_t)); + rule1.pktOpApp_ = RTL865X_ACL_L3_AND_L4; + rule1.actionType_ = RTL865X_ACL_DROP; + rule1.ruleType_ = RTL865X_ACL_IP; + + + rtl865x_add_acl(&rule1, RTL_DRV_LAN_NETIF_NAME, -500); + printk("now the information of netif(%s) is:\n\n",netif->name); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + + } + break; + + case 4: + { + rtl865x_netif_local_t *netif = NULL; + netif = _rtl865x_getNetifByName(RTL_DRV_LAN_NETIF_NAME); + printk("unregist the chain(-500)\n"); + _rtl865x_unRegist_aclChain(RTL_DRV_LAN_NETIF_NAME,-500,RTL865X_ACL_INGRESS); + printk("now the information of netif(br0) is:\n\n"); + _rtl865x_print_allChain_allAcl(netif); + _rtl865x_print_freeChainNum(); + } + break; + + case 5: + { + rtl865x_AclRule_t rule; + union + { + char pat[4]; + uint32 pattern; + }u; + int32 i; + + + printk("for url filter test...."); + memset(&rule,0,sizeof(rtl865x_AclRule_t)); + rule.actionType_ = RTL865X_ACL_TOCPU; + rule.ruleType_ = RTL865X_ACL_IP; + rule.ipHttpFilter_=rule.ipHttpFilterM_=1; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rtl865x_add_acl(&rule, RTL_DRV_LAN_NETIF_NAME, -10000); + + memset(&rule,0,sizeof(rtl865x_AclRule_t)); + rule.actionType_ = RTL865X_ACL_PERMIT; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rtl865x_add_acl(&rule, RTL_DRV_LAN_NETIF_NAME, -10000); + + u.pat[0]='T'; + u.pat[1]='T'; + u.pat[2]='P'; + u.pat[3]='/'; + for(i=0;i<RTL8651_PORT_NUMBER;i++) + { + if(rtl8651_setAsicPortPatternMatch(i, u.pattern, 0xffffffff, 0x2 /* fwd to CPU */)!=SUCCESS) + return FAILED; + } + + } + break; + + case 6: + { + /*print software netif table information*/ + int32 i; + for(i = 0; i < NETIF_NUMBER; i++) + { + printk("i(%d),netifTbl(0x%p),name(%s)\n",i,&netifTbl[i],netifTbl[i].name); + } + } + break; + + + } + return retval; +} + +#endif +#endif + +#if 0 +int rtl865x_show_all_netif(void) +{ + int32 i; + rtl865x_netif_local_t *netif = NULL; + + for(i = 0; i < NETIF_NUMBER; i++) + { + if(netifTbl[i].valid == 1 ) + { + netif = &netifTbl[i]; + printk("idx(%d),valid(%d),name(%s),vid(%d),is_slave(%d),type(%d)\n",i,netif->valid,netif->name,netif->vid,netif->is_slave,netif->if_type); + } + } + + return SUCCESS; +} +#endif + +#if 0 //defined (CONFIG_RTL_LOCAL_PUBLIC) +int32 rtl865x_getNetifFid(char *name, uint16 *fid) +{ + rtl865x_netif_local_t *entry; + rtl865x_vlan_entry_t *vlan; + + if(name == NULL) + { + return FAILED; + } + + entry = _rtl865x_getNetifByName(name); + + if(entry == NULL) + { + return FAILED; + } + + vlan = _rtl8651_getVlanTableEntry(entry->vid); + *fid = vlan->fid; + return SUCCESS; + +} +#endif +extern int rtk_vlan_support_enable; +int32 rtl865x_reConfigDefaultAcl(char *ifName) +{ + rtl865x_AclRule_t rule; + int ret=FAILED; + + unsigned long flags; + local_irq_save(flags); + +#if defined (CONFIG_RTK_VLAN_SUPPORT) + if(rtk_vlan_support_enable==0) + { + /*del old default permit acl*/ + bzero((void*)&rule,sizeof(rtl865x_AclRule_t)); + rule.ruleType_ = RTL865X_ACL_MAC; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rule.actionType_ = RTL865X_ACL_PERMIT; + ret=_rtl865x_del_acl(&rule, ifName, RTL865X_ACL_SYSTEM_USED); + + /*add new default permit acl*/ + bzero((void*)&rule,sizeof(rtl865x_AclRule_t)); + rule.ruleType_ = RTL865X_ACL_MAC; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rule.actionType_ = RTL865X_ACL_PERMIT; + ret=_rtl865x_add_acl(&rule, ifName, RTL865X_ACL_SYSTEM_USED); + } + else + { + /*del old default to cpu acl*/ + bzero((void*)&rule,sizeof(rtl865x_AclRule_t)); + rule.ruleType_ = RTL865X_ACL_MAC; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rule.actionType_ = RTL865X_ACL_TOCPU; + ret=_rtl865x_del_acl(&rule, ifName, RTL865X_ACL_SYSTEM_USED); + + /*add new default to cpu acl*/ + bzero((void*)&rule,sizeof(rtl865x_AclRule_t)); + rule.ruleType_ = RTL865X_ACL_MAC; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rule.actionType_ = RTL865X_ACL_TOCPU; + ret=_rtl865x_add_acl(&rule, ifName, RTL865X_ACL_SYSTEM_USED); + } +#else + { + /*del old default permit acl*/ + bzero((void*)&rule,sizeof(rtl865x_AclRule_t)); + rule.ruleType_ = RTL865X_ACL_MAC; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rule.actionType_ = RTL865X_ACL_PERMIT; + ret=_rtl865x_del_acl(&rule, ifName, RTL865X_ACL_SYSTEM_USED); + + /*add new default permit acl*/ + bzero((void*)&rule,sizeof(rtl865x_AclRule_t)); + rule.ruleType_ = RTL865X_ACL_MAC; + rule.pktOpApp_ = RTL865X_ACL_ALL_LAYER; + rule.actionType_ = RTL865X_ACL_PERMIT; + ret=_rtl865x_add_acl(&rule, ifName, RTL865X_ACL_SYSTEM_USED); + } +#endif + local_irq_restore(flags); + + return SUCCESS; +} + diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_netif_local.h b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_netif_local.h new file mode 100644 index 000000000..b65541cd8 --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_netif_local.h @@ -0,0 +1,85 @@ +/*
+* Copyright c Realtek Semiconductor Corporation, 2008
+* All rights reserved.
+*
+* Program : network interface driver header file
+* Abstract :
+* Author : hyking (hyking_liu@realsil.com.cn)
+*/
+
+#ifndef RTL865X_NETIF_LOCAL_H
+#define RTL865X_NETIF_LOCAL_H
+
+#if !defined(REDUCE_MEMORY_SIZE_FOR_16M)
+#define REDUCE_MEMORY_SIZE_FOR_16M
+#endif
+
+#if defined(REDUCE_MEMORY_SIZE_FOR_16M)
+#define RTL865X_ACL_CHAIN_NUMBER 32
+#else
+#define RTL865X_ACL_CHAIN_NUMBER 16
+#endif
+#define RTL865X_ACL_SYSTEM_USED -10000
+
+#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL
+typedef struct _rtl865x_acl_chain_s
+{
+ int32 ruleCnt;
+ int32 priority; /*chain priosity: the minimum value is the highest proirity*/
+ rtl865x_AclRule_t *head,*tail;
+ struct _rtl865x_acl_chain_s *preChain,*nextChain;
+}rtl865x_acl_chain_t;
+#endif
+
+/*the following fields are invalid when the interface is slave interface:
+* inAclStart, inAclEnd, outAclStart, outAclEnd,asicIdx,chainListHead
+*/
+typedef struct rtl865x_netif_local_s
+{
+ uint16 vid; /*netif->vid*/
+ uint16 mtu; /*netif's MTU*/
+ uint16 macAddrNumber; /*how many continuous mac is attached*/
+ uint16 inAclStart, inAclEnd, outAclStart, outAclEnd; /*acl index*/
+ uint16 enableRoute; /*enable route*/
+ uint32 valid:1, /*valid?*/
+ if_type:5, /*interface type, IF_ETHER, IF_PPPOE*/
+ refCnt:5, /*referenc count by other table entry*/
+ asicIdx:3, /*asic index, total 8 entrys in asic*/
+ is_wan:1, /*this interface is wan?*/
+ is_defaultWan:1, /*if there is multiple wan interface, which interface is default wan*/
+ dmz:1, /*dmz interface?*/
+ is_slave:1; /*is slave interface*/
+
+ ether_addr_t macAddr;
+ uint8 name[MAX_IFNAMESIZE];
+#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL
+ rtl865x_acl_chain_t *chainListHead[2]; /*0: ingress acl chain, 1: egress acl chain*/
+#endif //CONFIG_RTL_LAYERED_DRIVER_ACL
+ struct rtl865x_netif_local_s *master; /*point master interface when this interface is slave interface*/
+}rtl865x_netif_local_t;
+
+#define RTL_ACL_INGRESS 0
+#define RTL_ACL_EGRESS 1
+
+#ifdef CONFIG_RTL_LAYERED_DRIVER_ACL
+typedef struct rtl865x_aclBuf_s
+{
+ int16 totalCnt;
+ int16 freeCnt;
+ rtl865x_AclRule_t *freeHead;
+}rtl865x_aclBuf_t;
+#endif
+
+int32 rtl865x_enableNetifRouting(rtl865x_netif_local_t *netif);
+int32 rtl865x_disableNetifRouting(rtl865x_netif_local_t *netif);
+rtl865x_netif_local_t *_rtl865x_getNetifByName(char *name);
+rtl865x_netif_local_t *_rtl865x_getSWNetifByName(char * name);
+rtl865x_netif_local_t *_rtl865x_getDefaultWanNetif(void);
+int32 _rtl865x_setDefaultWanNetif(char *name);
+int32 _rtl865x_clearDefaultWanNetif(char * name);
+int32 _rtl865x_getNetifIdxByVid(uint16 vid);
+int32 _rtl865x_getNetifIdxByName(uint8 *name);
+int32 _rtl865x_getNetifIdxByNameExt(uint8 *name);
+int32 rtl865x_get_drvNetifName_by_psName(const char *psName,char *netifName);
+
+#endif
diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_vlan.c b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_vlan.c new file mode 100644 index 000000000..d55b592ea --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_vlan.c @@ -0,0 +1,532 @@ +/*
+* Copyright c Realtek Semiconductor Corporation, 2008
+* All rights reserved.
+*
+* Program : Vlan driver
+* Abstract :
+* Author : hyking (hyking_liu@realsil.com.cn)
+*/
+
+/* @doc RTL_LAYEREDDRV_API
+
+ @module rtl865x_vlan.c - RTL865x Home gateway controller Layered driver API documentation |
+ This document explains the API interface of the table driver module. Functions with rtl865x prefix
+ are external functions.
+ @normal Hyking Liu (Hyking_liu@realsil.com.cn) <date>
+
+ Copyright <cp>2008 Realtek<tm> Semiconductor Cooperation, All Rights Reserved.
+
+ @head3 List of Symbols |
+ Here is a list of all functions and variables in this module.
+
+ @index | RTL_LAYEREDDRV_API
+*/
+
+#include <net/rtl/rtl_types.h>
+#include <net/rtl/rtl_glue.h>
+#include "rtl_errno.h"
+//#include "rtl_utils.h"
+//#include "rtl_glue.h"
+#include "rtl865x_vlan.h"
+#ifdef CONFIG_RTL_LAYERED_ASIC_DRIVER
+#include "AsicDriver/rtl865x_asicCom.h"
+#else
+#include "AsicDriver/rtl865xC_tblAsicDrv.h"
+#endif
+#include "rtl865x_eventMgr.h"
+
+
+static rtl865x_vlan_entry_t *vlanTbl = NULL;
+
+static RTL_DECLARE_MUTEX(vlan_sem);
+
+static int32 _rtl865x_delVlan(uint16 vid);
+
+static int32 _rtl865x_setAsicVlan(uint16 vid,rtl865x_vlan_entry_t *vlanEntry)
+{
+ int32 retval = FAILED;
+ rtl865x_tblAsicDrv_vlanParam_t asicEntry;
+ /*add this entry to asic table*/
+ asicEntry.fid = vlanEntry->fid;
+ asicEntry.memberPortMask = vlanEntry->memberPortMask;
+ asicEntry.untagPortMask = vlanEntry->untagPortMask;
+ retval = rtl8651_setAsicVlan(vid,&asicEntry);
+ return retval;
+}
+
+
+static int32 _rtl865x_referVlan(uint16 vid)
+{
+ rtl865x_vlan_entry_t *entry;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER-1)
+ return RTL_EINVALIDVLANID;
+
+ entry = &vlanTbl[vid];
+ if(entry->valid != 1)
+ return RTL_EINVALIDVLANID;
+
+ entry->refCnt++;
+ return SUCCESS;
+}
+
+static int32 _rtl865x_deReferVlan(uint16 vid)
+{
+ rtl865x_vlan_entry_t *entry;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER-1)
+ return RTL_EINVALIDVLANID;
+
+ entry = &vlanTbl[vid];
+ if(entry->valid != 1)
+ return RTL_EINVALIDVLANID;
+
+ entry->refCnt--;
+ return SUCCESS;
+}
+
+int32 _rtl865x_addVlan(uint16 vid)
+{
+ int32 retval = FAILED;
+ rtl865x_vlan_entry_t *entry;
+ entry=&vlanTbl[vid];
+
+ if(1 == entry->valid)
+ return RTL_EVLANALREADYEXISTS;
+
+ /*add new vlan entry*/
+ memset(entry,0,sizeof(rtl865x_vlan_entry_t));
+ entry->vid = vid;
+ entry->valid = 1;
+ entry->refCnt = 1;
+
+ /*add this entry to asic table*/
+ retval = _rtl865x_setAsicVlan(vid,entry);
+
+ return retval;
+}
+
+
+static int32 _rtl865x_delVlan(uint16 vid)
+{
+ int32 retval = FAILED;
+ rtl865x_vlan_entry_t *vlanEntry,org;
+ vlanEntry=&vlanTbl[vid];
+ if(0 == vlanEntry->valid)
+ return RTL_EINVALIDVLANID;
+ /*
+ if(vlanEntry->refCnt > 1)
+ {
+ printk("vid(%d),reference(%d)\n",vid,vlanEntry->refCnt);
+ return RTL_EREFERENCEDBYOTHER;
+ }
+ */
+
+ memcpy(&org,vlanEntry,sizeof(rtl865x_vlan_entry_t));
+
+ /*delete vlan entry*/
+ vlanEntry->valid = 0;
+ /*ignor other member...*/
+
+ retval = rtl8651_delAsicVlan(vid);
+
+ if(SUCCESS == retval)
+ {
+ /*if vlan entry is deleted, this information should be noticed by uplayer module*/
+ #if 0
+ do_eventAction(EV_DEL_VLAN, (void *)&org);
+ #else
+ rtl865x_raiseEvent(EVENT_DEL_VLAN, (void *)&org);
+ #endif
+ }
+
+ return retval;
+}
+
+static int32 _rtl865x_addVlanPortMember(uint16 vid, uint32 portMask)
+{
+ int32 retval = FAILED;
+ rtl865x_vlan_entry_t *vlanEntry;
+
+ vlanEntry = &vlanTbl[vid];
+ if(vlanEntry->valid == 0)
+ return RTL_EINVALIDVLANID;
+
+ /*add member port*/
+ vlanEntry->memberPortMask |= portMask;
+ vlanEntry->untagPortMask |= portMask;
+
+ /*update this entry to asic table*/
+ retval = _rtl865x_setAsicVlan(vid,vlanEntry);
+
+ return retval;
+
+
+}
+
+
+static int32 _rtl865x_delVlanPortMember(uint16 vid, uint32 portMask)
+{
+ int32 retval = FAILED;
+ rtl865x_vlan_entry_t *vlanEntry;
+ //rtl865x_tblAsicDrv_vlanParam_t asicEntry;
+
+ vlanEntry = &vlanTbl[vid];
+ if(vlanEntry->valid == 0)
+ return RTL_EINVALIDVLANID;
+
+ /*add member port*/
+ vlanEntry->memberPortMask &= ~portMask;
+ vlanEntry->untagPortMask &=~portMask;
+
+ if(vlanEntry->memberPortMask == 0)
+ vlanEntry->valid = 0;
+
+ /*update this entry to asic table*/
+ retval = _rtl865x_setAsicVlan(vid,vlanEntry);
+
+ return retval;
+
+
+}
+
+
+static int32 _rtl865x_setVlanPortTag(uint16 vid, uint32 portMask, uint8 tag)
+{
+ int32 retval = FAILED;
+ rtl865x_vlan_entry_t *vlanEntry;
+
+ vlanEntry = &vlanTbl[vid];
+ if(vlanEntry->valid == 0)
+ return RTL_EINVALIDVLANID;
+
+ if(tag == 0)
+ vlanEntry->untagPortMask |= vlanEntry->memberPortMask & portMask;
+ else
+ vlanEntry->untagPortMask &=~(vlanEntry->memberPortMask & portMask);
+
+ /*update this entry to asic table*/
+ retval = _rtl865x_setAsicVlan(vid,vlanEntry);
+
+ return retval;
+
+}
+
+static int32 _rtl865x_setVlanFID(uint16 vid, uint32 fid)
+{
+ int32 retval = FAILED;
+ rtl865x_vlan_entry_t *vlanEntry;
+
+ if(fid >= RTL865X_FDB_NUMBER)
+ return RTL_EINVALIDFID;
+
+ vlanEntry = &vlanTbl[vid];
+ if(vlanEntry->valid == 0)
+ return RTL_EINVALIDVLANID;
+
+ vlanEntry->fid = fid;
+
+ /*update this entry to asic table*/
+ retval = _rtl865x_setAsicVlan(vid,vlanEntry);
+
+ return retval;
+}
+
+
+static int32 _rtl865x_getVlanFilterDatabaseId(uint16 vid, uint32 *fid)
+{
+ int32 retval = 0;
+
+ if(vid < 1 || vid > VLAN_NUMBER -1)
+ return RTL_EINVALIDVLANID;
+
+ if(vlanTbl[vid].valid == 1)
+ {
+ *fid = vlanTbl[vid].fid;
+ retval = SUCCESS;
+ }
+ else
+ {
+ printk("%s(%d):the vlan is invalid!!!BUG!!!!\n",__FUNCTION__,__LINE__);
+ retval = FAILED;
+ }
+
+ return retval;
+
+}
+rtl865x_vlan_entry_t *_rtl8651_getVlanTableEntry(uint16 vid)
+{
+ if(vlanTbl[vid].valid == 1)
+ return &vlanTbl[vid];
+ return NULL;
+}
+
+/*
+@func int32 | rtl865x_referVlan | reference a VLAN entry.
+@parm uint16 | vid | VLAN ID.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@comm
+if a vlan entry is referenced, please call this API.
+*/
+int32 rtl865x_referVlan(uint16 vid)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ //rtl_down_interruptible(&vlan_sem);
+ local_irq_save(flags);
+ retval = _rtl865x_referVlan(vid);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+ return retval;
+}
+
+/*
+@func int32 | rtl865x_deReferVlan | dereference a VLAN entry.
+@parm uint16 | vid | VLAN ID.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@comm
+if a vlan entry is dereferenced, please call this API.
+NOTE: rtl865x_deReferVlan should be called after rtl865x_referVlan.
+*/
+int32 rtl865x_deReferVlan(uint16 vid)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ //rtl_down_interruptible(&vlan_sem);
+ local_irq_save(flags);
+ retval = _rtl865x_deReferVlan(vid);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+ return retval;
+}
+
+/*
+@func int32 | rtl865x_addVlan | Add a VLAN.
+@parm uint16 | vid | VLAN ID.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@rvalue RTL_EVLANALREADYEXISTS | Vlan already exists.
+*/
+int32 rtl865x_addVlan(uint16 vid)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER-1)
+ return RTL_EINVALIDVLANID;
+
+ //rtl_down_interruptible(&vlan_sem);
+ local_irq_save(flags);
+ retval = _rtl865x_addVlan(vid);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+ return retval;
+
+}
+
+/*
+@func int32 | rtl865x_delVlan | Delete a VLAN.
+@parm uint16 | vid | VLAN ID.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@rvalue RTL_EREFERENCEDBYOTHER | the Vlan is referenced by other,please delete releated table entry first.
+*/
+int32 rtl865x_delVlan(uint16 vid)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER -1)
+ return RTL_EINVALIDVLANID;
+
+ //rtl_down_interruptible(&vlan_sem);
+ local_irq_save(flags);
+ retval = _rtl865x_delVlan(vid);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+ return retval;
+}
+
+/*
+@func int32 | rtl865x_addVlanPortMember | configure vlan member port
+@parm uint16 | vid | VLAN ID.
+@parm uint32 | portMask | Port mask.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@comm
+the parm portMask is the MASK of port. bit0 mapping to physical port 0,bit1 mapping to physical port 1.
+*/
+int32 rtl865x_addVlanPortMember(uint16 vid, uint32 portMask)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER -1)
+ return RTL_EINVALIDVLANID;
+
+ //rtl_down_interruptible(&vlan_sem);
+ local_irq_save(flags);
+ retval = _rtl865x_addVlanPortMember(vid,portMask);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+ return retval;
+}
+
+/*
+@func int32 | rtl865x_delVlanPortMember | delete vlan's member port
+@parm uint16 | vid | VLAN ID.
+@parm uint32 | portMask | Port mask.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@comm
+the parm portMask is the MASK of port. bit0 mapping to physical port 0,bit1 mapping to physical port 1.
+*/
+int32 rtl865x_delVlanPortMember(uint16 vid,uint32 portMask)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER -1)
+ return RTL_EINVALIDVLANID;
+
+ //rtl_down_interruptible(&vlan_sem);
+ local_irq_save(flags);
+ retval = _rtl865x_delVlanPortMember(vid,portMask);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+
+ return retval;
+
+}
+
+
+/*
+@func uint32 | rtl865x_getVlanPortMask | get the member portMask of a vlan
+@parm uint16 | vid | VLAN ID.
+@comm
+if the retrun value is zero, it means vlan entry is invalid or no member port in this vlan.
+*/
+uint32 rtl865x_getVlanPortMask(uint32 vid)
+{
+ rtl865x_vlan_entry_t *vlanEntry;
+
+ if((vid < 1) || (vid > VLAN_NUMBER -1))
+ {
+ return 0;
+ }
+
+ vlanEntry = &vlanTbl[vid];
+
+ if(vlanEntry->valid == 0)
+ {
+ return 0;
+ }
+
+ return vlanEntry->memberPortMask;
+}
+
+
+/*
+@func int32 | rtl865x_setVlanPortTag | configure member port vlan tag attribute
+@parm uint16 | vid | VLAN ID.
+@parm uint32 | portMask | Port mask.
+@parm uint8 | portMask | vlantag or untag.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@comm
+the parm portMask is the MASK of port. bit0 mapping to physical port 0,bit1 mapping to physical port 1.
+parm tag is used to indicated physical port is vlantag or untag. value 1 means vlan tagged, and vlan 0 means vlan untagged.
+*/
+int32 rtl865x_setVlanPortTag(uint16 vid,uint32 portMask,uint8 tag)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER -1)
+ return RTL_EINVALIDVLANID;
+
+ //rtl_down_interruptible(&vlan_sem);
+ local_irq_save(flags);
+ retval = _rtl865x_setVlanPortTag(vid,portMask,tag);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+ return retval;
+}
+
+/*
+@func int32 | rtl865x_setVlanFilterDatabase | configure the filter database for a vlan.
+@parm uint16 | vid | VLAN ID.
+@parm uint32 | fid | filter data base ID.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@rvalue RTL_EINVALIDFID | Invalid filter database ID.
+@comm
+in realtek 865x, 4 filter databases are support.
+if you want to configure SVL for all vlan, please set the fid of vlan is same.
+default configure is SVL.
+*/
+int32 rtl865x_setVlanFilterDatabase(uint16 vid, uint32 fid)
+{
+ int32 retval = FAILED;
+ unsigned long flags;
+ /* vid should be legal vlan ID */
+ if(vid < 1 || vid > VLAN_NUMBER -1)
+ return RTL_EINVALIDVLANID;
+
+ //rtl_down_interruptible(&vlan_sem);//Lock resource
+ local_irq_save(flags);
+ retval = _rtl865x_setVlanFID(vid,fid);
+ //rtl_up(&vlan_sem);
+ local_irq_restore(flags);
+
+ return retval;
+}
+
+/*
+@func int32 | rtl865x_getVlanFilterDatabaseId | get the vlan's filter database ID.
+@parm uint16 | vid | VLAN ID.
+@parm uint32 | fid | filter data base ID.
+@rvalue SUCCESS | Success.
+@rvalue RTL_EINVALIDVLANID | Invalid VLAN ID.
+@comm
+*/
+int32 rtl865x_getVlanFilterDatabaseId(uint16 vid, uint32 *fid)
+{
+ int32 retval = FAILED;
+ retval = _rtl865x_getVlanFilterDatabaseId(vid, fid);
+
+ return retval;
+}
+
+/*
+@func int32 | rtl865x_initVlanTable | initialize vlan table.
+@rvalue SUCCESS | Success.
+@rvalue FAILED | Failed,system should be reboot.
+*/
+int32 rtl865x_initVlanTable(void)
+{
+ TBL_MEM_ALLOC(vlanTbl, rtl865x_vlan_entry_t, VLAN_NUMBER);
+ memset(vlanTbl,0,sizeof(rtl865x_vlan_entry_t)*VLAN_NUMBER);
+
+ return SUCCESS;
+}
+
+/*
+@func int32 | rtl865x_reinitVlantable | initialize vlan table.
+@rvalue SUCCESS | Success.
+*/
+int32 rtl865x_reinitVlantable(void)
+{
+ uint16 i;
+ for(i = 0; i < VLAN_NUMBER; i++)
+ {
+ if(vlanTbl[i].valid)
+ {
+ _rtl865x_delVlan(i);
+ }
+ }
+ return SUCCESS;
+}
+
diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_vlan.h b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_vlan.h new file mode 100644 index 000000000..6222928a3 --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl865x_vlan.h @@ -0,0 +1,55 @@ +/* +* Copyright c Realtek Semiconductor Corporation, 2008 +* All rights reserved. +* +* Program : Vlan driver +* Abstract : +* Author : hyking (hyking_liu@realsil.com.cn) +*/ +#ifndef RTL865X_VLAN_H +#define RTL865X_VLAN_H + +//#include "rtl_types.h" + +#if !defined(REDUCE_MEMORY_SIZE_FOR_16M) +#define REDUCE_MEMORY_SIZE_FOR_16M +#endif + + + +#define VLAN_NUMBER 4096 +#define RTL865X_FDB_NUMBER 4 + +#define RTL865X_PPTP_HWACC_PORTMASK 0x80 +#define RTL865X_PPTP_HWACC_VLANID 10 + + +typedef struct rtl865x_vlan_entry_s { + uint32 memberPortMask; /*extension ports [rtl8651_totalExtPortNum-1:0] are located at bits [RTL8651_PORT_NUMBER+rtl8651_totalExtPortNum-1:RTL8651_PORT_NUMBER]*/ + uint32 untagPortMask; /*extension ports [rtl8651_totalExtPortNum-1:0] are located at bits [RTL8651_PORT_NUMBER+rtl8651_totalExtPortNum-1:RTL8651_PORT_NUMBER]*/ + uint32 valid:1, + fid:2, /*there are 4 fdbs in 865x*/ + vid:12, + refCnt:5; /*reference count: this vlan entry is referenced by networkInterface...*/ +}rtl865x_vlan_entry_t; + +int32 rtl865x_initVlanTable(void); +int32 rtl865x_reinitVlantable(void); +int32 rtl865x_addVlan(uint16 vid); +int32 rtl865x_delVlan(uint16 vid); +int32 rtl865x_addVlanPortMember(uint16 vid, uint32 portMask); +int32 rtl865x_delVlanPortMember(uint16 vid,uint32 portMask); + +#if defined (CONFIG_RTL_HARDWARE_MULTICAST) +uint32 rtl865x_getVlanPortMask(uint32 vid); +#endif + +int32 rtl865x_setVlanPortTag(uint16 vid,uint32 portMask,uint8 tag); +int32 rtl865x_setVlanFilterDatabase(uint16 vid, uint32 fid); +int32 rtl865x_getVlanFilterDatabaseId(uint16 vid, uint32 *fid); +rtl865x_vlan_entry_t *_rtl8651_getVlanTableEntry(uint16 vid); +int32 rtl865x_referVlan(uint16 vid); +int32 rtl865x_deReferVlan(uint16 vid); + +#endif + diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_errno.h b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_errno.h new file mode 100644 index 000000000..aa41bb13f --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_errno.h @@ -0,0 +1,314 @@ + +/* +* Copyright c Realtek Semiconductor Corporation, 2002 +* All rights reserved. +* +* Program : The header file of all error numbers +* Abstract : +* Author : David Chun-Feng Liu (cfliu@realtek.com.tw) +* $Id: rtl_errno.h,v 1.1 2007-12-21 10:29:52 davidhsu Exp $ +* $log$ +* ------------------------------------------------------- +*/ + +#ifndef _RTL_ERRNO_H +#define _RTL_ERRNO_H + +//Driver ERROR NUMBER Definition + +/* Error Number for common use */ +#define RTL_DUMMY -1 // NEVER use me!!! '-1' is used by FAILED. +#define RTL_EENTRYALREADYEXIST -2 //The specifyied entry already exists. +#define RTL_EENTRYNOTFOUND -3 //The specified entry was not found. +#define RTL_EINVALIDPORT -4 //Unknown port number +#define RTL_EINVALIDVLANID -5 //Invalid VLAN ID. +#define RTL_EINVALIDINPUT -6 //Invalid input parameter. +#define RTL_EINVNETIFNAME -7 //Invalid Network Interface name +#define RTL_ENEEDLOOPBACKSET -8 //Need loopback port set +#define RTL_ENOFREEBUFFER -9 //No Free buffer for new request +#define RTL_EINVALIDIPRANGE -10//Invalid IP RANGE +#define RTL_EINVALIDIPFILTER -11//Invalid Ip filter which for filter pkt's sip or dip + +/* Error Number for Port Mirror */ +#define RTL_EPORTISAMIRRORPORT -1000 //The specified port is already configured as a mirror port +#define RTL_EPORTISARXTXMIRRORED -1001 //The specified port is a Rx/Tx mirrored port +#define RTL_EPORTCANTBEAGGREGATED -1002 //The Mirror port cannot be aggregated. +#define RTL_EMIRRORPORTNOTFOUND -1003 //The specified Mirror port not found. + +/* DMZ Host error number */ +#define RTL_EDMZHOSTNOTFOUND -1100 //DMZ host not found +#define RTL_EDMZHOSTNEEDNAPTIP -1101 //DMZ host needs NAPT Ip address present +#define RTL_EDMZHOSTSHOULDBEINTIP -1102 //DMZ host should be internal ip address +#define RTL_EDMZHOSTCANNOTBEGWIP -1103 //DMZ host cannot be gateway ip address +#define RTL_EDMZHOSTFULL -1104 //DMZ host array is full. +#define RTL_EDMZHOSTDENYFILTEREDSIP -1105 //filtered PKT to DMZ because of the PKT's Sip in filterring range + +/* Error Number for ALG APIs */ +#define RTL_EINVALALGATTR -1200 //Invalid ALG attribute. Neither Server nor Client is + //specified to an ALG entry. +#define RTL_EINVALPORTRANGE -1201 //Invalid port range was specified. +#define RTL_EALGPORTRANGEOVERLAP -1202 //ALG port range overlap + +/* Error Number for Protocol Trap APIs */ +#define RTL_EUNKNOWPROTOTYPE -1300 //Unknown Protocol Trap's Protocol type + + +/* Error Number for ACL rule APIs */ +#define RTL_EACLRULEISNULL -1400 //The specified ACL rule is NULL +#define RTL_EINVALACTIONTYPE -1401 //ACL rule with invalid action type +#define RTL_EACLMODEISNOTALLOWED -1402 //ACL mode is not match. +#define RTL_EACLRULE_MATCHTYPEINCORRECT -1403 /* Incorrect match type */ +#define RTL_EACLEGRESSRULE_NOTSUPPORTPKTOP -1404 /* Egress ACL not support packet operation */ +#define RTL_EACLINVALIDRULETYPE -1405 /* Invalid acl rule type */ + +/* Error Number for NAPT APIs */ +#define RTL_ENAPTIPNOTEXTIP -1500 //The Specified NAPT IP is not an external IP address +#define RTL_ENAPTIPCANNOTBENAT -1501 //The Specified NAPT IP can not a NAT IP address + +/* Error Number for Ethernet port */ +#define RTL_EPORTOPMODECANNOTAGGREGATE -1600 //Can not set a port's operation mode if the port is aggreaged. +#define RTL_EUNKNOWPORTSPEED -1601 //Unknow port speed. The port speed should be either 10 or 100. +#define RTL_EPORTSPEEDCANNOTAGGREGATE -1602 //The specified port's speed can not be changed if the port is aggreaged. +#define RTL_EPORTAUTONEGOCANNOTAGGREGATE -1603 //Can not change a port's auto-negotiation capability if the port is aggregated. +#define RTL_EINVALIDDATARATE -1604 //Invalid data rate. +#define RTL_ENOTVLANPORTMEMBER -1605 //Specified port is not a member port of specified vlan. + +/* Error Number for Spanning Tree */ +#define RTL_EINVALIDSID -1700 //Invalid spanning tree ID. +#define RTL_ESIDALREADYEXIST -1701 //Spannding Tree ID already exists. +#define RTL_EINVALIDPORTSTATE -1702 //Invalid Port State. +#define RTL_ESIDISREFERENCEEDBYFID -1703 //Spanning Tree is being referenced by Filter Database. + +/* Error Number for Filter Database */ +#define RTL_EINVALIDFID -1800 //Invalid Filter database ID +#define RTL_EFIDALREADYEXISTS -1801 //Filter Database already exists. +#define RTL_EFIDISREFERENCEDBYVLAN -1802 //Filter Database is being referenced by VLAN +#define RTL_EFIDISNOTEMPTY -1803 //Filter Database is not empty +#define RTL_EINVALIDACTIONTYPE -1804 //Invalid Port Action Type. +#define RTL_ENULLMACADDR -1805 //The specified MAC address is NULL. +#define RTL_EL2ENTRYEXISTS -1806 //The filter database entry already exists. +#define RTL_EL2ENTRYNOTFOUND -1807 //The specified filter database entry was not found. +//#ifdef TEST_GETL2TBL +#define RTL_EGETL2_EMPTYL2TBL -1808 /* The L2 table is empty */ +#define RTL_EGETL2_INVALIDL2ENTRY -1809 /* User specifies an invalid MAC address */ +#define RTL_EGETL2_NOMOREVALIDL2ENTRY -1810 /* No more valid L2 entry */ +//#endif + +/* Error Number for Aggregator */ +#define RTL_EINVALIDAGGREGATORID -1900 //Invalid aggregator ID. +#define RTL_EALREADYTRUNKING -1901 //Aggregator already aggregates more than one port. +#define RTL_EAGGREGATORHASNOPORT -1902 //Not allow aggregator without port member +#define RTL_EAGGREGATOREXCEED -1903 //The number of aggregator excees the system capability. +#define RTL_EAGGREGATORIDGTPORTNO -1904 //Aggreagator ID > Port Number. When aggregating ports, + //any port No. > aggregator ID is disallowed. +#define RTL_EAGGREGATORSETINDIVIDUAL -1905 //Aggregator was set to individual, hence it can not + //aggreate more then one port. +#define RTL_EDIFFBROADCASTDOMAIN -1906 //Aggregator and port are in different broadcast domain. + +/* Error Number for VLAN */ +#define RTL_EVLANALREADYEXISTS -2000 //Vlan already exists. +#define RTL_ECANNOTREMOVEDEFVLAN -2001 //Cannot remove default VLAN. +#define RTL_EVLANISREFERENCEDBYNETIF -2002 //Vlan is referenced by network interface. +#define RTL_EVLANISREFERENCEDBYPPPOE -2003 //Vlan is referenced by PPPoE. +#define RTL_EVLANHASMACALLOCATED -2004 //Vlan still has MAC address allocated. +#define RTL_EVLANHASHPORTMEMBER -2005 //Vlan can not have member port while specifying its Filter database. +#define RTL_EVLANTXMIRRORSET -2006 //Vlan has Tx mirror set hence can not set to promiscuous mode. +#define RTL_EPORTNOTVLANMEMBER -2007 //The specified port is not a member of specified VLAN. +#define RTL_EVLANPROMISSET -2008 //If VLAN promiscuous is set, a network interface cannot attach to the VLAN. +#define RTL_EFWDTXMIRRORSET -2009 //Vlan Forwarding Tx Mirror set. +#define RTL_EVLANMACREFERENCEDBYPPPOE -2010 //Vlan MAC is referenced by pppoe +#define RTL_EVLANMACREFERENCEDBYNETIF -2011 //VLan MAC is referenced by network interface. +#define RTL_EINVVLANMAC -2012 //Specified VLAN MAC number should be (0, 1, 2, 4, 8) +#define RTL_ENOUSABLEMAC -2013 //No usable MAC address can be allocated +#define RTL_EVLANNOMAC -2014 //Vlan has no MAC Address +#define RTL_ENOVLAN -2015 //No more availiable VLAN entry + + + +/* Error Number for NAT */ +#define RTL_ENATIPNOTEXTERNALIP -2100 //The specified NAT IP address is not an External IP address. +#define RTL_ENATIPNOTINTERNALIP -2101 //The specified NAT Internal IP is not an Internal IP address. +#define RTL_EDUPLOCATENATIP -2102 //The specified NAT IP address already maps to an Internal IP address. +#define RTL_ENATIPCANNOTBENAPTIP -2103 //The specified NAT IP address cannot be a NAPT IP address. + + +/* Error Number for Routing */ +#define RTL_ERTALREADYEXIST -2300 //The routing entry already exists. +#define RTL_ERTINVALNEXTHOP -2301 //Invalid nextHop +#define RTL_ENOSESSIONALLOCATE -2302 //Need PPPoE session allocate +/*#ifdef TEST_GETRTTBL*/ +#define RTL_ERTCREATEBYIF -2303 //The route is added by IP interface creation. It can be removed. +#define RTL_EGETRT_EMPTYRTTBL -2304 /* The routing table is empty */ +#define RTL_EGETRT_NOMOREVALIDENTRY -2305 /* No more valid routing entry */ +#define RTL_EGETRT_INVALIDRTENTRY -2306 /* User specifies an invalid route */ +/*#endif */ + + + +/* Error Number for Arp */ +#define RTL_ENONBROADCASTNET -2400 //Non Boradcast network is forbidden to add ARP entry. +#define RTL_EARPALREADYEXIST -2401 //Arp entry already exists. +#define RTL_EARPCANNOTADDL2ENTRY -2402 //The L2 Entry cannot be added. +#define RTL_EARPCANNOTDELL2ENTRY -2403 //The L2 Entry cannot be deleted. +#define RTL_ENOARPFOUND -2404 //No ARP entry was found + + +/* Error Number for Network interface */ +#define RTL_ENETIFREFERENCEDBYIPIF -2500 //The network interface is referenced by IP interface. +#define RTL_ENETIFREFBYROUTE -2501 //The network interface is referenced by a routing entry. +#define RTL_ELINKTYPESHOULDBERESET -2502 //The link layer type should be reset before removing. +#define RTL_ENETIFREFERENCEDBYACL -2503 //The network interface is referenced by ACL. +#define RTL_EUNKNOWLINKLAYERTYPE -2504 //Unknow link layer type. +#define RTL_ECANNOTREMOVEIPUNNUMBER -2505 //Can not remove IP unnumbered network itnerface. Use rtl8651_delIpUnnumbered() first. +#define RTL_ENETHASNOLLTYPESPECIFY -2506 //The specified network interface has no link-layer type specified. +#define RTL_ENETISEXTERNAL -2507 //The removed network interface is an external interface. +#define RTL_ENAPTSTART -2508 //When NAPT starts, no manipulation about IP interface + //should be done +#define RTL_ENETIFALREADYEXTERNAL -2509 //The specified network interface already is an external network interface. +#define RTL_ESHOULDBEEXTIF -2510 //The network interface should be an external network interface +#define RTL_ESHOULDNOTDMZEXT -2511 //The network interface should not be a DMZ external. +#define RTL_ELIPUNNUMBEREDNOTALLOW -2512 //The specified network itnerface cannot be IP Unnumbered network. +#define RTL_ENETIFREFBYNATNAPT -2513 //Network Interface is referenced BY NAT +#define RTL_ENETIFLLTYPEALREADYSET -2514 //Link layer of the specified network itnerface type already set. +#define RTL_ENOLLTYPESPECIFY -2515 //The network interface has no link layer type specified. + + +/* Error Number for IP Unnumbered */ +#define RTL_EONLYONEIPUNNUMBERISALLOWED -2600 //The whole system only allows one IP unnumbered network. +#define RTL_ENETIFINVALID -2601 //One external and one internal network interfaces are needed. +#define RTL_EWANIFCANNOTHAVEIPINTF -2602 //The external network interface cannot have IP interface. +#define RTL_NETIFTYPENOTMATCH -2603 //The external network interface should be PPPoE type and internal interface should be VLAN type. +#define RTL_ENETIFNEEDIPUNNUMBERED -2604 //The specified network itnerface should be IP unnumbered. +#define RTL_EIPUNNUMBEREDHASHIPINTF -2605 //The IP Unnumebred still has external IP interface unnumebred attached. +#define RTL_ENETIFNOTIPUNNUMBERED -2606 //The specified network interface is not an IP Unnumbered Network interface. +#define RTL_ENOTIPUNNUMBEREDNETIF -2607 //The specified network interface is not IP Unnumbered Network interface. +#define RTL_EIPUNINTIPINTFNEED -2608 //The specified network interface should be IP Unnumbered internal network interface. +#define RTL_EIPUNISREFERENCEDBYPPPOE -2609 //The IP Unnumbered IP interface is referenced by PPPoE Session. +#define RTL_EEXTINTFSHOULDBEPPPOE -2610 //The specified external network interface should be PPPoE type. +#define RTL_ESHOULDBEEXTNETIF -2611 //The specified network interface should be external network interface. + + +/* Error Number for IP interface */ +#define RTL_ENETMASKCANNOTBEZERO -2701 //The netmask of IP interface cannot be zero. +#define RTL_EIPUNEXTIFCANNOTHASHIPINTF -2702 //Cannot attach IP interface to External Network itnerface in an IP Unnumbered network. +#define RTL_EIPIFALREADYEXIST -2703 //IP Interface already exists +#define RTL_EINVNETMASK -2704 //Invalid network mask. The specified netmask may be 0xffffffff in a VLAN type network. +#define RTL_ECANNOTREMOVEIPUNEXTIPINTF -2705 //Global IP interface of IP Unnumbered cannot be removed. Use rtl8651_setLanSideExternalIpInterface() first. +#define RTL_EIPINTFISREFERENCEDBYARP -2706 //IP interface is referenced by ARP entry. It cannot be removed. +#define RTL_EIPINTFISREFERENCEDBYLS -2707 //IP interface is referenced by Local Server. It cannot be removed. +#define RTL_EIPINTFISREFERENCEDBYRT -2708 //IP interface is referenced by routing entry. It cannot be removed. +#define RTL_EIPINTFISREFERENCEDNYNATNAPT -2709 //IP interface is referenced by NAT/NAPT. It cannot be removed. +#define RTL_ENOIPINTFFOUND -2710 //The specified IP interface was not found. +#define RTL_ENOTEXTIP -2711 //Specified external IP address doesn't belong to external interface +#define RTL_ENOTINTIP -2712 //Specified internal IP address doesn't belong to internal interface + +/* Error Number for PPPoE */ +#define RTL_EFORBIDPROMISCINPPPOE -2800 //If promiscuous mode was set, PPPoE cannot be created. +#define RTL_EVLANSHOULDBEPPPOE -2801 //The specified VLAN should be PPPoE Type. +#define RTL_EPPPOEALREADYEXISTS -2802 //The specified PPPoE already exists. +#define RTL_EOUTOFVLANMACADDR -2803 //Out of VLAN MAC address. +#define RTL_EINVALIDPPPOEID -2804 //Invalid PPPoE ID. +#define RTL_EPPPOEISINUSE -2805 //The specified PPPoE is in use. +#define RTL_EPPPOEISREFERENCEDBYRT -2806 //PPPoE is referenced by routing entry. +#define RTL_EINVALIDSESSIONID -2807 //Invalid PPPoE Session ID. +#define RTL_EPROPERTUALREADYSET -2808 //The specified PPPoE property was already set to another PPPoE ID. +#define RTL_EPPPOEHASPROPERTYSET -2809 //The specified PPPoE ID already has property set. +#define RTL_EPPPOECANNOTADDL2ENTRY -2810 //Cannot add L2 entry for the specified PPPoE. + +/* Error Number for Local Server */ +#define RTL_EINVALIDLSIPADDR -2900 //Invalid Local Server IP address. +#define RTL_ELSCANNOTBEGWIP -2901 //Local Server IP address cannot be gateway's IP address. +#define RTL_ELSALREADYEXISTS -2902 //Local Server already exists. + +/* Error Number for NAPT */ +#define RTL_EDSTIPISLS -3000 //NAPT DST IP is Local Server +#define RTL_EGETOFFSETFAIL -3001 //NAPT get offset fail +#define RTL_EINVALIDEXTPORT -3002 //Maybe the external port is in use or reserved +#define RTL_ENOTPERMIT -3003 //The action is not allowed +#define RTL_EEXTIDINUSE -3004 //NAPT ICMP external ID is in use +#define RTL_EDRVNAPTEXIST -3005 //NAPT connection already exist in driver table +#define RTL_EINVL4PORTNUM -3006 //Invalid UDP/TCP port number +#define RTL_EINVEXTIP -3007 //Invliad external port number for NAPT +#define RTL_EDEFAULTROUTENOTFOUND -3008 // Default Route is not defined. +#define RTL_EADDHASH2NEXTHOP -3009 // Add Hash2 nexthop error +#define RTL_EDEFAULTNAPTIPEXIST -3010 //Default Napt IP already exists +#define RTL_ENAPTCONNECTIONFULL -3011 // napt system is full and can not add any other new flows +#define RTL_ENAPTNOTFOUNDWITHINFO -3012 // Entry is not found, but return with infomation (for GetInbound()/Outbound()) + +/*Error Number for NAPTUSRMAPPING*/ +#define RTL_EIPFILTEROVERLAPPING -3050 //ipfilter overlap: the ip range and port is overloapping +#define RTL_ENAPTUSRMAPTYPEERROR -3051 //napt user map entry's type is error +#define RTL_ENAPTUSRMAPFLAGERROR -3052 //napt user map entry's flag is error +#define RTL_ENAPTUSRMAPFILTERNOTFOUND -3053 // napt user map ipFilter not found +#define RTL_ENAPTUSRMAPDIRECTIONERROR -3054 // napt usr map info's direction is error +#define RTL_ENAPTUSRMAPFILTERDROP -3055 //pkt was drop by usr filter + +/* Error Numebr for ALG */ +#define RTL_ERANGEOVERLAP -3100 //ALG port range overlap + +/* Error Number Session: PPPoE, L2TP, PPTP */ +#define RTL_ESESSIONNOTFOUND -3200 //The specified Session ID is not found +#define RTL_ESESSIONREFERENCEDBYRT -3201 //The specified Session is referenced by routing entry +#define RTL_ECANNOTMOVESESSION -3202 //Can not move session to another network interface +#define RTL_EALREADYHAVESESSION -3203 //The specified network interface already has session attached +#define RTL_ESESSIONISREFERENCED -3204 //Session is referenced +#define RTL_ECANNOTUSETHISVID -3205 //No more than one PPTP/L2TP VLAN is allowed + +/* Error Number for Protocol-based NAT */ +#define RTL_EPBNAT_ENTRY_EXIST -3301 //The given {protocol,extip,intip} exists +#define RTL_EPBNAT_NO_FREE_ENTRY -3302 //No free entry for Protocol-Based NAT +#define RTL_EPBNAT_ENTRY_NOT_FOUND -3303 //The specific entry is not found +#define RTL_EPBNAT_PROTOCOL_NOT_SUPPORTED -3304 //The specific protocol is not supported by protocol-based NAT + + +/* Error Number for Rate Limit */ +#define RTL_EDUPGROUPID -3401 //Duplicate Rate Limit Group ID +#define RTL_ERLENTRYISREFERENCE -3402 //The specified rate limit entry is being referenced. +#define RTL_ENOGROUPIDFOUND -3403 //The specified group ID was not found. +#define RTL_EEXCEEDTOTALBW -3404 //The specified ratio exceeds total allowed bandwidth + +/* Error Number for IPSec */ +#define RTL_EIPSEC_PARAM_ERROR -4001 //IPSec parameter error +#define RTL_EIPSEC_SPI_EXISTED -4002 //IPSec SPI has existed +#define RTL_EIPSEC_SPI_NOT_FOUNT -4003 //IPSec SPI not found +#define RTL_EIPSEC_NO_MORE_SPI -4004 //no more availiable IPSec SPI +#define RTL_EIPSEC_SPIGRP_EXISTED -4007 //IPSec SPIGRP has existed +#define RTL_EIPSEC_SPIGRP_NOT_FOUNT -4008 //IPSec SPIGRP not found +#define RTL_EIPSEC_NO_MORE_SPIGRP -4009 //no more availiable IPSec SPIGRP +#define RTL_EIPSEC_EROUTE_EXISTED -4012 //IPSec SPIGRP has existed +#define RTL_EIPSEC_EROUTE_NOT_FOUNT -4013 //IPSec SPIGRP not found +#define RTL_EIPSEC_NO_MORE_EROUTE -4014 //no more availiable IPSec SPIGRP +#define RTL_EIPSEC_INVALID_WINSIZE -4015 //Invalid window size (See RFC2046 3.4.3) +#define RTL_EIPSEC_NO_MORE_NBT_ENTRY -4016 //no more netBios entry + +/* Error Number for URL Filter */ +#define RTL_EURLFILTER_URLSTRINGLEN_EXCEEND -4501 // url filter string lenght exceeds system buffer size. +#define RTL_EURLFILTER_PATHSTRINGLEN_EXCEEND -4502 // path string of url exceeds system buffer size +#define RTL_EMEMALLOCATEFAILEDFORURLFILTER -4503 /* memory allocation failed for url filter operation */ +/* RTL865XB_URLFILTER_UNKNOWNURLTYPE_SUPPORT */ +#define RTL_EURLFILTER_INVALIDRULETYPE -4504 /* Invalid url rule type */ +/* RTL865XB_URLFILTER_ACTIONTYPE_SUPPORT */ +#define RTL_EURLFILTER_INVALIDACTIONTYPE -4505 /* Invalid action type of url filter rule */ +/* RTL865XB_WEB_CONTENT_HDR_FILTER */ +#define RTL_EURLFILTER_CONTENTSTRINGLEN_EXCEEND -4506 /* content string pattern exceeds system buffer size */ +#define RTL_EURLFILTER_HTTPHDRSTRINGLEN_EXCEEND -4507 /* http header string pattern exceeds system buffer size */ +#define RTL_EURLFILTER_CONTENTHDRFILTERINUSED -4508 /* the content/httpHdr filter is used by an napt flow, cannot be deleted */ + +/* Error Number for PCM drivers */ +#define RTL_EPCM_QUEUE_UNAV -5001 /* pcm queue not allocated */ +#define RTL_EPCM_PGAE_UNAV -5002 /* pcm page not allocated */ +#define RTL_EPCM_QUEUE_FULL -5003 /* pcm queue is full of data */ +#define RTL_EPCM_QUEUE_EMPTY -5004 /* pcm queue is no of data */ +#define RTL_EPCM_QUEUE_SUBSIZE -5005 /* pcm queue has not enough data */ +#define RTL_EPCM_BUF_UNAV -5006 /* requested buffer not allocated */ +#define RTL_EPCM_CHANNEL_NULL -5007 /* current channel is not allocated */ + +/*Error number for naptUsrMapping*/ +#define RTL_EVLANRANGETOOSMALL -5100 /* set multiple pppoe id range too small RTL8651_IDLETIMEOUT_FIXED */ +//#define RTL_NAPTUSRMAP_ + +/*Error number for reference count*/ +#define RTL_EREFERENCEDBYOTHER -5200 + + +#endif diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_utils.c b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_utils.c new file mode 100644 index 000000000..9e4610fba --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_utils.c @@ -0,0 +1,699 @@ +/* +* Copyright c Realtek Semiconductor Corporation, 2002 +* All rights reserved. +* +* Program : RTL utilities +* Abstract : +* Author : +* $Id: rtl_utils.c,v 1.1 2007-12-21 10:29:52 davidhsu Exp $ +*/ + +#include <net/rtl/rtl_types.h> +#include <net/rtl/rtl_glue.h> +#include "rtl_utils.h" +#if defined(CONFIG_RTL_819X) +#include "AsicDriver/asicRegs.h" +#endif + +#ifdef __linux__ +#include <linux/ctype.h> +#include <linux/string.h> +#else +#include <ctype.h> +#include <string.h> +#endif + +#if defined(RTL865X_MODEL_USER) || defined (RTL8316S_MODEL_USER) +#include <net/rtl/rtl_glue.h> +#endif + +//#include "assert.h" + +//const int8 *ntop4(const uint8 *src,int8 *dst, uint32 size); + +#define __rtl_isupper(c) (((c) >= 'A') && ((c) <= 'Z')) + +#if 0 +void *rtl_malloc(size_t NBYTES) { + if(NBYTES==0) return NULL; + return (void *)kmalloc(NBYTES,GFP_ATOMIC); +} + +void rtl_free(void *APTR) { + kfree(APTR); +} +#endif + +/* + copy string from 'src' to 'dst' and set all alphabets to lower-case in 'dst'. +*/ +void __strlowerncpy(char *dst, const char *src, int32 len) +{ + int32 cpLen = 0; + char p; + + while ((cpLen < len) && (src[cpLen] != 0)) + { + p = src[cpLen]; + dst[cpLen] = __rtl_isupper(p)?(p-'A'+'a'):p; + cpLen ++; + } +} + +int8 * _strncpy(int8 *dst0, const int8 *src0, int32 count) { + int8 *dscan; + const int8 *sscan; + + dscan = dst0; + sscan = src0; + while (count > 0) + { + --count; + if ((*dscan++ = *sscan++) == '\0') + break; + } + while (count-- > 0) + *dscan++ = '\0'; + + return dst0; +} + +int _strncasecmp(const char *s1, const char *s2, unsigned int n) +{ + if (n == 0) + return 0; + + while ((n-- != 0) + && (tolower(*(unsigned char *) s1) == + tolower(*(unsigned char *) s2))) { + if (n == 0 || *s1 == '\0' || *s2 == '\0') + return 0; + s1++; + s2++; + } + + return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); +} +int32 _strncmp(const int8 *s1, const int8 *s2, int32 n) { + + if (n == 0) + return 0; + + while (n-- != 0 && *s1 == *s2) + { + if (n == 0 || *s1 == '\0') + break; + s1++; + s2++; + } + return (*(uint8 *)s1) - (*(uint8 *)s2); +} + +void rtl8651_memcpy(void *dst,void*src,int32 len) +{ + memcpy(dst, src, (size_t)len); +#if 0 + if(len>16){ + memCopy( dst,src, len); + }else +#endif +#if 0 + { + int i=0; + char *dstp=(char*)dst; + char *srcp=(char*)src; + for (i=0;i<len;i++) + { + *dstp++=*srcp++; + + } + } +#endif +} + +#ifndef RTK_X86_CLE//RTK-CNSD2-NickWu-20061222: for x86 compile +/*cfliu: This function is only for debugging. Should not be used in production code...*/ +void memDump (void *start, uint32 size, int8 * strHeader) +{ + int32 row, column, index, index2, max; + uint32 buffer[5]; + uint8 *buf, *line, ascii[17]; + int8 empty = ' '; + + if(!start ||(size==0)) + return; + line = (uint8*)start; + + /* + 16 bytes per line + */ + if (strHeader) + rtlglue_printf ("%s", strHeader); + column = size % 16; + row = (size / 16) + 1; + for (index = 0; index < row; index++, line += 16) + { +#ifdef RTL865X_TEST + buf = (uint8*)line; +#else + /* for un-alignment access */ + buffer[0] = ntohl( READ_MEM32( (((uint32)line)&~3)+ 0 ) ); + buffer[1] = ntohl( READ_MEM32( (((uint32)line)&~3)+ 4 ) ); + buffer[2] = ntohl( READ_MEM32( (((uint32)line)&~3)+ 8 ) ); + buffer[3] = ntohl( READ_MEM32( (((uint32)line)&~3)+12 ) ); + buffer[4] = ntohl( READ_MEM32( (((uint32)line)&~3)+16 ) ); + buf = ((uint8*)buffer) + (((uint32)line)&3); +#endif + + memset (ascii, 0, 17); + + max = (index == row - 1) ? column : 16; + if ( max==0 ) break; /* If we need not dump this line, break it. */ + + rtlglue_printf ("\n%08x ", (memaddr) line); + + //Hex + for (index2 = 0; index2 < max; index2++) + { + if (index2 == 8) + rtlglue_printf (" "); + rtlglue_printf ("%02x ", (uint8) buf[index2]); + ascii[index2] = ((uint8) buf[index2] < 32) ? empty : buf[index2]; + } + + if (max != 16) + { + if (max < 8) + rtlglue_printf (" "); + for (index2 = 16 - max; index2 > 0; index2--) + rtlglue_printf (" "); + } + + //ASCII + rtlglue_printf (" %s", ascii); + } + rtlglue_printf ("\n"); + return; +} +#endif + + +/* + * Compare two memory and hilight the differences. + */ +int32 memComp( void* _p1, void *_p2, int32 len, uint8* strHeader ) +{ + uint8* p1; + uint8* p2; + int i, j; + uint8 ascii[17]; + + if ( memcmp( _p1, _p2, (size_t)len )==0 ) + return 0; /* identical */ + + if ( strHeader ) rtlglue_printf( "%s", strHeader ); + p1 = (uint8*)_p1; + p2 = (uint8*)_p2; + /* Show p1 */ + for( i = 0; i<len; i+=16 ) + { + rtlglue_printf( "\n%08x ", (uint32)(&p1[i]) ); + memset( ascii, 0, sizeof(ascii) ); + for( j = 0; j < 16; j++ ) + { + if ( (i+j)>=len ) + { + ascii[j] = ' '; + rtlglue_printf( " " ); + } + else + { + if ( (p1[i+j]>=0x20) && (p1[i+j]<=0x7e) ) /* Show visible char only */ + ascii[j] = p1[i+j]; + else + ascii[j] = '.'; + + if ( p1[i+j]==p2[i+j] ) + { + rtlglue_printf( "%02x ", (uint8) p1[i+j] ); + } + else + { + rtlglue_printf( "\033[41;33m%02x\033[m ", (uint8) p1[i+j] ); + } + } + } + + rtlglue_printf( " %s", ascii ); + } + rtlglue_printf( "\n--------" ); + /* Show p2 */ + for( i = 0; i<len; i+=16 ) + { + rtlglue_printf( "\n%08x ", (uint32)(&p2[i]) ); + memset( ascii, 0, sizeof(ascii) ); + for( j = 0; j < 16; j++ ) + { + if ( (i+j)>=len ) + { + ascii[j] = ' '; + rtlglue_printf( " " ); + } + else + { + if ( (p2[i+j]>=0x20) && (p2[i+j]<=0x7e) ) /* Show visible char only */ + ascii[j] = p2[i+j]; + else + ascii[j] = '.'; + + if ( p1[i+j]==p2[i+j] ) + { + rtlglue_printf( "%02x ", (uint8) p2[i+j] ); + } + else + { + rtlglue_printf( "\033[41;33m%02x\033[m ", (uint8) p2[i+j] ); + } + } + } + + rtlglue_printf( " %s", ascii ); + } + + rtlglue_printf( "\n" ); + return 1; +} + + +void IntToAscii(int32 n, int8 s[]){ + int8 c[32]; + int32 i, sign, j; + if((sign=n)<0) + n=-n; + i=0; + do{ + s[i++]=n%10+'0'; + }while((n/=10)>0); + if(sign<0) + s[i++]='-'; + s[i]='\0'; + //assert(i<31); + for(j=0,i--;i>=0;j++,i--) + c[j]=s[i]; + c[j]='\0'; + memcpy(s, c, (size_t)(j+1)); +} + +uint8 charToInt(char c) +{ + if ((c >= '0') && ( c <= '9')) + { + return (c - '0'); + } else if ((c >= 'a') && ( c <= 'f')) + { + return (c - 'a'); + } else if ((c >= 'A') && ( c <= 'F')) + { + return (c - 'A'); + } + return 0; +} + +static int8 *_ui8tod( uint8 n, int8 *p ) +{ + if( n > 99 ) *p++ = (n/100) + '0'; + if( n > 9 ) *p++ = ((n/10)%10) + '0'; + *p++ = (n%10) + '0'; + return p; +} + +//inet_ntoa which doens't need reentrant module +int8 *inet_ntoa_r(ipaddr_t ipaddr, int8 *p) +{ + uint8 *ucp = (unsigned char *)&ipaddr; + assert(p!=NULL); + p = _ui8tod( ucp[0] & 0xFF, p); + *p++ = '.'; + p = _ui8tod( ucp[1] & 0xFF, p); + *p++ = '.'; + p = _ui8tod( ucp[2] & 0xFF, p); + *p++ = '.'; + p = _ui8tod( ucp[3] & 0xFF, p); + *p++ = '\0'; + return (p); +} + +#ifndef RTL865X_TEST +int32 IpStrToAscii(const int8 *cp, uint32 *addr){ + uint32 val; + int32 base, n; + int8 c; + uint32 parts[4]; + uint32 *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + + //determine the base + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if ((val > 0xffffff) || (parts[0] > 0xff)) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + *addr = htonl(val); + return (1); +} +#endif /* RTL865X_TEST */ + + + + +/* + * Convert an ASCII string to a + * binary representation of mac address +*/ +static int32 strToMac(uint8 *pMac, int8 *pStr) +{ + int8 *ptr; + uint32 k; + + assert (pMac != NULL); + assert (pStr != NULL); + + bzero(pMac, sizeof(ether_addr_t)); + ptr = pStr; + + for ( k = 0 ; *ptr ; ptr ++ ) + { + if (*ptr == ' ') + { + } else if ( (*ptr == ':') || (*ptr == '-') ) + { + k ++; + } else if ( ('0' <= *ptr) && (*ptr <= '9') ) + { + pMac[k] = (pMac[k]<<4) + (*ptr-'0'); + } else if ( ('a' <= *ptr) && (*ptr <= 'f') ) + { + pMac[k] = (pMac[k]<<4) + (*ptr-'a'+10); + } else if( ('A' <= *ptr) && (*ptr <= 'F') ) + { + pMac[k] = (pMac[k]<<4) + (*ptr-'A'+10); + } else + { + break; + } + } + + if (k != 5) + { + return -1; + } + + return 0; +} + + +int32 ether_aton_r(int8 *a, ether_addr_t *eth){ + if ( strToMac(eth->octet, a) ) + return FAILED; + return SUCCESS; +} + +int32 ether_ntoa_r(ether_addr_t *n, uint8 *a){ + int32 i; + i = sprintf((int8*)a, "%02x:%02x:%02x:%02x:%02x:%02x", n->octet[0], n->octet[1], n->octet[2], n->octet[3], n->octet[4], n->octet[5]); + if (i < 11) + return FAILED; + return SUCCESS; +} + +#if 0 +#define SPRINTF(x) ((uint32)sprintf x) + +const int8 *ntop4(const uint8 *src,int8* dst, uint32 size) +{ + static const int8 fmt[] = "%u.%u.%u.%u"; + int8 tmp[sizeof "255.255.255.255"]; + + if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) + { + return (NULL); + } + strcpy(dst,tmp); + return (dst); +} + +#undef SPRINTF +#endif + +#ifndef RTL865X_TEST + int AsciiToInt( char **s) +{ + int i = 0; + while (isdigit(**s)) + i = i*20 + *((*s)++) - '0'; + return i; +} +#endif /* RTL865X_TEST */ + + +//Check whether 'number' is power of 2. +//if 'exponent' is non-NULL, the exponent of number is also returned. Ex: if number = 16, exponent would be 4 +int32 isPowerOf2(uint32 number, uint32 *exponent){ + uint32 size, bits; + if(exponent){ + //user is not interested in the exponent + for(bits=0, size=1; bits < (sizeof(uint32)<<3);bits++){ + if(number==size) + break; + else + size = size << 1; + } + if(bits == sizeof(uint32)*8 ) + return FALSE; + *exponent = bits; + return TRUE; + }else if(((number-1)&number)==0) + return TRUE; + return FALSE; +} + +//cfliu: Reserve these functions...need to see if they help. +//Ask me first if you want to delete them. +#if 0 +/* Set memory address from "pFrom" to "pFrom+iWords*4" with "iFill", Address value of "pFrom" should be 4 bytes aligned */ +void *memSet(void *pTo, uint8 cFill, uint32 iBytes) +{ + uint32 iIndex = 0, iRemain, iWords; + uint8 *pcTo; + uint32 iFill = (uint32) cFill; + + assert(pTo); + assert(iBytes > 0); + + pcTo = (uint8 *) pTo; + iRemain = sizeof(memaddr) - (((memaddr) pTo) & (sizeof(memaddr) - 1)); //modular 4 + + + for (; (iRemain > 0) && (iBytes > 0); iBytes--, pcTo++, iRemain--) + *pcTo = (uint8) cFill; + + if (iBytes == 0) + return (void *) (pcTo - 1); //return the address of last byte we have copied. + else if (iBytes < sizeof(memaddr)) + goto memset_last; + + iWords = (iBytes & ~(sizeof(memaddr) - 1)) / sizeof(memaddr); //calculate number of int32 words to copy + + for (iIndex = 0; iIndex < sizeof(memaddr) - 1; iIndex++) //prepare THE int32 word for copying + iFill = (iFill << (sizeof(uint8) * 8)) + (uint32) cFill; + + //Do actual memory filling. + //Assumption: An integer is 32 bits int32 + for (iIndex = 0; iIndex < iWords; + iIndex++, iBytes -= sizeof(memaddr), pcTo += sizeof(memaddr)) + *((memaddr *) pcTo) = (memaddr) cFill; + + //if there are rested bytes to copy.. + memset_last: + assert(iBytes < sizeof(memaddr)); + while (iBytes > 0) + { + *pcTo = cFill; + iBytes--; + pcTo++; + } + return (void *) (((memaddr *) pTo) + (iIndex - 1)); +} + + +/* Optimized memcpy function. + * Copy memory address from "pFrom" to "pTo", for "iBytes", + */ +void *memCopy( void *pTo,void * pFrom,uint32 iBytes) +{ + uint32 iIndex = 0, iRemain = 0, iLengthCheck = 0, iWords = 0; + int8 *pcFrom, *pcTo; + + assert(pFrom); + assert(pTo); + assert(iBytes > 0); + + /* + Check if memory is overlapped + */ + if ((memaddr) pFrom > (memaddr) pTo) + iLengthCheck = (memaddr) (pFrom - pTo); + else + iLengthCheck = (memaddr) (pTo - pFrom); + + if (iLengthCheck < iBytes) + return NULL; //memory overlapped. Copy is NOT performed. + + + pcFrom = (int8 *) pFrom; + pcTo = (int8 *) pTo; + + //modular 4, if remainders are not the same, copy bye by byte. + if ((((memaddr) pcFrom) & (sizeof(memaddr) - 1)) != + (((memaddr) pcTo) & (sizeof(memaddr) - 1))) + { + + for (iIndex = iBytes; iIndex > 0; iIndex--, pcTo++, pcFrom++) + *pcTo = *pcFrom; + goto memcpy_done; + } + + //faster memory copy + iRemain = sizeof(memaddr) - ((memaddr) pFrom & (sizeof(memaddr) - 1)); //modular 4 + for (; (iRemain > 0) && (iBytes > 0); + iBytes--, pcTo++, pcFrom++, iRemain--) + *pcTo = *pcFrom; + + if (iBytes == 0) + goto memcpy_done; //return the address of last byte we have copied. + else if (iBytes < sizeof(memaddr)) + goto memcpy_last; + + //Addresses now are 4 bytes aligned, do fast mem copy. Assumption: Pointers are 32 bits + assert(((memaddr) pcFrom & 0xFFFFFFFC) == (memaddr) pcFrom); + assert(((memaddr) pcTo & 0xFFFFFFFC) == (memaddr) pcTo); + + //Maybe we should use >>2 here, but just let compiler do it. + iWords = (iBytes & ~(sizeof(memaddr) - 1)) / sizeof(memaddr); //calculate number of int32 words to copy + + + //Do actual memory copy. + //Assumption: An integer is 32 bits int32 + for (iIndex = 0; iIndex < iWords; + iIndex++, iBytes -= sizeof(memaddr), pcTo += + sizeof(memaddr), pcFrom += sizeof(memaddr)) + *((memaddr *) pcTo) = *((memaddr *) pcFrom); + + //if there are rested bytes to copy.. + memcpy_last: + assert(iBytes < sizeof(memaddr)); + while (iBytes > 0) + { + *pcTo = *pcFrom; + iBytes--; + pcTo++; + pcFrom++; + } + memcpy_done: + return (void *) (pcTo - 1); //return the address of last byte we copied +} +#endif + +ipaddr_t convPrefix(int prefixLen) +{ + int i; + ipaddr_t mask = 0; + + for (i = 32 - prefixLen; i < 32; i++) + mask |= (1 << i); + + return mask; +} + +uint8* strtomac(ether_addr_t *mac, int8 *str) +{ + strToMac((uint8*)mac, str); + return (uint8*)mac; +} + diff --git a/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_utils.h b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_utils.h new file mode 100644 index 000000000..f5cad344e --- /dev/null +++ b/target/linux/realtek/files/drivers/net/rtl819x/common/rtl_utils.h @@ -0,0 +1,105 @@ +/* +* Copyright c Realtek Semiconductor Corporation, 2002 +* All rights reserved. +* +* Program : Header File for RTL utilities +* Abstract : +* Author : +* $Id: rtl_utils.h,v 1.1 2007-12-21 10:29:52 davidhsu Exp $ +*/ + +#ifndef RTL8651_UTILITY_H +#define RTL8651_UTILITY_H + +void __strlowerncpy(char *dst, const char *src, int32 len); +int8 *_strncpy(int8 *dst0, const int8 *src0, int32 count); +int _strncasecmp(const char *s1, const char *s2, unsigned int n); +int32 _strncmp(const int8 *s1, const int8 *s2, int32 n); +void rtl8651_memcpy(void *dst,void*src,int32 len); +int32 isPowerOf2(uint32 number, uint32 *exponent); +int32 IpStrToAscii(const int8 *cp, uint32 *addr); +void IntToAscii(int32 n, int8 s[]); +int AsciiToInt( char **s); +uint8 charToInt(char c); +int32 ether_aton_r(int8 *a, ether_addr_t *eth); +int32 ether_ntoa_r(ether_addr_t *n, uint8 *a); +int8 *inet_ntoa_r(ipaddr_t ipaddr, int8 *p); +int32 memComp( void* _p1, void *_p2, int32 len, uint8* strHeader ); +uint8* strtomac(ether_addr_t *mac, int8 *str); +void memDump (void *start, uint32 size, int8 * strHeader); + +#if 0 +void *rtl_malloc(uint32); +void rtl_free(void *APTR); +#endif + +#ifdef CONFIG_RTL865X_ROMEREAL + /*Turn on In-memory "ethereal" like pkt sniffing code.*/ + #define START_SNIFFING rtl8651_romerealRecord +#else + #define START_SNIFFING(x,y) do{}while(0) +#endif + +#ifdef CONFIG_RTL865X_ROMEPERF + /*Turn on CPU profiling code.*/ + #include "../romeperf.h" + #define PROFILING_START rtl8651_romeperfEnterPoint + #define PROFILING_END rtl8651_romeperfExitPoint +#else + #define PROFILING_START(x) do{}while(0) + #define PROFILING_END(x) do{}while(0) +#endif + +/*=================================================================== + * ONE's COMPLEMENT OPERATION + * All the operands and return value are 'host-order'. + * Please notice the endian problem. + *===================================================================*/ +/* One's Complement ADD */ +inline static uint16 OCADD( uint16 a, uint16 b ) +{ + uint32 t; /* temp */ + t = ((a)&0xffff)+((b)&0xffff); + t = (t&0xffff)+(t>>16); + return (uint16)t; +} + +/* One's Complement NEGtive */ +inline static uint16 OCNEG( uint16 a ) +{ + return (~a)&0xffff; +} + +/* One's Complement SUBtract */ +inline static uint16 OCSUB( uint16 a, uint16 b ) +{ + return OCADD( a, OCNEG(b) ); +} + +ipaddr_t convPrefix(int prefixLen); + +#if 0 +#define TBL_MEM_ALLOC(tbl, type, size) \ + { \ + (tbl) = (type *)rtl_malloc((size) * sizeof(type)); \ + if(!(tbl)){\ + rtlglue_printf("MEM alloc failed at line %d\n", __LINE__);\ + while(1);\ + return FAILED;\ + }\ + } + +#if defined(RTL865X_MODEL_USER) + /* User mode, compiler use STDINC, said that, bezro is defined. */ +#else + /* Not user mode, we need define. */ + #ifndef bzero + #define bzero( p, s ) memset( p, 0, s ) + #endif +#endif +#endif + +#endif /* RTL8651_UTILITY_H */ + + + |