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