/* * Packet Accelerator Interface * * vim:set expandtab shiftwidth=3 softtabstop=3: * * Copyright (c) 2011-2015 AVM GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification. * 2. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * Alternatively, this software may be distributed and/or modified under the * terms of the GNU General Public License as published by the Free Software * Foundation. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _LINUX_AVM_PA_H #define _LINUX_AVM_PA_H #include #include #ifdef __KERNEL__ struct sk_buff; #define PKT struct sk_buff #endif /* ------------------------------------------------------------------------ */ #define AVM_PA_HAS_LISP_SUPPORT #define AVM_PA_RECVHOOK_AVAILABLE #define AVM_PA_RTP_SESSION_AVAILABLE /* ------------------------------------------------------------------------ */ typedef unsigned char avm_pid_handle; /* 1 - AVM_PA_MAX_PID */ typedef unsigned char avm_vpid_handle; /* 1 - AVM_PA_MAX_VPID */ typedef unsigned short avm_session_handle; /* 1 - AVM_PA_MAX_SESSION */ struct avm_pa_dev_info { avm_pid_handle pid_handle; avm_vpid_handle vpid_handle; }; struct avm_pa_stats { unsigned short nsessions; unsigned short nbsessions; unsigned short maxsessions; /* packet/sec */ u32 rx_pps; u32 fw_pps; u32 overlimit_pps; /* in avm_pa_pid_receive */ u32 rx_pkts; u32 rx_bypass; u32 rx_ttl; u32 rx_broadcast; u32 rx_search; u32 rx_match; u32 rx_lispchanged; u32 rx_df; u32 rx_mod; u32 rx_overlimit; u32 rx_dropped; u32 rx_filtered; u32 rx_irq; u32 rx_irqdropped; u32 rx_headroom_too_small; u32 rx_realloc_headroom_failed; u32 rx_frag_list; u32 fw_output; u32 fw_local; u32 fw_rtp; u32 fw_rtp_drop; u32 fw_ill; /* in avm_pa_pid_snoop_transmit */ u32 tx_accelerated; u32 tx_local; u32 tx_already; u32 tx_bypass; u32 tx_sess_error; u32 tx_sess_ok; u32 tx_sess_exists; u32 tx_egress_error; u32 tx_egress_ok; /* in _pa_do_modify_and_send */ u32 tx_fast_gso; /* in avm_pa_add_local_session */ u32 local_sess_error; u32 local_sess_ok; u32 local_sess_exists; /* in avm_pa_add_rtp_session */ u32 rtp_sess_error; u32 rtp_sess_ok; u32 rtp_sess_exists; /* in pa_transmit() */ u32 fw_pkts; u32 fw_frags; u32 fw_drop; u32 fw_fail; u32 fw_frag_fail; u32 fw_drop_gone; /* in avm_pa_tbf_schedule() */ u32 tbf_schedule; u32 tbf_reschedule; /* in session_gc() */ u32 sess_timedout; u32 sess_flushed; u32 sess_pidchanged; /* rx channel */ u32 rx_channel_no_rx_slow; u32 rx_channel_stopped; /* tx channel */ u32 tx_channel_dropped; /* cputime per second */ u32 userms; u32 idlems; u32 irqms; }; enum avm_pa_framing { avm_pa_framing_ether = 1, /* start with ethernet header */ avm_pa_framing_ppp = 2, /* start with ppp header */ avm_pa_framing_ip = 3, /* start with ipv4/ipv6 header */ avm_pa_framing_dev = 4, /* start after ethhdr, check skb->protocol */ avm_pa_framing_ptype = 5, /* packet_type */ avm_pa_framing_llcsnap = 6, /* llc snap (WLAN) */ }; #define AVM_PA_MAX_NAME 32 struct avm_pa_pid_cfg { char name[AVM_PA_MAX_NAME]; enum avm_pa_framing framing; u16 default_mtu; void (*tx_func)(void *arg, PKT *pkt); void *tx_arg; struct packet_type *ptype; /* avm_pa_framing_ptype */ }; #define AVM_PA_PID_ECFG_VERSION 3 struct avm_pa_pid_ecfg { int version; /* version 0 */ #define AVM_PA_PID_FLAG_NONE 0x00000000 #define AVM_PA_PID_FLAG_NO_PID_CHANGED_CHECK 0x00000001 #define AVM_PA_PID_FLAG_HSTART_ON_INGRESS 0x00000002 #define AVM_PA_PID_FLAG_HSTART_ON_EGRESS 0x00000004 unsigned long flags; /* version 1 */ unsigned int cb_start; unsigned int cb_len; /* version 2 */ void (*rx_slow)(void *arg, PKT *pkt); void *rx_slow_arg; /* version 3 */ #define AVM_PA_PID_GROUP_WLAN_STA 1 int pid_group; }; struct avm_pa_vpid_cfg { char name[AVM_PA_MAX_NAME]; u16 v4_mtu; u16 v6_mtu; }; #define AVM_PA_IS_UNICAST 0 /* ((u32 *)(&stats->rx_unicast_pkt))[0] */ #define AVM_PA_IS_MULTICAST 1 /* ((u32 *)(&stats->rx_unicast_pkt))[1] */ #define AVM_PA_IS_BROADCAST 2 /* ((u32 *)(&stats->rx_unicast_pkt))[2] */ #define AVM_PA_MC_STATS struct avm_pa_vpid_stats { u32 rx_unicast_pkt; /* ((u32 *)(&stats->rx_unicast_pkt))[0] */ u32 rx_multicast_pkt; /* ((u32 *)(&stats->rx_unicast_pkt))[1] */ u32 rx_broadcast_pkt; /* ((u32 *)(&stats->rx_unicast_pkt))[2] */ u64 rx_bytes; /* ((u64 *)(&stats->rx_bytes))[0] */ u64 rx_multicast_bytes;/* ((u64 *)(&stats->rx_bytes))[1] */ u64 rx_broadcast_bytes;/* ((u64 *)(&stats->rx_bytes))[2] */ u32 rx_discard; u32 tx_unicast_pkt; /* ((u32 *)(&stats->tx_unicast_pkt))[0] */ u32 tx_multicast_pkt; /* ((u32 *)(&stats->tx_unicast_pkt))[1] */ u32 tx_broadcast_pkt; /* ((u32 *)(&stats->tx_unicast_pkt))[2] */ u64 tx_bytes; u32 tx_error; u32 tx_discard; unsigned long hardware_report_timestamp; /* jiffies, 0 if unknown */ }; #define AVM_PA_MAX_PRIOS 10 #define AVM_PA_TRAFFIC_STATS struct avm_pa_traffic_stats { u64 bytes; u32 pkts; }; #define AVM_PA_HAS_PRIO_STATS #define AVM_PA_HAS_PRIO_STATS_TIMESTAMP /* MDU: JZ-28867 */ #define AVM_PA_HAS_GUEST_STATS struct avm_pa_prio_stats { struct avm_pa_traffic_stats sw; struct avm_pa_traffic_stats hw; struct avm_pa_traffic_stats associated_sw; struct avm_pa_traffic_stats associated_hw; ktime_t timestamp; }; int avm_pa_init(void); void avm_pa_exit(void); #define AVM_PA_IS_ENABLED /* * avm_pa_is_enabled() * get enabled status */ int avm_pa_is_enabled(void); /* * avm_pa_get_stats() * get global stats */ void avm_pa_get_stats(struct avm_pa_stats *stats); /* * avm_pa_reset_stats() * reset global stats */ void avm_pa_reset_stats(void); /* * avm_pa_dev_init() * initialize dev_info * should be called in * - net/core/dev.c: alloc_netdev_mq() just before call to setup() */ void avm_pa_dev_init(struct avm_pa_dev_info *devinfo); /* * avm_pa_dev_pid_register_with_ingress() * register a pid for dev, with an other pid that will be used on ingress * returns: * 0: pid_handle registered * <0: no handle left to register pid */ int avm_pa_dev_pid_register_with_ingress(struct avm_pa_dev_info *devinfo, struct avm_pa_pid_cfg *cfg, avm_pid_handle ingress_pid_handle); /* * avm_pa_dev_pid_register() * register a pid for dev * returns: * 0: pid_handle registered * <0: no handle left to register pid */ int avm_pa_dev_pid_register(struct avm_pa_dev_info *devinfo, struct avm_pa_pid_cfg *cfg); #ifdef CONFIG_AVM_PA_TX_NAPI /* * avm_pa_dev_pid_register_tx_napi() * register a pid for dev. in contrast to avm_pa_dev_pid_register() it will * use NAPI for calling the tx_func(), for this reason the net_device pointer must * be given. * returns: * 0: pid_handle registered * <0: no handle left to register pid */ struct net_device; int avm_pa_dev_pid_register_tx_napi(struct avm_pa_dev_info *devinfo, struct avm_pa_pid_cfg *cfg, struct net_device *dev); #endif /* * avm_pa_dev_pidhandle_register_with_ingress() * register a pid for dev, with an other pid that will be used on ingress * returns: * 0: pid_handle registered * <0: no handle left to register pid */ int avm_pa_dev_pidhandle_register_with_ingress(struct avm_pa_dev_info *devinfo, avm_pid_handle pid_handle, struct avm_pa_pid_cfg *cfg, avm_pid_handle ingress_pid_handle); /* * avm_pa_dev_pidhandle_register() * register a pid for dev, use fixed pid_handle * returns: * pid_handle != 0 * 0: pid_handle registered * <0: different pid_handle already registered for devinfo * pid_handle == 0 * 0: pid_handle registered * <0: no handle left to register pid */ int avm_pa_dev_pidhandle_register(struct avm_pa_dev_info *devinfo, avm_pid_handle pid_handle, struct avm_pa_pid_cfg *cfg); /* * avm_pa_pid_set_ecfg() * set extended config for a pid * returns: * 0: extended config set * -1: pid_handle not registered * -2: cb save parameter illegal */ int avm_pa_pid_set_ecfg(avm_pid_handle pid_handle, struct avm_pa_pid_ecfg *ecfg); /* * avm_pa_pid_set_framing() * set framing for a pid * returns: * 0: framing set * -1: pid_handle not registered * -2: illegal ingress_framing * -3: illegal egress_framing */ #define AVM_PA_PID_SET_FRAMING_IMPLEMENTED int avm_pa_pid_set_framing(avm_pid_handle pid_handle, enum avm_pa_framing ingress_framing, enum avm_pa_framing egress_framing); /* * avm_pa_dev_pid_set_hwinfo() * set hw info for a registered pid for dev * returns: * 0: hw info set * <0: pid not registered */ //#if defined (CONFIG_IFX_PPA) || defined (CONFIG_AVM_CPMAC_ATH_PPA) #define AVMNET_DEVICE_IFXPPA_ETH_WAN (1 << 10) #define AVMNET_DEVICE_IFXPPA_ETH_LAN (1 << 11) #define AVMNET_DEVICE_IFXPPA_PTM_WAN (1 << 12) #define AVMNET_DEVICE_IFXPPA_ATM_WAN (1 << 13) #define AVMNET_DEVICE_IFXPPA_VIRT_RX (1 << 14) #define AVMNET_DEVICE_IFXPPA_VIRT_TX (1 << 15) #define AVMNET_DEVICE_IFXPPA_DISABLE_TX_ACL (1 << 16) //#endif #ifdef CONFIG_MACH_FUSIV #define AVM_PA_HWINFO_HAS_APID #endif #define AVM_PA_HWINFO_HAS_ATMVCC struct avm_pa_pid_hwinfo { void *atmvcc; /* points to struct atm_vcc for ATM */ struct avm_pa_virt_rx_dev *virt_rx_dev; struct avm_pa_virt_tx_dev *virt_tx_dev; #ifdef CONFIG_IFX_PPA int mac_nr; int flags; #endif #if defined(CONFIG_AVM_CPMAC_ATH_PPA) void *avmnet_switch_module; int port_number; int flags; #endif /*--- #if defined(CONFIG_AVM_CPMAC_ATH_PPA) ---*/ #ifdef CONFIG_GRX5 struct { struct net_device *netdev; uint32_t dp_subif_id; /* allocated via alloc_rx_channel */ uint8_t dp_enabled; bool local_stack; } ppa; #endif #ifdef CONFIG_MACH_FUSIV unsigned char apId; #endif #ifdef CONFIG_AVM_NET_EDMA int port_bmp; int flags; #endif }; #ifdef CONFIG_IFX_PPA void avm_pa_disable_atm_hw_tx_acl(void); void avm_pa_enable_atm_hw_tx_acl(void); #endif /* * set hwinfo for pid, hwinfo will be copied */ int avm_pa_pid_set_hwinfo(avm_pid_handle pid_handle, struct avm_pa_pid_hwinfo *hw); struct avm_pa_pid_hwinfo *avm_pa_pid_get_hwinfo(avm_pid_handle pid_handle); /* * call after all pid parameters set */ int avm_pa_pid_activate_hw_accelaration(avm_pid_handle pid_handle); #define AVM_PA_PRIO_MAP_TACK 0x0000 #define AVM_PA_PRIO_MAP_TGET 0x0001 #define AVM_PA_PID_HAS_PRIO_MAP_INTERFACE /* * avm_pa_pid_prio_map_enable() * enable or disable a priority map attached to a pid * returns: * 0: prio_map enabled/disabled * -1: pid_handle not registered * -2: prio_map does not exist */ int avm_pa_pid_prio_map_enable(avm_pid_handle pid_handle, unsigned short prio_map, int enable); /* * avm_pa_pid_prio_map_reset() * resets a priority map attached to a pid * returns: * 0: prio_map resetted * -1: pid_handle not registered * -2: prio_map does not exist */ int avm_pa_pid_prio_map_reset(avm_pid_handle pid_handle, unsigned short prio_map); /* * avm_pa_pid_prio_map_set_prio_per_queue() * sets the priority for a queue in a priority map attached to a pid * returns: * 0: priority set successfully * -1: pid_handle not registered * -2: prio_map does not exist * -3: prio_map queue out of bounds */ int avm_pa_pid_prio_map_set_prio_per_queue(avm_pid_handle pid_handle, unsigned short prio_map, unsigned int queue, unsigned int prio); /* * avm_pa_pid_activate_tcpackprio * enable tcpackprio handling for a pid * returns: * 0: prioack enabled * -1: pid_handle not registered */ #define AVM_PA_PID_ACTIVATE_TCPACKPRIO int avm_pa_pid_activate_tcpackprio(avm_pid_handle pid_handle, int enable, unsigned int prio); /* * avm_pa_pid_activate_tgetprio * enable tget (turbo http-get) handling for a pid * returns: * 0: tget enabled * -1: pid_handle not registered */ #define AVM_PA_PID_ACTIVATE_TGETPRIO int avm_pa_pid_activate_tgetprio(avm_pid_handle pid_handle, int enable, unsigned int prio); /* * avm_pa_dev_vpid_register() * register a vpid for dev * returns: * 0: vpid registered * <0: no handle left to register vpid */ int avm_pa_dev_vpid_register(struct avm_pa_dev_info *devinfo, struct avm_pa_vpid_cfg *cfg); /* * avm_pa_dev_vpid_register_with_tx_func() * register a vpid for dev * returns: * 0: vpid registered * <0: no handle left to register vpid */ int avm_pa_dev_vpid_register_with_tx_func(struct avm_pa_dev_info *devinfo, struct avm_pa_vpid_cfg *cfg, void (*tx_func)(void *arg, PKT *pkt), void *tx_arg); /* * avm_pa_dev_vpidhandle_register() * register a vpid for dev, use fixed vpid_handle * returns: * vpid_handle != 0 * 0: vpid_handle registered * <0: different vpid_handle already registered for devinfo * vpid_handle == 0 * 0: vpid_handle registered * <0: no handle left to register vpid */ int avm_pa_dev_vpidhandle_register(struct avm_pa_dev_info *devinfo, avm_vpid_handle vpid_handle, struct avm_pa_vpid_cfg *cfg); /* * avm_pa_dev_vpidhandle_register_with_tx_func() * register a vpid for dev, use fixed vpid_handle * returns: * vpid_handle != 0 * 0: vpid_handle registered * <0: different vpid_handle already registered for devinfo * vpid_handle == 0 * 0: vpid_handle registered * <0: no handle left to register vpid */ int avm_pa_dev_vpidhandle_register_with_tx_func( struct avm_pa_dev_info *devinfo, avm_vpid_handle vpid_handle, struct avm_pa_vpid_cfg *cfg, void (*tx_func)(void *arg, PKT *pkt), void *tx_arg); /* * avm_pa_dev_unregister() * unregister pid and pid * should be called in * - net/core/dev.c: netdev_run_todo() just before call to dev->destructor */ void avm_pa_dev_unregister(struct avm_pa_dev_info *devinfo); /* * avm_pa_vpid_set_ipv4_mtu * set mtu for ipv4 */ void avm_pa_dev_set_ipv4_mtu(struct avm_pa_dev_info *devinfo, u16 mtu); /* * avm_pa_vpid_set_ipv6_mtu * set mtu for ipv6 */ void avm_pa_dev_set_ipv6_mtu(struct avm_pa_dev_info *devinfo, u16 mtu); /* * avm_pa_dev_get_stats() * get vpid stats * returns: * < 0: vpid not registered, "stats" set to zero * 0: statistic copied to "stats" */ int avm_pa_dev_get_stats(struct avm_pa_dev_info *devinfo, struct avm_pa_vpid_stats *stats); /* Unaccelerated packets are counted in the vpid stats */ #define AVM_PA_VPID_STATS_COUNT_SLOW /* * avm_pa_dev_reset_stats() * reset vpid stats * returns: * < 0: vpid not registered. * 0: statistic reseted to zero */ int avm_pa_dev_reset_stats(struct avm_pa_dev_info *devinfo); /* * avm_pa_flush_sessions() * flushes all sessions */ void avm_pa_flush_sessions(void); /* * avm_pa_flush_lispencap_sessions() * flushes lisp encap sessions */ void avm_pa_flush_lispencap_sessions(void); /* * avm_pa_flush_rtp_session() * flushes a rtp session */ void avm_pa_flush_rtp_session(struct sock *sk); /* * avm_pa_flush_multicast_sessions() * flushes multicast sessions */ void avm_pa_flush_multicast_sessions(void); /* * avm_pa_flush_multicast_sessions_for_group() * flushes multicast sessions for specified group */ void avm_pa_flush_multicast_sessions_for_group(u32 group); /* * avm_pa_flush_sessions_for_vpid() * flushes all sessions having vpid as ingress or egress */ void avm_pa_flush_sessions_for_vpid(avm_vpid_handle vpid_handle); /* * avm_pa_flush_sessions_for_pid() * flushes all sessions having pid as ingress or egress */ void avm_pa_flush_sessions_for_pid(avm_pid_handle pid_handle); /* ------------------------------------------------------------------------ */ /* -------- pkt info structs and definitions ------------------------------ */ /* ------------------------------------------------------------------------ */ #define AVM_PA_MAX_HEADER_TO_SAVE 128 /* maximum bytes save from header */ #define AVM_PA_MAX_HDROFF 4 /* aligned to 4 bytes */ #define AVM_PA_MAX_HEADER (AVM_PA_MAX_HEADER_TO_SAVE+AVM_PA_MAX_HDROFF) #define AVM_PA_ETH 0 #define AVM_PA_VLAN 1 #define AVM_PA_PPPOE 2 #define AVM_PA_PPP 3 #define AVM_PA_IPV4 4 #define AVM_PA_IPV6 5 #define AVM_PA_PORTS 6 #define AVM_PA_ICMPV4 7 #define AVM_PA_ICMPV6 8 #define AVM_PA_LLC_SNAP 9 #define AVM_PA_LISP 10 #define AVM_PA_L2TP 11 #define AVM_PA_GRE 12 /* states */ #define AVM_PA_ETH_PROTO 13 #define AVM_PA_IP_PROTO 14 #define AVM_PA_MAX_MATCH 16 struct avm_pa_match_info { unsigned char type; unsigned char offset; }; /* * IPv6 + IPv4 + UDP => IPv4 + UDP * IPv4 + UDP => IPv4 + UDP * * IPV6 + UDP + LISP + IPV4 => IPV4 * IPV6 + UDP + LISP + IPV6 => IPV6 * IPV4 + UDP + LISP + IPV4 => IPV4 * IPV4 + UDP + LISP + IPV6 => IPV6 * * IPV6 + L2TP + ETH + IPV4 => IPV4 * IPV6 + L2TP + ETH + IPV6 => IPV6 * IPV4 + L2TP + ETH + IPV4 => IPV4 * IPV4 + L2TP + ETH + IPV6 => IPV6 */ #define AVM_PA_PKTTYPE_PROTO_MASK 0x00FF #define AVM_PA_PKTTYPE_IPPROTO(t) ((t) & AVM_PA_PKTTYPE_PROTO_MASK) #define AVM_PA_PKTTYPE_NONE 0x0000 #define AVM_PA_PKTTYPE_LISP 0x0100 /* used IPBIT1 0x0200 */ /* used IPBIT2 0x0400 */ #define AVM_PA_PKTTYPE_L2TP 0x0800 #define AVM_PA_PKTTYPE_IPV6 0x0600 #define AVM_PA_PKTTYPE_IPV4 0x0400 #define AVM_PA_PKTTYPE_IP_MASK 0x0600 #define AVM_PA_PKTTYPE_IP_VERSION(t) (((t)>>8)&0x6) #define AVM_PA_PKTTYPE_GRE 0x1000 /* used IPENCAPBIT1 0x2000 */ /* used IPENCAPBIT2 0x4000 */ /* FREE 0x8000 */ #define AVM_PA_PKTTYPE_IPV6ENCAP 0x6000 #define AVM_PA_PKTTYPE_IPV4ENCAP 0x4000 #define AVM_PA_PKTTYPE_IPENCAP_MASK 0x6000 #define AVM_PA_PKTTYPE_IPENCAP_VERSION(t) (((t)>>12)&0x6) #define AVM_PA_IPENCAP_VERSION_PKTTYPE(v) ((v&0x6)<<12) #define AVM_PA_PKTTYPE_IP2IPENCAP_VERSION(t) AVM_PA_IPENCAP_VERSION_PKTTYPE(AVM_PA_PKTTYPE_IP_VERSION(t)) #define AVM_PA_PKTTYPE_BASE_MASK (AVM_PA_PKTTYPE_IP_MASK|AVM_PA_PKTTYPE_PROTO_MASK) #define AVM_PA_PKTTYPE_BASE_EQ(t1,t2) ((t1) & AVM_PA_PKTTYPE_BASE_MASK) == ((t2) & AVM_PA_PKTTYPE_BASE_MASK) #define AVM_PA_PKTTYPE_EQ(t1,t2) (t1 == t2) #define AVM_PA_OFFSET_NOT_SET 0xff #define AVM_PA_MATCH_HAS_PKTLEN struct avm_pa_pkt_match { unsigned char casttype; /* unicast, multicast, broadcast */ unsigned char fragok:1, /* IPv4 without DF-Bit */ fin:1, /* TCP with fin or rst */ syn:1, /* TCP with syn */ ack_only:1; /* TCP with ack and without data */ /* 4 bits hole */ u16 pkttype; u32 hash; u8 hdrcopy[AVM_PA_MAX_HEADER]; struct avm_pa_match_info match[AVM_PA_MAX_MATCH]; unsigned char nmatch; unsigned char hdrlen; unsigned char hdroff; /* where hdrcopy starts (alignment) */ unsigned char pppoe_offset; /* offset of pppoe header */ unsigned char encap_offset; /* offset of tunnel header */ unsigned char lisp_offset; /* offset of lisp data header */ unsigned char ip_offset; /* offset of (inner) ip header */ /* 1 byte hole */ u16 pktlen; }; struct avm_pa_pkt_info { avm_pid_handle ingress_pid_handle; avm_vpid_handle ingress_vpid_handle; avm_vpid_handle egress_vpid_handle; avm_pid_handle ptype_pid_handle; avm_session_handle session_handle; u8 routed; u8 use_protocol_specific; u8 can_be_accelerated; u8 is_accelerated; u8 already_modified; u8 egress_offset; u8 vpid_counted_slow; struct avm_pa_pkt_match match; u32 session_uniq_id; unsigned int hstart; }; #define AVM_PA_RX_BROADCAST 5 /* is broadcast */ #define AVM_PA_RX_TTL 4 /* ttl/hoplimit is 1 */ #define AVM_PA_RX_FRAGMENT 3 /* is fragment, cannot be accelerated */ #define AVM_PA_RX_BYPASS 2 /* packet cannot be accelerated */ #define AVM_PA_RX_OK 1 /* packet maybe be accelerated */ #define AVM_PA_RX_STOLEN 0 /* packet consumed (accelerated) */ #define AVM_PA_RX_ACCELERATED AVM_PA_RX_STOLEN #define AVM_PA_RX_ERROR_STATE -1 /* state machine problem ? */ #define AVM_PA_RX_ERROR_LEN -2 /* packet too short */ #define AVM_PA_RX_ERROR_IPVERSION -3 /* illegal ip version */ #define AVM_PA_RX_ERROR_MATCH -4 /* too much header */ #define AVM_PA_RX_ERROR_HDR -5 /* too much ip header */ /* * avm_pa_dev_receive() * if vpid set: remember ingress vpid, for statistics * if pid set: function tries to accelerate packet * returns: * < 0: you can free the packet or send it the slow way to get it dropped * 0: packet was accelerated (so it is gone, don't free it) * > 0: send packet the slow way * should be called in * - net/core/dev.c: netif_receive_skb() before protocol handling */ int avm_pa_dev_receive(struct avm_pa_dev_info *devinfo, PKT *pkt); /* * avm_pa_dev_pid_receive() * if pid set: function tries to accelerate packet * returns: * < 0: you can free the packet or send it the slow way to get it dropped * 0: packet was accelerated (so it is gone, don't free it) * > 0: send packet the slow way * should be called when pid may have rx channel handling */ int avm_pa_dev_pid_receive(struct avm_pa_dev_info *devinfo, PKT *pkt); /* * avm_pa_dev_vpid_snoop_receive() * if vpid set: remember ingress vpid, for statistics */ void avm_pa_dev_vpid_snoop_receive(struct avm_pa_dev_info *devinfo, PKT *pkt); /* * avm_pa_mark_routed() * mark packet as routed * should be called in * - net/ipv4/ip_forward.c: ip_forward_finish() * - net/ipv6/ip6_output.c: ip6_forward_finish() */ void avm_pa_mark_routed(PKT *pkt); /* * avm_pa_use_protocol_specific_session() * if this packet creats a session, it should be * a protocol specific session (no bridge session). * should be called when protocol specific filting * or protocol specific queuing is done on datapath. */ void avm_pa_use_protocol_specific_session(PKT *pkt); /* * avm_pa_do_not_accelerate() * mark packet to not create a session * should be called * - for packets manipulate by ALG (FTP-Control, tftp, ...) * - in net/ipv4/mcfastforward.c: mcfw_multicast_forward() (for now) * - in net/bridge/br_forward.c: for flooded packets */ void avm_pa_do_not_accelerate(PKT *pkt); /* * avm_pa_set_hstart() * store offset where encap header starts * should be called, when hstart != 0 before calling * avm_pa_dev_receive() * avm_pa_dev_snoop_transmit() */ void avm_pa_set_hstart(PKT *pkt, unsigned int hstart); #define AVM_PA_TX_BYPASS 4 /* packet cannot be accelerated */ #define AVM_PA_TX_SESSION_EXISTS 3 /* session already exists */ #define AVM_PA_TX_EGRESS_ADDED 2 /* egress in session added */ #define AVM_PA_TX_SESSION_ADDED 1 /* session added */ #define AVM_PA_TX_OK 0 /* nothing done */ #define AVM_PA_TX_ERROR_SESSION -1 /* session creation failed */ #define AVM_PA_TX_ERROR_EGRESS -2 /* egress creation failed */ /* * avm_pa_dev_snoop_transmit() * if vpid set: remember egress vpid, for statistics * if pid set: try to create a session for this packet * returns: * > 0: some action done * 0: nothing done or egress vpid remembered * < 0: some error * should be called in * - net/core/dev.c: dev_queue_xmit() before picking tx queue * if dev has an pid set. */ int avm_pa_dev_snoop_transmit(struct avm_pa_dev_info *devinfo, PKT *pkt); /* * avm_pa_dev_vpid_snoop_transmit() * if vpid set: remember egress vpid, for statistics */ void avm_pa_dev_vpid_snoop_transmit(struct avm_pa_dev_info *devinfo, PKT *pkt); /* * avm_pa_add_local_session() * try to create a local session for this packet * - in include/net/inet_hashtables.h: __inet_lookup_skb() * - in include/net/inet6_hashtables.h: __inet6_lookup_skb() * - in net/ipv4/udp.c: __udp4_lib_lookup_skb() * - in net/ipv6/udp.c: __udp6_lib_lookup_skb() */ void _avm_pa_add_local_session(PKT *pkt, struct sock *sk); /* * avm_pa_add_rtp_session() * local session for this packet must exist. * session is rewritten to rtp session */ void avm_pa_add_rtp_session(PKT *pkt, struct sock *sk, void (*transmit)(struct sock *sk, PKT *pkt)); void avm_pa_filter_packet(PKT *pkt); /* * avm_pa_dev_get_hw_stats() * get upstream statistics for HW accelerated packets * @prio: upstream priority */ int avm_pa_dev_get_hw_stats(struct avm_pa_dev_info *devinfo, struct avm_pa_traffic_stats *stats, unsigned int prio); /* * avm_pa_dev_get_prio_stats() * get upstream statistics for SW and HW accelerated packets * @prio: upstream priority */ int avm_pa_dev_get_prio_stats(struct avm_pa_dev_info *devinfo, struct avm_pa_prio_stats *stats, unsigned int prio); #ifdef AVM_PA_HAS_GUEST_STATS /* * avm_pa_dev_get_hw_guest_stats() * get upstream statistics for HW accelerated guest_packets * @prio: upstream priority */ int avm_pa_dev_get_hw_guest_stats(struct avm_pa_dev_info *devinfo, struct avm_pa_traffic_stats *stats, unsigned int prio); /* * avm_pa_dev_get_guest_prio_stats() * get upstream guest statistics for SW and HW accelerated packets * @prio: upstream priority */ int avm_pa_dev_get_guest_prio_stats(struct avm_pa_dev_info *devinfo, struct avm_pa_prio_stats *stats, unsigned int prio); #endif /* * avm_pa_dev_get_ingress_prio_stats() * get ingress (downstream) statistics for SW and HW accelerated packets * @prio: ingress priority */ #define AVM_PA_DEV_GET_INGRESS_PRIO_STATS int avm_pa_dev_get_ingress_prio_stats(struct avm_pa_dev_info *devinfo, struct avm_pa_prio_stats *stats, unsigned int prio); /* * avm_pa_telefon_state() * notify avm pa about telephony acitivity. * state == 0, no phone calls active * state != 0, phone calls active or in progress */ void avm_pa_telefon_state(int state); /* * avm_pa_register_recvhook() * add a receive hook callback * prepend != 0, prepend the callback * prepend == 0, append the callback * recvhook, callback function to add */ int avm_pa_register_recvhook(int prepend, int (*recvhook)(struct sk_buff *skb, int framing)); /* * avm_pa_unregister_recvhook() * remove a receive hook callback * recvhook, callback function remove */ void avm_pa_unregister_recvhook(int (*recvhook)(struct sk_buff *skb, int framing)); #endif /* _LINUX_AVM_PA_H */