diff options
Diffstat (limited to 'drivers/s390/net/qeth.h')
-rw-r--r-- | drivers/s390/net/qeth.h | 1162 |
1 files changed, 1162 insertions, 0 deletions
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h new file mode 100644 index 000000000000..a341041a6cf7 --- /dev/null +++ b/drivers/s390/net/qeth.h | |||
@@ -0,0 +1,1162 @@ | |||
1 | #ifndef __QETH_H__ | ||
2 | #define __QETH_H__ | ||
3 | |||
4 | #include <linux/if.h> | ||
5 | #include <linux/if_arp.h> | ||
6 | |||
7 | #include <linux/if_tr.h> | ||
8 | #include <linux/trdevice.h> | ||
9 | #include <linux/etherdevice.h> | ||
10 | #include <linux/if_vlan.h> | ||
11 | |||
12 | #include <net/ipv6.h> | ||
13 | #include <linux/in6.h> | ||
14 | #include <net/if_inet6.h> | ||
15 | #include <net/addrconf.h> | ||
16 | |||
17 | |||
18 | #include <linux/bitops.h> | ||
19 | |||
20 | #include <asm/debug.h> | ||
21 | #include <asm/qdio.h> | ||
22 | #include <asm/ccwdev.h> | ||
23 | #include <asm/ccwgroup.h> | ||
24 | |||
25 | #include "qeth_mpc.h" | ||
26 | |||
27 | #define VERSION_QETH_H "$Revision: 1.135 $" | ||
28 | |||
29 | #ifdef CONFIG_QETH_IPV6 | ||
30 | #define QETH_VERSION_IPV6 ":IPv6" | ||
31 | #else | ||
32 | #define QETH_VERSION_IPV6 "" | ||
33 | #endif | ||
34 | #ifdef CONFIG_QETH_VLAN | ||
35 | #define QETH_VERSION_VLAN ":VLAN" | ||
36 | #else | ||
37 | #define QETH_VERSION_VLAN "" | ||
38 | #endif | ||
39 | |||
40 | /** | ||
41 | * Debug Facility stuff | ||
42 | */ | ||
43 | #define QETH_DBF_SETUP_NAME "qeth_setup" | ||
44 | #define QETH_DBF_SETUP_LEN 8 | ||
45 | #define QETH_DBF_SETUP_INDEX 3 | ||
46 | #define QETH_DBF_SETUP_NR_AREAS 1 | ||
47 | #define QETH_DBF_SETUP_LEVEL 5 | ||
48 | |||
49 | #define QETH_DBF_MISC_NAME "qeth_misc" | ||
50 | #define QETH_DBF_MISC_LEN 128 | ||
51 | #define QETH_DBF_MISC_INDEX 1 | ||
52 | #define QETH_DBF_MISC_NR_AREAS 1 | ||
53 | #define QETH_DBF_MISC_LEVEL 2 | ||
54 | |||
55 | #define QETH_DBF_DATA_NAME "qeth_data" | ||
56 | #define QETH_DBF_DATA_LEN 96 | ||
57 | #define QETH_DBF_DATA_INDEX 3 | ||
58 | #define QETH_DBF_DATA_NR_AREAS 1 | ||
59 | #define QETH_DBF_DATA_LEVEL 2 | ||
60 | |||
61 | #define QETH_DBF_CONTROL_NAME "qeth_control" | ||
62 | #define QETH_DBF_CONTROL_LEN 256 | ||
63 | #define QETH_DBF_CONTROL_INDEX 3 | ||
64 | #define QETH_DBF_CONTROL_NR_AREAS 2 | ||
65 | #define QETH_DBF_CONTROL_LEVEL 5 | ||
66 | |||
67 | #define QETH_DBF_TRACE_NAME "qeth_trace" | ||
68 | #define QETH_DBF_TRACE_LEN 8 | ||
69 | #define QETH_DBF_TRACE_INDEX 2 | ||
70 | #define QETH_DBF_TRACE_NR_AREAS 2 | ||
71 | #define QETH_DBF_TRACE_LEVEL 3 | ||
72 | extern debug_info_t *qeth_dbf_trace; | ||
73 | |||
74 | #define QETH_DBF_SENSE_NAME "qeth_sense" | ||
75 | #define QETH_DBF_SENSE_LEN 64 | ||
76 | #define QETH_DBF_SENSE_INDEX 1 | ||
77 | #define QETH_DBF_SENSE_NR_AREAS 1 | ||
78 | #define QETH_DBF_SENSE_LEVEL 2 | ||
79 | |||
80 | #define QETH_DBF_QERR_NAME "qeth_qerr" | ||
81 | #define QETH_DBF_QERR_LEN 8 | ||
82 | #define QETH_DBF_QERR_INDEX 1 | ||
83 | #define QETH_DBF_QERR_NR_AREAS 2 | ||
84 | #define QETH_DBF_QERR_LEVEL 2 | ||
85 | |||
86 | #define QETH_DBF_TEXT(name,level,text) \ | ||
87 | do { \ | ||
88 | debug_text_event(qeth_dbf_##name,level,text); \ | ||
89 | } while (0) | ||
90 | |||
91 | #define QETH_DBF_HEX(name,level,addr,len) \ | ||
92 | do { \ | ||
93 | debug_event(qeth_dbf_##name,level,(void*)(addr),len); \ | ||
94 | } while (0) | ||
95 | |||
96 | DECLARE_PER_CPU(char[256], qeth_dbf_txt_buf); | ||
97 | |||
98 | #define QETH_DBF_TEXT_(name,level,text...) \ | ||
99 | do { \ | ||
100 | char* dbf_txt_buf = get_cpu_var(qeth_dbf_txt_buf); \ | ||
101 | sprintf(dbf_txt_buf, text); \ | ||
102 | debug_text_event(qeth_dbf_##name,level,dbf_txt_buf); \ | ||
103 | put_cpu_var(qeth_dbf_txt_buf); \ | ||
104 | } while (0) | ||
105 | |||
106 | #define QETH_DBF_SPRINTF(name,level,text...) \ | ||
107 | do { \ | ||
108 | debug_sprintf_event(qeth_dbf_trace, level, ##text ); \ | ||
109 | debug_sprintf_event(qeth_dbf_trace, level, text ); \ | ||
110 | } while (0) | ||
111 | |||
112 | /** | ||
113 | * some more debug stuff | ||
114 | */ | ||
115 | #define PRINTK_HEADER "qeth: " | ||
116 | |||
117 | #define HEXDUMP16(importance,header,ptr) \ | ||
118 | PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ | ||
119 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ | ||
120 | *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \ | ||
121 | *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \ | ||
122 | *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \ | ||
123 | *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \ | ||
124 | *(((char*)ptr)+12),*(((char*)ptr)+13), \ | ||
125 | *(((char*)ptr)+14),*(((char*)ptr)+15)); \ | ||
126 | PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ | ||
127 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ | ||
128 | *(((char*)ptr)+16),*(((char*)ptr)+17), \ | ||
129 | *(((char*)ptr)+18),*(((char*)ptr)+19), \ | ||
130 | *(((char*)ptr)+20),*(((char*)ptr)+21), \ | ||
131 | *(((char*)ptr)+22),*(((char*)ptr)+23), \ | ||
132 | *(((char*)ptr)+24),*(((char*)ptr)+25), \ | ||
133 | *(((char*)ptr)+26),*(((char*)ptr)+27), \ | ||
134 | *(((char*)ptr)+28),*(((char*)ptr)+29), \ | ||
135 | *(((char*)ptr)+30),*(((char*)ptr)+31)); | ||
136 | |||
137 | static inline void | ||
138 | qeth_hex_dump(unsigned char *buf, size_t len) | ||
139 | { | ||
140 | size_t i; | ||
141 | |||
142 | for (i = 0; i < len; i++) { | ||
143 | if (i && !(i % 16)) | ||
144 | printk("\n"); | ||
145 | printk("%02x ", *(buf + i)); | ||
146 | } | ||
147 | printk("\n"); | ||
148 | } | ||
149 | |||
150 | #define SENSE_COMMAND_REJECT_BYTE 0 | ||
151 | #define SENSE_COMMAND_REJECT_FLAG 0x80 | ||
152 | #define SENSE_RESETTING_EVENT_BYTE 1 | ||
153 | #define SENSE_RESETTING_EVENT_FLAG 0x80 | ||
154 | |||
155 | #define atomic_swap(a,b) xchg((int *)a.counter, b) | ||
156 | |||
157 | /* | ||
158 | * Common IO related definitions | ||
159 | */ | ||
160 | extern struct device *qeth_root_dev; | ||
161 | extern struct ccw_driver qeth_ccw_driver; | ||
162 | extern struct ccwgroup_driver qeth_ccwgroup_driver; | ||
163 | |||
164 | #define CARD_RDEV(card) card->read.ccwdev | ||
165 | #define CARD_WDEV(card) card->write.ccwdev | ||
166 | #define CARD_DDEV(card) card->data.ccwdev | ||
167 | #define CARD_BUS_ID(card) card->gdev->dev.bus_id | ||
168 | #define CARD_RDEV_ID(card) card->read.ccwdev->dev.bus_id | ||
169 | #define CARD_WDEV_ID(card) card->write.ccwdev->dev.bus_id | ||
170 | #define CARD_DDEV_ID(card) card->data.ccwdev->dev.bus_id | ||
171 | #define CHANNEL_ID(channel) channel->ccwdev->dev.bus_id | ||
172 | |||
173 | #define CARD_FROM_CDEV(cdev) (struct qeth_card *) \ | ||
174 | ((struct ccwgroup_device *)cdev->dev.driver_data)\ | ||
175 | ->dev.driver_data; | ||
176 | |||
177 | /** | ||
178 | * card stuff | ||
179 | */ | ||
180 | #ifdef CONFIG_QETH_PERF_STATS | ||
181 | struct qeth_perf_stats { | ||
182 | unsigned int bufs_rec; | ||
183 | unsigned int bufs_sent; | ||
184 | |||
185 | unsigned int skbs_sent_pack; | ||
186 | unsigned int bufs_sent_pack; | ||
187 | |||
188 | unsigned int sc_dp_p; | ||
189 | unsigned int sc_p_dp; | ||
190 | /* qdio_input_handler: number of times called, time spent in */ | ||
191 | __u64 inbound_start_time; | ||
192 | unsigned int inbound_cnt; | ||
193 | unsigned int inbound_time; | ||
194 | /* qeth_send_packet: number of times called, time spent in */ | ||
195 | __u64 outbound_start_time; | ||
196 | unsigned int outbound_cnt; | ||
197 | unsigned int outbound_time; | ||
198 | /* qdio_output_handler: number of times called, time spent in */ | ||
199 | __u64 outbound_handler_start_time; | ||
200 | unsigned int outbound_handler_cnt; | ||
201 | unsigned int outbound_handler_time; | ||
202 | /* number of calls to and time spent in do_QDIO for inbound queue */ | ||
203 | __u64 inbound_do_qdio_start_time; | ||
204 | unsigned int inbound_do_qdio_cnt; | ||
205 | unsigned int inbound_do_qdio_time; | ||
206 | /* number of calls to and time spent in do_QDIO for outbound queues */ | ||
207 | __u64 outbound_do_qdio_start_time; | ||
208 | unsigned int outbound_do_qdio_cnt; | ||
209 | unsigned int outbound_do_qdio_time; | ||
210 | /* eddp data */ | ||
211 | unsigned int large_send_bytes; | ||
212 | unsigned int large_send_cnt; | ||
213 | unsigned int sg_skbs_sent; | ||
214 | unsigned int sg_frags_sent; | ||
215 | }; | ||
216 | #endif /* CONFIG_QETH_PERF_STATS */ | ||
217 | |||
218 | /* Routing stuff */ | ||
219 | struct qeth_routing_info { | ||
220 | enum qeth_routing_types type; | ||
221 | }; | ||
222 | |||
223 | /* IPA stuff */ | ||
224 | struct qeth_ipa_info { | ||
225 | __u32 supported_funcs; | ||
226 | __u32 enabled_funcs; | ||
227 | }; | ||
228 | |||
229 | static inline int | ||
230 | qeth_is_ipa_supported(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) | ||
231 | { | ||
232 | return (ipa->supported_funcs & func); | ||
233 | } | ||
234 | |||
235 | static inline int | ||
236 | qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) | ||
237 | { | ||
238 | return (ipa->supported_funcs & ipa->enabled_funcs & func); | ||
239 | } | ||
240 | |||
241 | #define qeth_adp_supported(c,f) \ | ||
242 | qeth_is_ipa_supported(&c->options.adp, f) | ||
243 | #define qeth_adp_enabled(c,f) \ | ||
244 | qeth_is_ipa_enabled(&c->options.adp, f) | ||
245 | #define qeth_is_supported(c,f) \ | ||
246 | qeth_is_ipa_supported(&c->options.ipa4, f) | ||
247 | #define qeth_is_enabled(c,f) \ | ||
248 | qeth_is_ipa_enabled(&c->options.ipa4, f) | ||
249 | #ifdef CONFIG_QETH_IPV6 | ||
250 | #define qeth_is_supported6(c,f) \ | ||
251 | qeth_is_ipa_supported(&c->options.ipa6, f) | ||
252 | #define qeth_is_enabled6(c,f) \ | ||
253 | qeth_is_ipa_enabled(&c->options.ipa6, f) | ||
254 | #else /* CONFIG_QETH_IPV6 */ | ||
255 | #define qeth_is_supported6(c,f) 0 | ||
256 | #define qeth_is_enabled6(c,f) 0 | ||
257 | #endif /* CONFIG_QETH_IPV6 */ | ||
258 | #define qeth_is_ipafunc_supported(c,prot,f) \ | ||
259 | (prot==QETH_PROT_IPV6)? qeth_is_supported6(c,f):qeth_is_supported(c,f) | ||
260 | #define qeth_is_ipafunc_enabled(c,prot,f) \ | ||
261 | (prot==QETH_PROT_IPV6)? qeth_is_enabled6(c,f):qeth_is_enabled(c,f) | ||
262 | |||
263 | |||
264 | #define QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT 0x0101 | ||
265 | #define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x0101 | ||
266 | #define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108 | ||
267 | #define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108 | ||
268 | |||
269 | #define QETH_MODELLIST_ARRAY \ | ||
270 | {{0x1731,0x01,0x1732,0x01,QETH_CARD_TYPE_OSAE,1, \ | ||
271 | QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \ | ||
272 | QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \ | ||
273 | QETH_MAX_QUEUES,0}, \ | ||
274 | {0x1731,0x05,0x1732,0x05,QETH_CARD_TYPE_IQD,0, \ | ||
275 | QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \ | ||
276 | QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \ | ||
277 | QETH_MAX_QUEUES,0x103}, \ | ||
278 | {0,0,0,0,0,0,0,0,0}} | ||
279 | |||
280 | #define QETH_REAL_CARD 1 | ||
281 | #define QETH_VLAN_CARD 2 | ||
282 | #define QETH_BUFSIZE 4096 | ||
283 | |||
284 | /** | ||
285 | * some more defs | ||
286 | */ | ||
287 | #define IF_NAME_LEN 16 | ||
288 | #define QETH_TX_TIMEOUT 100 * HZ | ||
289 | #define QETH_HEADER_SIZE 32 | ||
290 | #define MAX_PORTNO 15 | ||
291 | #define QETH_FAKE_LL_LEN ETH_HLEN | ||
292 | #define QETH_FAKE_LL_V6_ADDR_POS 24 | ||
293 | |||
294 | /*IPv6 address autoconfiguration stuff*/ | ||
295 | #define UNIQUE_ID_IF_CREATE_ADDR_FAILED 0xfffe | ||
296 | #define UNIQUE_ID_NOT_BY_CARD 0x10000 | ||
297 | |||
298 | /*****************************************************************************/ | ||
299 | /* QDIO queue and buffer handling */ | ||
300 | /*****************************************************************************/ | ||
301 | #define QETH_MAX_QUEUES 4 | ||
302 | #define QETH_IN_BUF_SIZE_DEFAULT 65536 | ||
303 | #define QETH_IN_BUF_COUNT_DEFAULT 16 | ||
304 | #define QETH_IN_BUF_COUNT_MIN 8 | ||
305 | #define QETH_IN_BUF_COUNT_MAX 128 | ||
306 | #define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12) | ||
307 | #define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \ | ||
308 | ((card)->qdio.in_buf_pool.buf_count / 2) | ||
309 | |||
310 | /* buffers we have to be behind before we get a PCI */ | ||
311 | #define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1) | ||
312 | /*enqueued free buffers left before we get a PCI*/ | ||
313 | #define QETH_PCI_THRESHOLD_B(card) 0 | ||
314 | /*not used unless the microcode gets patched*/ | ||
315 | #define QETH_PCI_TIMER_VALUE(card) 3 | ||
316 | |||
317 | #define QETH_MIN_INPUT_THRESHOLD 1 | ||
318 | #define QETH_MAX_INPUT_THRESHOLD 500 | ||
319 | #define QETH_MIN_OUTPUT_THRESHOLD 1 | ||
320 | #define QETH_MAX_OUTPUT_THRESHOLD 300 | ||
321 | |||
322 | /* priority queing */ | ||
323 | #define QETH_PRIOQ_DEFAULT QETH_NO_PRIO_QUEUEING | ||
324 | #define QETH_DEFAULT_QUEUE 2 | ||
325 | #define QETH_NO_PRIO_QUEUEING 0 | ||
326 | #define QETH_PRIO_Q_ING_PREC 1 | ||
327 | #define QETH_PRIO_Q_ING_TOS 2 | ||
328 | #define IP_TOS_LOWDELAY 0x10 | ||
329 | #define IP_TOS_HIGHTHROUGHPUT 0x08 | ||
330 | #define IP_TOS_HIGHRELIABILITY 0x04 | ||
331 | #define IP_TOS_NOTIMPORTANT 0x02 | ||
332 | |||
333 | /* Packing */ | ||
334 | #define QETH_LOW_WATERMARK_PACK 2 | ||
335 | #define QETH_HIGH_WATERMARK_PACK 5 | ||
336 | #define QETH_WATERMARK_PACK_FUZZ 1 | ||
337 | |||
338 | #define QETH_IP_HEADER_SIZE 40 | ||
339 | |||
340 | struct qeth_hdr_layer3 { | ||
341 | __u8 id; | ||
342 | __u8 flags; | ||
343 | __u16 inbound_checksum; /*TSO:__u16 seqno */ | ||
344 | __u32 token; /*TSO: __u32 reserved */ | ||
345 | __u16 length; | ||
346 | __u8 vlan_prio; | ||
347 | __u8 ext_flags; | ||
348 | __u16 vlan_id; | ||
349 | __u16 frame_offset; | ||
350 | __u8 dest_addr[16]; | ||
351 | } __attribute__ ((packed)); | ||
352 | |||
353 | struct qeth_hdr_layer2 { | ||
354 | __u8 id; | ||
355 | __u8 flags[3]; | ||
356 | __u8 port_no; | ||
357 | __u8 hdr_length; | ||
358 | __u16 pkt_length; | ||
359 | __u16 seq_no; | ||
360 | __u16 vlan_id; | ||
361 | __u32 reserved; | ||
362 | __u8 reserved2[16]; | ||
363 | } __attribute__ ((packed)); | ||
364 | |||
365 | struct qeth_hdr { | ||
366 | union { | ||
367 | struct qeth_hdr_layer2 l2; | ||
368 | struct qeth_hdr_layer3 l3; | ||
369 | } hdr; | ||
370 | } __attribute__ ((packed)); | ||
371 | |||
372 | |||
373 | /* flags for qeth_hdr.flags */ | ||
374 | #define QETH_HDR_PASSTHRU 0x10 | ||
375 | #define QETH_HDR_IPV6 0x80 | ||
376 | #define QETH_HDR_CAST_MASK 0x07 | ||
377 | enum qeth_cast_flags { | ||
378 | QETH_CAST_UNICAST = 0x06, | ||
379 | QETH_CAST_MULTICAST = 0x04, | ||
380 | QETH_CAST_BROADCAST = 0x05, | ||
381 | QETH_CAST_ANYCAST = 0x07, | ||
382 | QETH_CAST_NOCAST = 0x00, | ||
383 | }; | ||
384 | |||
385 | enum qeth_layer2_frame_flags { | ||
386 | QETH_LAYER2_FLAG_MULTICAST = 0x01, | ||
387 | QETH_LAYER2_FLAG_BROADCAST = 0x02, | ||
388 | QETH_LAYER2_FLAG_UNICAST = 0x04, | ||
389 | QETH_LAYER2_FLAG_VLAN = 0x10, | ||
390 | }; | ||
391 | |||
392 | enum qeth_header_ids { | ||
393 | QETH_HEADER_TYPE_LAYER3 = 0x01, | ||
394 | QETH_HEADER_TYPE_LAYER2 = 0x02, | ||
395 | QETH_HEADER_TYPE_TSO = 0x03, | ||
396 | }; | ||
397 | /* flags for qeth_hdr.ext_flags */ | ||
398 | #define QETH_HDR_EXT_VLAN_FRAME 0x01 | ||
399 | #define QETH_HDR_EXT_TOKEN_ID 0x02 | ||
400 | #define QETH_HDR_EXT_INCLUDE_VLAN_TAG 0x04 | ||
401 | #define QETH_HDR_EXT_SRC_MAC_ADDR 0x08 | ||
402 | #define QETH_HDR_EXT_CSUM_HDR_REQ 0x10 | ||
403 | #define QETH_HDR_EXT_CSUM_TRANSP_REQ 0x20 | ||
404 | #define QETH_HDR_EXT_UDP_TSO 0x40 /*bit off for TCP*/ | ||
405 | |||
406 | static inline int | ||
407 | qeth_is_last_sbale(struct qdio_buffer_element *sbale) | ||
408 | { | ||
409 | return (sbale->flags & SBAL_FLAGS_LAST_ENTRY); | ||
410 | } | ||
411 | |||
412 | enum qeth_qdio_buffer_states { | ||
413 | /* | ||
414 | * inbound: read out by driver; owned by hardware in order to be filled | ||
415 | * outbound: owned by driver in order to be filled | ||
416 | */ | ||
417 | QETH_QDIO_BUF_EMPTY, | ||
418 | /* | ||
419 | * inbound: filled by hardware; owned by driver in order to be read out | ||
420 | * outbound: filled by driver; owned by hardware in order to be sent | ||
421 | */ | ||
422 | QETH_QDIO_BUF_PRIMED, | ||
423 | }; | ||
424 | |||
425 | enum qeth_qdio_info_states { | ||
426 | QETH_QDIO_UNINITIALIZED, | ||
427 | QETH_QDIO_ALLOCATED, | ||
428 | QETH_QDIO_ESTABLISHED, | ||
429 | }; | ||
430 | |||
431 | struct qeth_buffer_pool_entry { | ||
432 | struct list_head list; | ||
433 | struct list_head init_list; | ||
434 | void *elements[QDIO_MAX_ELEMENTS_PER_BUFFER]; | ||
435 | }; | ||
436 | |||
437 | struct qeth_qdio_buffer_pool { | ||
438 | struct list_head entry_list; | ||
439 | int buf_count; | ||
440 | }; | ||
441 | |||
442 | struct qeth_qdio_buffer { | ||
443 | struct qdio_buffer *buffer; | ||
444 | volatile enum qeth_qdio_buffer_states state; | ||
445 | /* the buffer pool entry currently associated to this buffer */ | ||
446 | struct qeth_buffer_pool_entry *pool_entry; | ||
447 | }; | ||
448 | |||
449 | struct qeth_qdio_q { | ||
450 | struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; | ||
451 | struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q]; | ||
452 | /* | ||
453 | * buf_to_init means "buffer must be initialized by driver and must | ||
454 | * be made available for hardware" -> state is set to EMPTY | ||
455 | */ | ||
456 | volatile int next_buf_to_init; | ||
457 | } __attribute__ ((aligned(256))); | ||
458 | |||
459 | /* possible types of qeth large_send support */ | ||
460 | enum qeth_large_send_types { | ||
461 | QETH_LARGE_SEND_NO, | ||
462 | QETH_LARGE_SEND_EDDP, | ||
463 | QETH_LARGE_SEND_TSO, | ||
464 | }; | ||
465 | |||
466 | struct qeth_qdio_out_buffer { | ||
467 | struct qdio_buffer *buffer; | ||
468 | atomic_t state; | ||
469 | volatile int next_element_to_fill; | ||
470 | struct sk_buff_head skb_list; | ||
471 | struct list_head ctx_list; | ||
472 | }; | ||
473 | |||
474 | struct qeth_card; | ||
475 | |||
476 | enum qeth_out_q_states { | ||
477 | QETH_OUT_Q_UNLOCKED, | ||
478 | QETH_OUT_Q_LOCKED, | ||
479 | QETH_OUT_Q_LOCKED_FLUSH, | ||
480 | }; | ||
481 | |||
482 | struct qeth_qdio_out_q { | ||
483 | struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q]; | ||
484 | struct qeth_qdio_out_buffer bufs[QDIO_MAX_BUFFERS_PER_Q]; | ||
485 | int queue_no; | ||
486 | struct qeth_card *card; | ||
487 | atomic_t state; | ||
488 | volatile int do_pack; | ||
489 | /* | ||
490 | * index of buffer to be filled by driver; state EMPTY or PACKING | ||
491 | */ | ||
492 | volatile int next_buf_to_fill; | ||
493 | /* | ||
494 | * number of buffers that are currently filled (PRIMED) | ||
495 | * -> these buffers are hardware-owned | ||
496 | */ | ||
497 | atomic_t used_buffers; | ||
498 | /* indicates whether PCI flag must be set (or if one is outstanding) */ | ||
499 | atomic_t set_pci_flags_count; | ||
500 | } __attribute__ ((aligned(256))); | ||
501 | |||
502 | struct qeth_qdio_info { | ||
503 | volatile enum qeth_qdio_info_states state; | ||
504 | /* input */ | ||
505 | struct qeth_qdio_q *in_q; | ||
506 | struct qeth_qdio_buffer_pool in_buf_pool; | ||
507 | struct qeth_qdio_buffer_pool init_pool; | ||
508 | int in_buf_size; | ||
509 | |||
510 | /* output */ | ||
511 | int no_out_queues; | ||
512 | struct qeth_qdio_out_q **out_qs; | ||
513 | |||
514 | /* priority queueing */ | ||
515 | int do_prio_queueing; | ||
516 | int default_out_queue; | ||
517 | }; | ||
518 | |||
519 | enum qeth_send_errors { | ||
520 | QETH_SEND_ERROR_NONE, | ||
521 | QETH_SEND_ERROR_LINK_FAILURE, | ||
522 | QETH_SEND_ERROR_RETRY, | ||
523 | QETH_SEND_ERROR_KICK_IT, | ||
524 | }; | ||
525 | |||
526 | #define QETH_ETH_MAC_V4 0x0100 /* like v4 */ | ||
527 | #define QETH_ETH_MAC_V6 0x3333 /* like v6 */ | ||
528 | /* tr mc mac is longer, but that will be enough to detect mc frames */ | ||
529 | #define QETH_TR_MAC_NC 0xc000 /* non-canonical */ | ||
530 | #define QETH_TR_MAC_C 0x0300 /* canonical */ | ||
531 | |||
532 | #define DEFAULT_ADD_HHLEN 0 | ||
533 | #define MAX_ADD_HHLEN 1024 | ||
534 | |||
535 | /** | ||
536 | * buffer stuff for read channel | ||
537 | */ | ||
538 | #define QETH_CMD_BUFFER_NO 8 | ||
539 | |||
540 | /** | ||
541 | * channel state machine | ||
542 | */ | ||
543 | enum qeth_channel_states { | ||
544 | CH_STATE_UP, | ||
545 | CH_STATE_DOWN, | ||
546 | CH_STATE_ACTIVATING, | ||
547 | CH_STATE_HALTED, | ||
548 | CH_STATE_STOPPED, | ||
549 | }; | ||
550 | /** | ||
551 | * card state machine | ||
552 | */ | ||
553 | enum qeth_card_states { | ||
554 | CARD_STATE_DOWN, | ||
555 | CARD_STATE_HARDSETUP, | ||
556 | CARD_STATE_SOFTSETUP, | ||
557 | CARD_STATE_UP, | ||
558 | CARD_STATE_RECOVER, | ||
559 | }; | ||
560 | |||
561 | /** | ||
562 | * Protocol versions | ||
563 | */ | ||
564 | enum qeth_prot_versions { | ||
565 | QETH_PROT_SNA = 0x0001, | ||
566 | QETH_PROT_IPV4 = 0x0004, | ||
567 | QETH_PROT_IPV6 = 0x0006, | ||
568 | }; | ||
569 | |||
570 | enum qeth_ip_types { | ||
571 | QETH_IP_TYPE_NORMAL, | ||
572 | QETH_IP_TYPE_VIPA, | ||
573 | QETH_IP_TYPE_RXIP, | ||
574 | QETH_IP_TYPE_DEL_ALL_MC, | ||
575 | }; | ||
576 | |||
577 | enum qeth_cmd_buffer_state { | ||
578 | BUF_STATE_FREE, | ||
579 | BUF_STATE_LOCKED, | ||
580 | BUF_STATE_PROCESSED, | ||
581 | }; | ||
582 | /** | ||
583 | * IP address and multicast list | ||
584 | */ | ||
585 | struct qeth_ipaddr { | ||
586 | struct list_head entry; | ||
587 | enum qeth_ip_types type; | ||
588 | enum qeth_ipa_setdelip_flags set_flags; | ||
589 | enum qeth_ipa_setdelip_flags del_flags; | ||
590 | int is_multicast; | ||
591 | volatile int users; | ||
592 | enum qeth_prot_versions proto; | ||
593 | unsigned char mac[OSA_ADDR_LEN]; | ||
594 | union { | ||
595 | struct { | ||
596 | unsigned int addr; | ||
597 | unsigned int mask; | ||
598 | } a4; | ||
599 | struct { | ||
600 | struct in6_addr addr; | ||
601 | unsigned int pfxlen; | ||
602 | } a6; | ||
603 | } u; | ||
604 | }; | ||
605 | |||
606 | struct qeth_ipato_entry { | ||
607 | struct list_head entry; | ||
608 | enum qeth_prot_versions proto; | ||
609 | char addr[16]; | ||
610 | int mask_bits; | ||
611 | }; | ||
612 | |||
613 | struct qeth_ipato { | ||
614 | int enabled; | ||
615 | int invert4; | ||
616 | int invert6; | ||
617 | struct list_head entries; | ||
618 | }; | ||
619 | |||
620 | struct qeth_channel; | ||
621 | |||
622 | struct qeth_cmd_buffer { | ||
623 | enum qeth_cmd_buffer_state state; | ||
624 | struct qeth_channel *channel; | ||
625 | unsigned char *data; | ||
626 | int rc; | ||
627 | void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *); | ||
628 | }; | ||
629 | |||
630 | |||
631 | /** | ||
632 | * definition of a qeth channel, used for read and write | ||
633 | */ | ||
634 | struct qeth_channel { | ||
635 | enum qeth_channel_states state; | ||
636 | struct ccw1 ccw; | ||
637 | spinlock_t iob_lock; | ||
638 | wait_queue_head_t wait_q; | ||
639 | struct tasklet_struct irq_tasklet; | ||
640 | struct ccw_device *ccwdev; | ||
641 | /*command buffer for control data*/ | ||
642 | struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO]; | ||
643 | atomic_t irq_pending; | ||
644 | volatile int io_buf_no; | ||
645 | volatile int buf_no; | ||
646 | }; | ||
647 | |||
648 | /** | ||
649 | * OSA card related definitions | ||
650 | */ | ||
651 | struct qeth_token { | ||
652 | __u32 issuer_rm_w; | ||
653 | __u32 issuer_rm_r; | ||
654 | __u32 cm_filter_w; | ||
655 | __u32 cm_filter_r; | ||
656 | __u32 cm_connection_w; | ||
657 | __u32 cm_connection_r; | ||
658 | __u32 ulp_filter_w; | ||
659 | __u32 ulp_filter_r; | ||
660 | __u32 ulp_connection_w; | ||
661 | __u32 ulp_connection_r; | ||
662 | }; | ||
663 | |||
664 | struct qeth_seqno { | ||
665 | __u32 trans_hdr; | ||
666 | __u32 pdu_hdr; | ||
667 | __u32 pdu_hdr_ack; | ||
668 | __u16 ipa; | ||
669 | }; | ||
670 | |||
671 | struct qeth_reply { | ||
672 | struct list_head list; | ||
673 | wait_queue_head_t wait_q; | ||
674 | int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long); | ||
675 | u32 seqno; | ||
676 | unsigned long offset; | ||
677 | int received; | ||
678 | int rc; | ||
679 | void *param; | ||
680 | struct qeth_card *card; | ||
681 | atomic_t refcnt; | ||
682 | }; | ||
683 | |||
684 | #define QETH_BROADCAST_WITH_ECHO 1 | ||
685 | #define QETH_BROADCAST_WITHOUT_ECHO 2 | ||
686 | |||
687 | struct qeth_card_blkt { | ||
688 | int time_total; | ||
689 | int inter_packet; | ||
690 | int inter_packet_jumbo; | ||
691 | }; | ||
692 | |||
693 | |||
694 | |||
695 | struct qeth_card_info { | ||
696 | unsigned short unit_addr2; | ||
697 | unsigned short cula; | ||
698 | unsigned short chpid; | ||
699 | __u16 func_level; | ||
700 | char mcl_level[QETH_MCL_LENGTH + 1]; | ||
701 | int guestlan; | ||
702 | int layer2_mac_registered; | ||
703 | int portname_required; | ||
704 | int portno; | ||
705 | char portname[9]; | ||
706 | enum qeth_card_types type; | ||
707 | enum qeth_link_types link_type; | ||
708 | int is_multicast_different; | ||
709 | int initial_mtu; | ||
710 | int max_mtu; | ||
711 | int broadcast_capable; | ||
712 | int unique_id; | ||
713 | struct qeth_card_blkt blkt; | ||
714 | __u32 csum_mask; | ||
715 | }; | ||
716 | |||
717 | struct qeth_card_options { | ||
718 | struct qeth_routing_info route4; | ||
719 | struct qeth_ipa_info ipa4; | ||
720 | struct qeth_ipa_info adp; /*Adapter parameters*/ | ||
721 | #ifdef CONFIG_QETH_IPV6 | ||
722 | struct qeth_routing_info route6; | ||
723 | struct qeth_ipa_info ipa6; | ||
724 | #endif /* QETH_IPV6 */ | ||
725 | enum qeth_checksum_types checksum_type; | ||
726 | int broadcast_mode; | ||
727 | int macaddr_mode; | ||
728 | int fake_broadcast; | ||
729 | int add_hhlen; | ||
730 | int fake_ll; | ||
731 | int layer2; | ||
732 | enum qeth_large_send_types large_send; | ||
733 | }; | ||
734 | |||
735 | /* | ||
736 | * thread bits for qeth_card thread masks | ||
737 | */ | ||
738 | enum qeth_threads { | ||
739 | QETH_SET_IP_THREAD = 1, | ||
740 | QETH_RECOVER_THREAD = 2, | ||
741 | }; | ||
742 | |||
743 | struct qeth_card { | ||
744 | struct list_head list; | ||
745 | enum qeth_card_states state; | ||
746 | int lan_online; | ||
747 | spinlock_t lock; | ||
748 | /*hardware and sysfs stuff*/ | ||
749 | struct ccwgroup_device *gdev; | ||
750 | struct qeth_channel read; | ||
751 | struct qeth_channel write; | ||
752 | struct qeth_channel data; | ||
753 | |||
754 | struct net_device *dev; | ||
755 | struct net_device_stats stats; | ||
756 | |||
757 | struct qeth_card_info info; | ||
758 | struct qeth_token token; | ||
759 | struct qeth_seqno seqno; | ||
760 | struct qeth_card_options options; | ||
761 | |||
762 | wait_queue_head_t wait_q; | ||
763 | #ifdef CONFIG_QETH_VLAN | ||
764 | spinlock_t vlanlock; | ||
765 | struct vlan_group *vlangrp; | ||
766 | #endif | ||
767 | struct work_struct kernel_thread_starter; | ||
768 | spinlock_t thread_mask_lock; | ||
769 | volatile unsigned long thread_start_mask; | ||
770 | volatile unsigned long thread_allowed_mask; | ||
771 | volatile unsigned long thread_running_mask; | ||
772 | spinlock_t ip_lock; | ||
773 | struct list_head ip_list; | ||
774 | struct list_head *ip_tbd_list; | ||
775 | struct qeth_ipato ipato; | ||
776 | struct list_head cmd_waiter_list; | ||
777 | /* QDIO buffer handling */ | ||
778 | struct qeth_qdio_info qdio; | ||
779 | #ifdef CONFIG_QETH_PERF_STATS | ||
780 | struct qeth_perf_stats perf_stats; | ||
781 | #endif /* CONFIG_QETH_PERF_STATS */ | ||
782 | int use_hard_stop; | ||
783 | int (*orig_hard_header)(struct sk_buff *,struct net_device *, | ||
784 | unsigned short,void *,void *,unsigned); | ||
785 | }; | ||
786 | |||
787 | struct qeth_card_list_struct { | ||
788 | struct list_head list; | ||
789 | rwlock_t rwlock; | ||
790 | }; | ||
791 | |||
792 | extern struct qeth_card_list_struct qeth_card_list; | ||
793 | |||
794 | /*notifier list */ | ||
795 | struct qeth_notify_list_struct { | ||
796 | struct list_head list; | ||
797 | struct task_struct *task; | ||
798 | int signum; | ||
799 | }; | ||
800 | extern spinlock_t qeth_notify_lock; | ||
801 | extern struct list_head qeth_notify_list; | ||
802 | |||
803 | /*some helper functions*/ | ||
804 | |||
805 | #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "") | ||
806 | |||
807 | inline static __u8 | ||
808 | qeth_get_ipa_adp_type(enum qeth_link_types link_type) | ||
809 | { | ||
810 | switch (link_type) { | ||
811 | case QETH_LINK_TYPE_HSTR: | ||
812 | return 2; | ||
813 | default: | ||
814 | return 1; | ||
815 | } | ||
816 | } | ||
817 | |||
818 | inline static int | ||
819 | qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size) | ||
820 | { | ||
821 | struct sk_buff *new_skb = NULL; | ||
822 | |||
823 | if (skb_headroom(*skb) < size){ | ||
824 | new_skb = skb_realloc_headroom(*skb, size); | ||
825 | if (!new_skb) { | ||
826 | PRINT_ERR("qeth_prepare_skb: could " | ||
827 | "not realloc headroom for qeth_hdr " | ||
828 | "on interface %s", QETH_CARD_IFNAME(card)); | ||
829 | return -ENOMEM; | ||
830 | } | ||
831 | *skb = new_skb; | ||
832 | } | ||
833 | return 0; | ||
834 | } | ||
835 | static inline struct sk_buff * | ||
836 | qeth_pskb_unshare(struct sk_buff *skb, int pri) | ||
837 | { | ||
838 | struct sk_buff *nskb; | ||
839 | if (!skb_cloned(skb)) | ||
840 | return skb; | ||
841 | nskb = skb_copy(skb, pri); | ||
842 | kfree_skb(skb); /* free our shared copy */ | ||
843 | return nskb; | ||
844 | } | ||
845 | |||
846 | |||
847 | inline static void * | ||
848 | qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size) | ||
849 | { | ||
850 | void *hdr; | ||
851 | |||
852 | hdr = (void *) skb_push(*skb, size); | ||
853 | /* | ||
854 | * sanity check, the Linux memory allocation scheme should | ||
855 | * never present us cases like this one (the qdio header size plus | ||
856 | * the first 40 bytes of the paket cross a 4k boundary) | ||
857 | */ | ||
858 | if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) != | ||
859 | (((unsigned long) hdr + size + | ||
860 | QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) { | ||
861 | PRINT_ERR("qeth_prepare_skb: misaligned " | ||
862 | "packet on interface %s. Discarded.", | ||
863 | QETH_CARD_IFNAME(card)); | ||
864 | return NULL; | ||
865 | } | ||
866 | return hdr; | ||
867 | } | ||
868 | |||
869 | inline static int | ||
870 | qeth_get_hlen(__u8 link_type) | ||
871 | { | ||
872 | #ifdef CONFIG_QETH_IPV6 | ||
873 | switch (link_type) { | ||
874 | case QETH_LINK_TYPE_HSTR: | ||
875 | case QETH_LINK_TYPE_LANE_TR: | ||
876 | return sizeof(struct qeth_hdr) + TR_HLEN; | ||
877 | default: | ||
878 | #ifdef CONFIG_QETH_VLAN | ||
879 | return sizeof(struct qeth_hdr) + VLAN_ETH_HLEN; | ||
880 | #else | ||
881 | return sizeof(struct qeth_hdr) + ETH_HLEN; | ||
882 | #endif | ||
883 | } | ||
884 | #else /* CONFIG_QETH_IPV6 */ | ||
885 | #ifdef CONFIG_QETH_VLAN | ||
886 | return sizeof(struct qeth_hdr) + VLAN_HLEN; | ||
887 | #else | ||
888 | return sizeof(struct qeth_hdr); | ||
889 | #endif | ||
890 | #endif /* CONFIG_QETH_IPV6 */ | ||
891 | } | ||
892 | |||
893 | inline static unsigned short | ||
894 | qeth_get_netdev_flags(struct qeth_card *card) | ||
895 | { | ||
896 | if (card->options.layer2) | ||
897 | return 0; | ||
898 | switch (card->info.type) { | ||
899 | case QETH_CARD_TYPE_IQD: | ||
900 | return IFF_NOARP; | ||
901 | #ifdef CONFIG_QETH_IPV6 | ||
902 | default: | ||
903 | return 0; | ||
904 | #else | ||
905 | default: | ||
906 | return IFF_NOARP; | ||
907 | #endif | ||
908 | } | ||
909 | } | ||
910 | |||
911 | inline static int | ||
912 | qeth_get_initial_mtu_for_card(struct qeth_card * card) | ||
913 | { | ||
914 | switch (card->info.type) { | ||
915 | case QETH_CARD_TYPE_UNKNOWN: | ||
916 | return 1500; | ||
917 | case QETH_CARD_TYPE_IQD: | ||
918 | return card->info.max_mtu; | ||
919 | case QETH_CARD_TYPE_OSAE: | ||
920 | switch (card->info.link_type) { | ||
921 | case QETH_LINK_TYPE_HSTR: | ||
922 | case QETH_LINK_TYPE_LANE_TR: | ||
923 | return 2000; | ||
924 | default: | ||
925 | return 1492; | ||
926 | } | ||
927 | default: | ||
928 | return 1500; | ||
929 | } | ||
930 | } | ||
931 | |||
932 | inline static int | ||
933 | qeth_get_max_mtu_for_card(int cardtype) | ||
934 | { | ||
935 | switch (cardtype) { | ||
936 | case QETH_CARD_TYPE_UNKNOWN: | ||
937 | return 61440; | ||
938 | case QETH_CARD_TYPE_OSAE: | ||
939 | return 61440; | ||
940 | case QETH_CARD_TYPE_IQD: | ||
941 | return 57344; | ||
942 | default: | ||
943 | return 1500; | ||
944 | } | ||
945 | } | ||
946 | |||
947 | inline static int | ||
948 | qeth_get_mtu_out_of_mpc(int cardtype) | ||
949 | { | ||
950 | switch (cardtype) { | ||
951 | case QETH_CARD_TYPE_IQD: | ||
952 | return 1; | ||
953 | default: | ||
954 | return 0; | ||
955 | } | ||
956 | } | ||
957 | |||
958 | inline static int | ||
959 | qeth_get_mtu_outof_framesize(int framesize) | ||
960 | { | ||
961 | switch (framesize) { | ||
962 | case 0x4000: | ||
963 | return 8192; | ||
964 | case 0x6000: | ||
965 | return 16384; | ||
966 | case 0xa000: | ||
967 | return 32768; | ||
968 | case 0xffff: | ||
969 | return 57344; | ||
970 | default: | ||
971 | return 0; | ||
972 | } | ||
973 | } | ||
974 | |||
975 | inline static int | ||
976 | qeth_mtu_is_valid(struct qeth_card * card, int mtu) | ||
977 | { | ||
978 | switch (card->info.type) { | ||
979 | case QETH_CARD_TYPE_OSAE: | ||
980 | return ((mtu >= 576) && (mtu <= 61440)); | ||
981 | case QETH_CARD_TYPE_IQD: | ||
982 | return ((mtu >= 576) && | ||
983 | (mtu <= card->info.max_mtu + 4096 - 32)); | ||
984 | case QETH_CARD_TYPE_UNKNOWN: | ||
985 | default: | ||
986 | return 1; | ||
987 | } | ||
988 | } | ||
989 | |||
990 | inline static int | ||
991 | qeth_get_arphdr_type(int cardtype, int linktype) | ||
992 | { | ||
993 | switch (cardtype) { | ||
994 | case QETH_CARD_TYPE_OSAE: | ||
995 | switch (linktype) { | ||
996 | case QETH_LINK_TYPE_LANE_TR: | ||
997 | case QETH_LINK_TYPE_HSTR: | ||
998 | return ARPHRD_IEEE802_TR; | ||
999 | default: | ||
1000 | return ARPHRD_ETHER; | ||
1001 | } | ||
1002 | case QETH_CARD_TYPE_IQD: | ||
1003 | default: | ||
1004 | return ARPHRD_ETHER; | ||
1005 | } | ||
1006 | } | ||
1007 | |||
1008 | #ifdef CONFIG_QETH_PERF_STATS | ||
1009 | inline static int | ||
1010 | qeth_get_micros(void) | ||
1011 | { | ||
1012 | return (int) (get_clock() >> 12); | ||
1013 | } | ||
1014 | #endif | ||
1015 | |||
1016 | static inline int | ||
1017 | qeth_get_qdio_q_format(struct qeth_card *card) | ||
1018 | { | ||
1019 | switch (card->info.type) { | ||
1020 | case QETH_CARD_TYPE_IQD: | ||
1021 | return 2; | ||
1022 | default: | ||
1023 | return 0; | ||
1024 | } | ||
1025 | } | ||
1026 | |||
1027 | static inline void | ||
1028 | qeth_ipaddr4_to_string(const __u8 *addr, char *buf) | ||
1029 | { | ||
1030 | sprintf(buf, "%i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]); | ||
1031 | } | ||
1032 | |||
1033 | static inline int | ||
1034 | qeth_string_to_ipaddr4(const char *buf, __u8 *addr) | ||
1035 | { | ||
1036 | const char *start, *end; | ||
1037 | char abuf[4]; | ||
1038 | char *tmp; | ||
1039 | int len; | ||
1040 | int i; | ||
1041 | |||
1042 | start = buf; | ||
1043 | for (i = 0; i < 3; i++) { | ||
1044 | if (!(end = strchr(start, '.'))) | ||
1045 | return -EINVAL; | ||
1046 | len = end - start; | ||
1047 | memset(abuf, 0, 4); | ||
1048 | strncpy(abuf, start, len); | ||
1049 | addr[i] = simple_strtoul(abuf, &tmp, 10); | ||
1050 | start = end + 1; | ||
1051 | } | ||
1052 | memset(abuf, 0, 4); | ||
1053 | strcpy(abuf, start); | ||
1054 | addr[3] = simple_strtoul(abuf, &tmp, 10); | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | static inline void | ||
1059 | qeth_ipaddr6_to_string(const __u8 *addr, char *buf) | ||
1060 | { | ||
1061 | sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x" | ||
1062 | ":%02x%02x:%02x%02x:%02x%02x:%02x%02x", | ||
1063 | addr[0], addr[1], addr[2], addr[3], | ||
1064 | addr[4], addr[5], addr[6], addr[7], | ||
1065 | addr[8], addr[9], addr[10], addr[11], | ||
1066 | addr[12], addr[13], addr[14], addr[15]); | ||
1067 | } | ||
1068 | |||
1069 | static inline int | ||
1070 | qeth_string_to_ipaddr6(const char *buf, __u8 *addr) | ||
1071 | { | ||
1072 | const char *start, *end; | ||
1073 | u16 *tmp_addr; | ||
1074 | char abuf[5]; | ||
1075 | char *tmp; | ||
1076 | int len; | ||
1077 | int i; | ||
1078 | |||
1079 | tmp_addr = (u16 *)addr; | ||
1080 | start = buf; | ||
1081 | for (i = 0; i < 7; i++) { | ||
1082 | if (!(end = strchr(start, ':'))) | ||
1083 | return -EINVAL; | ||
1084 | len = end - start; | ||
1085 | memset(abuf, 0, 5); | ||
1086 | strncpy(abuf, start, len); | ||
1087 | tmp_addr[i] = simple_strtoul(abuf, &tmp, 16); | ||
1088 | start = end + 1; | ||
1089 | } | ||
1090 | memset(abuf, 0, 5); | ||
1091 | strcpy(abuf, start); | ||
1092 | tmp_addr[7] = simple_strtoul(abuf, &tmp, 16); | ||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | static inline void | ||
1097 | qeth_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr, | ||
1098 | char *buf) | ||
1099 | { | ||
1100 | if (proto == QETH_PROT_IPV4) | ||
1101 | return qeth_ipaddr4_to_string(addr, buf); | ||
1102 | else if (proto == QETH_PROT_IPV6) | ||
1103 | return qeth_ipaddr6_to_string(addr, buf); | ||
1104 | } | ||
1105 | |||
1106 | static inline int | ||
1107 | qeth_string_to_ipaddr(const char *buf, enum qeth_prot_versions proto, | ||
1108 | __u8 *addr) | ||
1109 | { | ||
1110 | if (proto == QETH_PROT_IPV4) | ||
1111 | return qeth_string_to_ipaddr4(buf, addr); | ||
1112 | else if (proto == QETH_PROT_IPV6) | ||
1113 | return qeth_string_to_ipaddr6(buf, addr); | ||
1114 | else | ||
1115 | return -EINVAL; | ||
1116 | } | ||
1117 | |||
1118 | extern int | ||
1119 | qeth_setrouting_v4(struct qeth_card *); | ||
1120 | extern int | ||
1121 | qeth_setrouting_v6(struct qeth_card *); | ||
1122 | |||
1123 | extern int | ||
1124 | qeth_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *); | ||
1125 | |||
1126 | extern void | ||
1127 | qeth_del_ipato_entry(struct qeth_card *, enum qeth_prot_versions, u8 *, int); | ||
1128 | |||
1129 | extern int | ||
1130 | qeth_add_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *); | ||
1131 | |||
1132 | extern void | ||
1133 | qeth_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *); | ||
1134 | |||
1135 | extern int | ||
1136 | qeth_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *); | ||
1137 | |||
1138 | extern void | ||
1139 | qeth_del_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *); | ||
1140 | |||
1141 | extern int | ||
1142 | qeth_notifier_register(struct task_struct *, int ); | ||
1143 | |||
1144 | extern int | ||
1145 | qeth_notifier_unregister(struct task_struct * ); | ||
1146 | |||
1147 | extern void | ||
1148 | qeth_schedule_recovery(struct qeth_card *); | ||
1149 | |||
1150 | extern int | ||
1151 | qeth_realloc_buffer_pool(struct qeth_card *, int); | ||
1152 | |||
1153 | extern int | ||
1154 | qeth_set_large_send(struct qeth_card *); | ||
1155 | |||
1156 | extern void | ||
1157 | qeth_fill_header(struct qeth_card *, struct qeth_hdr *, | ||
1158 | struct sk_buff *, int, int); | ||
1159 | extern void | ||
1160 | qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int); | ||
1161 | |||
1162 | #endif /* __QETH_H__ */ | ||