• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Common interfaces for XRadio drivers
3  *
4  * Copyright (c) 2013
5  * Xradio Technology Co., Ltd. <www.xradiotech.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 
12 #ifndef XRADIO_COMMON_H
13 #define XRADIO_COMMON_H
14 
15 #include <linux/version.h>
16 
17 /*******************************************************
18  interfaces for parse frame protocol info.
19 ********************************************************/
20 #define LLC_LEN       8
21 #define LLC_TYPE_OFF  6		/*Ether type offset*/
22 #define IP_PROTO_OFF  9		/*protocol offset*/
23 #define IP_S_ADD_OFF  12
24 #define IP_D_ADD_OFF  16
25 #define UDP_LEN       8
26 /*DHCP*/
27 #define DHCP_BOOTP_C  68
28 #define DHCP_BOOTP_S  67
29 #define UDP_BOOTP_LEN 236	/*exclude "Options:64"*/
30 #define BOOTP_OPS_LEN 64
31 #define DHCP_MAGIC    0x63825363
32 #define DHCP_DISCOVER 0x01
33 #define DHCP_OFFER    0x02
34 #define DHCP_REQUEST  0x03
35 #define DHCP_DECLINE  0x04
36 #define DHCP_ACK      0x05
37 #define DHCP_NACK     0x06
38 #define DHCP_RELEASE  0x07
39 /*ARP*/
40 #define ARP_REQUEST   0x0001
41 #define ARP_RESPONSE   0x0002
42 #define ARP_TYPE_OFFSET 6
43 
44 /*LLC layer.*/
is_SNAP(u8 * llc_data)45 static inline bool is_SNAP(u8 *llc_data)
46 {
47 	/* 0xAA, 0xAA, 0x03. */
48 	return (bool)(*(u16 *)(llc_data) == 0xAAAA && llc_data[2] == 0x03);
49 }
50 
is_STP(u8 * llc_data)51 static inline bool is_STP(u8 *llc_data)
52 {
53 	/* 0x42, 0x42, 0x03.*/
54 	return (bool)(*(u16 *)(llc_data) == 0x4242 && llc_data[2] == 0x03);
55 }
56 
57 /*IP/IPV6/ARP layer...*/
is_ip(u8 * llc_data)58 static inline bool is_ip(u8 *llc_data)
59 {
60 	/* 0x0800 */
61 	return (bool)(*(u16 *)(llc_data+LLC_TYPE_OFF) == cpu_to_be16(ETH_P_IP));
62 }
63 
is_ipv6(u8 * llc_data)64 static inline bool is_ipv6(u8 *llc_data)
65 {
66 	/* 0x08dd */
67 	return (bool)(*(u16 *)(llc_data+LLC_TYPE_OFF) == cpu_to_be16(ETH_P_IPV6));
68 }
69 
is_arp(u8 * llc_data)70 static inline bool is_arp(u8 *llc_data)
71 {
72 	/* 0x0806 */
73 	return (bool)(*(u16 *)(llc_data+LLC_TYPE_OFF) == cpu_to_be16(ETH_P_ARP));
74 }
75 
is_8021x(u8 * llc_data)76 static inline bool is_8021x(u8 *llc_data)
77 {
78 	/* 0x888E */
79 	return (bool)(*(u16 *)(llc_data+LLC_TYPE_OFF) == cpu_to_be16(ETH_P_PAE));
80 }
81 
82 /*TCP/UDP layer...*/
is_tcp(u8 * llc_data)83 static inline bool is_tcp(u8 *llc_data)
84 {
85 	return (bool) (llc_data[LLC_LEN + IP_PROTO_OFF] == IPPROTO_TCP);
86 }
87 
is_udp(u8 * llc_data)88 static inline bool is_udp(u8 *llc_data)
89 {
90 	return (bool)(llc_data[LLC_LEN+IP_PROTO_OFF] == IPPROTO_UDP);
91 }
92 
is_icmp(u8 * llc_data)93 static inline bool is_icmp(u8 *llc_data)
94 {
95 	return (bool) (llc_data[LLC_LEN + IP_PROTO_OFF] == IPPROTO_ICMP);
96 }
97 
is_igmp(u8 * llc_data)98 static inline bool is_igmp(u8 *llc_data)
99 {
100 	return (bool) (llc_data[LLC_LEN + IP_PROTO_OFF] == IPPROTO_IGMP);
101 }
102 
is_dhcp(u8 * llc_data)103 static inline bool is_dhcp(u8 *llc_data)
104 {
105 	u8 *ip_hdr = llc_data + LLC_LEN;
106 	if (!is_ip(llc_data))
107 		return (bool) 0;
108 	if (ip_hdr[IP_PROTO_OFF] == IPPROTO_UDP) {
109 		u8 *udp_hdr = ip_hdr + ((ip_hdr[0] & 0xf) << 2);	/*ihl:words*/
110 		/* DHCP client or DHCP server*/
111 		return (bool)((((udp_hdr[0]<<8)|udp_hdr[1]) == DHCP_BOOTP_C) ||
112 			      (((udp_hdr[0]<<8)|udp_hdr[1]) == DHCP_BOOTP_S));
113 	}
114 	return (bool)0;
115 }
116 
xr_alloc_skb(unsigned int len)117 static inline struct sk_buff *xr_alloc_skb(unsigned int len)
118 {
119 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
120 	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
121 	return __dev_alloc_skb(len, flags);
122 #else
123 	return dev_alloc_skb(len);
124 #endif
125 }
126 
xr_alloc_skb_pf(unsigned int len)127 static inline struct sk_buff *xr_alloc_skb_pf(unsigned int len)
128 {
129 	struct sk_buff *skb = __dev_alloc_skb(len, GFP_ATOMIC);
130 	if (!skb)
131 		return xr_alloc_skb(len);
132 	return skb;
133 }
134 
xr_kmalloc(unsigned int len,bool isDMA)135 static inline void *xr_kmalloc(unsigned int len, bool isDMA)
136 {
137 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
138 	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
139 #else
140 	gfp_t flags = GFP_ATOMIC;
141 #endif
142 	flags = isDMA ? (flags | GFP_DMA) : flags;
143 	return kmalloc(len, flags);
144 }
145 
xr_kzalloc(unsigned int len,bool isDMA)146 static inline void *xr_kzalloc(unsigned int len, bool isDMA)
147 {
148 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
149 	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
150 #else
151 	gfp_t flags = GFP_ATOMIC;
152 #endif
153 	flags = isDMA ? (flags | GFP_DMA) : flags;
154 	return kzalloc(len, flags);
155 }
156 
157 
xr_krealloc(void * buf,unsigned int len,bool isDMA)158 static inline void *xr_krealloc(void *buf, unsigned int len, bool isDMA)
159 {
160 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
161 	gfp_t flags = (in_atomic()) ? GFP_ATOMIC : GFP_KERNEL;
162 #else
163 	gfp_t flags = GFP_ATOMIC;
164 #endif
165 	flags = isDMA ? (flags | GFP_DMA) : flags;
166 	return krealloc(buf, len, flags);
167 }
168 
169 #define ROUND4(a)  ((a + 3) & (~0x3))
170 
171 #endif /*XRADIO_COMMON_H*/
172