1 /*
2 *
3 * linux/drivers/s390/net/qeth.c ($Revision: 1.337.4.24 $)
4 *
5 * Linux on zSeries OSA Express and HiperSockets support
6 *
7 * Copyright 2000,2003 IBM Corporation
8 *
9 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
10 * Cornelia Huck <cohuck@de.ibm.com> (chandev stuff,
11 * numerous bugfixes)
12 * Frank Pavlic <pavlic@de.ibm.com> (query/purge ARP, SNMP, fixes)
13 * Andreas Herrmann <aherrman@de.ibm.com> (bugfixes)
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30 /*
31 * For all devices, three channels must be available to the driver. One
32 * channel is the read channel, one is the write channel and the third
33 * one is the channel used to control QDIO.
34 *
35 * There are several stages from the channel recognition to the running
36 * network device:
37 * - The channels are scanned and ordered due to the parameters (see
38 * MODULE_PARM_DESC)
39 * - The card is hardsetup: this means, that the communication channels
40 * are prepared
41 * - The card is softsetup: this means, that commands are issued
42 * to activate the network parameters
43 * - After that, data can flow through the card (transported by QDIO)
44 *
45 *IPA Takeover:
46 * /proc/qeth_ipa_takeover provides the possibility to add and remove
47 * certain ranges of IP addresses to the driver. As soon as these
48 * addresses have to be set by the driver, the driver uses the OSA
49 * Address Takeover mechanism.
50 * reading out of the proc-file displays the registered addresses;
51 * writing into it changes the information. Only one command at one
52 * time must be written into the file. Subsequent commands are ignored.
53 * The following commands are available:
54 * inv4
55 * inv6
56 * add4 <ADDR>/<mask bits>[:<interface>]
57 * add6 <ADDR>/<mask bits>[:<interface>]
58 * del4 <ADDR>/<mask bits>[:<interface>]
59 * del6 <ADDR>/<mask bits>[:<interface>]
60 * inv4 and inv6 toggle the IPA takeover behaviour for all interfaces:
61 * when inv4 was input once, all addresses specified with add4 are not
62 * set using the takeover mechanism, but all other IPv4 addresses are set so.
63 *
64 * add# adds an address range, del# deletes an address range. # corresponds
65 * to the IP version (4 or 6).
66 * <ADDR> is a 8 or 32byte hexadecimal view of the IP address.
67 * <mask bits> specifies the number of bits which are set in the network mask.
68 * <interface> is optional and specifies the interface name to which the
69 * address range is bound.
70 * E. g.
71 * add4 C0a80100/24
72 * activates all addresses in the 192.168.10 subnet for address takeover.
73 * Note, that the address is not taken over before an according ifconfig
74 * is executed.
75 *
76 *VIPA:
77 * add_vipa4 <ADDR>:<interface>
78 * add_vipa6 <ADDR>:<interface>
79 * del_vipa4 <ADDR>:<interface>
80 * del_vipa6 <ADDR>:<interface>
81 *
82 * the specified address is set/unset as VIPA on the specified interface.
83 * use the src_vipa package to exploit this out of arbitrary applications.
84 *
85 *Proxy ARP:
86 *
87 * add_rxip4 <ADDR>:<interface>
88 * add_rxip6 <ADDR>:<interface>
89 * del_rxip4 <ADDR>:<interface>
90 * del_rxip6 <ADDR>:<interface>
91 *
92 * the specified address is set/unset as "do not fail a gratuitous ARP"
93 * on the specified interface. this can be used to act as a proxy ARP.
94 */
95
qeth_eyecatcher(void)96 void volatile qeth_eyecatcher(void)
97 {
98 return;
99 }
100
101 #include <linux/config.h>
102
103 #ifndef CONFIG_CHANDEV
104 #error "qeth can only be compiled with chandev support"
105 #endif /* CONFIG_CHANDEV */
106
107 #include <linux/module.h>
108
109 #include <linux/string.h>
110 #include <linux/errno.h>
111 #include <linux/mm.h>
112
113 #include <linux/version.h>
114
115 #include <asm/io.h>
116 #include <asm/ebcdic.h>
117 #include <linux/ctype.h>
118 #include <asm/semaphore.h>
119 #include <linux/if.h>
120 #include <linux/if_arp.h>
121 #include <linux/ip.h>
122 #include <linux/inetdevice.h>
123 #include <linux/netdevice.h>
124 #include <linux/sched.h>
125 #include <linux/kernel.h>
126 #include <linux/slab.h>
127 #include <linux/interrupt.h>
128 #include <linux/tcp.h>
129 #include <linux/icmp.h>
130 #include <linux/skbuff.h>
131 #ifdef CONFIG_PROC_FS
132 #include <linux/proc_fs.h>
133 #endif /* CONFIG_PROC_FS */
134 #include <net/route.h>
135 #include <net/arp.h>
136 #include <linux/in.h>
137 #include <linux/igmp.h>
138 #include <net/ip.h>
139 #include <asm/uaccess.h>
140 #include <linux/init.h>
141 #include <net/ipv6.h>
142 #include <linux/in6.h>
143 #include <net/if_inet6.h>
144 #include <net/addrconf.h>
145 #include <linux/if_tr.h>
146 #include <linux/trdevice.h>
147 #include <linux/etherdevice.h>
148 #include <linux/reboot.h>
149
150 #include <linux/if_vlan.h>
151 #include <asm/chandev.h>
152
153 #include <asm/irq.h>
154 #include <asm/s390dyn.h>
155 #include <asm/debug.h>
156 #include <asm/processor.h>
157
158 #include <asm/qdio.h>
159
160 #include "qeth_mpc.h"
161 #include "qeth.h"
162
163 /****************** MODULE PARAMETER VARIABLES ********************/
164 static int qeth_sparebufs=0;
165 MODULE_PARM(qeth_sparebufs,"i");
166 MODULE_PARM_DESC(qeth_sparebufs,"the number of pre-allocated spare buffers " \
167 "reserved for low memory situations");
168
169 static int global_stay_in_mem=0;
170
171 /****************** MODULE STUFF **********************************/
172 #define VERSION_QETH_C "$Revision: 1.337.4.24 $"
173 static const char *version="qeth S/390 OSA-Express driver (" \
174 VERSION_QETH_C "/" VERSION_QETH_H "/" VERSION_QETH_MPC_H
175 QETH_VERSION_IPV6 QETH_VERSION_VLAN ")";
176
177 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
178 MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \
179 "Copyright 2000,2003 IBM Corporation\n");
180 MODULE_LICENSE("GPL");
181
182 /******************** HERE WE GO ***********************************/
183
184
185
186 static qeth_card_t *firstcard=NULL;
187
188 static sparebufs_t sparebufs[MAX_SPARE_BUFFERS];
189 static int sparebuffer_count;
190
191 static unsigned int known_devices[][10]=QETH_MODELLIST_ARRAY;
192
193 static spinlock_t setup_lock;
194 static rwlock_t list_lock=RW_LOCK_UNLOCKED;
195
196 static debug_info_t *qeth_dbf_setup=NULL;
197 static debug_info_t *qeth_dbf_data=NULL;
198 static debug_info_t *qeth_dbf_misc=NULL;
199 static debug_info_t *qeth_dbf_control=NULL;
200 static debug_info_t *qeth_dbf_trace=NULL;
201 static debug_info_t *qeth_dbf_sense=NULL;
202 static debug_info_t *qeth_dbf_qerr=NULL;
203
204 static int proc_file_registration;
205 #ifdef QETH_PERFORMANCE_STATS
206 static int proc_perf_file_registration;
207 #define NOW qeth_get_micros()
208 #endif /* QETH_PERFORMANCE_STATS */
209 static int proc_ipato_file_registration;
210
211 static int ipato_inv4=0,ipato_inv6=0;
212 static ipato_entry_t *ipato_entries=NULL;
213 static spinlock_t ipato_list_lock;
214
215 typedef struct {
216 char *data;
217 int len;
218 } tempinfo_t;
219
220 /* thought I could get along without forward declarations...
221 * just lazyness here */
222 static int qeth_reinit_thread(void*);
223 static inline void qeth_schedule_recovery(qeth_card_t *card);
224 static int qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
225 unsigned short type, void *daddr, void *saddr,
226 unsigned len);
227
QETH_IP_VERSION(struct sk_buff * skb)228 static inline int QETH_IP_VERSION(struct sk_buff *skb)
229 {
230 switch (skb->protocol) {
231 case ETH_P_IPV6: return 6;
232 case ETH_P_IP: return 4;
233 default: return 0;
234 }
235 }
236 /* not a macro, as one of the arguments is atomic_read */
qeth_min(int a,int b)237 static inline int qeth_min(int a,int b)
238 {
239 if (a<b)
240 return a;
241 else
242 return b;
243 }
244
245 /*
246 * This is our local skb_unshare, only with pskb_copy instead of skb_copy.
247 * We place our headers whare Ethernet MAC was, so we do not need
248 * full skb_copy.
249 */
qeth_pskb_unshare(struct sk_buff * skb,int pri)250 static inline struct sk_buff *qeth_pskb_unshare(struct sk_buff *skb, int pri)
251 {
252 struct sk_buff *nskb;
253 if (!skb_cloned(skb))
254 return skb;
255 nskb = skb_copy(skb, pri);
256 kfree_skb(skb); /* free our shared copy */
257 return nskb;
258 }
259
qeth_get_millis(void)260 static inline unsigned int qeth_get_millis(void)
261 {
262 __u64 time;
263
264 asm volatile ("STCK %0" : "=m" (time));
265 return (int) (time>>22); /* time>>12 is microseconds, we divide it
266 by 1024 */
267 }
268
269 #ifdef QETH_PERFORMANCE_STATS
qeth_get_micros(void)270 static inline unsigned int qeth_get_micros(void)
271 {
272 __u64 time;
273
274 asm volatile ("STCK %0" : "=m" (time));
275 return (int) (time>>12);
276 }
277 #endif /* QETH_PERFORMANCE_STATS */
278
qeth_delay_millis(unsigned long msecs)279 static void qeth_delay_millis(unsigned long msecs)
280 {
281 unsigned int start;
282
283 start=qeth_get_millis();
284 while (qeth_get_millis()-start<msecs)
285 ;
286 }
287
qeth_wait_nonbusy(unsigned int timeout)288 static void qeth_wait_nonbusy(unsigned int timeout)
289 {
290 unsigned int start;
291 char dbf_text[15];
292
293 sprintf(dbf_text,"wtnb%4x",timeout);
294 QETH_DBF_TEXT3(0,trace,dbf_text);
295
296 start=qeth_get_millis();
297 for (;;) {
298 set_task_state(current,TASK_INTERRUPTIBLE);
299 if (qeth_get_millis()-start>timeout) {
300 goto out;
301 }
302 schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ);
303 }
304 out:
305 set_task_state(current,TASK_RUNNING);
306 }
307
qeth_get_mac_for_ipm(__u32 ipm,char * mac,struct net_device * dev)308 static inline void qeth_get_mac_for_ipm(__u32 ipm,char *mac,
309 struct net_device *dev) {
310 if (dev->type==ARPHRD_IEEE802_TR)
311 ip_tr_mc_map(ipm,mac);
312 else
313 ip_eth_mc_map(ipm,mac);
314 }
315
316 #define HEXDUMP16(importance,header,ptr) \
317 PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
318 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
319 *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
320 *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
321 *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
322 *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
323 *(((char*)ptr)+12),*(((char*)ptr)+13), \
324 *(((char*)ptr)+14),*(((char*)ptr)+15)); \
325 PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
326 "%02x %02x %02x %02x %02x %02x %02x %02x\n", \
327 *(((char*)ptr)+16),*(((char*)ptr)+17), \
328 *(((char*)ptr)+18),*(((char*)ptr)+19), \
329 *(((char*)ptr)+20),*(((char*)ptr)+21), \
330 *(((char*)ptr)+22),*(((char*)ptr)+23), \
331 *(((char*)ptr)+24),*(((char*)ptr)+25), \
332 *(((char*)ptr)+26),*(((char*)ptr)+27), \
333 *(((char*)ptr)+28),*(((char*)ptr)+29), \
334 *(((char*)ptr)+30),*(((char*)ptr)+31));
335
336 #define atomic_swap(a,b) xchg((int*)a.counter,b)
337
338 #ifdef QETH_DBF_LIKE_HELL
339
340 #define my_read_lock(x) do { \
341 void *ptr=x; \
342 QETH_DBF_TEXT6(0,trace,"rd_lck"); \
343 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
344 read_lock(x); \
345 } while (0)
346 #define my_read_unlock(x) do { \
347 void *ptr=x; \
348 QETH_DBF_TEXT6(0,trace,"rd_unlck"); \
349 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
350 read_unlock(x); \
351 } while (0)
352 #define my_write_lock(x) do { \
353 void *ptr=x; \
354 QETH_DBF_TEXT6(0,trace,"wr_lck"); \
355 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
356 write_lock(x); \
357 } while (0)
358 #define my_write_unlock(x) do { \
359 void *ptr=x; \
360 QETH_DBF_TEXT6(0,trace,"wr_unlck"); \
361 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
362 write_unlock(x); \
363 } while (0)
364
365 #define my_spin_lock(x) do { \
366 void *ptr=x; \
367 QETH_DBF_TEXT6(0,trace,"sp_lck"); \
368 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
369 spin_lock(x); \
370 } while (0)
371 #define my_spin_unlock(x) do { \
372 void *ptr=x; \
373 QETH_DBF_TEXT6(0,trace,"sp_unlck"); \
374 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
375 spin_unlock(x); \
376 } while (0)
377 #define my_spin_lock_irqsave(x,y) do { \
378 void *ptr=x; \
379 QETH_DBF_TEXT6(0,trace,"sp_lck_i"); \
380 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
381 spin_lock_irqsave(x,y); \
382 } while (0)
383 #define my_spin_unlock_irqrestore(x,y) do { \
384 void *ptr=x; \
385 QETH_DBF_TEXT6(0,trace,"sp_nlk_i"); \
386 QETH_DBF_HEX6(0,trace,&ptr,sizeof(void*)); \
387 spin_unlock_irqrestore(x,y); \
388 } while (0)
389
390 #else /* QETH_DBF_LIKE_HELL */
391
392 #define my_read_lock(x) read_lock(x)
393 #define my_write_lock(x) write_lock(x)
394 #define my_read_unlock(x) read_unlock(x)
395 #define my_write_unlock(x) write_unlock(x)
396
397 #define my_spin_lock(x) spin_lock(x)
398 #define my_spin_unlock(x) spin_unlock(x)
399 #define my_spin_lock_irqsave(x,y) spin_lock_irqsave(x,y)
400 #define my_spin_unlock_irqrestore(x,y) spin_unlock_irqrestore(x,y)
401
402 #endif /* QETH_DBF_LIKE_HELL */
403
my_spin_lock_nonbusy(qeth_card_t * card,spinlock_t * lock)404 static int inline my_spin_lock_nonbusy(qeth_card_t *card,spinlock_t *lock)
405 {
406 for (;;) {
407 if (card) {
408 if (atomic_read(&card->shutdown_phase)) return -1;
409 }
410 if (spin_trylock(lock)) return 0;
411 qeth_wait_nonbusy(QETH_IDLE_WAIT_TIME);
412 }
413 }
414
415 #ifdef CONFIG_ARCH_S390X
416 #define QETH_GET_ADDR(x) ((__u32)(unsigned long)x)
417 #else /* CONFIG_ARCH_S390X */
418 #define QETH_GET_ADDR(x) ((__u32)x)
419 #endif /* CONFIG_ARCH_S390X */
420
qeth_does_card_exist(qeth_card_t * card)421 static inline int qeth_does_card_exist(qeth_card_t *card)
422 {
423 qeth_card_t *c=firstcard;
424 int rc=0;
425
426 my_read_lock(&list_lock);
427 while (c) {
428 if (c==card) {
429 rc=1;
430 break;
431 }
432 c=c->next;
433 }
434 my_read_unlock(&list_lock);
435 return rc;
436 }
437
qeth_get_card_by_irq(int irq)438 static inline qeth_card_t *qeth_get_card_by_irq(int irq)
439 {
440 qeth_card_t *card;
441
442 my_read_lock(&list_lock);
443 card=firstcard;
444 while (card) {
445 if ((card->irq0==irq)&&
446 (atomic_read(&card->shutdown_phase)!=
447 QETH_REMOVE_CARD_QUICK)) break;
448 if ((card->irq1==irq)&&
449 (atomic_read(&card->shutdown_phase)!=
450 QETH_REMOVE_CARD_QUICK)) break;
451 if ((card->irq2==irq)&&
452 (atomic_read(&card->shutdown_phase)!=
453 QETH_REMOVE_CARD_QUICK)) break;
454 card=card->next;
455 }
456 my_read_unlock(&list_lock);
457
458 return card;
459 }
460
qeth_getxdigit(char c)461 static int qeth_getxdigit(char c)
462 {
463 if ((c>='0') && (c<='9')) return c-'0';
464 if ((c>='a') && (c<='f')) return c+10-'a';
465 if ((c>='A') && (c<='F')) return c+10-'A';
466 return -1;
467 }
468
qeth_get_card_by_name(char * name)469 static qeth_card_t *qeth_get_card_by_name(char *name)
470 {
471 qeth_card_t *card;
472
473 my_read_lock(&list_lock);
474 card=firstcard;
475 while (card) {
476 if (!strncmp(name,card->dev_name,DEV_NAME_LEN)) break;
477 card=card->next;
478 }
479 my_read_unlock(&list_lock);
480
481 return card;
482 }
483
qeth_convert_addr_to_text(int version,__u8 * addr,char * text)484 static void qeth_convert_addr_to_text(int version,__u8 *addr,char *text)
485 {
486 if (version==4) {
487 sprintf(text,"%02x%02x%02x%02x",
488 addr[0],addr[1],addr[2],addr[3]);
489 } else {
490 sprintf(text,"%02x%02x%02x%02x%02x%02x%02x%02x" \
491 "%02x%02x%02x%02x%02x%02x%02x%02x",
492 addr[0],addr[1],addr[2],addr[3],
493 addr[4],addr[5],addr[6],addr[7],
494 addr[8],addr[9],addr[10],addr[11],
495 addr[12],addr[13],addr[14],addr[15]);
496 }
497 }
498
qeth_convert_text_to_addr(int version,char * text,__u8 * addr)499 static int qeth_convert_text_to_addr(int version,char *text,__u8 *addr)
500 {
501 int olen=(version==4)?4:16;
502
503 while (olen--) {
504 if ( (!isxdigit(*text)) || (!isxdigit(*(text+1))) )
505 return -EINVAL;
506 *addr=(qeth_getxdigit(*text)<<4)+qeth_getxdigit(*(text+1));
507 addr++;
508 text+=2;
509 }
510 return 0;
511 }
512
qeth_add_ipato_entry(int version,__u8 * addr,int mask_bits,char * dev_name)513 static void qeth_add_ipato_entry(int version,__u8 *addr,int mask_bits,
514 char *dev_name)
515 {
516 ipato_entry_t *entry,*e;
517 int len=(version==4)?4:16;
518
519 entry=(ipato_entry_t*)kmalloc(sizeof(ipato_entry_t),GFP_KERNEL);
520 if (!entry) {
521 PRINT_ERR("not enough memory for ipato allocation\n");
522 return;
523 }
524 entry->version=version;
525 memcpy(entry->addr,addr,len);
526 if (dev_name) {
527 strncpy(entry->dev_name,dev_name,DEV_NAME_LEN);
528 if (qeth_get_card_by_name(dev_name)->options.ena_ipat!=
529 ENABLE_TAKEOVER)
530 PRINT_WARN("IP takeover is not enabled on %s! " \
531 "Ignoring line\n",dev_name);
532 } else
533 memset(entry->dev_name,0,DEV_NAME_LEN);
534 entry->mask_bits=mask_bits;
535 entry->next=NULL;
536
537 my_spin_lock(&ipato_list_lock);
538 if (ipato_entries) {
539 e=ipato_entries;
540 while (e) {
541 if ( (e->version==version) &&
542 (e->mask_bits==mask_bits) &&
543 ( ((dev_name)&&!strncmp(e->dev_name,dev_name,
544 DEV_NAME_LEN)) ||
545 (!dev_name) ) &&
546 (!memcmp(e->addr,addr,len)) ) {
547 PRINT_INFO("ipato to be added does already " \
548 "exist\n");
549 kfree(entry);
550 goto out;
551 }
552 if (e->next) e=e->next; else break;
553 }
554 e->next=entry;
555 } else
556 ipato_entries=entry;
557 out:
558 my_spin_unlock(&ipato_list_lock);
559 }
560
qeth_del_ipato_entry(int version,__u8 * addr,int mask_bits,char * dev_name)561 static void qeth_del_ipato_entry(int version,__u8 *addr,int mask_bits,
562 char *dev_name)
563 {
564 ipato_entry_t *e,*e_before;
565 int len=(version==4)?4:16;
566 int found=0;
567
568 my_spin_lock(&ipato_list_lock);
569 e=ipato_entries;
570 if ( (e->version==version) &&
571 (e->mask_bits==mask_bits) &&
572 (!memcmp(e->addr,addr,len)) ) {
573 ipato_entries=e->next;
574 kfree(e);
575 } else while (e) {
576 e_before=e;
577 e=e->next;
578 if (!e) break;
579 if ( (e->version==version) &&
580 (e->mask_bits==mask_bits) &&
581 ( ((dev_name)&&!strncmp(e->dev_name,dev_name,
582 DEV_NAME_LEN)) ||
583 (!dev_name) ) &&
584 (!memcmp(e->addr,addr,len)) ) {
585 e_before->next=e->next;
586 kfree(e);
587 found=1;
588 break;
589 }
590 }
591 if (!found)
592 PRINT_INFO("ipato to be deleted does not exist\n");
593 my_spin_unlock(&ipato_list_lock);
594 }
595
qeth_convert_addr_to_bits(__u8 * addr,char * bits,int len)596 static void qeth_convert_addr_to_bits(__u8 *addr,char *bits,int len)
597 {
598 int i,j;
599 __u8 octet;
600
601 for (i=0;i<len;i++) {
602 octet=addr[i];
603 for (j=7;j>=0;j--) {
604 bits[i*8+j]=(octet&1)?1:0;
605 octet>>=1;
606 }
607 }
608 }
609
qeth_is_ipa_covered_by_ipato_entries(int version,__u8 * addr,qeth_card_t * card)610 static int qeth_is_ipa_covered_by_ipato_entries(int version,__u8 *addr,
611 qeth_card_t *card)
612 {
613 char *memarea,*addr_bits,*entry_bits;
614 int len=(version==4)?4:16;
615 int invert=(version==4)?ipato_inv4:ipato_inv6;
616 int result=0;
617 ipato_entry_t *e;
618
619 if (card->options.ena_ipat!=ENABLE_TAKEOVER) {
620 return 0;
621 }
622
623 memarea=kmalloc(256,GFP_KERNEL);
624 if (!memarea) {
625 PRINT_ERR("not enough memory to check out whether to " \
626 "use ipato\n");
627 return 0;
628 }
629 addr_bits=memarea;
630 entry_bits=memarea+128;
631 qeth_convert_addr_to_bits(addr,addr_bits,len);
632 e=ipato_entries;
633 while (e) {
634 qeth_convert_addr_to_bits(e->addr,entry_bits,len);
635 if ( (!memcmp(addr_bits,entry_bits,
636 __min(len*8,e->mask_bits))) &&
637 ( (e->dev_name[0]&&
638 (!strncmp(e->dev_name,card->dev_name,DEV_NAME_LEN))) ||
639 (!e->dev_name[0]) ) ) {
640 result=1;
641 break;
642 }
643 e=e->next;
644 }
645
646 kfree(memarea);
647 if (invert)
648 return !result;
649 else
650 return result;
651 }
652
qeth_set_dev_flag_running(qeth_card_t * card)653 static void qeth_set_dev_flag_running(qeth_card_t *card)
654 {
655 if (card) {
656 card->dev->flags|=IFF_RUNNING;
657 /*
658 clear_bit(__LINK_STATE_DOWN,&dev->flags);
659 */
660 }
661 }
662
qeth_set_dev_flag_norunning(qeth_card_t * card)663 static void qeth_set_dev_flag_norunning(qeth_card_t *card)
664 {
665 if (card) {
666 card->dev->flags&=~IFF_RUNNING;
667 /*
668 set_bit(__LINK_STATE_DOWN,&dev->flags);
669 */
670 }
671 }
672
qeth_restore_dev_flag_state(qeth_card_t * card)673 static void qeth_restore_dev_flag_state(qeth_card_t *card)
674 {
675 if (card) {
676 if (card->saved_dev_flags&IFF_RUNNING)
677 card->dev->flags|=IFF_RUNNING;
678 else
679 card->dev->flags&=~IFF_RUNNING;
680 /*
681 if (card->saved_dev_flags&__LINK_STATE_DOWN)
682 set_bit(__LINK_STATE_DOWN,&card->dev->flags);
683 else
684 clear_bit(__LINK_STATE_DOWN,&card->dev->flags);
685 */
686 }
687 }
688
qeth_save_dev_flag_state(qeth_card_t * card)689 static void qeth_save_dev_flag_state(qeth_card_t *card)
690 {
691 if (card) {
692 card->saved_dev_flags=card->dev->flags&IFF_RUNNING;
693 /*
694 card->saved_dev_flags=card->dev->flags&__LINK_STATE_DOWN;
695 */
696 }
697 }
698
netif_is_busy(struct net_device * dev)699 static inline int netif_is_busy(struct net_device *dev)
700 {
701 return(test_bit(__LINK_STATE_XOFF,&dev->flags));
702 }
703
qeth_open(struct net_device * dev)704 static int qeth_open(struct net_device *dev)
705 {
706 char dbf_text[15];
707 qeth_card_t *card;
708
709 card=(qeth_card_t *)dev->priv;
710 sprintf(dbf_text,"open%4x",card->irq0);
711 QETH_DBF_TEXT2(0,trace,dbf_text);
712 QETH_DBF_TEXT2(0,setup,dbf_text);
713
714 qeth_save_dev_flag_state(card);
715
716 netif_start_queue(dev);
717 if (!atomic_swap(&((qeth_card_t*)dev->priv)->is_open,1)) {
718 MOD_INC_USE_COUNT;
719 }
720 return 0;
721 }
722
qeth_set_config(struct net_device * dev,struct ifmap * map)723 static int qeth_set_config(struct net_device *dev,struct ifmap *map)
724 {
725 qeth_card_t *card=(qeth_card_t*)dev->priv;
726 char dbf_text[15];
727
728 sprintf(dbf_text,"nscf%04x",card->irq0);
729 QETH_DBF_TEXT3(0,trace,dbf_text);
730
731 return -EOPNOTSUPP;
732 }
733
qeth_is_multicast_skb_at_all(struct sk_buff * skb,int version)734 static int qeth_is_multicast_skb_at_all(struct sk_buff *skb,int version)
735 {
736 int i=RTN_UNSPEC;
737 qeth_card_t *card = (qeth_card_t *)skb->dev->priv;
738
739 if (skb->dst && skb->dst->neighbour) {
740 i=skb->dst->neighbour->type;
741 return ((i==RTN_BROADCAST)||
742 (i==RTN_MULTICAST)||
743 (i==RTN_ANYCAST))?i:0;
744 }
745 /* ok, we've to try it somehow else */
746 if (version==4) {
747 return ((skb->nh.raw[16]&0xf0)==0xe0)?RTN_MULTICAST:0;
748 } else if (version==6) {
749 return (skb->nh.raw[24]==0xff)?RTN_MULTICAST:0;
750 }
751 if (!memcmp(skb->nh.raw,skb->dev->broadcast,6)) {
752 i=RTN_BROADCAST;
753 } else {
754 __u16 hdr_mac;
755 hdr_mac=*((__u16*)skb->nh.raw);
756 /* tr multicast? */
757 switch (card->link_type) {
758 case QETH_MPC_LINK_TYPE_HSTR:
759 case QETH_MPC_LINK_TYPE_LANE_TR:
760 if ( (hdr_mac==QETH_TR_MAC_NC) ||
761 (hdr_mac==QETH_TR_MAC_C) )
762 i = RTN_MULTICAST;
763 break;
764 /* eth or so multicast? */
765 default:
766 if ( (hdr_mac==QETH_ETH_MAC_V4) ||
767 (hdr_mac==QETH_ETH_MAC_V6) )
768 i = RTN_MULTICAST;
769 }
770 }
771 return ((i==RTN_BROADCAST)||
772 (i==RTN_MULTICAST)||
773 (i==RTN_ANYCAST))?i:0;
774 }
775
qeth_get_prioqueue(qeth_card_t * card,struct sk_buff * skb,int multicast,int version)776 static int qeth_get_prioqueue(qeth_card_t *card,struct sk_buff *skb,
777 int multicast,int version)
778 {
779 if (!version &&
780 (card->type==QETH_CARD_TYPE_OSAE))
781 return QETH_DEFAULT_QUEUE;
782 switch (card->no_queues) {
783 case 1:
784 return 0;
785 case 4:
786 if ( (card->can_do_async_iqd) &&
787 (card->options.async_iqd==ASYNC_IQD) ) {
788 return card->no_queues-1;
789 }
790 if (card->is_multicast_different) {
791 if (multicast) {
792 return card->is_multicast_different&
793 (card->no_queues-1);
794 } else {
795 return 0;
796 }
797 }
798 if (card->options.do_prio_queueing) {
799 if (version==4) {
800 if (card->options.do_prio_queueing==
801 PRIO_QUEUEING_TOS) {
802 if (skb->nh.iph->tos&
803 IP_TOS_NOTIMPORTANT) {
804 return 3;
805 }
806 if (skb->nh.iph->tos&
807 IP_TOS_LOWDELAY) {
808 return 0;
809 }
810 if (skb->nh.iph->tos&
811 IP_TOS_HIGHTHROUGHPUT) {
812 return 1;
813 }
814 if (skb->nh.iph->tos&
815 IP_TOS_HIGHRELIABILITY) {
816 return 2;
817 }
818 return QETH_DEFAULT_QUEUE;
819 }
820 if (card->options.do_prio_queueing==
821 PRIO_QUEUEING_PREC) {
822 return 3-(skb->nh.iph->tos>>6);
823 }
824 } else if (version==6) {
825 /********************
826 ********************
827 TODO: IPv6!!!
828 ********************/
829 }
830 return card->options.default_queue;
831 } else return card->options.default_queue;
832 default:
833 return 0;
834 }
835 }
836
qeth_wakeup(qeth_card_t * card)837 static void qeth_wakeup(qeth_card_t *card) {
838 char dbf_text[15];
839
840 sprintf(dbf_text,"wkup%4x",card->irq0);
841 QETH_DBF_TEXT5(0,trace,dbf_text);
842
843 atomic_set(&card->data_has_arrived,1);
844 spin_lock(&card->wait_q_lock);
845 if (atomic_read(&card->wait_q_active)) {
846 wake_up(&card->wait_q);
847 }
848 spin_unlock(&card->wait_q_lock);
849 }
850
qeth_check_idx_response(unsigned char * buffer)851 static int qeth_check_idx_response(unsigned char *buffer)
852 {
853 if (!buffer)
854 return 0;
855 if ((buffer[2]&0xc0)==0xc0) {
856 return -EIO;
857 }
858 return 0;
859 }
860
qeth_get_cards_problem(qeth_card_t * card,unsigned char * buffer,int irq,int dstat,int cstat,int rqparam,char * irb,char * sense)861 static int qeth_get_cards_problem(qeth_card_t *card,unsigned char *buffer,
862 int irq,int dstat,int cstat,int rqparam,
863 char *irb,char *sense)
864 {
865 char dbf_text[15];
866 int problem=0;
867
868 if (atomic_read(&card->shutdown_phase)) return 0;
869 if (dstat&DEV_STAT_UNIT_CHECK) {
870 if (irq==card->irq2) {
871 sprintf(dbf_text,"ACHK%04x",card->irq0);
872 QETH_DBF_TEXT1(0,trace,dbf_text);
873 problem=PROBLEM_ACTIVATE_CHECK_CONDITION;
874 goto out;
875 }
876 if (sense[SENSE_RESETTING_EVENT_BYTE]&
877 SENSE_RESETTING_EVENT_FLAG) {
878 sprintf(dbf_text,"REVN%04x",card->irq0);
879 QETH_DBF_TEXT1(0,trace,dbf_text);
880 problem=PROBLEM_RESETTING_EVENT_INDICATOR;
881 goto out;
882 }
883 if (sense[SENSE_COMMAND_REJECT_BYTE]&
884 SENSE_COMMAND_REJECT_FLAG) {
885 sprintf(dbf_text,"CREJ%04x",card->irq0);
886 QETH_DBF_TEXT1(0,trace,dbf_text);
887 problem=PROBLEM_COMMAND_REJECT;
888 goto out;
889 }
890 if ( (sense[2]==0xaf)&&(sense[3]==0xfe) ) {
891 sprintf(dbf_text,"AFFE%04x",card->irq0);
892 QETH_DBF_TEXT1(0,trace,dbf_text);
893 problem=PROBLEM_AFFE;
894 goto out;
895 }
896 if ( (!sense[0]) && (!sense[1]) &&
897 (!sense[2]) && (!sense[3]) ) {
898 sprintf(dbf_text,"ZSNS%04x",card->irq0);
899 QETH_DBF_TEXT1(0,trace,dbf_text);
900 problem=PROBLEM_ZERO_SENSE_DATA;
901 goto out;
902 }
903 sprintf(dbf_text,"GCHK%04x",card->irq0);
904 QETH_DBF_TEXT1(0,trace,dbf_text);
905 problem=PROBLEM_GENERAL_CHECK;
906 goto out;
907 }
908 if (cstat& (SCHN_STAT_CHN_CTRL_CHK|SCHN_STAT_INTF_CTRL_CHK|
909 SCHN_STAT_CHN_DATA_CHK|SCHN_STAT_CHAIN_CHECK|
910 SCHN_STAT_PROT_CHECK|SCHN_STAT_PROG_CHECK) ) {
911 sprintf(dbf_text,"GCHK%04x",card->irq0);
912 QETH_DBF_TEXT1(0,trace,dbf_text);
913 QETH_DBF_HEX1(0,misc,irb,__max(QETH_DBF_MISC_LEN,64));
914 PRINT_WARN("check on irq x%x, dstat=x%x, cstat=x%x, " \
915 "rqparam=x%x\n",irq,dstat,cstat,rqparam);
916 HEXDUMP16(WARN,"irb: ",irb);
917 HEXDUMP16(WARN,"irb: ",((char*)irb)+32);
918 problem=PROBLEM_GENERAL_CHECK;
919 goto out;
920 }
921 if (qeth_check_idx_response(buffer)) {
922 PRINT_WARN("received an IDX TERMINATE on irq 0x%X/0x%X " \
923 "with cause code 0x%02x%s\n",
924 card->irq0,card->irq1,buffer[4],
925 (buffer[4]==0x22)?" -- try another portname":"");
926 sprintf(dbf_text,"RTRM%04x",card->irq0);
927 QETH_DBF_TEXT1(0,trace,dbf_text);
928 problem=PROBLEM_RECEIVED_IDX_TERMINATE;
929 goto out;
930 }
931 if (IS_IPA(buffer) && !IS_IPA_REPLY(buffer)) {
932 if ( *(PDU_ENCAPSULATION(buffer))==IPA_CMD_STOPLAN ) {
933 atomic_set(&card->is_startlaned,0);
934 /* we don't do a netif_stop_queue(card->dev);
935 we better discard all packets --
936 the outage could take longer */
937 PRINT_WARN("Link failure on %s (CHPID 0x%X) -- " \
938 "there is a network problem or someone " \
939 "pulled the cable or disabled the port."
940 "Discarding outgoing packets.\n",
941 card->dev_name,card->chpid);
942 sprintf(dbf_text,"CBOT%04x",card->irq0);
943 QETH_DBF_TEXT1(0,trace,dbf_text);
944 qeth_set_dev_flag_norunning(card);
945 problem=0;
946 goto out;
947 }
948 /* we checked for buffer!=0 in IS_IPA */
949 if ( *(PDU_ENCAPSULATION(buffer))==IPA_CMD_STARTLAN ) {
950 if (!atomic_read(&card->is_startlaned)) {
951 atomic_set(&card->is_startlaned,1);
952 problem=PROBLEM_CARD_HAS_STARTLANED;
953 }
954 goto out;
955 }
956 if ( *(PDU_ENCAPSULATION(buffer))==
957 IPA_CMD_REGISTER_LOCAL_ADDR ) {
958 sprintf(dbf_text,"irla%04x",card->irq0);
959 QETH_DBF_TEXT3(0,trace,dbf_text);
960 }
961 if ( *(PDU_ENCAPSULATION(buffer))==
962 IPA_CMD_UNREGISTER_LOCAL_ADDR ) {
963 sprintf(dbf_text,"irla%04x",card->irq0);
964 QETH_DBF_TEXT3(0,trace,dbf_text);
965 }
966 PRINT_WARN("probably a problem on %s: received data is " \
967 "IPA, but not a reply: command=0x%x\n",
968 card->dev_name,*(PDU_ENCAPSULATION(buffer)+1));
969 sprintf(dbf_text,"INRP%04x",card->irq0);
970 QETH_DBF_TEXT1(0,trace,dbf_text);
971 goto out;
972 }
973 /* no probs */
974 out:
975 if (problem) {
976 sprintf(dbf_text,"gcpr%4x",card->irq0);
977 QETH_DBF_TEXT3(0,trace,dbf_text);
978 sprintf(dbf_text,"%2x%2x%4x",dstat,cstat,problem);
979 QETH_DBF_TEXT3(0,trace,dbf_text);
980 sprintf(dbf_text,"%8x",rqparam);
981 QETH_DBF_TEXT3(0,trace,dbf_text);
982 if (buffer)
983 QETH_DBF_HEX3(0,trace,&buffer,sizeof(void*));
984 QETH_DBF_HEX3(0,trace,&irb,sizeof(void*));
985 QETH_DBF_HEX3(0,trace,&sense,sizeof(void*));
986 }
987 atomic_set(&card->problem,problem);
988 return problem;
989 }
990
991
qeth_issue_next_read(qeth_card_t * card)992 static void qeth_issue_next_read(qeth_card_t *card)
993 {
994 int result,result2;
995 char dbf_text[15];
996
997 sprintf(dbf_text,"isnr%04x",card->irq0);
998 QETH_DBF_TEXT5(0,trace,dbf_text);
999
1000 /* set up next read ccw */
1001 memcpy(&card->dma_stuff->read_ccw,READ_CCW,sizeof(ccw1_t));
1002 card->dma_stuff->read_ccw.count=QETH_BUFSIZE;
1003 /* recbuf is not yet used by read channel program */
1004 card->dma_stuff->read_ccw.cda=QETH_GET_ADDR(card->dma_stuff->recbuf);
1005
1006 /* we don't s390irq_spin_lock_irqsave(card->irq0,flags), as
1007 we are only called in the interrupt handler */
1008 result=do_IO(card->irq0,&card->dma_stuff->read_ccw,
1009 MPC_SETUP_STATE,0,0);
1010 if (result) {
1011 qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO);
1012 result2=do_IO(card->irq0,&card->dma_stuff->read_ccw,
1013 MPC_SETUP_STATE,0,0);
1014 PRINT_WARN("read handler on irq x%x, read: do_IO " \
1015 "returned %i, next try returns %i\n",
1016 card->irq0,result,result2);
1017 sprintf(dbf_text,"IsNR%04x",card->irq0);
1018 QETH_DBF_TEXT1(0,trace,dbf_text);
1019 sprintf(dbf_text,"%04x%04x",(__s16)result,(__s16)result2);
1020 QETH_DBF_TEXT1(0,trace,dbf_text);
1021 }
1022 }
1023
qeth_is_to_recover(qeth_card_t * card,int problem)1024 static int qeth_is_to_recover(qeth_card_t *card,int problem)
1025 {
1026 switch (problem) {
1027 case PROBLEM_CARD_HAS_STARTLANED:
1028 return 1;
1029 case PROBLEM_RECEIVED_IDX_TERMINATE:
1030 if (atomic_read(&card->in_recovery)) {
1031 return 1;
1032 } else {
1033 qeth_set_dev_flag_norunning(card);
1034 return 0;
1035 }
1036 case PROBLEM_ACTIVATE_CHECK_CONDITION:
1037 return 1;
1038 case PROBLEM_RESETTING_EVENT_INDICATOR:
1039 return 1;
1040 case PROBLEM_COMMAND_REJECT:
1041 return 0;
1042 case PROBLEM_ZERO_SENSE_DATA:
1043 return 0;
1044 case PROBLEM_GENERAL_CHECK:
1045 return 1;
1046 case PROBLEM_BAD_SIGA_RESULT:
1047 return 1;
1048 case PROBLEM_USER_TRIGGERED_RECOVERY:
1049 return 1;
1050 case PROBLEM_AFFE:
1051 return 1;
1052 case PROBLEM_MACHINE_CHECK:
1053 return 1;
1054 case PROBLEM_TX_TIMEOUT:
1055 return 1;
1056 }
1057 return 0;
1058 }
1059
qeth_wait_for_event(atomic_t * var,unsigned int timeout)1060 static int qeth_wait_for_event(atomic_t *var,unsigned int timeout)
1061 {
1062 unsigned int start;
1063 int retval;
1064 char dbf_text[15];
1065
1066 QETH_DBF_TEXT5(0,trace,"wait4evn");
1067 sprintf(dbf_text,"%08x",timeout);
1068 QETH_DBF_TEXT5(0,trace,dbf_text);
1069 QETH_DBF_HEX5(0,trace,&var,sizeof(void*));
1070
1071 start=qeth_get_millis();
1072 for (;;) {
1073 set_task_state(current,TASK_INTERRUPTIBLE);
1074 if (atomic_read(var)) {
1075 retval=0;
1076 goto out;
1077 }
1078 if (qeth_get_millis()-start>timeout) {
1079 retval=-ETIME;
1080 goto out;
1081 }
1082 schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ);
1083 }
1084 out:
1085 set_task_state(current,TASK_RUNNING);
1086
1087 return retval;
1088 }
1089
qeth_get_spare_buf(void)1090 static inline int qeth_get_spare_buf(void)
1091 {
1092 int i=0;
1093 char dbf_text[15];
1094
1095 while (i<sparebuffer_count) {
1096 if (!atomic_compare_and_swap(SPAREBUF_FREE,SPAREBUF_USED,
1097 &sparebufs[i].status)) {
1098 sprintf(dbf_text,"gtspb%3x",i);
1099 QETH_DBF_TEXT4(0,trace,dbf_text);
1100 return i;
1101 }
1102 i++;
1103 }
1104 QETH_DBF_TEXT3(0,trace,"nospbuf");
1105
1106 return -1;
1107 }
1108
qeth_put_spare_buf(int no)1109 static void qeth_put_spare_buf(int no)
1110 {
1111 char dbf_text[15];
1112
1113 sprintf(dbf_text,"ptspb%3x",no);
1114 QETH_DBF_TEXT4(0,trace,dbf_text);
1115 atomic_set(&sparebufs[no].status, SPAREBUF_FREE);
1116 }
1117
qeth_put_buffer_pool_entry(qeth_card_t * card,int entry_no)1118 static inline void qeth_put_buffer_pool_entry(qeth_card_t *card,int entry_no)
1119 {
1120 if (entry_no&SPAREBUF_MASK)
1121 qeth_put_spare_buf(entry_no&(~SPAREBUF_MASK));
1122 else
1123 card->inbound_buffer_pool_entry_used[entry_no]=BUFFER_UNUSED;
1124 }
1125
qeth_get_empty_buffer_pool_entry(qeth_card_t * card)1126 static inline int qeth_get_empty_buffer_pool_entry(qeth_card_t *card)
1127 {
1128 int i;
1129 int max_buffers=card->options.inbound_buffer_count;
1130
1131 for (i=0;i<max_buffers;i++) {
1132 if (xchg((int*)&card->inbound_buffer_pool_entry_used[i],
1133 BUFFER_USED)==BUFFER_UNUSED) return i;
1134 }
1135 return -1;
1136 }
1137
qeth_clear_input_buffer(qeth_card_t * card,int bufno)1138 static inline void qeth_clear_input_buffer(qeth_card_t *card,int bufno)
1139 {
1140 qdio_buffer_t *buffer;
1141 int i;
1142 int elements,el_m_1;
1143 void *ptr;
1144 #ifdef QETH_DBF_LIKE_HELL
1145 char dbf_text[15];
1146
1147 sprintf(dbf_text,"clib%4x",card->irq0);
1148 QETH_DBF_TEXT6(0,trace,dbf_text);
1149 sprintf(dbf_text,"bufno%3x",bufno);
1150 QETH_DBF_TEXT6(0,trace,dbf_text);
1151 #endif /* QETH_DBF_LIKE_HELL */
1152
1153 buffer=&card->inbound_qdio_buffers[bufno];
1154 elements=BUFFER_MAX_ELEMENTS;
1155 el_m_1=elements-1;
1156
1157 for (i=0;i<elements;i++) {
1158 if (i==el_m_1)
1159 buffer->element[i].flags=SBAL_FLAGS_LAST_ENTRY;
1160 else
1161 buffer->element[i].flags=0;
1162
1163 buffer->element[i].length=PAGE_SIZE;
1164 ptr=INBOUND_BUFFER_POS(card,bufno,i);
1165 if (card->do_pfix) {
1166 /* we assume here, that ptr&(PAGE_SIZE-1)==0 */
1167 buffer->element[i].addr=(void *)pfix_get_page_addr(ptr);
1168 card->real_inb_buffer_addr[bufno][i]=ptr;
1169 } else {
1170 buffer->element[i].addr=ptr;
1171 }
1172 }
1173 }
1174
qeth_queue_input_buffer(qeth_card_t * card,int bufno,unsigned int under_int)1175 static inline void qeth_queue_input_buffer(qeth_card_t *card,int bufno,
1176 unsigned int under_int)
1177 {
1178 int count=0,start=0,stop=0,pos;
1179 int result;
1180 int cnt1,cnt2=0;
1181 int wrapped=0;
1182 int i;
1183 int requeue_counter;
1184 char dbf_text[15];
1185 int no;
1186
1187 #ifdef QETH_DBF_LIKE_HELL
1188 sprintf(dbf_text,"qibf%4x",card->irq0);
1189 QETH_DBF_TEXT5(0,trace,dbf_text);
1190 sprintf(dbf_text,"%4x%4x",under_int,bufno);
1191 QETH_DBF_TEXT5(0,trace,dbf_text);
1192 #endif /* QETH_DBF_LIKE_HELL */
1193 atomic_inc(&card->requeue_counter);
1194 if (atomic_read(&card->requeue_counter) > QETH_REQUEUE_THRESHOLD) {
1195 if (!spin_trylock(&card->requeue_input_lock)) {
1196 #ifndef QETH_DBF_LIKE_HELL
1197 sprintf(dbf_text,"qibl%4x",card->irq0);
1198 QETH_DBF_TEXT5(0,trace,dbf_text);
1199 #endif /* QETH_DBF_LIKE_HELL */
1200 return;
1201 }
1202 requeue_counter=atomic_read(&card->requeue_counter);
1203 pos=atomic_read(&card->requeue_position);
1204
1205 start=pos;
1206 /* omit the situation with 128 simultaneously
1207 enqueued buffers, as then we can't benefit from PCI
1208 avoidance anymore -- therefore we let count not grow as
1209 big as requeue_counter */
1210 while ( (!atomic_read(&card->inbound_buffer_refcnt[pos])) &&
1211 (count<requeue_counter-1) ) {
1212 no=qeth_get_empty_buffer_pool_entry(card);
1213 if (no==-1) {
1214 if (count) break;
1215 no=qeth_get_spare_buf();
1216 if (no==-1) {
1217 PRINT_ERR("%s: no more input "\
1218 "buffers available! " \
1219 "Inbound traffic could " \
1220 "be lost! Try to spend " \
1221 "more memory for qeth\n",
1222 card->dev_name);
1223 sprintf(dbf_text,"QINB%4x",card->irq0);
1224 QETH_DBF_TEXT2(1,trace,dbf_text);
1225 goto out;
1226 }
1227 card->inbound_buffer_entry_no[pos]=
1228 no|SPAREBUF_MASK;
1229 }
1230 card->inbound_buffer_entry_no[pos]=no;
1231 atomic_set(&card->inbound_buffer_refcnt[pos],1);
1232 count++;
1233 if (pos>=QDIO_MAX_BUFFERS_PER_Q-1) {
1234 pos=0;
1235 wrapped=1;
1236 } else pos++;
1237 }
1238 /* stop points to the position after the last element */
1239 stop=pos;
1240
1241 #ifdef QETH_DBF_LIKE_HELL
1242 sprintf(dbf_text,"qibi%4x",card->irq0);
1243 QETH_DBF_TEXT3(0,trace,dbf_text);
1244 sprintf(dbf_text,"%4x",requeue_counter);
1245 QETH_DBF_TEXT3(0,trace,dbf_text);
1246 sprintf(dbf_text,"%4x%4x",start,stop);
1247 QETH_DBF_TEXT3(0,trace,dbf_text);
1248 #endif /* QETH_DBF_LIKE_HELL */
1249 if (wrapped) {
1250 cnt1=QDIO_MAX_BUFFERS_PER_Q-start;
1251 cnt2=stop;
1252 } else {
1253 cnt1=count;
1254 /* cnt2 is already set to 0 */
1255 }
1256
1257 atomic_sub(count,&card->requeue_counter);
1258 /* this is the only place where card->requeue_position is
1259 written to, so that's ok (as it is in a lock) */
1260 atomic_set(&card->requeue_position,
1261 (atomic_read(&card->requeue_position)+count)
1262 &(QDIO_MAX_BUFFERS_PER_Q-1));
1263
1264 if (cnt1) {
1265 for (i=start;i<start+cnt1;i++) {
1266 qeth_clear_input_buffer(card,i);
1267 }
1268 result=do_QDIO(card->irq2,
1269 QDIO_FLAG_SYNC_INPUT|under_int,
1270 0,start,cnt1,
1271 NULL);
1272 if (result) {
1273 PRINT_WARN("qeth_queue_input_buffer's " \
1274 "do_QDIO returnd %i " \
1275 "(irq 0x%x)\n",
1276 result,card->irq2);
1277 sprintf(dbf_text,"QIDQ%4x",card->irq0);
1278 QETH_DBF_TEXT1(0,trace,dbf_text);
1279 sprintf(dbf_text,"%4x%4x",result,
1280 requeue_counter);
1281 QETH_DBF_TEXT1(0,trace,dbf_text);
1282 sprintf(dbf_text,"%4x%4x",start,cnt1);
1283 QETH_DBF_TEXT1(1,trace,dbf_text);
1284 }
1285 }
1286 if (cnt2) {
1287 for (i=0;i<cnt2;i++) {
1288 qeth_clear_input_buffer(card,i);
1289 }
1290 result=do_QDIO(card->irq2,
1291 QDIO_FLAG_SYNC_INPUT|under_int,0,
1292 0,cnt2,
1293 NULL);
1294 if (result) {
1295 PRINT_WARN("qeth_queue_input_buffer's " \
1296 "do_QDIO returnd %i " \
1297 "(irq 0x%x)\n",
1298 result,card->irq2);
1299 sprintf(dbf_text,"QIDQ%4x",card->irq0);
1300 QETH_DBF_TEXT1(0,trace,dbf_text);
1301 sprintf(dbf_text,"%4x%4x",result,
1302 requeue_counter);
1303 QETH_DBF_TEXT1(0,trace,dbf_text);
1304 sprintf(dbf_text,"%4x%4x",0,cnt2);
1305 QETH_DBF_TEXT1(1,trace,dbf_text);
1306 }
1307 }
1308 out:
1309 my_spin_unlock(&card->requeue_input_lock);
1310 }
1311
1312 }
1313
qeth_get_skb(unsigned int len)1314 static inline struct sk_buff *qeth_get_skb(unsigned int len)
1315 {
1316 struct sk_buff *skb;
1317
1318 #ifdef QETH_VLAN
1319 skb=dev_alloc_skb(len+VLAN_HLEN);
1320 if (skb) skb_reserve(skb,VLAN_HLEN);
1321 #else /* QETH_VLAN */
1322 skb=dev_alloc_skb(len);
1323 #endif /* QETH_VLAN */
1324 return skb;
1325 }
1326
qeth_get_next_skb(qeth_card_t * card,int * element_ptr,int * pos_in_el_ptr,void ** hdr_ptr,qdio_buffer_t * buffer)1327 static inline struct sk_buff *qeth_get_next_skb(qeth_card_t *card,
1328 int *element_ptr,
1329 int *pos_in_el_ptr,
1330 void **hdr_ptr,
1331 qdio_buffer_t *buffer)
1332 {
1333 int length;
1334 char *data_ptr;
1335 int step,len_togo,element,pos_in_el;
1336 int curr_len;
1337 int max_elements;
1338 struct sk_buff *skb;
1339 char dbf_text[15];
1340
1341 max_elements=BUFFER_MAX_ELEMENTS;
1342
1343 #define SBALE_LEN(x) ((x>=max_elements)?0:(buffer->element[x].length))
1344 #define SBALE_ADDR(x) (buffer->element[x].addr)
1345
1346 element=*element_ptr;
1347
1348 if (element>=max_elements) {
1349 PRINT_WARN("irq 0x%x: error in interpreting buffer (data " \
1350 "too long), %i elements.\n",card->irq0,element);
1351 sprintf(dbf_text,"IEDL%4x",card->irq0);
1352 QETH_DBF_TEXT0(0,trace,dbf_text);
1353 sprintf(dbf_text,"%4x%4x",*element_ptr,*pos_in_el_ptr);
1354 QETH_DBF_TEXT0(1,trace,dbf_text);
1355 QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN);
1356 QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN,
1357 QETH_DBF_MISC_LEN);
1358 return NULL;
1359 }
1360
1361 pos_in_el=*pos_in_el_ptr;
1362
1363 curr_len=SBALE_LEN(element);
1364 if (curr_len>PAGE_SIZE) {
1365 PRINT_WARN("irq 0x%x: bad element length in element %i: " \
1366 "0x%x\n",card->irq0,element,curr_len);
1367 sprintf(dbf_text,"BELN%4x",card->irq0);
1368 QETH_DBF_TEXT0(0,trace,dbf_text);
1369 sprintf(dbf_text,"%4x",curr_len);
1370 QETH_DBF_TEXT0(0,trace,dbf_text);
1371 sprintf(dbf_text,"%4x%4x",*element_ptr,*pos_in_el_ptr);
1372 QETH_DBF_TEXT0(1,trace,dbf_text);
1373 QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN);
1374 QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN,
1375 QETH_DBF_MISC_LEN);
1376 return NULL;
1377 }
1378 /* header fits in current element? */
1379 if (curr_len<pos_in_el+QETH_HEADER_SIZE) {
1380 if (!pos_in_el) {
1381 #ifdef QETH_DBF_LIKE_HELL
1382 sprintf(dbf_text,"gnmh%4x",card->irq0);
1383 QETH_DBF_TEXT6(0,trace,dbf_text);
1384 #endif /* QETH_DBF_LIKE_HELL */
1385 return NULL; /* no more data in buffer */
1386 }
1387 /* set hdr to next element */
1388 element++;
1389 pos_in_el=0;
1390 curr_len=SBALE_LEN(element);
1391 /* does it fit in there? */
1392 if (curr_len<QETH_HEADER_SIZE) {
1393 #ifdef QETH_DBF_LIKE_HELL
1394 sprintf(dbf_text,"gdnf%4x",card->irq0);
1395 QETH_DBF_TEXT6(0,trace,dbf_text);
1396 #endif /* QETH_DBF_LIKE_HELL */
1397 return NULL;
1398 }
1399 }
1400
1401 *hdr_ptr=SBALE_ADDR(element)+pos_in_el;
1402
1403 length=*(__u16*)((char*)(*hdr_ptr)+QETH_HEADER_LEN_POS);
1404
1405 #ifdef QETH_DBF_LIKE_HELL
1406 sprintf(dbf_text,"gnHd%4x",card->irq0);
1407 QETH_DBF_TEXT6(0,trace,dbf_text);
1408 QETH_DBF_HEX6(0,trace,hdr_ptr,sizeof(void*));
1409 #endif /* QETH_DBF_LIKE_HELL */
1410
1411 pos_in_el+=QETH_HEADER_SIZE;
1412 if (curr_len<=pos_in_el) {
1413 /* switch to next element for data */
1414 pos_in_el=0;
1415 element++;
1416 curr_len=SBALE_LEN(element);
1417 if (!curr_len) {
1418 PRINT_WARN("irq 0x%x: inb. buffer with more headers " \
1419 "than data areas (%i elements).\n",
1420 card->irq0,element);
1421 sprintf(dbf_text,"IEMH%4x",card->irq0);
1422 QETH_DBF_TEXT0(0,trace,dbf_text);
1423 sprintf(dbf_text,"%2x%2x%4x",element,*element_ptr,
1424 *pos_in_el_ptr);
1425 QETH_DBF_TEXT0(1,trace,dbf_text);
1426 QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN);
1427 QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN,
1428 QETH_DBF_MISC_LEN);
1429 return NULL;
1430 }
1431 }
1432
1433 data_ptr=SBALE_ADDR(element)+pos_in_el;
1434
1435 if (card->options.fake_ll==FAKE_LL) {
1436 skb=qeth_get_skb(length+QETH_FAKE_LL_LEN);
1437 if (!skb) goto nomem;
1438 skb_pull(skb,QETH_FAKE_LL_LEN);
1439 } else {
1440 skb=qeth_get_skb(length);
1441 if (!skb) goto nomem;
1442 }
1443
1444 if (card->easy_copy_cap)
1445 memcpy(skb_put(skb,length),data_ptr,length);
1446
1447 #ifdef QETH_DBF_LIKE_HELL
1448 QETH_DBF_HEX6(0,trace,&data_ptr,sizeof(void*));
1449 QETH_DBF_HEX6(0,trace,&skb,sizeof(void*));
1450 #endif /* QETH_DBF_LIKE_HELL */
1451
1452 len_togo=length;
1453 while (1) {
1454 step=qeth_min(len_togo,curr_len-pos_in_el);
1455 if (!step) {
1456 PRINT_WARN("irq 0x%x: unexpected end of buffer, " \
1457 "length of element %i is 0. Discarding " \
1458 "packet.\n",card->irq0,element);
1459 sprintf(dbf_text,"IEUE%4x",card->irq0);
1460 QETH_DBF_TEXT0(0,trace,dbf_text);
1461 sprintf(dbf_text,"%2x%2x%4x",element,*element_ptr,
1462 *pos_in_el_ptr);
1463 QETH_DBF_TEXT0(0,trace,dbf_text);
1464 sprintf(dbf_text,"%4x%4x",len_togo,step);
1465 QETH_DBF_TEXT0(0,trace,dbf_text);
1466 sprintf(dbf_text,"%4x%4x",curr_len,pos_in_el);
1467 QETH_DBF_TEXT0(1,trace,dbf_text);
1468 QETH_DBF_HEX0(0,misc,buffer,QETH_DBF_MISC_LEN);
1469 QETH_DBF_HEX0(0,misc,buffer+QETH_DBF_MISC_LEN,
1470 QETH_DBF_MISC_LEN);
1471 dev_kfree_skb_irq(skb);
1472 return NULL;
1473 }
1474 if (!card->easy_copy_cap)
1475 memcpy(skb_put(skb,step),data_ptr,step);
1476 len_togo-=step;
1477 if (len_togo) {
1478 pos_in_el=0;
1479 element++;
1480 curr_len=SBALE_LEN(element);
1481 data_ptr=SBALE_ADDR(element);
1482 } else {
1483 #ifdef QETH_INBOUND_PACKING_1_PACKET_PER_SBALE
1484 element++;
1485 /* we don't need to calculate curr_len */
1486 pos_in_el=0;
1487 #else /* QETH_INBOUND_PACKING_1_PACKET_PER_SBALE */
1488 pos_in_el+=step;
1489 #endif /* QETH_INBOUND_PACKING_1_PACKET_PER_SBALE */
1490 break;
1491 }
1492 }
1493
1494 #ifdef QETH_DBF_LIKE_HELL
1495 sprintf(dbf_text,"%4x%4x",element,pos_in_el);
1496 QETH_DBF_TEXT6(0,trace,dbf_text);
1497 #endif /* QETH_DBF_LIKE_HELL */
1498
1499 *element_ptr=element;
1500 *pos_in_el_ptr=pos_in_el;
1501
1502 return skb;
1503
1504 nomem:
1505 if (net_ratelimit()) {
1506 PRINT_WARN("no memory for packet from %s\n",card->dev_name);
1507 }
1508 sprintf(dbf_text,"NOMM%4x",card->irq0);
1509 QETH_DBF_TEXT0(0,trace,dbf_text);
1510 return NULL;
1511 }
1512
qeth_transform_outbound_addrs(qeth_card_t * card,qdio_buffer_t * buffer)1513 static inline void qeth_transform_outbound_addrs(qeth_card_t *card,
1514 qdio_buffer_t *buffer)
1515 {
1516 int i;
1517 void *ptr;
1518
1519 if (card->do_pfix) {
1520 for (i=0;i<QDIO_MAX_ELEMENTS_PER_BUFFER;i++) {
1521 ptr=buffer->element[i].addr;
1522 buffer->element[i].addr=(void *)pfix_get_addr(ptr);
1523 }
1524 }
1525 }
qeth_get_linux_addrs_for_buffer(qeth_card_t * card,int buffer_no)1526 static inline void qeth_get_linux_addrs_for_buffer(qeth_card_t *card,
1527 int buffer_no)
1528 {
1529 int i;
1530 void *ptr;
1531
1532 if (card->do_pfix) {
1533 for (i=0;i<QDIO_MAX_ELEMENTS_PER_BUFFER;i++) {
1534 ptr=card->inbound_qdio_buffers[buffer_no].
1535 element[i].addr;
1536 card->inbound_qdio_buffers[buffer_no].element[i].addr=
1537 card->real_inb_buffer_addr[buffer_no][i]+
1538 ((unsigned long)ptr&(PAGE_SIZE-1));
1539 }
1540 }
1541 }
1542
qeth_read_in_buffer(qeth_card_t * card,int buffer_no)1543 static inline void qeth_read_in_buffer(qeth_card_t *card,int buffer_no)
1544 {
1545 struct sk_buff *skb;
1546 void *hdr_ptr;
1547 int element=0,pos_in_el=0;
1548 int version;
1549 qdio_buffer_t *buffer;
1550 unsigned short cast_type;
1551 #ifdef QETH_VLAN
1552 __u16 *vlan_tag;
1553 #endif
1554 int i;
1555 int max_elements;
1556 char dbf_text[15];
1557 struct net_device *dev;
1558
1559 dev=card->dev;
1560 max_elements=BUFFER_MAX_ELEMENTS;
1561
1562 buffer=&card->inbound_qdio_buffers[buffer_no];
1563
1564 /* inform about errors */
1565 if (buffer->element[15].flags&0xff) {
1566 PRINT_WARN("on irq 0x%x: incoming SBALF 15 on buffer " \
1567 "0x%x are 0x%x\n",card->irq0,buffer_no,
1568 buffer->element[15].flags&0xff);
1569 sprintf(dbf_text,"SF##%2x%2x",buffer_no,
1570 buffer->element[15].flags&0xff);
1571 *((__u16*)(&dbf_text[2]))=(__u16)card->irq0;
1572 QETH_DBF_HEX1(1,trace,dbf_text,QETH_DBF_TRACE_LEN);
1573 }
1574
1575 for (i=0;i<max_elements-1;i++) {
1576 if (buffer->element[i].flags&SBAL_FLAGS_LAST_ENTRY) {
1577 buffer->element[i+1].length=0;
1578 break;
1579 }
1580 }
1581 #ifdef QETH_PERFORMANCE_STATS
1582 card->perf_stats.bufs_rec++;
1583 #endif /* QETH_PERFORMANCE_STATS */
1584
1585 #ifdef QETH_DBF_LIKE_HELL
1586 sprintf(dbf_text,"ribX%4x",card->irq0);
1587 dbf_text[3]=buffer_no;
1588 QETH_DBF_HEX6(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
1589 #endif /* QETH_DBF_LIKE_HELL */
1590
1591 while ((skb=qeth_get_next_skb(card,&element,&pos_in_el,
1592 &hdr_ptr,buffer))) {
1593
1594 #ifdef QETH_PERFORMANCE_STATS
1595 card->perf_stats.skbs_rec++;
1596 #endif /* QETH_PERFORMANCE_STATS */
1597
1598 if (skb) {
1599 skb->dev=dev;
1600
1601 #ifdef QETH_IPV6
1602 if ( (*(__u16 *)(hdr_ptr))&(QETH_HEADER_PASSTHRU) ) {
1603 skb->protocol=card->type_trans(skb,dev);
1604 } else
1605 #endif /* QETH_IPV6 */
1606 {
1607 version=((*(__u16 *)(hdr_ptr))&
1608 (QETH_HEADER_IPV6))?6:4;
1609 skb->protocol=htons((version==4)?ETH_P_IP:
1610 (version==6)?ETH_P_IPV6:
1611 ETH_P_ALL);
1612 cast_type=(*(__u16 *)(hdr_ptr))&
1613 (QETH_CAST_FLAGS);
1614 if (cast_type==QETH_CAST_UNICAST) {
1615 skb->pkt_type=PACKET_HOST;
1616 } else if (cast_type==QETH_CAST_MULTICAST) {
1617 skb->pkt_type=PACKET_MULTICAST;
1618 } else if (cast_type==QETH_CAST_BROADCAST) {
1619 skb->pkt_type=PACKET_BROADCAST;
1620 } else if ( (cast_type==QETH_CAST_ANYCAST) ||
1621 (cast_type==QETH_CAST_NOCAST) ) {
1622 sprintf(dbf_text,"ribf%4x",card->irq0);
1623 QETH_DBF_TEXT2(0,trace,dbf_text);
1624 sprintf(dbf_text,"castan%2x",cast_type);
1625 QETH_DBF_TEXT2(1,trace,dbf_text);
1626 skb->pkt_type=PACKET_HOST;
1627 } else {
1628 PRINT_WARN("adapter is using an " \
1629 "unknown casting value " \
1630 "of 0x%x. Using " \
1631 "unicasting instead.\n",
1632 cast_type);
1633 skb->pkt_type=PACKET_HOST;
1634 sprintf(dbf_text,"ribf%4x",card->irq0);
1635 QETH_DBF_TEXT2(0,trace,dbf_text);
1636 sprintf(dbf_text,"castun%2x",cast_type);
1637 QETH_DBF_TEXT2(1,trace,dbf_text);
1638 }
1639
1640 if (card->options.fake_ll==FAKE_LL) {
1641 skb->mac.raw=skb->data-QETH_FAKE_LL_LEN;
1642 if (skb->pkt_type==PACKET_MULTICAST) {
1643 switch (skb->protocol) {
1644 #ifdef QETH_IPV6
1645 case __constant_htons(ETH_P_IPV6):
1646 ndisc_mc_map((struct in6_addr *)
1647 skb->data+QETH_FAKE_LL_V6_ADDR_POS,
1648 skb->mac.raw+
1649 QETH_FAKE_LL_DEST_MAC_POS,
1650 card->dev,0);
1651 break;
1652 #endif /* QETH_IPV6 */
1653 case __constant_htons(ETH_P_IP):
1654 qeth_get_mac_for_ipm(*(__u32*)
1655 skb->data+QETH_FAKE_LL_V4_ADDR_POS,
1656 skb->mac.raw+
1657 QETH_FAKE_LL_DEST_MAC_POS,
1658 card->dev);
1659 break;
1660 default:
1661 memcpy(skb->mac.raw+
1662 QETH_FAKE_LL_DEST_MAC_POS,
1663 card->dev->dev_addr,
1664 QETH_FAKE_LL_ADDR_LEN);
1665 }
1666 } else if (skb->pkt_type==PACKET_BROADCAST) {
1667 memset(skb->mac.raw+
1668 QETH_FAKE_LL_DEST_MAC_POS,0xff,
1669 QETH_FAKE_LL_ADDR_LEN);
1670 } else {
1671 memcpy(skb->mac.raw+
1672 QETH_FAKE_LL_DEST_MAC_POS,
1673 card->dev->dev_addr,
1674 QETH_FAKE_LL_ADDR_LEN);
1675 }
1676 if (*(__u8*)(hdr_ptr+11)&
1677 QETH_EXT_HEADER_SRC_MAC_ADDRESS) {
1678 memcpy(skb->mac.raw+
1679 QETH_FAKE_LL_SRC_MAC_POS,
1680 hdr_ptr+QETH_FAKE_LL_SRC_MAC_POS_IN_QDIO_HDR,
1681 QETH_FAKE_LL_ADDR_LEN);
1682 } else {
1683 /* clear source MAC for security reasons */
1684 memset(skb->mac.raw+
1685 QETH_FAKE_LL_SRC_MAC_POS,0,
1686 QETH_FAKE_LL_ADDR_LEN);
1687 }
1688 memcpy(skb->mac.raw+
1689 QETH_FAKE_LL_PROT_POS,
1690 &skb->protocol,
1691 QETH_FAKE_LL_PROT_LEN);
1692 } else {
1693 skb->mac.raw=skb->data;
1694 }
1695
1696 if (card->options.checksum_type==HW_CHECKSUMMING) {
1697 /* do we have a checksummed packet? */
1698
1699 /* we only check for TCP/UDP checksums when the
1700 * pseudo header was also checked sucessfully -- for
1701 * the rest of the packets, it's not clear, whether
1702 * the upper layer csum is alright. And they
1703 * shouldn't occur too often anyway in real life */
1704 if ( (*(__u8*)(hdr_ptr+11)&
1705 (QETH_EXT_HEADER_CSUM_HDR_REQ|
1706 QETH_EXT_HEADER_CSUM_TRANSP_REQ)) ==
1707 (QETH_EXT_HEADER_CSUM_HDR_REQ|
1708 QETH_EXT_HEADER_CSUM_TRANSP_REQ) ) {
1709 /* csum does not need to be set
1710 * inbound anyway
1711 *
1712 * vlan is not an issue here, it's still in
1713 * the QDIO header, not pushed in the
1714 * skb yet *
1715 int ip_len=(skb->data[0]&0x0f)<<2;
1716
1717 if (*(__u8*)(hdr_ptr+11)&
1718 QETH_EXT_HEADER_CSUM_TRANSP_FRAME_TYPE) {
1719 * get the UDP checksum *
1720 skb->csum=*(__u16*)
1721 (&skb->data[ip_len+
1722 QETH_UDP_CSUM_OFFSET]);
1723 } else {
1724 * get the TCP checksum *
1725 skb->csum=*(__u16*)
1726 (&skb->data[ip_len+
1727 QETH_TCP_CSUM_OFFSET]);
1728 }
1729 */
1730 skb->ip_summed=CHECKSUM_UNNECESSARY;
1731 } else {
1732 /* make the stack check it */
1733 skb->ip_summed=CHECKSUM_NONE;
1734 }
1735 } else {
1736 skb->ip_summed=card->options.checksum_type;
1737 }
1738
1739 #ifdef QETH_VLAN
1740 if (*(__u8*)(hdr_ptr+11)&
1741 QETH_EXT_HEADER_VLAN_FRAME) {
1742 vlan_tag=(__u16 *)skb_push(skb,
1743 VLAN_HLEN);
1744 /*
1745 if (*(__u8*)(hdr_ptr+11) &
1746 QETH_EXT_HEADER_INCLUDE_VLAN_TAG) {
1747 *vlan_tag = *(__u16*)(hdr_ptr+28);
1748 *(vlan_tag+1)= *(__u16*)(hdr_ptr+30);
1749 } else {
1750 */
1751 *vlan_tag = *(__u16*)(hdr_ptr+12);
1752 *(vlan_tag+1) = skb->protocol;
1753 /*
1754 }
1755 */
1756 skb->protocol=
1757 __constant_htons(ETH_P_8021Q);
1758 }
1759 #endif
1760 }
1761
1762 #ifdef QETH_PERFORMANCE_STATS
1763 card->perf_stats.inbound_time+=
1764 NOW-card->perf_stats.inbound_start_time;
1765 card->perf_stats.inbound_cnt++;
1766 #endif /* QETH_PERFORMANCE_STATS */
1767
1768 #ifdef QETH_DBF_LIKE_HELL
1769 sprintf(dbf_text,"rxpk%4x",card->irq0);
1770 QETH_DBF_TEXT6(0,trace,dbf_text);
1771 #endif /* QETH_DBF_LIKE_HELL */
1772
1773 netif_rx(skb);
1774
1775 card->stats->rx_packets++;
1776 card->stats->rx_bytes+=skb->len;
1777 } else {
1778 PRINT_WARN("%s: dropped packet, no buffers " \
1779 "available.\n",card->dev_name);
1780 sprintf(dbf_text,"DROP%4x",card->irq0);
1781 QETH_DBF_TEXT2(1,trace,dbf_text);
1782 card->stats->rx_dropped++;
1783 }
1784 }
1785 atomic_set(&card->inbound_buffer_refcnt[buffer_no],0);
1786 qeth_put_buffer_pool_entry(card,card->inbound_buffer_entry_no[
1787 buffer_no]);
1788 }
1789
qeth_fill_header(qeth_hdr_t * hdr,struct sk_buff * skb,int version,int multicast)1790 static inline void qeth_fill_header(qeth_hdr_t *hdr,struct sk_buff *skb,
1791 int version,int multicast)
1792 {
1793 #ifdef QETH_DBF_LIKE_HELL
1794 char dbf_text[15];
1795 #endif /* QETH_DBF_LIKE_HELL */
1796 #ifdef QETH_VLAN
1797 qeth_card_t *card;
1798 #endif
1799
1800 hdr->id=1;
1801 hdr->ext_flags=0;
1802
1803 #ifdef QETH_VLAN
1804 /* before we're going to overwrite
1805 * this location with next hop ip.
1806 * v6 uses passthrough, v4 sets the tag in the QDIO header */
1807 card = (qeth_card_t *)skb->dev->priv;
1808 if ((card->vlangrp != NULL) &&
1809 vlan_tx_tag_present(skb))
1810 {
1811 if (version == 4) {
1812 hdr->ext_flags = QETH_EXT_HEADER_VLAN_FRAME;
1813 } else {
1814 hdr->ext_flags = QETH_EXT_HEADER_INCLUDE_VLAN_TAG;
1815 }
1816 hdr->vlan_id = vlan_tx_tag_get(skb);
1817 }
1818 #endif
1819
1820 hdr->length=skb->len-QETH_HEADER_SIZE; /* as skb->len includes
1821 the header now */
1822
1823 /* yes, I know this is doubled code, but a small little bit
1824 faster maybe */
1825 if (version==4) { /* IPv4 */
1826 if (multicast==RTN_MULTICAST) {
1827 hdr->flags=QETH_CAST_MULTICAST;
1828 } else if (multicast==RTN_BROADCAST) {
1829 hdr->flags=QETH_CAST_BROADCAST;
1830 } else {
1831 hdr->flags=QETH_CAST_UNICAST;
1832 }
1833 *((__u32*)(&hdr->dest_addr[0]))=0;
1834 *((__u32*)(&hdr->dest_addr[4]))=0;
1835 *((__u32*)(&hdr->dest_addr[8]))=0;
1836 if ((skb->dst) && (skb->dst->neighbour)) {
1837 *((__u32*)(&hdr->dest_addr[12]))=
1838 *((__u32*)skb->dst->neighbour->primary_key);
1839 } else {
1840 /* fill in destination address used
1841 * in ip header */
1842 *((__u32*)(&hdr->dest_addr[12]))=
1843 skb->nh.iph->daddr;
1844 }
1845 } else if (version==6) { /* IPv6 or passthru */
1846 if (multicast==RTN_MULTICAST) {
1847 hdr->flags=QETH_CAST_MULTICAST|
1848 QETH_HEADER_PASSTHRU|
1849 QETH_HEADER_IPV6;
1850 } else if (multicast==RTN_ANYCAST) {
1851 hdr->flags=QETH_CAST_ANYCAST|
1852 QETH_HEADER_PASSTHRU|
1853 QETH_HEADER_IPV6;
1854 } else if (multicast==RTN_BROADCAST) {
1855 hdr->flags=QETH_CAST_BROADCAST|
1856 QETH_HEADER_PASSTHRU|
1857 QETH_HEADER_IPV6;
1858 } else { /* default: RTN_UNICAST */
1859 hdr->flags=QETH_CAST_UNICAST|
1860 QETH_HEADER_PASSTHRU|
1861 QETH_HEADER_IPV6;
1862 }
1863
1864 if ((skb->dst) && (skb->dst->neighbour)) {
1865 memcpy(hdr->dest_addr,
1866 skb->dst->neighbour->primary_key,16);
1867 } else {
1868 /* fill in destination address used
1869 * in ip header */
1870 memcpy(hdr->dest_addr,
1871 &skb->nh.ipv6h->daddr,16);
1872 }
1873 } else { /* passthrough */
1874 if (!memcmp(skb->data+QETH_HEADER_SIZE,
1875 skb->dev->broadcast,6)) { /* broadcast? */
1876 hdr->flags=QETH_CAST_BROADCAST|QETH_HEADER_PASSTHRU;
1877 } else {
1878 if (multicast==RTN_MULTICAST) {
1879 hdr->flags=QETH_CAST_MULTICAST|
1880 QETH_HEADER_PASSTHRU;
1881 } else {
1882 hdr->flags=QETH_CAST_UNICAST|
1883 QETH_HEADER_PASSTHRU;
1884 }
1885 }
1886 }
1887 #ifdef QETH_DBF_LIKE_HELL
1888 sprintf(dbf_text,"filhdr%2x",version);
1889 QETH_DBF_TEXT6(0,trace,dbf_text);
1890 sprintf(dbf_text,"%2x",multicast);
1891 QETH_DBF_TEXT6(0,trace,dbf_text);
1892 QETH_DBF_HEX6(0,trace,&skb,sizeof(void*));
1893 QETH_DBF_HEX6(0,trace,&skb->data,sizeof(void*));
1894 QETH_DBF_HEX6(0,misc,hdr,__max(QETH_HEADER_SIZE,QETH_DBF_MISC_LEN));
1895 QETH_DBF_HEX6(0,data,skb->data,
1896 __max(QETH_DBF_DATA_LEN,QETH_DBF_DATA_LEN));
1897 #endif /* QETH_DBF_LIKE_HELL */
1898 }
1899
qeth_fill_buffer(qdio_buffer_t * buffer,char * dataptr,int length,int element)1900 static inline int qeth_fill_buffer(qdio_buffer_t *buffer,char *dataptr,
1901 int length,int element)
1902 {
1903 int length_here;
1904 int first_lap=1;
1905 #ifdef QETH_DBF_LIKE_HELL
1906 char dbf_text[15];
1907 #endif /* QETH_DBF_LIKE_HELL */
1908 int first_element=element;
1909
1910 while (length>0) {
1911 /* length_here is the remaining amount of data in this page */
1912 length_here=PAGE_SIZE-((unsigned long)dataptr&(PAGE_SIZE-1));
1913 if (length<length_here) length_here=length;
1914
1915 buffer->element[element].addr=dataptr;
1916 buffer->element[element].length=length_here;
1917 length-=length_here;
1918 if (!length) {
1919 if (first_lap) {
1920 buffer->element[element].flags=0;
1921 } else {
1922 buffer->element[element].flags=
1923 SBAL_FLAGS_LAST_FRAG;
1924 }
1925 } else {
1926 if (first_lap) {
1927 buffer->element[element].flags=
1928 SBAL_FLAGS_FIRST_FRAG;
1929 } else {
1930 buffer->element[element].flags=
1931 SBAL_FLAGS_MIDDLE_FRAG;
1932 }
1933 }
1934 dataptr=dataptr+length_here;
1935 element++;
1936 if (element>QDIO_MAX_ELEMENTS_PER_BUFFER) {
1937 PRINT_ERR("qeth_fill_buffer: IP packet too big!\n");
1938 QETH_DBF_TEXT1(0,trace,"IPpktobg");
1939 QETH_DBF_HEX1(1,trace,&dataptr,sizeof(void*));
1940 buffer->element[first_element].length=0;
1941 break;
1942 }
1943 first_lap=0;
1944 }
1945 #ifdef QETH_DBF_LIKE_HELL
1946 sprintf(dbf_text,"filbuf%2x",element);
1947 QETH_DBF_TEXT6(0,trace,dbf_text);
1948 QETH_DBF_HEX3(0,misc,buffer,QETH_DBF_MISC_LEN);
1949 QETH_DBF_HEX3(0,misc,buffer+QETH_DBF_MISC_LEN,QETH_DBF_MISC_LEN);
1950 #endif /* QETH_DBF_LIKE_HELL */
1951
1952 return element;
1953 }
1954
qeth_flush_packed_packets(qeth_card_t * card,int queue,int under_int)1955 static inline void qeth_flush_packed_packets(qeth_card_t *card,int queue,
1956 int under_int)
1957 {
1958 qdio_buffer_t *buffer;
1959 int result;
1960 int position;
1961 int position_for_do_qdio;
1962 char dbf_text[15];
1963 int last_pci;
1964
1965 position=card->outbound_first_free_buffer[queue];
1966 /* can happen, when in the time between deciding to pack and sending
1967 the next packet the lower mark was reached: */
1968 if (!card->outbound_ringbuffer[queue]->ringbuf_element[position].
1969 next_element_to_fill)
1970 return;
1971
1972 buffer=&card->outbound_ringbuffer[queue]->buffer[position];
1973 buffer->element[card->outbound_ringbuffer[queue]->
1974 ringbuf_element[position].
1975 next_element_to_fill-1].flags|=SBAL_FLAGS_LAST_ENTRY;
1976
1977 card->dev->trans_start=jiffies;
1978
1979 #ifdef QETH_PERFORMANCE_STATS
1980 if (card->outbound_buffer_send_state[queue][position]==
1981 SEND_STATE_DONT_PACK) {
1982 card->perf_stats.bufs_sent_dont_pack++;
1983 } else if (card->outbound_buffer_send_state[queue][position]==
1984 SEND_STATE_PACK) {
1985 card->perf_stats.bufs_sent_pack++;
1986 }
1987 card->perf_stats.bufs_sent++;
1988 #endif /* QETH_PERFORMANCE_STATS */
1989
1990 position_for_do_qdio=position;
1991
1992 position=(position+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
1993 card->outbound_first_free_buffer[queue]=position;
1994
1995 card->outbound_bytes_in_buffer[queue]=0;
1996 /* we can override that, as we have at most 127 buffers enqueued */
1997 card->outbound_ringbuffer[queue]->ringbuf_element[position].
1998 next_element_to_fill=0;
1999
2000 atomic_inc(&card->outbound_used_buffers[queue]);
2001
2002 #ifdef QETH_DBF_LIKE_HELL
2003 sprintf(dbf_text,"flsp%4x",card->irq0);
2004 QETH_DBF_TEXT5(0,trace,dbf_text);
2005 sprintf(dbf_text,"%4x%2x%2x",position_for_do_qdio,under_int,queue);
2006 QETH_DBF_TEXT5(0,trace,dbf_text);
2007 QETH_DBF_HEX5(0,misc,buffer,QETH_DBF_MISC_LEN);
2008 QETH_DBF_HEX5(0,misc,buffer+QETH_DBF_MISC_LEN,QETH_DBF_MISC_LEN);
2009 #endif /* QETH_DBF_LIKE_HELL */
2010
2011 /* we always set the outbound pci flag, don't care, whether the
2012 * adapter honors it or not */
2013 switch (card->send_state[queue]) {
2014 case SEND_STATE_DONT_PACK:
2015 /* only request a PCI, if the fill level of the queue
2016 * is close to the high watermark, so that we don't
2017 * loose initiative during packing */
2018 if (atomic_read(&card->outbound_used_buffers[queue])
2019 <HIGH_WATERMARK_PACK-WATERMARK_FUZZ) break;
2020
2021 last_pci=atomic_read(&card->last_pci_pos[queue]);
2022 /* compensate queues that wrapped around */
2023 if (position_for_do_qdio<last_pci)
2024 last_pci-=QDIO_MAX_BUFFERS_PER_Q;
2025
2026 /* reduce the number of PCIs in cases where we are always
2027 * a little below the high watermark for packing -- request
2028 * PCIs less frequently */
2029 if (position_for_do_qdio-last_pci<
2030 HIGH_WATERMARK_PACK-WATERMARK_FUZZ) break;
2031
2032 /* set the PCI bit */
2033 card->outbound_ringbuffer[queue]->
2034 buffer[position_for_do_qdio].element[0].flags|=0x40;
2035 atomic_set(&card->last_pci_pos[queue],position_for_do_qdio);
2036 break;
2037 case SEND_STATE_PACK:
2038 last_pci=atomic_read(&card->last_pci_pos[queue]);
2039 if (position_for_do_qdio<last_pci)
2040 last_pci-=QDIO_MAX_BUFFERS_PER_Q;
2041 /* so:
2042 * last_pci is the position of the last pci we've set
2043 * position_for_do_qdio is the position we will send out now
2044 * outbound_used_buffers is the number of buffers used (means
2045 * all buffers OSA has, inclusive position_for_do_qdio)
2046 *
2047 * we have to request a pci, if we have got the buffer of the
2048 * last_pci position back.
2049 *
2050 * position_for_do_qdio-outbound_used_buffers is the newest
2051 * buffer that we got back from OSA
2052 *
2053 * if this is greater or equal than the last_pci position,
2054 * we should request a pci, as no pci request is
2055 * outstanding anymore
2056 */
2057 if (position_for_do_qdio-
2058 atomic_read(&card->outbound_used_buffers[queue])>=
2059 last_pci) {
2060 /* set the PCI bit */
2061 card->outbound_ringbuffer[queue]->
2062 buffer[position_for_do_qdio].
2063 element[0].flags|=0x40;
2064 atomic_set(&card->last_pci_pos[queue],
2065 position_for_do_qdio);
2066 }
2067 }
2068
2069 qeth_transform_outbound_addrs(card,
2070 &card->outbound_ringbuffer[queue]->
2071 buffer[position_for_do_qdio]);
2072 /* this has to be at the end, otherwise a buffer could be flushed
2073 twice (see coment in qeth_do_send_packet) */
2074 result=do_QDIO(card->irq2,QDIO_FLAG_SYNC_OUTPUT|under_int,queue,
2075 position_for_do_qdio,1,
2076 NULL);
2077
2078 if (result) {
2079 PRINT_WARN("Outbound do_QDIO returned %i " \
2080 "(irq 0x%x)\n",result,card->irq2);
2081 sprintf(dbf_text,"FLSP%4x",card->irq0);
2082 QETH_DBF_TEXT5(0,trace,dbf_text);
2083 sprintf(dbf_text,"odoQ%4x",result);
2084 QETH_DBF_TEXT5(0,trace,dbf_text);
2085 sprintf(dbf_text,"%4x%2x%2x",position_for_do_qdio,
2086 under_int,queue);
2087 QETH_DBF_TEXT5(0,trace,dbf_text);
2088 QETH_DBF_HEX5(0,misc,buffer,QETH_DBF_MISC_LEN);
2089 QETH_DBF_HEX5(0,misc,buffer+QETH_DBF_MISC_LEN,
2090 QETH_DBF_MISC_LEN);
2091 }
2092 }
2093
2094 #define ERROR_NONE 0
2095 #define ERROR_RETRY 1
2096 #define ERROR_LINK_FAILURE 2
2097 #define ERROR_KICK_THAT_PUPPY 3
qeth_determine_send_error(int cc,int qdio_error,int sbalf15)2098 static inline int qeth_determine_send_error(int cc,int qdio_error,int sbalf15)
2099 {
2100 char dbf_text[15];
2101
2102 switch (cc&3) {
2103 case 0:
2104 if (qdio_error)
2105 return ERROR_LINK_FAILURE;
2106 return ERROR_NONE;
2107 case 2:
2108 if (cc&QDIO_SIGA_ERROR_B_BIT_SET) {
2109 QETH_DBF_TEXT3(0,trace,"sigacc2b");
2110 return ERROR_KICK_THAT_PUPPY;
2111 }
2112 if (qeth_sbalf15_in_retrieable_range(sbalf15))
2113 return ERROR_RETRY;
2114 return ERROR_LINK_FAILURE;
2115 /* look at qdio_error and sbalf 15 */
2116 case 1:
2117 PRINT_WARN("siga returned cc 1! cc=0x%x, " \
2118 "qdio_error=0x%x, sbalf15=0x%x\n",
2119 cc,qdio_error,sbalf15);
2120
2121 QETH_DBF_TEXT3(0,trace,"siga-cc1");
2122 QETH_DBF_TEXT2(0,qerr,"siga-cc1");
2123 sprintf(dbf_text,"%1x%2x%2x",cc,qdio_error,sbalf15);
2124 QETH_DBF_TEXT3(0,trace,dbf_text);
2125 QETH_DBF_TEXT2(0,qerr,dbf_text);
2126 return ERROR_LINK_FAILURE;
2127 case 3:
2128 QETH_DBF_TEXT3(0,trace,"siga-cc3");
2129 return ERROR_KICK_THAT_PUPPY;
2130 }
2131 return ERROR_LINK_FAILURE; /* should never happen */
2132 }
2133
qeth_free_buffer(qeth_card_t * card,int queue,int bufno,int qdio_error,int siga_error)2134 static inline void qeth_free_buffer(qeth_card_t *card,int queue,int bufno,
2135 int qdio_error,int siga_error)
2136 {
2137 struct sk_buff *skb;
2138 int error;
2139 int retries;
2140 int sbalf15;
2141 char dbf_text[15];
2142 qdio_buffer_t *buffer;
2143
2144 switch (card->outbound_buffer_send_state[queue][bufno]) {
2145 case SEND_STATE_DONT_PACK: /* fallthrough */
2146 case SEND_STATE_PACK:
2147 #ifdef QETH_DBF_LIKE_HELL
2148 sprintf(dbf_text,"frbf%4x",card->irq0);
2149 QETH_DBF_TEXT5(0,trace,dbf_text);
2150 sprintf(dbf_text,"%2x%2x%4x",queue,bufno,
2151 card->outbound_buffer_send_state[queue][bufno]);
2152 QETH_DBF_TEXT5(0,trace,dbf_text);
2153 #endif /* QETH_DBF_LIKE_HELL */
2154
2155 buffer=&card->outbound_ringbuffer[queue]->buffer[bufno];
2156 sbalf15=buffer->element[15].flags&0xff;
2157 error=qeth_determine_send_error(siga_error,qdio_error,sbalf15);
2158 if (error==ERROR_KICK_THAT_PUPPY) {
2159 sprintf(dbf_text,"KP%4x%2x",card->irq0,queue);
2160 QETH_DBF_TEXT2(0,trace,dbf_text);
2161 QETH_DBF_TEXT2(0,qerr,dbf_text);
2162 QETH_DBF_TEXT2(1,setup,dbf_text);
2163 sprintf(dbf_text,"%2x%2x%2x%2x",bufno,
2164 siga_error,qdio_error,sbalf15);
2165 QETH_DBF_TEXT2(1,trace,dbf_text);
2166 QETH_DBF_TEXT2(1,qerr,dbf_text);
2167 PRINT_ERR("Outbound queue x%x on irq x%x (%s); " \
2168 "errs: siga: x%x, qdio: x%x, flags15: " \
2169 "x%x. The device will be taken down.\n",
2170 queue,card->irq0,card->dev_name,
2171 siga_error,qdio_error,sbalf15);
2172 netif_stop_queue(card->dev);
2173 qeth_set_dev_flag_norunning(card);
2174 atomic_set(&card->problem,PROBLEM_BAD_SIGA_RESULT);
2175 qeth_schedule_recovery(card);
2176 } else if (error==ERROR_RETRY) {
2177 /* analyze, how many retries we did so far */
2178 retries=card->send_retries[queue][bufno];
2179
2180 sprintf(dbf_text,"Rt%4x%2x",card->irq0,queue);
2181 QETH_DBF_TEXT4(0,trace,dbf_text);
2182 sprintf(dbf_text,"b%2x:%2x%2x",bufno,
2183 sbalf15,retries);
2184 QETH_DBF_TEXT4(0,trace,dbf_text);
2185
2186 if (++retries>SEND_RETRIES_ALLOWED) {
2187 error=ERROR_LINK_FAILURE;
2188 QETH_DBF_TEXT4(1,trace,"ndegelnd");
2189 }
2190 /* else error stays RETRY for the switch statemnet */
2191 } else if (error==ERROR_LINK_FAILURE) {
2192 /* we don't want to log failures resulting from
2193 * too many retries */
2194 sprintf(dbf_text,"Fail%4x",card->irq0);
2195 QETH_DBF_TEXT3(1,trace,dbf_text);
2196 QETH_DBF_HEX3(0,misc,buffer,QETH_DBF_MISC_LEN);
2197 QETH_DBF_HEX3(0,misc,buffer+QETH_DBF_MISC_LEN,
2198 QETH_DBF_MISC_LEN);
2199 }
2200
2201 while ((skb=skb_dequeue(&card->outbound_ringbuffer[queue]->
2202 ringbuf_element[bufno].skb_list))) {
2203 switch (error) {
2204 case ERROR_NONE:
2205 atomic_dec(&skb->users);
2206 dev_kfree_skb_irq(skb);
2207 break;
2208 case ERROR_RETRY:
2209 QETH_DBF_TEXT3(0,qerr,"RETRY!!!");
2210 QETH_DBF_TEXT4(0,trace,"RETRY!!!");
2211 /* retry packet async (quickly) ... */
2212 atomic_dec(&skb->users);
2213 dev_kfree_skb_irq(skb);
2214 break;
2215 case ERROR_LINK_FAILURE:
2216 case ERROR_KICK_THAT_PUPPY:
2217 QETH_DBF_TEXT4(0,trace,"endeglnd");
2218 card->stats->tx_dropped++;
2219 card->stats->tx_errors++;
2220 atomic_dec(&skb->users);
2221 dev_kfree_skb_irq(skb);
2222 break;
2223 }
2224 }
2225 break;
2226 default:
2227 PRINT_WARN("oops... wrong send_state on %s. " \
2228 "shouldn't happen " \
2229 "(line %i). q=%i, bufno=x%x, state=%i\n",
2230 card->dev_name,__LINE__,queue,bufno,
2231 card->outbound_buffer_send_state[queue][bufno]);
2232 sprintf(dbf_text,"UPSf%4x",card->irq0);
2233 QETH_DBF_TEXT0(1,trace,dbf_text);
2234 QETH_DBF_TEXT0(1,qerr,dbf_text);
2235 sprintf(dbf_text,"%2x%2x%4x",queue,bufno,
2236 card->outbound_buffer_send_state[queue][bufno]);
2237 QETH_DBF_TEXT0(1,trace,dbf_text);
2238 QETH_DBF_TEXT0(1,qerr,dbf_text);
2239 }
2240 card->outbound_buffer_send_state[queue][bufno]=SEND_STATE_INACTIVE;
2241 card->send_retries[queue][bufno]=0;
2242 }
2243
qeth_free_all_skbs(qeth_card_t * card)2244 static inline void qeth_free_all_skbs(qeth_card_t *card)
2245 {
2246 int q,b;
2247
2248 for (q=0;q<card->no_queues;q++)
2249 for (b=0;b<QDIO_MAX_BUFFERS_PER_Q;b++)
2250 if (card->outbound_buffer_send_state[q][b]!=
2251 SEND_STATE_INACTIVE)
2252 qeth_free_buffer(card,q,b,0,0);
2253 }
2254
qeth_flush_buffer(qeth_card_t * card,int queue,int under_int)2255 static inline void qeth_flush_buffer(qeth_card_t *card,int queue,
2256 int under_int)
2257 {
2258 #ifdef QETH_DBF_LIKE_HELL
2259 char dbf_text[15];
2260 sprintf(dbf_text,"flsb%4x",card->irq0);
2261 QETH_DBF_TEXT5(0,trace,dbf_text);
2262 sprintf(dbf_text,"%2x%2x%2x",queue,under_int,
2263 card->outbound_buffer_send_state[queue][
2264 card->outbound_first_free_buffer[queue] ]);
2265 QETH_DBF_TEXT5(0,trace,dbf_text);
2266 #endif /* QETH_DBF_LIKE_HELL */
2267
2268 switch (card->outbound_buffer_send_state[queue][
2269 card->outbound_first_free_buffer[queue] ]) {
2270 case SEND_STATE_DONT_PACK: break;
2271 case SEND_STATE_PACK:
2272 qeth_flush_packed_packets(card,queue,under_int);
2273 break;
2274 default:break;
2275 }
2276 }
2277 #ifdef QETH_VLAN
2278
qeth_insert_ipv6_vlan_tag(struct sk_buff * __skb)2279 static inline void qeth_insert_ipv6_vlan_tag(struct sk_buff *__skb)
2280 {
2281
2282 /* Move the mac addresses to the beginning of the new header.
2283 * We are using three memcpys instead of one memmove to save
2284 * cycles.
2285 */
2286 #define TMP_CPYSIZE 4
2287 __u16 *tag;
2288 tag = (__u16*)skb_push(__skb, VLAN_HLEN);
2289 memcpy(__skb->data,
2290 __skb->data+TMP_CPYSIZE,TMP_CPYSIZE);
2291 memcpy(__skb->data+TMP_CPYSIZE,
2292 __skb->data+(2*TMP_CPYSIZE),TMP_CPYSIZE);
2293 memcpy(__skb->data+(2*TMP_CPYSIZE),
2294 __skb->data+(3*TMP_CPYSIZE),TMP_CPYSIZE);
2295 tag = (__u16*)(__skb->data+(3*TMP_CPYSIZE));
2296
2297 /*first two bytes = ETH_P_8021Q (0x8100)
2298 *second two bytes = VLANID
2299 */
2300
2301 *tag = __constant_htons(ETH_P_8021Q);
2302 *(tag+1) = vlan_tx_tag_get(__skb);
2303 *(tag+1)=htons(*(tag+1));
2304 #undef TMP_CPYSIZE
2305 }
2306 #endif
2307
2308
2309
qeth_send_packet_fast(qeth_card_t * card,struct sk_buff * skb,struct net_device * dev,int queue,int version,int multicast)2310 static inline void qeth_send_packet_fast(qeth_card_t *card,struct sk_buff *skb,
2311 struct net_device *dev,
2312 int queue,int version,int multicast)
2313 {
2314 qeth_ringbuffer_element_t *mybuffer;
2315 int position;
2316 qeth_hdr_t *hdr;
2317 char *dataptr;
2318 char dbf_text[15];
2319 struct sk_buff *nskb;
2320
2321 position=card->outbound_first_free_buffer[queue];
2322
2323 card->outbound_buffer_send_state[queue][position]=SEND_STATE_DONT_PACK;
2324
2325 mybuffer=&card->outbound_ringbuffer[queue]->ringbuf_element[position];
2326 if (skb_headroom(skb)<QETH_HEADER_SIZE) {
2327 if ((version)&&(!card->realloc_message)) {
2328 card->realloc_message=1;
2329 PRINT_WARN("%s: not enough headroom in skb. " \
2330 "Increasing the " \
2331 "add_hhlen parameter by %i may help.\n",
2332 card->dev_name,
2333 QETH_HEADER_SIZE-skb_headroom(skb));
2334 }
2335 PRINT_STUPID("%s: not enough headroom in skb (missing: %i)\n",
2336 card->dev_name,QETH_HEADER_SIZE-skb_headroom(skb));
2337 sprintf(dbf_text,"NHRf%4x",card->irq0);
2338 QETH_DBF_TEXT3(0,trace,dbf_text);
2339 sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb),
2340 version,multicast,queue);
2341 QETH_DBF_TEXT3(0,trace,dbf_text);
2342 QETH_DBF_HEX3(0,trace,&skb->head,sizeof(void*));
2343 QETH_DBF_HEX3(0,trace,&skb->data,sizeof(void*));
2344 nskb=skb_realloc_headroom(skb,QETH_HEADER_SIZE);
2345 if (!nskb) {
2346 PRINT_WARN("%s: could not realloc headroom\n",
2347 card->dev_name);
2348 sprintf(dbf_text,"CNRf%4x",card->irq0);
2349 QETH_DBF_TEXT2(0,trace,dbf_text);
2350 dev_kfree_skb_irq(skb);
2351 return;
2352 }
2353 dev_kfree_skb_irq(skb);
2354 skb=nskb;
2355 }
2356 #ifdef QETH_VLAN
2357 if ( (card->vlangrp != NULL) &&
2358 vlan_tx_tag_present(skb) &&
2359 (version==6)) {
2360 qeth_insert_ipv6_vlan_tag(skb);
2361 }
2362 #endif
2363 hdr=(qeth_hdr_t*)(skb_push(skb,QETH_HEADER_SIZE));
2364 /* sanity check, the Linux memory allocation scheme should
2365 never present us cases like this one (the 32bytes header plus
2366 the first 40 bytes of the paket cross a 4k boundary) */
2367 dataptr=(char*)hdr;
2368 if ( (((unsigned long)dataptr)&(~(PAGE_SIZE-1))) !=
2369 ( ((unsigned long)dataptr+QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE)&
2370 (~(PAGE_SIZE-1)) ) ) {
2371 PRINT_ERR("%s: packet misaligned -- the first %i bytes " \
2372 "are not in the same page. Discarding packet!\n",
2373 card->dev_name,
2374 QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE);
2375 PRINT_ERR("head=%p, data=%p\n",skb->head,skb->data);
2376 sprintf(dbf_text,"PMAf%4x",card->irq0);
2377 QETH_DBF_TEXT1(0,trace,dbf_text);
2378 sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb),
2379 version,multicast,queue);
2380 QETH_DBF_TEXT1(0,trace,dbf_text);
2381 QETH_DBF_HEX1(0,trace,&skb->head,sizeof(void*));
2382 QETH_DBF_HEX1(1,trace,&skb->data,sizeof(void*));
2383 dev_kfree_skb_irq(skb);
2384 return;
2385 }
2386
2387 atomic_inc(&skb->users);
2388 skb_queue_tail(&mybuffer->skb_list,skb);
2389 qeth_fill_header(hdr,skb,version,multicast);
2390 /* we need to write to next_element_to_fill as
2391 qeth_flush_packed_packets checks it */
2392 card->outbound_ringbuffer[queue]->ringbuf_element[position].
2393 next_element_to_fill=
2394 qeth_fill_buffer(&card->outbound_ringbuffer[queue]->
2395 buffer[position],(char *)hdr,
2396 skb->len,0);
2397
2398 #ifdef QETH_PERFORMANCE_STATS
2399 card->perf_stats.skbs_sent_dont_pack++;
2400 #endif /* QETH_PERFORMANCE_STATS */
2401
2402 qeth_flush_packed_packets(card,queue,0);
2403 }
2404
2405 /* no checks, if all elements are used, as then we would not be here (at most
2406 127 buffers are enqueued) */
qeth_send_packet_packed(qeth_card_t * card,struct sk_buff * skb,struct net_device * dev,int queue,int version,int multicast)2407 static inline void qeth_send_packet_packed(qeth_card_t *card,
2408 struct sk_buff *skb,
2409 struct net_device *dev,
2410 int queue,int version,
2411 int multicast)
2412 {
2413 qeth_ringbuffer_element_t *mybuffer;
2414 int elements_needed;
2415 int element_to_fill;
2416 int buffer_no;
2417 int length;
2418 char *dataptr;
2419 qeth_hdr_t *hdr;
2420 char dbf_text[15];
2421 struct sk_buff *nskb;
2422
2423 /* sanity check, dev->hard_header_len should prevent this */
2424 if (skb_headroom(skb)<QETH_HEADER_SIZE) {
2425 if ((version)&&(!card->realloc_message)) {
2426 card->realloc_message=1;
2427 PRINT_WARN("%s: not enough headroom in skb. " \
2428 "Try increasing the " \
2429 "add_hhlen parameter by %i.\n",
2430 card->dev_name,
2431 QETH_HEADER_SIZE-skb_headroom(skb));
2432 }
2433 PRINT_STUPID("%s: not enough headroom in skb (missing: %i)\n",
2434 card->dev_name,QETH_HEADER_SIZE-skb_headroom(skb));
2435 sprintf(dbf_text,"NHRp%4x",card->irq0);
2436 QETH_DBF_TEXT3(0,trace,dbf_text);
2437 sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb),
2438 version,multicast,queue);
2439 QETH_DBF_TEXT3(0,trace,dbf_text);
2440 QETH_DBF_HEX3(0,trace,&skb->head,sizeof(void*));
2441 QETH_DBF_HEX3(0,trace,&skb->data,sizeof(void*));
2442 nskb=skb_realloc_headroom(skb,QETH_HEADER_SIZE);
2443 if (!nskb) {
2444 PRINT_WARN("%s: could not realloc headroom\n",
2445 card->dev_name);
2446 sprintf(dbf_text,"CNRp%4x",card->irq0);
2447 QETH_DBF_TEXT2(0,trace,dbf_text);
2448 dev_kfree_skb_irq(skb);
2449 return;
2450 }
2451 dev_kfree_skb_irq(skb);
2452 skb=nskb;
2453 }
2454 #ifdef QETH_VLAN
2455 if ( (card->vlangrp != NULL) &&
2456 vlan_tx_tag_present(skb) &&
2457 (version==6)) {
2458 qeth_insert_ipv6_vlan_tag(skb);
2459 }
2460
2461 #endif
2462 hdr=(qeth_hdr_t*)(skb_push(skb,QETH_HEADER_SIZE));
2463
2464 length=skb->len;
2465
2466 /* sanity check, the Linux memory allocation scheme should
2467 never present us cases like this one (the 32bytes header plus
2468 the first 40 bytes of the paket cross a 4k boundary) */
2469 dataptr=(char*)hdr;
2470 if ( (((unsigned long)dataptr)&(~(PAGE_SIZE-1))) !=
2471 ( ((unsigned long)dataptr+QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE)&
2472 (~(PAGE_SIZE-1)) ) ) {
2473 PRINT_ERR("%s: packet misaligned -- the first %i bytes " \
2474 "are not in the same page. Discarding packet!\n",
2475 card->dev_name,
2476 QETH_HEADER_SIZE+QETH_IP_HEADER_SIZE);
2477 sprintf(dbf_text,"PMAp%4x",card->irq0);
2478 QETH_DBF_TEXT1(0,trace,dbf_text);
2479 sprintf(dbf_text,"%2x%2x%2x%2x",skb_headroom(skb),
2480 version,multicast,queue);
2481 QETH_DBF_TEXT1(0,trace,dbf_text);
2482 QETH_DBF_HEX1(0,trace,&skb->head,sizeof(void*));
2483 QETH_DBF_HEX1(1,trace,&skb->data,sizeof(void*));
2484 dev_kfree_skb_irq(skb);
2485 return;
2486 }
2487
2488 buffer_no=card->outbound_first_free_buffer[queue];
2489
2490 element_to_fill=card->outbound_ringbuffer[queue]->
2491 ringbuf_element[buffer_no].
2492 next_element_to_fill;
2493
2494 elements_needed=1+( ( (((unsigned long)dataptr)&(PAGE_SIZE-1))+
2495 length ) >>PAGE_SHIFT);
2496 if ( (elements_needed>(QDIO_MAX_ELEMENTS_PER_BUFFER-element_to_fill)) ||
2497 ( (elements_needed==
2498 (QDIO_MAX_ELEMENTS_PER_BUFFER-element_to_fill)) &&
2499 ((element_to_fill>>PAGE_SHIFT)==
2500 card->outbound_bytes_in_buffer[queue]) ) ) {
2501 qeth_flush_packed_packets(card,queue,0);
2502 element_to_fill=0;
2503 card->outbound_bytes_in_buffer[queue]=0;
2504 buffer_no=(buffer_no+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
2505 }
2506
2507 if (!element_to_fill)
2508 card->outbound_buffer_send_state[queue][buffer_no]
2509 =SEND_STATE_PACK;
2510
2511 #ifdef QETH_PERFORMANCE_STATS
2512 card->perf_stats.skbs_sent_pack++;
2513 #endif /* QETH_PERFORMANCE_STATS */
2514
2515 mybuffer=&card->outbound_ringbuffer[queue]->ringbuf_element[buffer_no];
2516 atomic_inc(&skb->users);
2517 skb_queue_tail(&mybuffer->skb_list,skb);
2518 qeth_fill_header(hdr,skb,version,multicast);
2519 card->outbound_bytes_in_buffer[queue]+=length+QETH_HEADER_SIZE;
2520 card->outbound_ringbuffer[queue]->ringbuf_element[buffer_no].
2521 next_element_to_fill=
2522 qeth_fill_buffer(&card->outbound_ringbuffer[queue]->
2523 buffer[buffer_no],
2524 dataptr,length,element_to_fill);
2525 }
2526
qeth_alloc_spare_bufs(void)2527 static void qeth_alloc_spare_bufs(void)
2528 {
2529 int i;
2530 int dont_alloc_more=0;
2531 char dbf_text[15];
2532
2533 sparebuffer_count=0;
2534 for (i=0;i<qeth_sparebufs;i++) {
2535 if (!dont_alloc_more) {
2536 sparebufs[i].buf=(char*)
2537 kmalloc(DEFAULT_BUFFER_SIZE,GFP_KERNEL);
2538 if (sparebufs[i].buf)
2539 sparebuffer_count++;
2540 else
2541 dont_alloc_more=1;
2542 }
2543 atomic_set(&sparebufs[i].status,(dont_alloc_more)?
2544 SPAREBUF_UNAVAIL:SPAREBUF_FREE);
2545 }
2546 sprintf(dbf_text,"alspb%3x",sparebuffer_count);
2547 QETH_DBF_TEXT2(0,trace,dbf_text);
2548
2549 PRINT_INFO("allocated %i spare buffers\n",sparebuffer_count);
2550 }
2551
qeth_free_all_spare_bufs(void)2552 static void qeth_free_all_spare_bufs(void)
2553 {
2554 int i;
2555
2556 QETH_DBF_TEXT2(0,trace,"frealspb");
2557
2558 for (i=0;i<qeth_sparebufs;i++)
2559 if (atomic_read(&sparebufs[i].status)!=SPAREBUF_UNAVAIL) {
2560 kfree(sparebufs[i].buf);
2561 atomic_set(&sparebufs[i].status,SPAREBUF_UNAVAIL);
2562 }
2563 }
2564
atomic_return_sub(int i,atomic_t * v)2565 static __inline__ int atomic_return_sub(int i, atomic_t *v)
2566 {
2567 int old_val, new_val;
2568 __CS_LOOP(old_val, new_val, v, i, "sr");
2569 return old_val;
2570 }
2571
qeth_do_send_packet(qeth_card_t * card,struct sk_buff * skb,struct net_device * dev)2572 static inline int qeth_do_send_packet(qeth_card_t *card,struct sk_buff *skb,
2573 struct net_device *dev)
2574 {
2575 int queue,result=0;
2576 int multicast,version;
2577 char dbf_text[15];
2578 char dbf_text2[15]="stchupXX";
2579
2580 version=QETH_IP_VERSION(skb);
2581 multicast=qeth_is_multicast_skb_at_all(skb,version);
2582 queue=qeth_get_prioqueue(card,skb,multicast,version);
2583
2584 #ifdef QETH_DBF_LIKE_HELL
2585 sprintf(dbf_text,"dsp:%4x",card->irq0);
2586 QETH_DBF_TEXT6(0,trace,dbf_text);
2587 sprintf(dbf_text,"%c %c%4x",(version==4)?'4':((version==6)?'6':'0'),
2588 (multicast)?'m':'_',queue);
2589 QETH_DBF_TEXT6(0,trace,dbf_text);
2590 sprintf(dbf_text,"%4x%4x",
2591 card->outbound_first_free_buffer[queue],
2592 atomic_read(&card->outbound_used_buffers[queue]));
2593 QETH_DBF_TEXT6(0,trace,dbf_text);
2594 if (qeth_sbal_packing_on_card(card->type)) {
2595 switch (card->send_state[queue]) {
2596 case SEND_STATE_DONT_PACK:
2597 QETH_DBF_TEXT6(0,trace,"usngfast");
2598 break;
2599 case SEND_STATE_PACK:
2600 QETH_DBF_TEXT6(0,trace,"usngpack");
2601 break;
2602 }
2603 } else {
2604 QETH_DBF_TEXT6(0,trace,"usngfast");
2605 }
2606 #endif /* QETH_DBF_LIKE_HELL */
2607
2608 if (atomic_read(&card->outbound_used_buffers[queue])
2609 >=QDIO_MAX_BUFFERS_PER_Q-1) {
2610 sprintf(dbf_text,"cdbs%4x",card->irq0);
2611 QETH_DBF_TEXT2(1,trace,dbf_text);
2612 netif_stop_queue(dev);
2613 return -EBUSY;
2614 }
2615
2616 /* we are not called under int, so we just spin */
2617 /* happens around once a second under heavy traffic. takes a little
2618 * bit less than 10usec in avg. on a z900 */
2619 if (atomic_compare_and_swap(QETH_LOCK_UNLOCKED,QETH_LOCK_NORMAL,
2620 &card->outbound_ringbuffer_lock[queue])) {
2621 sprintf(dbf_text,"SPIN%4x",card->irq0);
2622 QETH_DBF_TEXT2(0,trace,dbf_text);
2623 while (atomic_compare_and_swap
2624 (QETH_LOCK_UNLOCKED,QETH_LOCK_NORMAL,
2625 &card->outbound_ringbuffer_lock[queue]))
2626 ;
2627 sprintf(dbf_text,"spin%4x",card->irq0);
2628 QETH_DBF_TEXT2(0,trace,dbf_text);
2629 }
2630
2631 #ifdef QETH_PERFORMANCE_STATS
2632 card->perf_stats.skbs_sent++;
2633 #endif /* QETH_PERFORMANCE_STATS */
2634
2635 if (qeth_sbal_packing_on_card(card->type)) {
2636 switch (card->send_state[queue]) {
2637 case SEND_STATE_DONT_PACK:
2638 qeth_send_packet_fast(card,skb,dev,queue,
2639 version,multicast);
2640 if (atomic_read(&card->outbound_used_buffers[queue])
2641 >=HIGH_WATERMARK_PACK) {
2642 card->send_state[queue]=SEND_STATE_PACK;
2643 *((__u16*)(&dbf_text2[6]))=card->irq0;
2644 QETH_DBF_HEX3(0,trace,dbf_text2,
2645 QETH_DBF_TRACE_LEN);
2646 #ifdef QETH_PERFORMANCE_STATS
2647 card->perf_stats.sc_dp_p++;
2648 #endif /* QETH_PERFORMANCE_STATS */
2649 }
2650 break;
2651 case SEND_STATE_PACK:
2652 qeth_send_packet_packed(card,skb,dev,queue,
2653 version,multicast);
2654 break;
2655 default:
2656 result=-EBUSY;
2657 sprintf(dbf_text,"UPSs%4x",card->irq0);
2658 QETH_DBF_TEXT0(1,trace,dbf_text);
2659 PRINT_ALL("oops... shouldn't happen (line %i:%i).\n",
2660 __LINE__,card->send_state[queue]);
2661 }
2662 } else {
2663 qeth_send_packet_fast(card,skb,dev,queue,
2664 version,multicast);
2665 }
2666
2667 again:
2668 /* ATOMIC: (NORMAL->UNLOCKED, FLUSH->NORMAL) */
2669 if (atomic_dec_return(&card->outbound_ringbuffer_lock[queue])) {
2670 qeth_flush_buffer(card,queue,0);
2671 card->send_state[queue]=SEND_STATE_DONT_PACK;
2672 goto again;
2673 }
2674
2675 #ifdef QETH_PERFORMANCE_STATS
2676 card->perf_stats.outbound_time+=
2677 NOW-card->perf_stats.outbound_start_time;
2678 card->perf_stats.outbound_cnt++;
2679 #endif /* QETH_PERFORMANCE_STATS */
2680
2681 card->stats->tx_packets++;
2682 card->stats->tx_bytes+=skb->len;
2683
2684 return result;
2685 }
2686
qeth_hard_start_xmit(struct sk_buff * skb,struct net_device * dev)2687 static int qeth_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
2688 {
2689 qeth_card_t *card;
2690 char dbf_text[15];
2691 int result;
2692 unsigned long stackptr;
2693
2694 card=(qeth_card_t*)(dev->priv);
2695
2696 if (skb==NULL)
2697 return 0;
2698
2699 #ifdef CONFIG_ARCH_S390X
2700 asm volatile ("lgr %0,15" : "=d" (stackptr));
2701 #else /* CONFIG_ARCH_S390X */
2702 asm volatile ("lr %0,15" : "=d" (stackptr));
2703 #endif /* CONFIG_ARCH_S390X */
2704 /* prevent stack overflows */
2705 /* normal and async stack is both 8k on s390 and 16k on s390x,
2706 * so it doesn't matter whether we're in an interrupt */
2707 if ( (stackptr & STACK_PTR_MASK)<
2708 (sizeof(struct task_struct) + WORST_CASE_STACK_USAGE) ) {
2709 PRINT_ERR("delaying packet transmission " \
2710 "due to potential stack overflow\n");
2711 sprintf(dbf_text,"STOF%4x",card->irq0);
2712 QETH_DBF_TEXT1(1,trace,dbf_text);
2713 PRINT_ERR("Backtrace follows:\n");
2714 show_trace((unsigned long *)stackptr);
2715 return -EBUSY;
2716 }
2717
2718 #ifdef QETH_DBF_LIKE_HELL
2719 QETH_DBF_HEX4(0,data,skb->data,__max(QETH_DBF_DATA_LEN,skb->len));
2720 #endif /* QETH_DBF_LIKE_HELL */
2721
2722 netif_stop_queue(dev);
2723
2724 if (!card) {
2725 QETH_DBF_TEXT2(0,trace,"XMNSNOCD");
2726 card->stats->tx_dropped++;
2727 card->stats->tx_errors++;
2728 dev_kfree_skb_irq(skb);
2729 return 0;
2730 }
2731
2732 #ifdef QETH_PERFORMANCE_STATS
2733 card->perf_stats.outbound_start_time=NOW;
2734 #endif /* QETH_PERFORMANCE_STATS */
2735
2736 if (!atomic_read(&card->is_startlaned)) {
2737 card->stats->tx_carrier_errors++;
2738 sprintf(dbf_text,"XMNS%4x",card->irq0);
2739 QETH_DBF_TEXT2(0,trace,dbf_text);
2740 card->stats->tx_dropped++;
2741 card->stats->tx_errors++;
2742 dev_kfree_skb_irq(skb);
2743 return 0;
2744 }
2745
2746 if (dev->hard_header == qeth_fake_header) {
2747 /*
2748 * in theory, if we run in undef-ed QETH_IPV6, we should
2749 * always unshare, because we do skb_push, then overwrite
2750 * that place with OSA header in qeth_send_packet_fast().
2751 * But it is only visible to one application - tcpdump.
2752 * Nobody else cares if (fake) MAC header gets smashed.
2753 * So, we only do it if fake_ll is in effect.
2754 */
2755 if ((skb = qeth_pskb_unshare(skb, GFP_ATOMIC)) == NULL) {
2756 card->stats->tx_dropped++;
2757 dev_kfree_skb_irq(skb);
2758 return 0;
2759 }
2760 skb_pull(skb, QETH_FAKE_LL_LEN);
2761 }
2762
2763 result=qeth_do_send_packet(card,skb,dev);
2764
2765 if (!result)
2766 netif_wake_queue(card->dev);
2767
2768 return result;
2769 }
2770
2771 /*
2772 * This function is needed to tell af_packet.c to process headers.
2773 * It is not called from there, but only from the transmit path,
2774 * when we do not need any actual header.
2775 *
2776 * N.B. Why do we insist on kludging here instead of fixing tcpdump?
2777 * Because tcpdump is shared among gazillions of platforms, and
2778 * there is a) no reliable way to identify qeth or its packets
2779 * in pcap-linux.c (sll->sll_halen is the only hope); b) no easy
2780 * way to pass this information from libpcap to tcpdump proper.
2781 *
2782 * XXX This fails with TR: traffic flows ok, but tcpdump remains confused.
2783 */
qeth_fake_header(struct sk_buff * skb,struct net_device * dev,unsigned short type,void * daddr,void * saddr,unsigned len)2784 int qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
2785 unsigned short type, void *daddr, void *saddr,
2786 unsigned len)
2787 {
2788 unsigned char *hdr;
2789
2790 hdr = skb_push(skb, QETH_FAKE_LL_LEN);
2791 memcpy(hdr, "FAKELLFAKELL", ETH_ALEN*2);
2792 if (type != ETH_P_802_3)
2793 *(u16 *)(hdr + ETH_ALEN*2) = htons(type);
2794 else
2795 *(u16 *)(hdr + ETH_ALEN*2) = htons(len);
2796
2797 /* XXX Maybe dev->hard_header_len here? Then skb_pull by same size. */
2798 return QETH_FAKE_LL_LEN;
2799 }
2800
qeth_get_stats(struct net_device * dev)2801 static struct net_device_stats* qeth_get_stats(struct net_device *dev)
2802 {
2803 qeth_card_t *card;
2804 char dbf_text[15];
2805
2806 card=(qeth_card_t*)(dev->priv);
2807
2808 sprintf(dbf_text,"gtst%4x",card->irq0);
2809 QETH_DBF_TEXT3(0,trace,dbf_text);
2810
2811 return card->stats;
2812 }
2813
qeth_change_mtu(struct net_device * dev,int new_mtu)2814 static int qeth_change_mtu(struct net_device *dev,int new_mtu)
2815 {
2816 qeth_card_t *card;
2817 char dbf_text[15];
2818
2819 card=(qeth_card_t*)(dev->priv);
2820
2821 sprintf(dbf_text,"mtu %4x",card->irq0);
2822 QETH_DBF_TEXT2(0,trace,dbf_text);
2823 sprintf(dbf_text,"%8x",new_mtu);
2824 QETH_DBF_TEXT2(0,trace,dbf_text);
2825
2826 if (new_mtu<64) return -EINVAL;
2827 if (new_mtu>65535) return -EINVAL;
2828 if ((!qeth_is_supported(IPA_IP_FRAGMENTATION)) &&
2829 (!qeth_mtu_is_valid(card,new_mtu)))
2830 return -EINVAL;
2831 dev->mtu=new_mtu;
2832 return 0;
2833 }
2834
qeth_start_softsetup_thread(qeth_card_t * card)2835 static void qeth_start_softsetup_thread(qeth_card_t *card)
2836 {
2837 char dbf_text[15];
2838 if (!atomic_read(&card->shutdown_phase)) {
2839 sprintf(dbf_text,"stss%4x",card->irq0);
2840 QETH_DBF_TEXT2(0,trace,dbf_text);
2841 up(&card->softsetup_thread_sem);
2842 }
2843 }
2844
qeth_sleepon(qeth_card_t * card,int timeout)2845 static int qeth_sleepon(qeth_card_t *card,int timeout)
2846 {
2847 unsigned long flags;
2848 unsigned long start;
2849 int retval;
2850 char dbf_text[15];
2851
2852 DECLARE_WAITQUEUE (current_wait_q,current);
2853
2854 sprintf(dbf_text,"slpn%4x",card->irq0);
2855 QETH_DBF_TEXT5(0,trace,dbf_text);
2856 sprintf(dbf_text,"%08x",timeout);
2857 QETH_DBF_TEXT5(0,trace,dbf_text);
2858
2859 add_wait_queue(&card->wait_q,¤t_wait_q);
2860 atomic_set(&card->wait_q_active,1);
2861 start=qeth_get_millis();
2862 for (;;) {
2863 set_task_state(current,TASK_INTERRUPTIBLE);
2864 if (atomic_read(&card->data_has_arrived)) {
2865 atomic_set(&card->data_has_arrived,0);
2866 retval=0;
2867 goto out;
2868 }
2869 if (qeth_get_millis()-start>timeout) {
2870 retval=-ETIME;
2871 goto out;
2872 }
2873 schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ);
2874 }
2875 out:
2876 spin_lock_irqsave(&card->wait_q_lock,flags);
2877 atomic_set(&card->wait_q_active,0);
2878 spin_unlock_irqrestore(&card->wait_q_lock,flags);
2879
2880 /* we've got to check once again to close the window */
2881 if (atomic_read(&card->data_has_arrived)) {
2882 atomic_set(&card->data_has_arrived,0);
2883 retval=0;
2884 }
2885
2886 set_task_state(current,TASK_RUNNING);
2887 remove_wait_queue(&card->wait_q,¤t_wait_q);
2888
2889 return retval;
2890 }
2891
qeth_wakeup_ioctl(qeth_card_t * card)2892 static void qeth_wakeup_ioctl(qeth_card_t *card) {
2893 char dbf_text[15];
2894
2895 sprintf(dbf_text,"wkup%4x",card->irq0);
2896 QETH_DBF_TEXT5(0,trace,dbf_text);
2897
2898 atomic_set(&card->ioctl_data_has_arrived,1);
2899 spin_lock(&card->ioctl_wait_q_lock);
2900 if (atomic_read(&card->ioctl_wait_q_active)) {
2901 wake_up(&card->ioctl_wait_q);
2902 }
2903 spin_unlock(&card->ioctl_wait_q_lock);
2904 }
2905
qeth_sleepon_ioctl(qeth_card_t * card,int timeout)2906 static int qeth_sleepon_ioctl(qeth_card_t *card,int timeout)
2907 {
2908 unsigned long flags;
2909 unsigned long start;
2910 int retval;
2911 char dbf_text[15];
2912
2913 DECLARE_WAITQUEUE (current_wait_q,current);
2914
2915 sprintf(dbf_text,"ioctlslpn%4x",card->irq0);
2916 QETH_DBF_TEXT5(0,trace,dbf_text);
2917 sprintf(dbf_text,"%08x",timeout);
2918 QETH_DBF_TEXT5(0,trace,dbf_text);
2919
2920 save_flags(flags);
2921 add_wait_queue(&card->ioctl_wait_q,¤t_wait_q);
2922 atomic_set(&card->ioctl_wait_q_active,1);
2923 start=qeth_get_millis();
2924 for (;;) {
2925 set_task_state(current,TASK_INTERRUPTIBLE);
2926 if (atomic_read(&card->ioctl_data_has_arrived)) {
2927 atomic_set(&card->ioctl_data_has_arrived,0);
2928 retval=0;
2929 goto out;
2930 }
2931 if (qeth_get_millis()-start>timeout) {
2932 retval=-ETIME;
2933 goto out;
2934 }
2935 schedule_timeout(((start+timeout-qeth_get_millis())>>10)*HZ);
2936 }
2937 out:
2938 spin_lock_irqsave(&card->ioctl_wait_q_lock,flags);
2939 atomic_set(&card->ioctl_wait_q_active,0);
2940 spin_unlock_irqrestore(&card->ioctl_wait_q_lock,flags);
2941
2942 /* we've got to check once again to close the window */
2943 if (atomic_read(&card->ioctl_data_has_arrived)) {
2944 atomic_set(&card->ioctl_data_has_arrived,0);
2945 retval=0;
2946 }
2947
2948 set_task_state(current,TASK_RUNNING);
2949 remove_wait_queue(&card->ioctl_wait_q,¤t_wait_q);
2950
2951 return retval;
2952 }
2953
qeth_snmp_notify(void)2954 static void qeth_snmp_notify(void)
2955 {
2956 /*notify all registered processes */
2957 struct list_head *l;
2958 struct qeth_notify_list *n_entry;
2959
2960 QETH_DBF_TEXT5(0,trace,"snmpnoti");
2961 spin_lock(¬ify_lock);
2962 list_for_each(l, ¬ify_list) {
2963 n_entry = list_entry(l, struct qeth_notify_list, list);
2964 send_sig(n_entry->signum, n_entry->task, 1);
2965 }
2966 spin_unlock(¬ify_lock);
2967 }
2968
qeth_send_control_data(qeth_card_t * card,unsigned char * buffer,int len,unsigned long intparam)2969 static char* qeth_send_control_data(qeth_card_t *card,unsigned char *buffer,
2970 int len,unsigned long intparam)
2971 {
2972 unsigned long flags;
2973 int result,result2;
2974 char dbf_text[15];
2975 unsigned char *rec_buf;
2976 int setip=(intparam&IPA_SETIP_FLAG)?1:0;
2977
2978 again:
2979 if (atomic_read(&card->shutdown_phase)==
2980 QETH_REMOVE_CARD_QUICK) return NULL;
2981 if (atomic_read(&card->escape_softsetup))
2982 return NULL;
2983
2984 /* we lock very early to synchronize access to seqnos */
2985 if (atomic_swap(&card->write_busy,1)) {
2986 qeth_wait_nonbusy(QETH_IDLE_WAIT_TIME);
2987 sprintf(dbf_text,"LSCD%4x",card->irq0);
2988 QETH_DBF_TEXT2(0,trace,dbf_text);
2989 goto again;
2990 }
2991 memcpy(card->dma_stuff->sendbuf,card->send_buf,QETH_BUFSIZE);
2992
2993 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(buffer),
2994 &card->seqno.trans_hdr,QETH_SEQ_NO_LENGTH);
2995 card->seqno.trans_hdr++;
2996
2997 memcpy(QETH_PDU_HEADER_SEQ_NO(buffer),
2998 &card->seqno.pdu_hdr,QETH_SEQ_NO_LENGTH);
2999 card->seqno.pdu_hdr++;
3000 memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(buffer),
3001 &card->seqno.pdu_hdr_ack,QETH_SEQ_NO_LENGTH);
3002
3003 /* there is noone doing this except sleep and this function */
3004 atomic_set(&card->data_has_arrived,0);
3005
3006 memcpy(&card->dma_stuff->write_ccw,WRITE_CCW,sizeof(ccw1_t));
3007 card->dma_stuff->write_ccw.count=len;
3008 card->dma_stuff->write_ccw.cda=
3009 QETH_GET_ADDR(card->dma_stuff->sendbuf);
3010
3011 sprintf(dbf_text,"scdw%4x",card->irq0);
3012 QETH_DBF_TEXT2(0,trace,dbf_text);
3013 sprintf(dbf_text,"%8x",len);
3014 QETH_DBF_TEXT4(0,trace,dbf_text);
3015 QETH_DBF_HEX4(0,trace,&intparam,QETH_DBF_TRACE_LEN);
3016 QETH_DBF_HEX2(0,control,buffer,QETH_DBF_CONTROL_LEN);
3017
3018 s390irq_spin_lock_irqsave(card->irq1,flags);
3019 result=do_IO(card->irq1,&card->dma_stuff->write_ccw,intparam,0,0);
3020 if (result) {
3021 qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO);
3022 result2=do_IO(card->irq1,&card->dma_stuff->write_ccw,
3023 intparam,0,0);
3024 if (result2!=-ENODEV)
3025 PRINT_WARN("qeth_send_control_data: do_IO " \
3026 "returned %i, next try returns %i\n",
3027 result,result2);
3028 result=result2;
3029 }
3030 s390irq_spin_unlock_irqrestore(card->irq1,flags);
3031
3032 if (result) {
3033 QETH_DBF_TEXT2(0,trace,"scd:doio");
3034 sprintf(dbf_text,"%4x",(__s16)result);
3035 QETH_DBF_TEXT2(0,trace,dbf_text);
3036 /* re-enable qeth_send_control_data again */
3037 atomic_set(&card->write_busy,0);
3038 return NULL;
3039 }
3040
3041 if (intparam==IPA_IOCTL_STATE) {
3042 if (qeth_sleepon_ioctl(card,QETH_IPA_TIMEOUT)) {
3043 QETH_DBF_TEXT2(0,trace,"scd:ioct");
3044 /* re-enable qeth_send_control_data again */
3045 atomic_set(&card->write_busy,0);
3046 return NULL;
3047 }
3048 rec_buf=card->dma_stuff->recbuf;
3049 sprintf(dbf_text,"scro%4x",card->irq0);
3050 } else {
3051 if (qeth_sleepon(card,(setip)?QETH_IPA_TIMEOUT:
3052 QETH_MPC_TIMEOUT)) {
3053 QETH_DBF_TEXT2(0,trace,"scd:time");
3054 /* re-enable qeth_send_control_data again */
3055 atomic_set(&card->write_busy,0);
3056 return NULL;
3057 }
3058 rec_buf=card->ipa_buf;
3059 sprintf(dbf_text,"scri%4x",card->irq0);
3060 }
3061 QETH_DBF_TEXT2(0,trace,dbf_text);
3062 QETH_DBF_HEX2(0,control,rec_buf,QETH_DBF_CONTROL_LEN);
3063
3064 memcpy(&card->seqno.pdu_hdr_ack,
3065 QETH_PDU_HEADER_SEQ_NO(rec_buf),
3066 QETH_SEQ_NO_LENGTH);
3067
3068 return rec_buf;
3069 }
3070
qeth_send_ipa_cmd(qeth_card_t * card,ipa_cmd_t * cmd,int update_cmd,int ipatype)3071 static int qeth_send_ipa_cmd(qeth_card_t *card,ipa_cmd_t *cmd,int update_cmd,
3072 int ipatype)
3073 {
3074 unsigned char *buffer;
3075 ipa_cmd_t *reply;
3076 int ipa_cmd;
3077 int result;
3078
3079 /* don't muck around with ipv6 if there's no use to do so */
3080 if ( (cmd->prot_version==6) &&
3081 (!qeth_is_supported(IPA_IPv6)) ) return 0;
3082
3083 ipa_cmd=cmd->command;
3084
3085 memcpy(card->send_buf,IPA_PDU_HEADER,
3086 IPA_PDU_HEADER_SIZE);
3087
3088 memcpy(QETH_IPA_CMD_DEST_ADDR(card->send_buf),
3089 &card->token.ulp_connection_r,QETH_MPC_TOKEN_LENGTH);
3090
3091 memcpy(card->send_buf+IPA_PDU_HEADER_SIZE,
3092 cmd,sizeof(ipa_cmd_t));
3093
3094 buffer=qeth_send_control_data(card,card->send_buf,
3095 IPA_PDU_HEADER_SIZE+sizeof(ipa_cmd_t),
3096 ipatype);
3097
3098 if (!buffer) {
3099 if (atomic_read(&card->escape_softsetup)) result=0;
3100 else result=-1;
3101 } else {
3102 reply=(ipa_cmd_t*)PDU_ENCAPSULATION(buffer);
3103 if ((update_cmd)&&(reply)) memcpy(cmd,reply,sizeof(ipa_cmd_t));
3104 result=reply->return_code;
3105
3106 if ((ipa_cmd==IPA_CMD_SETASSPARMS)&&(result==0)) {
3107 result=reply->data.setassparms.return_code;
3108 }
3109 if ((ipa_cmd==IPA_CMD_SETADAPTERPARMS)&&(result==0)) {
3110 result=reply->data.setadapterparms.return_code;
3111 }
3112 if ( (ipa_cmd==IPA_CMD_SETASSPARMS) &&
3113 (result==0) &&
3114 (reply->data.setassparms.assist_no==
3115 IPA_INBOUND_CHECKSUM) &&
3116 (reply->data.setassparms.command_code==
3117 IPA_CMD_ASS_START) ) {
3118 card->csum_enable_mask=
3119 reply->data.setassparms.data.flags_32bit;
3120 }
3121 }
3122 return result;
3123 }
3124
qeth_fill_ipa_cmd(qeth_card_t * card,ipa_cmd_t * cmd,__u8 command,int ip_vers)3125 static void qeth_fill_ipa_cmd(qeth_card_t *card,ipa_cmd_t *cmd,
3126 __u8 command,int ip_vers)
3127 {
3128 memset(cmd,0,sizeof(ipa_cmd_t));
3129 cmd->command=command;
3130 cmd->initiator=INITIATOR_HOST;
3131 cmd->seq_no=card->seqno.ipa++;
3132 cmd->adapter_type=qeth_get_adapter_type_for_ipa(card->link_type);
3133 cmd->rel_adapter_no=(__u8)card->options.portno;
3134 cmd->prim_version_no=1;
3135 cmd->param_count=1;
3136 cmd->prot_version=ip_vers;
3137 cmd->ipa_supported=0;
3138 cmd->ipa_enabled=0;
3139 }
3140
qeth_send_startstoplan(qeth_card_t * card,__u8 ipacmd,__u16 ip_vers)3141 static int qeth_send_startstoplan(qeth_card_t *card,__u8 ipacmd,__u16 ip_vers)
3142 {
3143 ipa_cmd_t cmd;
3144 int result;
3145
3146 qeth_fill_ipa_cmd(card,&cmd,ipacmd,0);
3147 cmd.param_count=0;
3148 cmd.prot_version=ip_vers;
3149 cmd.ipa_supported=0;
3150 cmd.ipa_enabled=0;
3151
3152 result=qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE);
3153 return result;
3154 }
3155
qeth_send_startlan(qeth_card_t * card,__u16 ip_vers)3156 static int qeth_send_startlan(qeth_card_t *card,__u16 ip_vers)
3157 {
3158 int result;
3159 char dbf_text[15];
3160
3161 sprintf(dbf_text,"stln%4x",card->irq0);
3162 QETH_DBF_TEXT4(0,trace,dbf_text);
3163
3164 result=qeth_send_startstoplan(card,IPA_CMD_STARTLAN,ip_vers);
3165 if (!result) atomic_set(&card->is_startlaned,1);
3166
3167 if (result) {
3168 QETH_DBF_TEXT2(0,trace,"STRTLNFL");
3169 sprintf(dbf_text,"%4x%4x",card->irq0,result);
3170 QETH_DBF_TEXT2(0,trace,dbf_text);
3171 }
3172
3173 return result;
3174 }
3175
qeth_send_stoplan(qeth_card_t * card)3176 static int qeth_send_stoplan(qeth_card_t *card)
3177 {
3178 #ifdef QETH_SEND_STOPLAN_ON_SHUTDOWN
3179 int result;
3180 char dbf_text[15];
3181
3182 atomic_set(&card->is_startlaned,0);
3183
3184 sprintf(dbf_text,"spln%4x",card->irq0);
3185 QETH_DBF_TEXT4(0,trace,dbf_text);
3186
3187 result=qeth_send_startstoplan(card,IPA_CMD_STOPLAN,4);
3188
3189 if (result) {
3190 QETH_DBF_TEXT2(0,trace,"STPLNFLD");
3191 sprintf(dbf_text,"%4x%4x",card->irq0,result);
3192 QETH_DBF_TEXT2(0,trace,dbf_text);
3193 }
3194
3195 return result;
3196 #else /* QETH_SEND_STOPLAN_ON_SHUTDOWN */
3197 return 0;
3198 #endif /* QETH_SEND_STOPLAN_ON_SHUTDOWN */
3199 }
3200
qeth_send_qipassist(qeth_card_t * card,short ip_vers)3201 static int qeth_send_qipassist(qeth_card_t *card,short ip_vers)
3202 {
3203 ipa_cmd_t cmd;
3204 int result;
3205
3206 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_QIPASSIST,ip_vers);
3207
3208 result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE);
3209
3210 if (!result) {
3211 if (ip_vers==4) {
3212 card->ipa_supported=cmd.ipa_supported;
3213 card->ipa_enabled=cmd.ipa_enabled;
3214 } else {
3215 card->ipa6_supported=cmd.ipa_supported;
3216 card->ipa6_enabled=cmd.ipa_enabled;
3217 }
3218 }
3219
3220 return result;
3221 }
3222
qeth_send_ipa_arpcmd(qeth_card_t * card,arp_cmd_t * cmd,int update_cmd,int ipatype,__u32 req_size)3223 static int qeth_send_ipa_arpcmd(qeth_card_t *card,arp_cmd_t *cmd,
3224 int update_cmd,int ipatype,__u32 req_size)
3225 {
3226 unsigned char *buffer;
3227 int ipa_cmd;
3228 int result;
3229 __u16 s1,s2;
3230
3231 /* don't muck around with ipv6 if there's no use to do so */
3232 if ( (cmd->prot_version==6) &&
3233 (!qeth_is_supported(IPA_IPv6)) ) return 0;
3234 result = 0;
3235 ipa_cmd=cmd->command;
3236
3237 memcpy(card->send_buf,IPA_PDU_HEADER,
3238 IPA_PDU_HEADER_SIZE);
3239 memcpy(QETH_IPA_CMD_DEST_ADDR(card->send_buf),
3240 &card->token.ulp_connection_r,QETH_MPC_TOKEN_LENGTH);
3241 memcpy(card->send_buf+IPA_PDU_HEADER_SIZE,
3242 cmd,sizeof(arp_cmd_t));
3243
3244 if (req_size) {
3245 /* adjust sizes for big requests */
3246 s1=(__u32)IPA_PDU_HEADER_SIZE+SNMP_BASE_CMDLENGTH+req_size;
3247 s2=(__u32)SNMP_BASE_CMDLENGTH+req_size;
3248 memcpy(QETH_IPA_PDU_LEN_TOTAL(card->send_buf),&s1,2);
3249 memcpy(QETH_IPA_PDU_LEN_PDU1(card->send_buf),&s2,2);
3250 memcpy(QETH_IPA_PDU_LEN_PDU2(card->send_buf),&s2,2);
3251 memcpy(QETH_IPA_PDU_LEN_PDU3(card->send_buf),&s2,2);
3252 }
3253
3254 buffer=qeth_send_control_data(card,card->send_buf,
3255 IPA_PDU_HEADER_SIZE+sizeof(arp_cmd_t),
3256 ipatype);
3257 if (!buffer)
3258 result = -ENODATA;
3259 else
3260 result = card->ioctl_returncode;
3261 return result;
3262 }
3263
qeth_ioctl_handle_snmp_data(qeth_card_t * card,arp_cmd_t * reply)3264 static int qeth_ioctl_handle_snmp_data(qeth_card_t *card,arp_cmd_t *reply)
3265 {
3266 __u16 data_len;
3267
3268 #define SNMP_HEADER_SIZE_WITH_TOKEN 36
3269
3270 data_len = *((__u16*)QETH_IPA_PDU_LEN_PDU1(card->dma_stuff->recbuf));
3271
3272 if (reply->data.setadapterparms.frame_seq_no == 1) {
3273 data_len = data_len -
3274 (__u16)((char*)reply->data.setadapterparms.
3275 data.snmp_subcommand.
3276 snmp_data - (char*)reply);
3277 } else {
3278 data_len = data_len -
3279 (__u16)((char*)&reply->data.setadapterparms.data.
3280 snmp_subcommand.
3281 snmp_request - (char*)reply);
3282 }
3283 if (reply->data.setadapterparms.frame_seq_no == 1) {
3284 if (card->ioctl_buffersize <= (SNMP_HEADER_SIZE_WITH_TOKEN +
3285 reply->data.setadapterparms.frames_used_total *
3286 ARP_DATA_SIZE)) {
3287 card->ioctl_returncode = ARP_RETURNCODE_ERROR;
3288 reply->data.setadapterparms.data.
3289 snmp_subcommand.snmp_returncode = -ENOMEM;
3290 } else {
3291 card->ioctl_returncode = ARP_RETURNCODE_SUCCESS;
3292 card->number_of_entries = 0;
3293 memcpy(((char *)card->ioctl_data_buffer),
3294 reply->data.setadapterparms.snmp_token,
3295 SNMP_HEADER_SIZE_WITH_TOKEN);
3296 card->ioctl_buffer_pointer = card->ioctl_data_buffer+
3297 SNMP_HEADER_SIZE_WITH_TOKEN;
3298 }
3299 }
3300
3301 if (card->ioctl_returncode != ARP_RETURNCODE_ERROR &&
3302 reply->data.setadapterparms.frame_seq_no <=
3303 reply->data.setadapterparms.frames_used_total) {
3304 if (reply->data.setadapterparms.return_code==
3305 IPA_REPLY_SUCCESS) {
3306 if (reply->data.setadapterparms.frame_seq_no == 1) {
3307 memcpy(card->ioctl_buffer_pointer,
3308 reply->data.setadapterparms.data.
3309 snmp_subcommand.snmp_data,data_len);
3310 } else {
3311 memcpy(card->ioctl_buffer_pointer,
3312 (char*)&reply->data.setadapterparms.
3313 data.snmp_subcommand.
3314 snmp_request,data_len);
3315 }
3316 card->ioctl_buffer_pointer =
3317 card->ioctl_buffer_pointer + data_len;
3318 card->ioctl_returncode = ARP_RETURNCODE_SUCCESS;
3319
3320 if (reply->data.setadapterparms.frame_seq_no ==
3321 reply->data.setadapterparms.frames_used_total) {
3322 card->ioctl_returncode =
3323 ARP_RETURNCODE_LASTREPLY;
3324 }
3325 } else {
3326 card->ioctl_returncode = ARP_RETURNCODE_ERROR;
3327 memset(card->ioctl_data_buffer,0,
3328 card->ioctl_buffersize);
3329 reply->data.setadapterparms.data.
3330 snmp_subcommand.snmp_returncode =
3331 reply->data.setadapterparms.return_code;
3332 }
3333 }
3334 #undef SNMP_HEADER_SIZE_WITH_TOKEN
3335
3336 return card->ioctl_returncode;
3337 }
3338
qeth_ioctl_handle_arp_data(qeth_card_t * card,arp_cmd_t * reply)3339 static int qeth_ioctl_handle_arp_data(qeth_card_t *card, arp_cmd_t *reply)
3340 {
3341 if ( (reply->data.setassparms.command_code==
3342 IPA_CMD_ASS_ARP_SET_NO_ENTRIES) ||
3343 (reply->data.setassparms.command_code==
3344 IPA_CMD_ASS_ARP_ADD_ENTRY) ||
3345 (reply->data.setassparms.command_code==
3346 IPA_CMD_ASS_ARP_REMOVE_ENTRY) ) {
3347 if (reply->data.setassparms.return_code) {
3348 return ARP_RETURNCODE_ERROR;
3349 } else {
3350 return ARP_RETURNCODE_LASTREPLY;
3351 }
3352 }
3353 if (reply->data.setassparms.seq_no == 1) {
3354 if (card->ioctl_buffersize <=
3355 (sizeof(__u16) + sizeof(int) + reply->data.
3356 setassparms.number_of_replies * ARP_DATA_SIZE)) {
3357 card->ioctl_returncode = ARP_RETURNCODE_ERROR;
3358 } else {
3359 card->ioctl_returncode = ARP_RETURNCODE_SUCCESS;
3360 card->number_of_entries = 0;
3361 card->ioctl_buffer_pointer = card->ioctl_data_buffer+
3362 sizeof(__u16) + sizeof(int);
3363 }
3364 }
3365
3366 if (card->ioctl_returncode != ARP_RETURNCODE_ERROR &&
3367 reply->data.setassparms.seq_no <=
3368 reply->data.setassparms.number_of_replies) {
3369
3370 if (reply->data.setassparms.return_code==IPA_REPLY_SUCCESS) {
3371
3372 card->number_of_entries = card->number_of_entries +
3373 reply->data.setassparms.
3374 data.queryarp_data.
3375 number_of_entries;
3376 memcpy(card->ioctl_buffer_pointer,
3377 reply->data.setassparms.data.queryarp_data.
3378 arp_data,ARP_DATA_SIZE);
3379 card->ioctl_buffer_pointer = card->
3380 ioctl_buffer_pointer + ARP_DATA_SIZE;
3381 card->ioctl_returncode = ARP_RETURNCODE_SUCCESS;
3382 if (reply->data.setassparms.seq_no ==
3383 reply->data.setassparms.number_of_replies) {
3384 memcpy(card->ioctl_data_buffer,
3385 &reply->data.setassparms.data.
3386 queryarp_data.osa_setbitmask,
3387 sizeof(__u16));
3388 card->ioctl_returncode=
3389 ARP_RETURNCODE_LASTREPLY;
3390 }
3391 } else {
3392 card->ioctl_returncode = ARP_RETURNCODE_ERROR;
3393 memset(card->ioctl_data_buffer,0,
3394 card->ioctl_buffersize);
3395 }
3396 }
3397 return card->ioctl_returncode;
3398 }
qeth_is_arp_command(int cmd)3399 static int qeth_is_arp_command(int cmd)
3400 {
3401 switch (cmd) {
3402 case IPA_CMD_ASS_ARP_SET_NO_ENTRIES:
3403 case IPA_CMD_ASS_ARP_QUERY_CACHE:
3404 case IPA_CMD_ASS_ARP_ADD_ENTRY:
3405 case IPA_CMD_ASS_ARP_REMOVE_ENTRY:
3406 case IPA_CMD_ASS_ARP_FLUSH_CACHE:
3407 case IPA_CMD_ASS_ARP_QUERY_INFO:
3408 case IPA_CMD_ASS_ARP_QUERY_STATS:
3409 return 1;
3410 default:
3411 return 0;
3412 }
3413 }
3414
qeth_look_for_arp_data(qeth_card_t * card)3415 static int qeth_look_for_arp_data(qeth_card_t *card)
3416 {
3417 arp_cmd_t *reply;
3418 int result;
3419
3420
3421 reply=(arp_cmd_t*)PDU_ENCAPSULATION(card->dma_stuff->recbuf);
3422
3423 if ( (reply->command==IPA_CMD_SETASSPARMS) &&
3424 (reply->data.setassparms.assist_no==IPA_ARP_PROCESSING) &&
3425 (reply->data.setassparms.command_code==
3426 IPA_CMD_ASS_ARP_FLUSH_CACHE) ) {
3427 result=ARP_FLUSH;
3428 } else if ( (reply->command == IPA_CMD_SETASSPARMS) &&
3429 (reply->data.setassparms.assist_no == IPA_ARP_PROCESSING) &&
3430 (qeth_is_arp_command(reply->data.setassparms.command_code)) ) {
3431 result = qeth_ioctl_handle_arp_data(card,reply);
3432 } else if ( (reply->command == IPA_CMD_SETADAPTERPARMS) &&
3433 (reply->data.setadapterparms.command_code ==
3434 IPA_SETADP_SET_SNMP_CONTROL) &&
3435 (card->ioctl_returncode == ARP_RETURNCODE_SUCCESS) ){
3436 result = qeth_ioctl_handle_snmp_data(card,reply);
3437 } else
3438 result = ARP_RETURNCODE_NOARPDATA;
3439
3440 return result;
3441 }
3442
3443
3444
qeth_queryarp(qeth_card_t * card,struct ifreq * req,int version,__u32 assist_no,__u16 command_code,char * c_data,__u16 len)3445 static int qeth_queryarp(qeth_card_t *card,struct ifreq *req,int version,
3446 __u32 assist_no, __u16 command_code,char *c_data,
3447 __u16 len)
3448 {
3449 int data_size;
3450 arp_cmd_t *cmd;
3451 int result;
3452
3453
3454 cmd = (arp_cmd_t *) kmalloc(sizeof(arp_cmd_t),GFP_KERNEL);
3455 if (!cmd) {
3456 return IPA_REPLY_FAILED;
3457 }
3458
3459 memcpy(&data_size,c_data,sizeof(int));
3460
3461 qeth_fill_ipa_cmd(card,(ipa_cmd_t*)cmd,IPA_CMD_SETASSPARMS,version);
3462
3463 cmd->data.setassparms.assist_no=assist_no;
3464 cmd->data.setassparms.length=8+len;
3465 cmd->data.setassparms.command_code=command_code;
3466 cmd->data.setassparms.return_code=0;
3467 cmd->data.setassparms.seq_no=0;
3468
3469 card->ioctl_buffersize = data_size;
3470 card->ioctl_data_buffer = (char *) vmalloc(data_size);
3471 if (!card->ioctl_data_buffer) {
3472 kfree(cmd);
3473 return IPA_REPLY_FAILED;
3474 }
3475
3476 card->ioctl_returncode = ARP_RETURNCODE_SUCCESS;
3477
3478 result=qeth_send_ipa_arpcmd(card,cmd,1,IPA_IOCTL_STATE,0);
3479
3480 if ((result == ARP_RETURNCODE_ERROR) ||
3481 (result == -ENODATA)) {
3482 result = IPA_REPLY_FAILED;
3483 }
3484 else {
3485 result = IPA_REPLY_SUCCESS;
3486 memcpy(((char *)(card->ioctl_data_buffer)) + sizeof(__u16),
3487 &(card->number_of_entries),sizeof(int));
3488 if (copy_to_user(req->ifr_ifru.ifru_data,
3489 card->ioctl_data_buffer,data_size))
3490 result =-EFAULT;
3491 }
3492 card->ioctl_buffer_pointer = NULL;
3493 vfree(card->ioctl_data_buffer);
3494 kfree(cmd);
3495 card->number_of_entries = 0;
3496 card->ioctl_buffersize = 0;
3497
3498 return result;
3499 }
3500
snmp_set_setadapterparms_command(qeth_card_t * card,arp_cmd_t * cmd,struct ifreq * req,char * data,__u16 len,__u16 command_code,int req_size)3501 static int snmp_set_setadapterparms_command(qeth_card_t *card,
3502 arp_cmd_t *cmd,struct ifreq *req,
3503 char *data,__u16 len,
3504 __u16 command_code,int req_size)
3505 {
3506 __u32 data_size;
3507
3508 memcpy(&data_size,data,sizeof(__u32));
3509
3510 card->ioctl_buffersize = data_size;
3511 card->ioctl_data_buffer = (char *) vmalloc(data_size);
3512 if (!card->ioctl_data_buffer) {
3513 return -ENOMEM;
3514 }
3515 card->ioctl_returncode = ARP_RETURNCODE_SUCCESS;
3516
3517 memcpy(cmd->data.setadapterparms.snmp_token,
3518 data+SNMP_REQUEST_DATA_OFFSET,req_size);
3519
3520 cmd->data.setadapterparms.cmdlength=SNMP_SETADP_CMDLENGTH+req_size;
3521 cmd->data.setadapterparms.command_code = command_code;
3522 cmd->data.setadapterparms.frames_used_total=1;
3523 cmd->data.setadapterparms.frame_seq_no=1;
3524
3525 return 0;
3526 }
3527
qeth_send_snmp_control(qeth_card_t * card,struct ifreq * req,__u32 command,__u16 command_code,char * c_data,__u16 len)3528 static int qeth_send_snmp_control(qeth_card_t *card,struct ifreq *req,
3529 __u32 command,__u16 command_code,
3530 char *c_data,__u16 len)
3531 {
3532 arp_cmd_t *cmd;
3533 __u32 result,req_size;
3534
3535 cmd = (arp_cmd_t *) kmalloc(sizeof(arp_cmd_t),GFP_KERNEL);
3536 if (!cmd) {
3537 return IPA_REPLY_FAILED;
3538 }
3539
3540 qeth_fill_ipa_cmd(card,(ipa_cmd_t*)cmd,command,4);
3541
3542 memcpy(&req_size,((char*)c_data)+sizeof(__u32),sizeof(__u32));
3543
3544 if (snmp_set_setadapterparms_command(card,cmd,req,c_data,
3545 len,command_code,req_size))
3546 {
3547 kfree(cmd);
3548 return IPA_REPLY_FAILED;
3549 }
3550
3551 result=qeth_send_ipa_arpcmd(card,cmd,1,IPA_IOCTL_STATE,req_size);
3552
3553 if (result == -ENODATA) {
3554 result = IPA_REPLY_FAILED;
3555 goto snmp_out;
3556 }
3557 if (result == ARP_RETURNCODE_ERROR )
3558 result = IPA_REPLY_FAILED;
3559 else
3560 result = IPA_REPLY_SUCCESS;
3561
3562 if (copy_to_user(req->ifr_ifru.ifru_data + SNMP_REQUEST_DATA_OFFSET,
3563 card->ioctl_data_buffer, card->ioctl_buffersize))
3564 result = -EFAULT;
3565 snmp_out:
3566 card->number_of_entries = 0;
3567 card->ioctl_buffersize = 0;
3568 card->ioctl_buffer_pointer = NULL;
3569 vfree(card->ioctl_data_buffer);
3570 kfree(cmd);
3571
3572 return result;
3573 }
3574
qeth_send_setassparms(qeth_card_t * card,int version,__u32 assist_no,__u16 command_code,long data,__u16 len)3575 static int qeth_send_setassparms(qeth_card_t *card,int version,
3576 __u32 assist_no,__u16 command_code,
3577 long data,__u16 len)
3578 {
3579 ipa_cmd_t cmd;
3580 int result;
3581
3582 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETASSPARMS,version);
3583
3584 cmd.data.setassparms.assist_no=assist_no;
3585 cmd.data.setassparms.length=8+len;
3586 cmd.data.setassparms.command_code=command_code;
3587 cmd.data.setassparms.return_code=0;
3588 cmd.data.setassparms.seq_no=0;
3589
3590 if (len<=sizeof(__u32))
3591 cmd.data.setassparms.data.flags_32bit=(__u32)data;
3592 else if (len>sizeof(__u32))
3593 memcpy(&cmd.data.setassparms.data,(void*)data,
3594 /* limit here to a page or so */
3595 qeth_min(len,PAGE_SIZE));
3596 if (command_code != IPA_CMD_ASS_START) {
3597 result=qeth_send_ipa_cmd(card,&cmd,0,
3598 ((assist_no==IPA_ARP_PROCESSING)&&
3599 (command_code!=IPA_CMD_ASS_ARP_FLUSH_CACHE))?
3600 IPA_IOCTL_STATE:IPA_CMD_STATE);
3601
3602 } else
3603 result=qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE);
3604
3605 return result;
3606 }
3607
qeth_send_setadapterparms_query(qeth_card_t * card)3608 static int qeth_send_setadapterparms_query(qeth_card_t *card)
3609 {
3610 ipa_cmd_t cmd;
3611 int result;
3612
3613 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETADAPTERPARMS,
3614 IPA_SETADAPTERPARMS_IP_VERSION);
3615 cmd.data.setadapterparms.cmdlength=sizeof(struct ipa_setadp_cmd);
3616 cmd.data.setadapterparms.command_code=
3617 IPA_SETADP_QUERY_COMMANDS_SUPPORTED;
3618 cmd.data.setadapterparms.frames_used_total=1;
3619 cmd.data.setadapterparms.frame_seq_no=1;
3620 result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE);
3621
3622 if (cmd.data.setadapterparms.data.query_cmds_supp.lan_type&0x7f)
3623 card->link_type=cmd.data.setadapterparms.data.
3624 query_cmds_supp.lan_type;
3625
3626 card->adp_supported=
3627 cmd.data.setadapterparms.data.query_cmds_supp.supported_cmds;
3628
3629 return result;
3630 }
3631
qeth_send_setadapterparms_mode(qeth_card_t * card,__u32 command,__u32 mode)3632 static int qeth_send_setadapterparms_mode(qeth_card_t *card,__u32 command,
3633 __u32 mode)
3634 {
3635 ipa_cmd_t cmd;
3636 int result;
3637
3638 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETADAPTERPARMS,
3639 IPA_SETADAPTERPARMS_IP_VERSION);
3640 cmd.data.setadapterparms.cmdlength=sizeof(struct ipa_setadp_cmd);
3641 cmd.data.setadapterparms.command_code=command;
3642 cmd.data.setadapterparms.frames_used_total=1;
3643 cmd.data.setadapterparms.frame_seq_no=1;
3644 cmd.data.setadapterparms.data.mode=mode;
3645 result=qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE);
3646
3647 return result;
3648 }
3649
qeth_send_setadapterparms_change_addr(qeth_card_t * card,__u32 command,__u32 subcmd,__u8 * mac_addr,int addr_len)3650 static int qeth_send_setadapterparms_change_addr(qeth_card_t *card,
3651 __u32 command,
3652 __u32 subcmd,__u8 *mac_addr,
3653 int addr_len)
3654 {
3655 ipa_cmd_t cmd;
3656 int result;
3657
3658 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETADAPTERPARMS,
3659 IPA_SETADAPTERPARMS_IP_VERSION);
3660 cmd.data.setadapterparms.cmdlength=sizeof(struct ipa_setadp_cmd);
3661 cmd.data.setadapterparms.command_code=command;
3662 cmd.data.setadapterparms.frames_used_total=1;
3663 cmd.data.setadapterparms.frame_seq_no=1;
3664 cmd.data.setadapterparms.data.change_addr.cmd=subcmd;
3665 cmd.data.setadapterparms.data.change_addr.addr_size=addr_len;
3666 memcpy(&cmd.data.setadapterparms.data.change_addr.addr,
3667 mac_addr,addr_len);
3668
3669 result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE);
3670
3671 memcpy(mac_addr,&cmd.data.setadapterparms.data.change_addr.addr,
3672 addr_len);
3673
3674 return result;
3675 }
3676
qeth_send_setassparms_simple_with_data(qeth_card_t * card,__u32 assist_no,__u16 command_code,long data)3677 static int qeth_send_setassparms_simple_with_data(qeth_card_t *card,
3678 __u32 assist_no,
3679 __u16 command_code,
3680 long data)
3681 {
3682 return qeth_send_setassparms(card,4,assist_no,command_code,data,4);
3683 }
3684
qeth_send_setassparms_simple_without_data(qeth_card_t * card,__u32 assist_no,__u16 command_code)3685 static int qeth_send_setassparms_simple_without_data(qeth_card_t *card,
3686 __u32 assist_no,
3687 __u16 command_code)
3688 {
3689 return qeth_send_setassparms(card,4,assist_no,command_code,0,0);
3690 }
3691
qeth_send_setassparms_simple_without_data6(qeth_card_t * card,__u32 assist_no,__u16 command_code)3692 static int qeth_send_setassparms_simple_without_data6(qeth_card_t *card,
3693 __u32 assist_no,
3694 __u16 command_code)
3695 {
3696 return qeth_send_setassparms(card,6,assist_no,command_code,0,0);
3697 }
3698
qeth_send_setdelip(qeth_card_t * card,__u8 * ip,__u8 * netmask,int ipacmd,short ip_vers,unsigned int flags)3699 static int qeth_send_setdelip(qeth_card_t *card,__u8 *ip,__u8 *netmask,
3700 int ipacmd,short ip_vers,unsigned int flags)
3701 {
3702 ipa_cmd_t cmd;
3703 int ip_len=(ip_vers==6)?16:4;
3704
3705 qeth_fill_ipa_cmd(card,&cmd,ipacmd,ip_vers);
3706 if (ip_vers==6) {
3707 memcpy(&cmd.data.setdelip6.ip,ip,ip_len);
3708 memcpy(&cmd.data.setdelip6.netmask,netmask,ip_len);
3709 cmd.data.setdelip6.flags=flags;
3710 } else {
3711 memcpy(&cmd.data.setdelip4.ip,ip,ip_len);
3712 memcpy(&cmd.data.setdelip4.netmask,netmask,ip_len);
3713 cmd.data.setdelip4.flags=flags;
3714 }
3715
3716 return qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE|
3717 ((ipacmd==IPA_CMD_SETIP)?IPA_SETIP_FLAG:0));
3718 }
3719
qeth_send_setdelipm(qeth_card_t * card,__u8 * ip,__u8 * mac,int ipacmd,short ip_vers)3720 static int qeth_send_setdelipm(qeth_card_t *card,__u8 *ip,__u8 *mac,
3721 int ipacmd,short ip_vers)
3722 {
3723 ipa_cmd_t cmd;
3724 int ip_len=(ip_vers==6)?16:4;
3725
3726 qeth_fill_ipa_cmd(card,&cmd,ipacmd,ip_vers);
3727 memcpy(&cmd.data.setdelipm.mac,mac,6);
3728 if (ip_vers==6) {
3729 memcpy(&cmd.data.setdelipm.ip6,ip,ip_len);
3730 } else {
3731 memcpy(&cmd.data.setdelipm.ip4_6,ip,ip_len);
3732 }
3733
3734 return qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE|
3735 ((ipacmd==IPA_CMD_SETIPM)?IPA_SETIP_FLAG:0));
3736 }
3737
3738 #define PRINT_SETIP_ERROR(x) \
3739 if (result) \
3740 PRINT_ERR("setip%c: return code 0x%x (%s)\n",x,result, \
3741 (result==0xe002)?"invalid mtu size": \
3742 (result==0xe005)?"duplicate ip address": \
3743 (result==0xe0a5)?"duplicate ip address": \
3744 (result==0xe006)?"ip table full": \
3745 (result==0xe008)?"startlan not received": \
3746 (result==0xe009)?"setip already received": \
3747 (result==0xe00a)?"dup network ip address": \
3748 (result==0xe00b)?"mblk no free main task entry": \
3749 (result==0xe00d)?"invalid ip version": \
3750 (result==0xe00e)?"unsupported arp assist cmd": \
3751 (result==0xe00f)?"arp assist not enabled": \
3752 (result==0xe080)?"startlan disabled": \
3753 (result==0xf012)?"unicast IP address invalid": \
3754 (result==0xf013)?"multicast router limit reached": \
3755 (result==0xf014)?"stop assist not supported": \
3756 (result==0xf015)?"multicast assist not set": \
3757 (result==0xf080)?"VM: startlan disabled": \
3758 (result==-1)?"IPA communication timeout": \
3759 "unknown return code")
3760
qeth_send_setip(qeth_card_t * card,__u8 * ip,__u8 * netmask,short ip_vers,int use_retries)3761 static inline int qeth_send_setip(qeth_card_t *card,__u8 *ip,
3762 __u8 *netmask,short ip_vers,int use_retries)
3763 {
3764 int result;
3765 int retries;
3766 char dbf_text[15];
3767 int takeover=0;
3768
3769 retries=(use_retries)?QETH_SETIP_RETRIES:1;
3770 if (qeth_is_ipa_covered_by_ipato_entries(ip_vers,ip,card)) {
3771 sprintf(dbf_text,"ipto%4x",card->irq0);
3772 QETH_DBF_TEXT2(0,trace,dbf_text);
3773 if (ip_vers==4) {
3774 *((__u32*)(&dbf_text[0]))=*((__u32*)ip);
3775 *((__u32*)(&dbf_text[4]))=*((__u32*)netmask);
3776 QETH_DBF_HEX2(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
3777 } else {
3778 QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN);
3779 QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN,
3780 QETH_DBF_TRACE_LEN);
3781 QETH_DBF_HEX2(0,trace,netmask,QETH_DBF_TRACE_LEN);
3782 QETH_DBF_HEX2(0,trace,netmask+QETH_DBF_TRACE_LEN,
3783 QETH_DBF_TRACE_LEN);
3784 }
3785 takeover=1;
3786 }
3787 retry:
3788 result=qeth_send_setdelip(card,ip,netmask,IPA_CMD_SETIP,ip_vers,
3789 (takeover)?IPA_SETIP_TAKEOVER_FLAGS:
3790 IPA_SETIP_FLAGS);
3791 PRINT_SETIP_ERROR(' ');
3792
3793 if (result) {
3794 QETH_DBF_TEXT2(0,trace,"SETIPFLD");
3795 sprintf(dbf_text,"%4x%4x",card->irq0,result);
3796 QETH_DBF_TEXT2(0,trace,dbf_text);
3797 }
3798
3799 if ( ((result==-1)||(result==0xe080)||(result==0xf080))&&
3800 (retries--) ) {
3801 sprintf(dbf_text,"sipr%4x",card->irq0);
3802 QETH_DBF_TEXT2(0,trace,dbf_text);
3803 if (ip_vers==4) {
3804 *((__u32*)(&dbf_text[0]))=*((__u32*)ip);
3805 *((__u32*)(&dbf_text[4]))=*((__u32*)netmask);
3806 QETH_DBF_HEX2(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
3807 } else {
3808 QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN);
3809 QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN,
3810 QETH_DBF_TRACE_LEN);
3811 QETH_DBF_HEX2(0,trace,netmask,QETH_DBF_TRACE_LEN);
3812 QETH_DBF_HEX2(0,trace,netmask+QETH_DBF_TRACE_LEN,
3813 QETH_DBF_TRACE_LEN);
3814 }
3815 PRINT_WARN("trying again...\n");
3816 goto retry;
3817 }
3818
3819 return result;
3820 }
3821
qeth_send_delip(qeth_card_t * card,__u8 * ip,__u8 * netmask,short ip_vers)3822 static inline int qeth_send_delip(qeth_card_t *card,__u8 *ip,
3823 __u8 *netmask,short ip_vers)
3824 {
3825 return qeth_send_setdelip(card,ip,netmask,IPA_CMD_DELIP,ip_vers,
3826 IPA_DELIP_FLAGS);
3827 }
3828
qeth_send_setipm(qeth_card_t * card,__u8 * ip,__u8 * mac,short ip_vers,int use_retries)3829 static inline int qeth_send_setipm(qeth_card_t *card,__u8 *ip,
3830 __u8 *mac,short ip_vers,int use_retries)
3831 {
3832 int result;
3833 int retries;
3834 char dbf_text[15];
3835
3836 retries=(use_retries)?QETH_SETIP_RETRIES:1;
3837 if (qeth_is_ipa_covered_by_ipato_entries(ip_vers,ip,card)) {
3838 sprintf(dbf_text,"imto%4x",card->irq0);
3839 QETH_DBF_TEXT2(0,trace,dbf_text);
3840 if (ip_vers==4) {
3841 *((__u32*)(&dbf_text[0]))=*((__u32*)ip);
3842 QETH_DBF_HEX2(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
3843 } else {
3844 QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN);
3845 QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN,
3846 QETH_DBF_TRACE_LEN);
3847 }
3848 }
3849
3850 retry:
3851 result=qeth_send_setdelipm(card,ip,mac,IPA_CMD_SETIPM,ip_vers);
3852 PRINT_SETIP_ERROR('m');
3853
3854 if (result) {
3855 QETH_DBF_TEXT2(0,trace,"SETIMFLD");
3856 sprintf(dbf_text,"%4x%4x",card->irq0,result);
3857 QETH_DBF_TEXT2(0,trace,dbf_text);
3858 }
3859
3860 if ((result==-1)&&(retries--)) {
3861 sprintf(dbf_text,"simr%4x",card->irq0);
3862 QETH_DBF_TEXT2(0,trace,dbf_text);
3863 if (ip_vers==4) {
3864 sprintf(dbf_text,"%08x",*((__u32*)ip));
3865 QETH_DBF_TEXT2(0,trace,dbf_text);
3866 } else {
3867 QETH_DBF_HEX2(0,trace,ip,QETH_DBF_TRACE_LEN);
3868 QETH_DBF_HEX2(0,trace,ip+QETH_DBF_TRACE_LEN,
3869 QETH_DBF_TRACE_LEN);
3870 }
3871 QETH_DBF_HEX2(0,trace,mac,OSA_ADDR_LEN);
3872 PRINT_WARN("trying again...\n");
3873 goto retry;
3874 }
3875
3876 return result;
3877 }
3878
qeth_send_delipm(qeth_card_t * card,__u8 * ip,__u8 * mac,short ip_vers)3879 static inline int qeth_send_delipm(qeth_card_t *card,__u8 *ip,
3880 __u8 *mac,short ip_vers)
3881 {
3882 return qeth_send_setdelipm(card,ip,mac,IPA_CMD_DELIPM,ip_vers);
3883 }
3884
qeth_add_vipa_entry(qeth_card_t * card,int version,__u8 * addr,int flag)3885 static int qeth_add_vipa_entry(qeth_card_t *card,int version,__u8 *addr,
3886 int flag)
3887 {
3888 qeth_vipa_entry_t *entry,*e;
3889 int result=0;
3890
3891 entry=(qeth_vipa_entry_t*)kmalloc(sizeof(qeth_vipa_entry_t),
3892 GFP_KERNEL);
3893 if (!entry) {
3894 PRINT_ERR("not enough memory for vipa handling\n");
3895 return -ENOMEM;
3896 }
3897 entry->version=version;
3898 entry->flag=flag;
3899 memcpy(entry->ip,addr,16);
3900 entry->state=VIPA_2_B_ADDED;
3901
3902 my_write_lock(&card->vipa_list_lock);
3903 e=card->vipa_list;
3904 while (e) {
3905 if (e->version!=version) goto next;
3906 if (memcmp(e->ip,addr,(version==4)?4:16)) goto next;
3907 if (flag==IPA_SETIP_VIPA_FLAGS) {
3908 PRINT_ERR("vipa already set\n");
3909 } else {
3910 PRINT_ERR("rxip already set\n");
3911 }
3912 kfree(entry);
3913 result=-EALREADY;
3914 goto out;
3915 next:
3916 e=e->next;
3917 }
3918 entry->next=card->vipa_list;
3919 card->vipa_list=entry;
3920 out:
3921 my_write_unlock(&card->vipa_list_lock);
3922 return result;
3923 }
3924
qeth_del_vipa_entry(qeth_card_t * card,int version,__u8 * addr,int flag)3925 static int qeth_del_vipa_entry(qeth_card_t *card,int version,__u8 *addr,
3926 int flag)
3927 {
3928 qeth_vipa_entry_t *e;
3929 int result=0;
3930
3931 my_write_lock(&card->vipa_list_lock);
3932 e=card->vipa_list;
3933 while (e) {
3934 if (e->version!=version) goto next;
3935 if (e->flag!=flag) goto next;
3936 if (memcmp(e->ip,addr,(version==4)?4:16)) goto next;
3937 e->state=VIPA_2_B_REMOVED;
3938 goto out;
3939 next:
3940 e=e->next;
3941 }
3942 if (flag==IPA_SETIP_VIPA_FLAGS) {
3943 PRINT_ERR("vipa not found\n");
3944 } else {
3945 PRINT_ERR("rxip not found\n");
3946 }
3947 result=-ENOENT;
3948 out:
3949 my_write_unlock(&card->vipa_list_lock);
3950 return result;
3951 }
3952
qeth_set_vipas(qeth_card_t * card,int set_only)3953 static void qeth_set_vipas(qeth_card_t *card,int set_only)
3954 {
3955 qeth_vipa_entry_t *e,*le=NULL,*ne; /* ne stands for new entry,
3956 le is last entry */
3957 char dbf_text[15];
3958 int result;
3959 __u8 netmask[16]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
3960 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
3961 qeth_vipa_entry_t *priv_add_list=NULL;
3962 qeth_vipa_entry_t *priv_del_list=NULL;
3963
3964 my_write_lock(&card->vipa_list_lock);
3965 e=card->vipa_list;
3966 while (e) {
3967 switch (e->state) {
3968 case VIPA_2_B_ADDED:
3969 if (!set_only) break;
3970 if (!atomic_read(&card->is_open)) break;
3971 /* we don't want to hold the lock for a long time...
3972 * so we clone the entry */
3973 ne=(qeth_vipa_entry_t*)
3974 kmalloc(sizeof(qeth_vipa_entry_t),
3975 GFP_KERNEL);
3976 if (ne) {
3977 ne->version=e->version;
3978 ne->flag=e->flag;
3979 memcpy(ne->ip,e->ip,16);
3980 ne->next=priv_add_list;
3981 priv_add_list=ne;
3982
3983 e->state=VIPA_ESTABLISHED;
3984 } else {
3985 PRINT_ERR("not enough for internal vipa " \
3986 "handling... trying to set " \
3987 "vipa next time.\n");
3988 qeth_start_softsetup_thread(card);
3989 }
3990 break;
3991 case VIPA_2_B_REMOVED:
3992 if (set_only) break;
3993 if (le)
3994 le->next=e->next;
3995 else card->vipa_list=e->next;
3996 ne=e->next;
3997 e->next=priv_del_list;
3998 priv_del_list=e;
3999 e=ne;
4000 continue;
4001 case VIPA_ESTABLISHED:
4002 if (atomic_read(&card->is_open)) break;
4003 /* we don't want to hold the lock for a long time...
4004 * so we clone the entry */
4005 ne=(qeth_vipa_entry_t*)
4006 kmalloc(sizeof(qeth_vipa_entry_t),
4007 GFP_KERNEL);
4008 if (ne) {
4009 ne->version=e->version;
4010 ne->flag=e->flag;
4011 memcpy(ne->ip,e->ip,16);
4012 ne->next=priv_del_list;
4013 priv_del_list=ne;
4014
4015 e->state=VIPA_2_B_ADDED;
4016 } else {
4017 PRINT_ERR("not enough for internal vipa " \
4018 "handling... VIPA/RXIP remains set " \
4019 "although device is stopped.\n");
4020 qeth_start_softsetup_thread(card);
4021 }
4022 break;
4023 default:
4024 break;
4025 }
4026 le=e;
4027 e=e->next;
4028 }
4029 my_write_unlock(&card->vipa_list_lock);
4030
4031 while (priv_add_list) {
4032 result=qeth_send_setdelip(card,priv_add_list->ip,netmask,
4033 IPA_CMD_SETIP,priv_add_list->version,
4034 priv_add_list->flag);
4035 PRINT_SETIP_ERROR('s');
4036
4037 if (result) {
4038 QETH_DBF_TEXT2(0,trace,"SETSVFLD");
4039 sprintf(dbf_text,"%4x%4x",card->irq0,result);
4040 QETH_DBF_TEXT2(0,trace,dbf_text);
4041 if (priv_add_list->version==4) {
4042 PRINT_ERR("going to leave vipa/rxip x%08x " \
4043 "unset...\n",
4044 *((__u32*)&priv_add_list->ip[0]));
4045 sprintf(dbf_text,"%08x",
4046 *((__u32*)&priv_add_list->ip[0]));
4047 QETH_DBF_TEXT2(0,trace,dbf_text);
4048 } else {
4049 PRINT_ERR("going to leave vipa/rxip " \
4050 "%08x%08x%08x%08x unset...\n",
4051 *((__u32*)&priv_add_list->ip[0]),
4052 *((__u32*)&priv_add_list->ip[4]),
4053 *((__u32*)&priv_add_list->ip[8]),
4054 *((__u32*)&priv_add_list->ip[12]));
4055 QETH_DBF_HEX2(0,trace,&priv_add_list->ip[0],
4056 QETH_DBF_TRACE_LEN);
4057 QETH_DBF_HEX2(0,trace,&priv_add_list->ip[8],
4058 QETH_DBF_TRACE_LEN);
4059 }
4060 }
4061 e=priv_add_list;
4062 priv_add_list=priv_add_list->next;
4063 kfree(e);
4064 }
4065
4066 while (priv_del_list) {
4067 result=qeth_send_setdelip(card,priv_del_list->ip,netmask,
4068 IPA_CMD_DELIP,priv_del_list->version,
4069 priv_del_list->flag);
4070 if (result) {
4071 QETH_DBF_TEXT2(0,trace,"DELSVFLD");
4072 sprintf(dbf_text,"%4x%4x",card->irq0,result);
4073 QETH_DBF_TEXT2(0,trace,dbf_text);
4074 if (priv_del_list->version==4) {
4075 PRINT_ERR("could not delete vipa/rxip " \
4076 "%08x...\n",
4077 *((__u32*)&priv_del_list->ip[0]));
4078 sprintf(dbf_text,"%08x",
4079 *((__u32*)&priv_del_list->ip[0]));
4080 QETH_DBF_TEXT2(0,trace,dbf_text);
4081 } else {
4082 PRINT_ERR("could not delete vipa/rxip " \
4083 "%08x%08x%08x%08x...\n",
4084 *((__u32*)&priv_del_list->ip[0]),
4085 *((__u32*)&priv_del_list->ip[4]),
4086 *((__u32*)&priv_del_list->ip[8]),
4087 *((__u32*)&priv_del_list->ip[12]));
4088 QETH_DBF_HEX2(0,trace,&priv_del_list->ip[0],
4089 QETH_DBF_TRACE_LEN);
4090 QETH_DBF_HEX2(0,trace,&priv_del_list->ip[8],
4091 QETH_DBF_TRACE_LEN);
4092 }
4093 }
4094 e=priv_del_list;
4095 priv_del_list=priv_del_list->next;
4096 kfree(e);
4097 }
4098 }
4099
qeth_refresh_vipa_states(qeth_card_t * card)4100 static void qeth_refresh_vipa_states(qeth_card_t *card)
4101 {
4102 qeth_vipa_entry_t *e;
4103
4104 my_write_lock(&card->vipa_list_lock);
4105 e=card->vipa_list;
4106 while (e) {
4107 if (e->state==VIPA_ESTABLISHED) e->state=VIPA_2_B_ADDED;
4108 e=e->next;
4109 }
4110 my_write_unlock(&card->vipa_list_lock);
4111 }
4112
qeth_send_setrtg(qeth_card_t * card,int routing_type,short ip_vers)4113 static inline int qeth_send_setrtg(qeth_card_t *card,int routing_type,
4114 short ip_vers)
4115 {
4116 ipa_cmd_t cmd;
4117
4118 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_SETRTG,ip_vers);
4119 /* strip off RESET_ROUTING_FLAG */
4120 cmd.data.setrtg.type=(routing_type)&(ROUTER_MASK);
4121
4122 return qeth_send_ipa_cmd(card,&cmd,0,IPA_CMD_STATE);
4123 }
4124
qeth_is_ipa_in_list(struct in_ifaddr * ip,struct in_ifaddr * list)4125 static int qeth_is_ipa_in_list(struct in_ifaddr *ip,struct in_ifaddr *list)
4126 {
4127 while (list) {
4128 if (ip->ifa_address==list->ifa_address) return 1;
4129 list=list->ifa_next;
4130 }
4131 return 0;
4132 }
4133
4134 #ifdef QETH_IPV6
qeth_is_ipa_in_list6(struct inet6_ifaddr * ip,struct inet6_ifaddr * list)4135 static int qeth_is_ipa_in_list6(struct inet6_ifaddr *ip,
4136 struct inet6_ifaddr *list)
4137 {
4138 while (list) {
4139 if (!memcmp(&ip->addr.s6_addr,&list->addr.s6_addr,16))
4140 return 1;
4141 list=list->if_next;
4142 }
4143 return 0;
4144 }
4145
qeth_add_ifa6_to_list(struct inet6_ifaddr ** list,struct inet6_ifaddr * ifa)4146 static int qeth_add_ifa6_to_list(struct inet6_ifaddr **list,
4147 struct inet6_ifaddr *ifa)
4148 {
4149 struct inet6_ifaddr *i;
4150
4151 if (*list==NULL) {
4152 *list=ifa;
4153 } else {
4154 if (qeth_is_ipa_in_list6(ifa,*list))
4155 return -EALREADY;
4156 i=*list;
4157 while (i->if_next) {
4158 i=i->if_next;
4159 }
4160 i->if_next=ifa;
4161 }
4162 ifa->if_next=NULL;
4163 return 0;
4164 }
4165 #endif /* QETH_IPV6 */
4166
qeth_add_ifa_to_list(struct in_ifaddr ** list,struct in_ifaddr * ifa)4167 static int qeth_add_ifa_to_list(struct in_ifaddr **list,struct in_ifaddr *ifa)
4168 {
4169 struct in_ifaddr *i;
4170
4171 if (*list==NULL) {
4172 *list=ifa;
4173 } else {
4174 if (qeth_is_ipa_in_list(ifa,*list))
4175 return -EALREADY;
4176 i=*list;
4177 while (i->ifa_next) {
4178 i=i->ifa_next;
4179 }
4180 i->ifa_next=ifa;
4181 }
4182 ifa->ifa_next=NULL;
4183 return 0;
4184 }
4185
qeth_setips(qeth_card_t * card,int use_setip_retries)4186 static int qeth_setips(qeth_card_t *card,int use_setip_retries)
4187 {
4188 struct in_ifaddr *addr;
4189 int result;
4190 char dbf_text[15];
4191 #ifdef QETH_IPV6
4192 struct inet6_ifaddr *addr6;
4193 __u8 netmask[16];
4194 #endif /* QETH_IPV6 */
4195
4196 sprintf(dbf_text,"stip%4x",card->irq0);
4197 QETH_DBF_TEXT3(0,trace,dbf_text);
4198
4199 addr=card->ip_current_state.ip_ifa;
4200 while (addr) {
4201 if (!qeth_is_ipa_in_list(addr,card->ip_new_state.ip_ifa)) {
4202 QETH_DBF_TEXT3(0,trace,"setipdel");
4203 *((__u32*)(&dbf_text[0]))=*((__u32*)&addr->ifa_address);
4204 *((__u32*)(&dbf_text[4]))=*((__u32*)&addr->ifa_mask);
4205 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
4206 result=qeth_send_delip(card,(__u8*)&addr->ifa_address,
4207 (__u8*)&addr->ifa_mask,4);
4208 if (result) {
4209 PRINT_ERR("was not able to delete ip " \
4210 "%08x/%08x on irq x%x " \
4211 "(result: 0x%x), " \
4212 "trying to continue\n",
4213 addr->ifa_address,
4214 addr->ifa_mask,card->irq0,result);
4215 sprintf(dbf_text,"stdl%4x",result);
4216 QETH_DBF_TEXT3(0,trace,dbf_text);
4217 }
4218 }
4219 addr=addr->ifa_next;
4220 }
4221
4222 addr=card->ip_new_state.ip_ifa;
4223 while (addr) {
4224 if (!qeth_is_ipa_in_list(addr,
4225 card->ip_current_state.ip_ifa)) {
4226 QETH_DBF_TEXT3(0,trace,"setipset");
4227 *((__u32*)(&dbf_text[0]))=
4228 *((__u32*)&addr->ifa_address);
4229 *((__u32*)(&dbf_text[4]))=
4230 *((__u32*)&addr->ifa_mask);
4231 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
4232 result=qeth_send_setip(card,(__u8*)&addr->ifa_address,
4233 (__u8*)&addr->ifa_mask,4,
4234 use_setip_retries);
4235 if (result) {
4236 PRINT_ERR("was not able to set ip " \
4237 "%08x/%08x on irq x%x, trying to " \
4238 "continue\n",
4239 addr->ifa_address,
4240 addr->ifa_mask,card->irq0);
4241 sprintf(dbf_text,"stst%4x",result);
4242 QETH_DBF_TEXT3(0,trace,dbf_text);
4243 }
4244 }
4245 addr=addr->ifa_next;
4246 }
4247
4248 #ifdef QETH_IPV6
4249 #define FILL_NETMASK(len) { \
4250 int i,j; \
4251 for (i=0;i<16;i++) { \
4252 j=(len)-(i*8); \
4253 if (j>=8) netmask[i]=0xff; else \
4254 if (j<=0) netmask[i]=0x0; else \
4255 netmask[i]=(__u8)(0xFF00>>j); \
4256 } \
4257 }
4258 /* here we go with IPv6 */
4259 addr6=card->ip_current_state.ip6_ifa;
4260 while (addr6) {
4261 if (!qeth_is_ipa_in_list6(addr6,card->ip_new_state.ip6_ifa)) {
4262 QETH_DBF_TEXT3(0,trace,"setipdl6");
4263 QETH_DBF_HEX3(0,trace,&addr6->addr.s6_addr,
4264 QETH_DBF_TRACE_LEN);
4265 QETH_DBF_HEX3(0,trace,
4266 ((char *)(&addr6->addr.s6_addr))+
4267 QETH_DBF_TRACE_LEN,QETH_DBF_TRACE_LEN);
4268 sprintf(dbf_text,"nmsk%4u",addr6->prefix_len);
4269 QETH_DBF_TEXT3(0,trace,dbf_text);
4270 FILL_NETMASK(addr6->prefix_len);
4271 result=qeth_send_delip(card,
4272 (__u8*)&addr6->addr.s6_addr,
4273 (__u8*)&netmask,6);
4274 if (result) {
4275 PRINT_ERR("was not able to delete ip " \
4276 "%04x:%04x:%04x:%04x:%04x:%04x:" \
4277 "%04x:%04x/%u on irq x%x " \
4278 "(result: 0x%x), " \
4279 "trying to continue\n",
4280 addr6->addr.s6_addr16[0],
4281 addr6->addr.s6_addr16[1],
4282 addr6->addr.s6_addr16[2],
4283 addr6->addr.s6_addr16[3],
4284 addr6->addr.s6_addr16[4],
4285 addr6->addr.s6_addr16[5],
4286 addr6->addr.s6_addr16[6],
4287 addr6->addr.s6_addr16[7],
4288 addr6->prefix_len,
4289 card->irq0,result);
4290 sprintf(dbf_text,"std6%4x",result);
4291 QETH_DBF_TEXT3(0,trace,dbf_text);
4292 }
4293 }
4294 addr6=addr6->if_next;
4295 }
4296
4297 addr6=card->ip_new_state.ip6_ifa;
4298 while (addr6) {
4299 if (!qeth_is_ipa_in_list6(addr6,
4300 card->ip_current_state.ip6_ifa)) {
4301 QETH_DBF_TEXT3(0,trace,"setipst6");
4302 QETH_DBF_HEX3(0,trace,&addr6->addr.s6_addr,
4303 QETH_DBF_TRACE_LEN);
4304 QETH_DBF_HEX3(0,trace,
4305 ((char *)(&addr6->addr.s6_addr))+
4306 QETH_DBF_TRACE_LEN,QETH_DBF_TRACE_LEN);
4307 sprintf(dbf_text,"nmsk%4u",addr6->prefix_len);
4308 QETH_DBF_TEXT3(0,trace,dbf_text);
4309 FILL_NETMASK(addr6->prefix_len);
4310 result=qeth_send_setip(card,
4311 (__u8*)&addr6->addr.s6_addr,
4312 (__u8*)&netmask,6,
4313 use_setip_retries);
4314 if (result) {
4315 PRINT_ERR("was not able to set ip " \
4316 "%04x:%04x:%04x:%04x:%04x:%04x:" \
4317 "%04x:%04x/%u on irq x%x " \
4318 "(result: 0x%x), " \
4319 "trying to continue\n",
4320 addr6->addr.s6_addr16[0],
4321 addr6->addr.s6_addr16[1],
4322 addr6->addr.s6_addr16[2],
4323 addr6->addr.s6_addr16[3],
4324 addr6->addr.s6_addr16[4],
4325 addr6->addr.s6_addr16[5],
4326 addr6->addr.s6_addr16[6],
4327 addr6->addr.s6_addr16[7],
4328 addr6->prefix_len,
4329 card->irq0,result);
4330 sprintf(dbf_text,"sts6%4x",result);
4331 QETH_DBF_TEXT3(0,trace,dbf_text);
4332 }
4333 }
4334 addr6=addr6->if_next;
4335 }
4336 #endif /* QETH_IPV6 */
4337
4338 return 0;
4339 }
4340
qeth_is_ipma_in_list(struct qeth_ipm_mac * ipma,struct qeth_ipm_mac * list)4341 static int qeth_is_ipma_in_list(struct qeth_ipm_mac *ipma,
4342 struct qeth_ipm_mac *list)
4343 {
4344 while (list) {
4345 if ( (!memcmp(ipma->ip,list->ip,16)) &&
4346 (!memcmp(ipma->mac,list->mac,6)) ) return 1;
4347 list=list->next;
4348 }
4349 return 0;
4350 }
4351
qeth_remove_mc_ifa_from_list(struct qeth_ipm_mac ** list,struct qeth_ipm_mac * ipma)4352 static void qeth_remove_mc_ifa_from_list(struct qeth_ipm_mac **list,
4353 struct qeth_ipm_mac *ipma)
4354 {
4355 struct qeth_ipm_mac *i,*li=NULL;
4356
4357 if ((!(*list)) || (!ipma)) return;
4358
4359 if (*list==ipma) {
4360 *list=ipma->next;
4361 } else {
4362 i=*list;
4363 while (i) {
4364 if (i==ipma) {
4365 li->next=i->next;
4366 } else {
4367 li=i;
4368 }
4369 i=i->next;
4370 }
4371 }
4372 }
4373
qeth_add_mc_ifa_to_list(struct qeth_ipm_mac ** list,struct qeth_ipm_mac * ipma)4374 static int qeth_add_mc_ifa_to_list(struct qeth_ipm_mac **list,
4375 struct qeth_ipm_mac *ipma)
4376 {
4377 struct qeth_ipm_mac *i;
4378
4379 if (qeth_is_ipma_in_list(ipma,*list))
4380 return -EALREADY;
4381
4382 if (*list==NULL) {
4383 *list=ipma;
4384 } else {
4385 i=*list;
4386 while (i->next) {
4387 i=i->next;
4388 }
4389 i->next=ipma;
4390 }
4391 ipma->next=NULL;
4392 return 0;
4393 }
4394
qeth_setipms(qeth_card_t * card,int use_setipm_retries)4395 static int qeth_setipms(qeth_card_t *card,int use_setipm_retries)
4396 {
4397 struct qeth_ipm_mac *addr;
4398 int result;
4399 char dbf_text[15];
4400
4401 sprintf(dbf_text,"stim%4x",card->irq0);
4402 QETH_DBF_TEXT3(0,trace,dbf_text);
4403
4404 if (qeth_is_supported(IPA_MULTICASTING)) {
4405 addr=card->ip_mc_current_state.ipm_ifa;
4406 while (addr) {
4407 if (!qeth_is_ipma_in_list(addr,card->
4408 ip_mc_new_state.ipm_ifa)) {
4409 QETH_DBF_TEXT3(0,trace,"setimdel");
4410 sprintf(dbf_text,"%08x",
4411 *((__u32*)&addr->ip[0]));
4412 QETH_DBF_TEXT3(0,trace,dbf_text);
4413 *((__u32*)(&dbf_text[0]))=
4414 *((__u32*)&addr->mac);
4415 *((__u32*)(&dbf_text[4]))=
4416 *(((__u32*)&addr->mac)+1);
4417 QETH_DBF_HEX3(0,trace,dbf_text,
4418 QETH_DBF_TRACE_LEN);
4419 result=qeth_send_delipm(
4420 card,(__u8*)&addr->ip[0],
4421 (__u8*)addr->mac,4);
4422 if (result) {
4423 PRINT_ERR("was not able to delete " \
4424 "multicast ip %08x/" \
4425 "%02x%02x%02x%02x%02x%02x " \
4426 "on irq x%x " \
4427 "(result: 0x%x), " \
4428 "trying to continue\n",
4429 *((__u32*)&addr->ip[0]),
4430 addr->mac[0],addr->mac[1],
4431 addr->mac[2],addr->mac[3],
4432 addr->mac[4],addr->mac[5],
4433 card->irq0,result);
4434 sprintf(dbf_text,"smdl%4x",result);
4435 QETH_DBF_TEXT3(0,trace,dbf_text);
4436 }
4437 }
4438 addr=addr->next;
4439 }
4440
4441 addr=card->ip_mc_new_state.ipm_ifa;
4442 while (addr) {
4443 if (!qeth_is_ipma_in_list(addr,card->
4444 ip_mc_current_state.
4445 ipm_ifa)) {
4446 QETH_DBF_TEXT3(0,trace,"setimset");
4447 sprintf(dbf_text,"%08x",
4448 *((__u32*)&addr->ip[0]));
4449 QETH_DBF_TEXT3(0,trace,dbf_text);
4450 *((__u32*)(&dbf_text[0]))=
4451 *((__u32*)&addr->mac);
4452 *((__u32*)(&dbf_text[4]))=
4453 *(((__u32*)&addr->mac)+1);
4454 QETH_DBF_HEX3(0,trace,dbf_text,
4455 QETH_DBF_TRACE_LEN);
4456 result=qeth_send_setipm(
4457 card,(__u8*)&addr->ip[0],
4458 (__u8*)addr->mac,4,
4459 use_setipm_retries);
4460 if (result) {
4461 PRINT_ERR("was not able to set " \
4462 "multicast ip %08x/" \
4463 "%02x%02x%02x%02x%02x%02x " \
4464 "on irq x%x " \
4465 "(result: 0x%x), " \
4466 "trying to continue\n",
4467 *((__u32*)&addr->ip[0]),
4468 addr->mac[0],addr->mac[1],
4469 addr->mac[2],addr->mac[3],
4470 addr->mac[4],addr->mac[5],
4471 card->irq0,result);
4472 sprintf(dbf_text,"smst%4x",result);
4473 QETH_DBF_TEXT3(0,trace,dbf_text);
4474 qeth_remove_mc_ifa_from_list(
4475 &card->ip_mc_current_state.
4476 ipm_ifa,addr);
4477 }
4478 }
4479 addr=addr->next;
4480 }
4481
4482 #ifdef QETH_IPV6
4483 /* here we go with IPv6 */
4484 addr=card->ip_mc_current_state.ipm6_ifa;
4485 while (addr) {
4486 if (!qeth_is_ipma_in_list(addr,card->
4487 ip_mc_new_state.ipm6_ifa)) {
4488 QETH_DBF_TEXT3(0,trace,"setimdl6");
4489 QETH_DBF_HEX3(0,trace,&addr->ip[0],
4490 QETH_DBF_TRACE_LEN);
4491 QETH_DBF_HEX3(0,trace,(&addr->ip[0])+
4492 QETH_DBF_TRACE_LEN,
4493 QETH_DBF_TRACE_LEN);
4494 QETH_DBF_HEX3(0,trace,&addr->mac,
4495 QETH_DBF_TRACE_LEN);
4496 result=qeth_send_delipm(
4497 card,(__u8*)&addr->ip[0],
4498 (__u8*)addr->mac,6);
4499 if (result) {
4500 PRINT_ERR("was not able to delete " \
4501 "multicast ip %04x:%04x:" \
4502 "%04x:%04x:%04x:%04x:" \
4503 "%04x:%04x/" \
4504 "%02x%02x%02x%02x%02x%02x " \
4505 "on irq x%x " \
4506 "(result: 0x%x), " \
4507 "trying to continue\n",
4508 *((__u16*)&addr->ip[0]),
4509 *((__u16*)&addr->ip[2]),
4510 *((__u16*)&addr->ip[4]),
4511 *((__u16*)&addr->ip[6]),
4512 *((__u16*)&addr->ip[8]),
4513 *((__u16*)&addr->ip[10]),
4514 *((__u16*)&addr->ip[12]),
4515 *((__u16*)&addr->ip[14]),
4516 addr->mac[0],addr->mac[1],
4517 addr->mac[2],addr->mac[3],
4518 addr->mac[4],addr->mac[5],
4519 card->irq0,result);
4520 sprintf(dbf_text,"smd6%4x",result);
4521 QETH_DBF_TEXT3(0,trace,dbf_text);
4522 }
4523 }
4524 addr=addr->next;
4525 }
4526
4527 addr=card->ip_mc_new_state.ipm6_ifa;
4528 while (addr) {
4529 if (!qeth_is_ipma_in_list(addr,card->
4530 ip_mc_current_state.
4531 ipm6_ifa)) {
4532 QETH_DBF_TEXT3(0,trace,"setimst6");
4533 QETH_DBF_HEX3(0,trace,&addr->ip[0],
4534 QETH_DBF_TRACE_LEN);
4535 QETH_DBF_HEX3(0,trace,(&addr->ip[0])+
4536 QETH_DBF_TRACE_LEN,
4537 QETH_DBF_TRACE_LEN);
4538 QETH_DBF_HEX3(0,trace,&addr->mac,
4539 QETH_DBF_TRACE_LEN);
4540 result=qeth_send_setipm(
4541 card,(__u8*)&addr->ip[0],
4542 (__u8*)addr->mac,6,
4543 use_setipm_retries);
4544 if (result) {
4545 PRINT_ERR("was not able to set " \
4546 "multicast ip %04x:%04x:" \
4547 "%04x:%04x:%04x:%04x:" \
4548 "%04x:%04x/" \
4549 "%02x%02x%02x%02x%02x%02x " \
4550 "on irq x%x " \
4551 "(result: 0x%x), " \
4552 "trying to continue\n",
4553 *((__u16*)&addr->ip[0]),
4554 *((__u16*)&addr->ip[2]),
4555 *((__u16*)&addr->ip[4]),
4556 *((__u16*)&addr->ip[6]),
4557 *((__u16*)&addr->ip[8]),
4558 *((__u16*)&addr->ip[10]),
4559 *((__u16*)&addr->ip[12]),
4560 *((__u16*)&addr->ip[14]),
4561 addr->mac[0],addr->mac[1],
4562 addr->mac[2],addr->mac[3],
4563 addr->mac[4],addr->mac[5],
4564 card->irq0,result);
4565 sprintf(dbf_text,"sms6%4x",result);
4566 QETH_DBF_TEXT3(0,trace,dbf_text);
4567 qeth_remove_mc_ifa_from_list(
4568 &card->ip_mc_current_state.
4569 ipm6_ifa,addr);
4570 }
4571 }
4572 addr=addr->next;
4573 }
4574 #endif /* QETH_IPV6 */
4575 return 0;
4576 } else return 0;
4577 }
4578
qeth_clone_ifa(struct in_ifaddr * src,struct in_ifaddr * dest)4579 static void qeth_clone_ifa(struct in_ifaddr *src,struct in_ifaddr *dest)
4580 {
4581 memcpy(dest,src,sizeof(struct in_ifaddr));
4582 dest->ifa_next=NULL;
4583 }
4584
4585 #ifdef QETH_IPV6
qeth_clone_ifa6(struct inet6_ifaddr * src,struct inet6_ifaddr * dest)4586 static void qeth_clone_ifa6(struct inet6_ifaddr *src,
4587 struct inet6_ifaddr *dest)
4588 {
4589 memcpy(dest,src,sizeof(struct inet6_ifaddr));
4590 dest->if_next=NULL;
4591 }
4592 #endif /* QETH_IPV6 */
4593
4594
4595
4596 #define QETH_STANDARD_RETVALS \
4597 ret_val=-EIO; \
4598 if (result==IPA_REPLY_SUCCESS) ret_val=0; \
4599 if (result==-EFAULT) ret_val=-EFAULT; \
4600 if (result==IPA_REPLY_FAILED) ret_val=-EIO; \
4601 if (result==IPA_REPLY_OPNOTSUPP) ret_val=-EOPNOTSUPP
4602
qeth_do_ioctl(struct net_device * dev,struct ifreq * rq,int cmd)4603 static int qeth_do_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
4604 {
4605 char *data;
4606 int result,i,ret_val;
4607 int version=4;
4608 qeth_card_t *card;
4609 char dbf_text[15];
4610 char buff[100];
4611
4612 card=(qeth_card_t*)dev->priv;
4613
4614 sprintf(dbf_text,"ioct%4x",card->irq0);
4615 QETH_DBF_TEXT2(0,trace,dbf_text);
4616 sprintf(dbf_text,"cmd=%4x",cmd);
4617 QETH_DBF_TEXT2(0,trace,dbf_text);
4618 QETH_DBF_HEX2(0,trace,&rq,sizeof(void*));
4619
4620 if ((cmd<SIOCDEVPRIVATE) || (cmd>SIOCDEVPRIVATE+5))
4621 return -EOPNOTSUPP;
4622 if (copy_from_user(buff,rq->ifr_ifru.ifru_data,sizeof(buff)))
4623 return -EFAULT;
4624 data=buff;
4625
4626 if ((cmd<SIOCDEVPRIVATE) || (cmd>SIOCDEVPRIVATE+5))
4627 return -EOPNOTSUPP;
4628 if (copy_from_user(buff,rq->ifr_ifru.ifru_data,sizeof(buff)))
4629 return -EFAULT;
4630 data=buff;
4631
4632 if ( (!atomic_read(&card->is_registered))||
4633 (!atomic_read(&card->is_hardsetup))||
4634 (atomic_read(&card->is_gone)) ) return -ENODEV;
4635
4636 if (atomic_read(&card->shutdown_phase)) return -ENODEV;
4637
4638 if (down_interruptible ( &card->ioctl_sem ) )
4639 return -ERESTARTSYS;
4640
4641 if (atomic_read(&card->shutdown_phase)) {
4642 ret_val=-ENODEV;
4643 goto out;
4644 }
4645
4646 if ( (!atomic_read(&card->is_registered))||
4647 (!atomic_read(&card->is_hardsetup))||
4648 (atomic_read(&card->is_gone)) ) {
4649 ret_val=-ENODEV;
4650 goto out;
4651 }
4652
4653 switch (cmd) {
4654 case SIOCDEVPRIVATE+0:
4655 if (!capable(CAP_NET_ADMIN)) {
4656 ret_val=-EPERM;
4657 break;
4658 }
4659 result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING,
4660 IPA_CMD_ASS_ARP_SET_NO_ENTRIES,
4661 rq->ifr_ifru.ifru_ivalue,4);
4662 QETH_STANDARD_RETVALS;
4663 if (result==3) ret_val=-EINVAL;
4664 break;
4665 case SIOCDEVPRIVATE+1:
4666 if (!capable(CAP_NET_ADMIN)) {
4667 ret_val=-EPERM;
4668 break;
4669 }
4670 result = qeth_queryarp(card,rq,version,IPA_ARP_PROCESSING,
4671 IPA_CMD_ASS_ARP_QUERY_INFO,data,4);
4672
4673 QETH_STANDARD_RETVALS;
4674 break;
4675 case SIOCDEVPRIVATE+2:
4676 if (!capable(CAP_NET_ADMIN)) {
4677 ret_val=-EPERM;
4678 break;
4679 }
4680 for (i=12;i<24;i++) if (data[i]) version=6;
4681 result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING,
4682 IPA_CMD_ASS_ARP_ADD_ENTRY,
4683 (long)data,56);
4684 QETH_STANDARD_RETVALS;
4685 break;
4686 case SIOCDEVPRIVATE+3:
4687 if (!capable(CAP_NET_ADMIN)) {
4688 ret_val=-EPERM;
4689 break;
4690 }
4691 for (i=12;i<24;i++) if (data[i]) version=6;
4692 result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING,
4693 IPA_CMD_ASS_ARP_REMOVE_ENTRY,
4694 (long)data,16);
4695 QETH_STANDARD_RETVALS;
4696 break;
4697 case SIOCDEVPRIVATE+4:
4698 if (!capable(CAP_NET_ADMIN)) {
4699 ret_val=-EPERM;
4700 break;
4701 }
4702 result=qeth_send_setassparms(card,version,IPA_ARP_PROCESSING,
4703 IPA_CMD_ASS_ARP_FLUSH_CACHE,
4704 0,0);
4705 QETH_STANDARD_RETVALS;
4706 break;
4707 case SIOCDEVPRIVATE+5:
4708 result=qeth_send_snmp_control(card,rq,
4709 IPA_CMD_SETADAPTERPARMS,
4710 IPA_SETADP_SET_SNMP_CONTROL,
4711 data,4);
4712 QETH_STANDARD_RETVALS;
4713 break;
4714 case SIOCDEVPRIVATE+6:
4715 if (!card->is_guest_lan &&
4716 (card->type == QETH_CARD_TYPE_OSAE))
4717 ret_val = 1;
4718 else
4719 ret_val = 0;
4720 break;
4721
4722 default:
4723 ret_val=-EOPNOTSUPP;
4724 goto out;
4725 }
4726 out:
4727 up (&card->ioctl_sem);
4728
4729 sprintf(dbf_text,"ret=%4x",ret_val);
4730 QETH_DBF_TEXT2(0,trace,dbf_text);
4731
4732 return ret_val;
4733 }
4734
qeth_clear_ifamc_list(struct qeth_ipm_mac ** ifa_list)4735 static void qeth_clear_ifamc_list(struct qeth_ipm_mac **ifa_list)
4736 {
4737 struct qeth_ipm_mac *ifa;
4738 while (*ifa_list) {
4739 ifa=*ifa_list;
4740 *ifa_list=ifa->next;
4741 kfree(ifa);
4742 }
4743 }
4744
4745 #ifdef QETH_IPV6
qeth_clear_ifa6_list(struct inet6_ifaddr ** ifa_list)4746 static void qeth_clear_ifa6_list(struct inet6_ifaddr **ifa_list)
4747 {
4748 struct inet6_ifaddr *ifa;
4749 while (*ifa_list) {
4750 ifa=*ifa_list;
4751 *ifa_list=ifa->if_next;
4752 kfree(ifa);
4753 }
4754 }
4755
qeth_takeover_ip_ipms6(qeth_card_t * card)4756 static void qeth_takeover_ip_ipms6(qeth_card_t *card)
4757 {
4758 struct inet6_ifaddr *ifa,*ifanew;
4759 char dbf_text[15];
4760 int remove;
4761 #ifdef QETH_VLAN
4762 struct vlan_group *card_group;
4763 int i;
4764 #endif
4765
4766 struct qeth_ipm_mac *ipmanew;
4767 struct ifmcaddr6 *im6;
4768 struct inet6_dev *in6_dev;
4769 #ifdef QETH_VLAN
4770 struct inet6_dev *in6_vdev;
4771 #endif
4772 char buf[MAX_ADDR_LEN];
4773
4774 sprintf(dbf_text,"tip6%4x",card->irq0);
4775 QETH_DBF_TEXT3(0,trace,dbf_text);
4776 /* unicast */
4777 /* clear ip_current_state */
4778 qeth_clear_ifa6_list(&card->ip_current_state.ip6_ifa);
4779 /* take it over */
4780 card->ip_current_state.ip6_ifa=card->ip_new_state.ip6_ifa;
4781 card->ip_new_state.ip6_ifa=NULL;
4782
4783 /* multicast */
4784 /* clear ip_mc_current_state */
4785 qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm6_ifa);
4786 /* take it over */
4787 card->ip_mc_current_state.ipm6_ifa=card->ip_mc_new_state.ipm6_ifa;
4788 /* get new one, we try to have the same order as ifa_list in device
4789 structure, for what reason ever*/
4790 card->ip_mc_new_state.ipm6_ifa=NULL;
4791
4792 if((in6_dev=in6_dev_get(card->dev))==NULL) {
4793 sprintf(dbf_text,"id16%4x",card->irq0);
4794 QETH_DBF_TEXT2(0,trace,dbf_text);
4795 goto out;
4796 }
4797 read_lock(&in6_dev->lock);
4798
4799 /* get new one, we try to have the same order as ifa_list in device
4800 structure, for what reason ever*/
4801 QETH_DBF_TEXT4(0,trace,"to-ip6s");
4802 if ( (atomic_read(&card->is_open)) && (card->dev->ip6_ptr) &&
4803 (((struct inet6_dev*)card->dev->ip6_ptr)->addr_list) ) {
4804 ifa=((struct inet6_dev*)card->dev->ip6_ptr)->addr_list;
4805
4806 while (ifa) {
4807 ifanew=kmalloc(sizeof(struct inet6_ifaddr),GFP_KERNEL);
4808 if (!ifanew) {
4809 PRINT_WARN("No memory for IP address " \
4810 "handling. Some of the IPs " \
4811 "will not be set on %s.\n",
4812 card->dev_name);
4813 QETH_DBF_TEXT2(0,trace,"TOIPNMEM");
4814 } else {
4815 qeth_clone_ifa6(ifa,ifanew);
4816 remove=qeth_add_ifa6_to_list(
4817 &card->ip_new_state.ip6_ifa,ifanew);
4818 QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr,
4819 QETH_DBF_TRACE_LEN);
4820 QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr+
4821 QETH_DBF_TRACE_LEN,
4822 QETH_DBF_TRACE_LEN);
4823 sprintf(dbf_text,"pref%4u",ifanew->prefix_len);
4824 QETH_DBF_TEXT4(0,trace,dbf_text);
4825 if (remove) {
4826 kfree(ifanew);
4827 QETH_DBF_TEXT4(0,trace,"alrdy6rm");
4828 }
4829 }
4830 ifa=ifa->if_next;
4831 }
4832 }
4833 #ifdef QETH_VLAN
4834 /*append all known VLAN IP Addresses corresponding
4835 to the real device card->dev->ifindex
4836 */
4837 QETH_DBF_TEXT4(0,trace,"to-vip6s");
4838 if ( (qeth_is_supported(IPA_FULL_VLAN)) &&
4839 (atomic_read(&card->is_open)) ) {
4840 card_group = (struct vlan_group *) card->vlangrp;
4841 if (card_group) for (i=0;i<VLAN_GROUP_ARRAY_LEN;i++) {
4842 if ( (card_group->vlan_devices[i]) &&
4843 (card_group->vlan_devices[i]->flags&IFF_UP)&&
4844 ((struct inet6_dev *) card_group->
4845 vlan_devices[i]->ip6_ptr) ) {
4846 ifa=((struct inet6_dev *)
4847 card_group->vlan_devices[i]->ip6_ptr)->
4848 addr_list;
4849
4850 while (ifa) {
4851 ifanew=kmalloc(sizeof(struct inet6_ifaddr),GFP_KERNEL);
4852 if (!ifanew) {
4853 PRINT_WARN("No memory for IP address " \
4854 "handling. Some of the IPs " \
4855 "will not be set on %s.\n",
4856 card->dev_name);
4857 QETH_DBF_TEXT2(0,trace,"TOIPNMEM");
4858 } else {
4859 qeth_clone_ifa6(ifa,ifanew);
4860 remove=qeth_add_ifa6_to_list
4861 (&card->ip_new_state.ip6_ifa,ifanew);
4862 QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr,
4863 QETH_DBF_TRACE_LEN);
4864 QETH_DBF_HEX4(0,trace,&ifanew->addr.s6_addr+
4865 QETH_DBF_TRACE_LEN,
4866 QETH_DBF_TRACE_LEN);
4867 sprintf(dbf_text,"pref%4u",ifanew->prefix_len);
4868 QETH_DBF_TEXT4(0,trace,dbf_text);
4869 if (remove) {
4870 kfree(ifanew);
4871 QETH_DBF_TEXT4(0,trace,"alrdv6rm");
4872 }
4873 }
4874 ifa=ifa->if_next;
4875 }
4876 }
4877 }
4878 }
4879 #endif
4880
4881 QETH_DBF_TEXT4(0,trace,"to-ipm6s");
4882 if (atomic_read(&card->is_open))
4883 for (im6=in6_dev->mc_list;im6;im6=im6->next) {
4884 ndisc_mc_map(&im6->mca_addr,buf,card->dev,0);
4885 ipmanew=(struct qeth_ipm_mac*)kmalloc(
4886 sizeof(struct qeth_ipm_mac),GFP_KERNEL);
4887 if (!ipmanew) {
4888 PRINT_WARN("No memory for IPM address " \
4889 "handling. Multicast IP " \
4890 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" \
4891 "will not be set on %s.\n",
4892 im6->mca_addr.s6_addr16[0],
4893 im6->mca_addr.s6_addr16[1],
4894 im6->mca_addr.s6_addr16[2],
4895 im6->mca_addr.s6_addr16[3],
4896 im6->mca_addr.s6_addr16[4],
4897 im6->mca_addr.s6_addr16[5],
4898 im6->mca_addr.s6_addr16[6],
4899 im6->mca_addr.s6_addr16[7],
4900 card->dev_name);
4901 QETH_DBF_TEXT2(0,trace,"TOIPMNMM");
4902 } else {
4903 memset(ipmanew,0,sizeof(struct qeth_ipm_mac));
4904 memcpy(ipmanew->mac,buf,OSA_ADDR_LEN);
4905 memcpy(ipmanew->ip,im6->mca_addr.s6_addr,16);
4906 ipmanew->next=NULL;
4907 remove=qeth_add_mc_ifa_to_list(
4908 &card->ip_mc_new_state.ipm6_ifa,ipmanew);
4909 QETH_DBF_HEX4(0,trace,&ipmanew->ip,
4910 QETH_DBF_TRACE_LEN);
4911 QETH_DBF_HEX4(0,trace,&ipmanew->ip+
4912 QETH_DBF_TRACE_LEN,
4913 QETH_DBF_TRACE_LEN);
4914 QETH_DBF_HEX4(0,trace,&ipmanew->mac,
4915 QETH_DBF_TRACE_LEN);
4916 if (remove) {
4917 QETH_DBF_TEXT4(0,trace,"mlrdy6rm");
4918 kfree(ipmanew);
4919 }
4920 }
4921 }
4922 #ifdef QETH_VLAN
4923 QETH_DBF_TEXT4(0,trace,"tovipm6s");
4924 if ( (qeth_is_supported(IPA_FULL_VLAN)) &&
4925 (atomic_read(&card->is_open)) ) {
4926 card_group = (struct vlan_group *) card->vlangrp;
4927 if (card_group) for (i=0;i<VLAN_GROUP_ARRAY_LEN;i++) {
4928 if ((card_group->vlan_devices[i])&&
4929 (card_group->vlan_devices[i]->flags&IFF_UP)) {
4930 in6_vdev=in6_dev_get(card_group->
4931 vlan_devices[i]);
4932 if(!(in6_vdev==NULL)) {
4933 read_lock(&in6_vdev->lock);
4934 for (im6=in6_vdev->mc_list;
4935 im6;im6=im6->next) {
4936 ndisc_mc_map(&im6->mca_addr,
4937 buf,card_group->vlan_devices[i],
4938 0);
4939 ipmanew=(struct qeth_ipm_mac*)
4940 kmalloc(sizeof(struct qeth_ipm_mac),
4941 GFP_KERNEL);
4942 if (!ipmanew) {
4943 PRINT_WARN("No memory for IPM address " \
4944 "handling. Multicast IP " \
4945 "%04x:%04x:%04x:%04x:" \
4946 "%04x:%04x:%04x:%04x" \
4947 "will not be set on %s.\n",
4948 im6->mca_addr.s6_addr16[0],
4949 im6->mca_addr.s6_addr16[1],
4950 im6->mca_addr.s6_addr16[2],
4951 im6->mca_addr.s6_addr16[3],
4952 im6->mca_addr.s6_addr16[4],
4953 im6->mca_addr.s6_addr16[5],
4954 im6->mca_addr.s6_addr16[6],
4955 im6->mca_addr.s6_addr16[7],
4956 card->dev_name);
4957 QETH_DBF_TEXT2(0,trace,"TOIPMNMM");
4958 } else {
4959 memset(ipmanew,0,
4960 sizeof(struct qeth_ipm_mac));
4961 memcpy(ipmanew->mac,buf,OSA_ADDR_LEN);
4962 memcpy(ipmanew->ip,
4963 im6->mca_addr.s6_addr,16);
4964 ipmanew->next=NULL;
4965 remove=qeth_add_mc_ifa_to_list
4966 (&card->ip_mc_new_state.ipm6_ifa,
4967 ipmanew);
4968 QETH_DBF_HEX4(0,trace,&ipmanew->ip,
4969 QETH_DBF_TRACE_LEN);
4970 QETH_DBF_HEX4(0,trace,&ipmanew->ip+
4971 QETH_DBF_TRACE_LEN,
4972 QETH_DBF_TRACE_LEN);
4973 QETH_DBF_HEX4(0,trace,&ipmanew->mac,
4974 QETH_DBF_TRACE_LEN);
4975
4976 if (remove) {
4977 QETH_DBF_TEXT4(0,trace,"mlrdv6rm");
4978 kfree(ipmanew);
4979 }
4980 }
4981 }
4982 read_unlock(&in6_vdev->lock);
4983 in6_dev_put(in6_vdev);
4984 } else {
4985 sprintf(dbf_text,"id26%4x",card->irq0);
4986 QETH_DBF_TEXT2(0,trace,dbf_text);
4987 }
4988 }
4989 }
4990 }
4991 #endif
4992 read_unlock(&in6_dev->lock);
4993 in6_dev_put(in6_dev);
4994 out:
4995 ;
4996 }
4997 #endif /* QETH_IPV6 */
4998
qeth_clear_ifa4_list(struct in_ifaddr ** ifa_list)4999 static void qeth_clear_ifa4_list(struct in_ifaddr **ifa_list)
5000 {
5001 struct in_ifaddr *ifa;
5002 while (*ifa_list) {
5003 ifa=*ifa_list;
5004 *ifa_list=ifa->ifa_next;
5005 kfree(ifa);
5006 }
5007 }
5008
qeth_takeover_ip_ipms(qeth_card_t * card)5009 static void qeth_takeover_ip_ipms(qeth_card_t *card)
5010 {
5011 struct in_ifaddr *ifa,*ifanew;
5012 char dbf_text[15];
5013 int remove;
5014 #ifdef QETH_VLAN
5015 struct vlan_group *card_group;
5016 int i;
5017 struct in_device *vin4_dev;
5018 #endif
5019
5020 struct qeth_ipm_mac *ipmanew;
5021 struct ip_mc_list *im4;
5022 struct in_device *in4_dev;
5023 char buf[MAX_ADDR_LEN];
5024 __u32 maddr;
5025
5026 sprintf(dbf_text,"tips%4x",card->irq0);
5027 QETH_DBF_TEXT3(0,trace,dbf_text);
5028 /* unicast */
5029 /* clear ip_current_state */
5030 qeth_clear_ifa4_list(&card->ip_current_state.ip_ifa);
5031 /* take it over */
5032 card->ip_current_state.ip_ifa=card->ip_new_state.ip_ifa;
5033 card->ip_new_state.ip_ifa=NULL;
5034
5035 /* multicast */
5036 /* clear ip_mc_current_state */
5037 qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm_ifa);
5038 /* take it over */
5039 card->ip_mc_current_state.ipm_ifa=card->ip_mc_new_state.ipm_ifa;
5040 /* get new one, we try to have the same order as ifa_list in device
5041 structure, for what reason ever*/
5042 card->ip_mc_new_state.ipm_ifa=NULL;
5043
5044 if((in4_dev=in_dev_get(card->dev))==NULL) {
5045 QETH_DBF_TEXT2(0,trace,"nodvhol1");
5046 QETH_DBF_TEXT2(0,trace,card->dev_name);
5047 return;
5048 }
5049 read_lock(&in4_dev->lock);
5050
5051 /* get new one, we try to have the same order as ifa_list in device
5052 structure, for what reason ever*/
5053 QETH_DBF_TEXT4(0,trace,"to-ips");
5054 if ( (atomic_read(&card->is_open)) && (card->dev->ip_ptr) &&
5055 (((struct in_device*)card->dev->ip_ptr)->ifa_list) ) {
5056 ifa=((struct in_device*)card->dev->ip_ptr)->ifa_list;
5057
5058 while (ifa) {
5059 ifanew=kmalloc(sizeof(struct in_ifaddr),GFP_KERNEL);
5060 if (!ifanew) {
5061 PRINT_WARN("No memory for IP address " \
5062 "handling. Some of the IPs " \
5063 "will not be set on %s.\n",
5064 card->dev_name);
5065 QETH_DBF_TEXT2(0,trace,"TOIPNMEM");
5066 } else {
5067 qeth_clone_ifa(ifa,ifanew);
5068 remove=qeth_add_ifa_to_list(
5069 &card->ip_new_state.ip_ifa,ifanew);
5070 *((__u32*)(&dbf_text[0]))=
5071 *((__u32*)&ifanew->ifa_address);
5072 *((__u32*)(&dbf_text[4]))=
5073 *((__u32*)&ifanew->ifa_mask);
5074 QETH_DBF_TEXT4(0,trace,dbf_text);
5075 if (remove) {
5076 kfree(ifanew);
5077 QETH_DBF_TEXT4(0,trace,"alrdy4rm");
5078 }
5079 }
5080
5081 ifa=ifa->ifa_next;
5082 }
5083 }
5084
5085 #ifdef QETH_VLAN
5086 /* append all known VLAN IP Addresses corresponding to the
5087 * real device card->dev->ifindex */
5088 QETH_DBF_TEXT4(0,trace,"to-vips");
5089 if ( (qeth_is_supported(IPA_FULL_VLAN)) &&
5090 (atomic_read(&card->is_open)) ) {
5091 card_group = (struct vlan_group *) card->vlangrp;
5092 if (card_group) {
5093 for (i=0;i<VLAN_GROUP_ARRAY_LEN;i++) {
5094 if ((vin4_dev=in_dev_get(card->dev))) {
5095 read_lock(&vin4_dev->lock);
5096 if ((card_group->vlan_devices[i])&&
5097 (card_group->vlan_devices[i]->flags&IFF_UP)) {
5098 ifa=((struct in_device*)
5099 card_group->vlan_devices[i]->ip_ptr)->
5100 ifa_list;
5101 while (ifa) {
5102 ifanew=kmalloc(sizeof(struct in_ifaddr),
5103 GFP_KERNEL);
5104 if (!ifanew) {
5105 PRINT_WARN("No memory for IP address " \
5106 "handling. Some of the IPs " \
5107 "will not be set on %s.\n",
5108 card->dev_name);
5109 QETH_DBF_TEXT2(0,trace,"TOIPNMEM");
5110 } else {
5111 qeth_clone_ifa(ifa,ifanew);
5112 remove=qeth_add_ifa_to_list(
5113 &card->ip_new_state.ip_ifa,
5114 ifanew);
5115 *((__u32*)(&dbf_text[0]))=
5116 *((__u32*)&ifanew->
5117 ifa_address);
5118 *((__u32*)(&dbf_text[4]))=
5119 *((__u32*)&ifanew->ifa_mask);
5120 QETH_DBF_TEXT4(0,trace,dbf_text);
5121 if (remove) {
5122 kfree(ifanew);
5123 QETH_DBF_TEXT4(0,trace,
5124 "alrdv4rm");
5125 }
5126 }
5127 ifa=ifa->ifa_next;
5128 }
5129 }
5130 read_unlock(&vin4_dev->lock);
5131 in_dev_put(vin4_dev);
5132 } else {
5133 QETH_DBF_TEXT2(0,trace,"nodvhol2");
5134 QETH_DBF_TEXT2(0,trace,card->dev_name);
5135 }
5136 }
5137 }
5138 }
5139 #endif /* QETH_VLAN */
5140
5141 QETH_DBF_TEXT4(0,trace,"to-ipms");
5142 if (atomic_read(&card->is_open))
5143 for (im4=in4_dev->mc_list;im4;im4=im4->next) {
5144 qeth_get_mac_for_ipm(im4->multiaddr,buf,in4_dev->dev);
5145 ipmanew=(struct qeth_ipm_mac*)kmalloc(
5146 sizeof(struct qeth_ipm_mac),GFP_KERNEL);
5147 if (!ipmanew) {
5148 PRINT_WARN("No memory for IPM address " \
5149 "handling. Multicast IP %08x" \
5150 "will not be set on %s.\n",
5151 (__u32)im4->multiaddr,
5152 card->dev_name);
5153 QETH_DBF_TEXT2(0,trace,"TOIPMNMM");
5154 } else {
5155 memset(ipmanew,0,sizeof(struct qeth_ipm_mac));
5156 memcpy(ipmanew->mac,buf,OSA_ADDR_LEN);
5157 maddr=im4->multiaddr;
5158 memcpy(&(ipmanew->ip[0]),&maddr,4);
5159 memset(&(ipmanew->ip[4]),0xff,12);
5160 ipmanew->next=NULL;
5161 remove=qeth_add_mc_ifa_to_list(
5162 &card->ip_mc_new_state.ipm_ifa,ipmanew);
5163 sprintf(dbf_text,"%08x",*((__u32*)&ipmanew->ip));
5164 QETH_DBF_TEXT4(0,trace,dbf_text);
5165 QETH_DBF_HEX4(0,trace,&ipmanew->mac,
5166 QETH_DBF_TRACE_LEN);
5167 if (remove) {
5168 QETH_DBF_TEXT4(0,trace,"mlrdy4rm");
5169 kfree(ipmanew);
5170 }
5171 }
5172 }
5173
5174 #ifdef QETH_VLAN
5175 QETH_DBF_TEXT4(0,trace,"to-vipms");
5176 if ( (qeth_is_supported(IPA_FULL_VLAN)) &&
5177 (atomic_read(&card->is_open)) ) {
5178 card_group = (struct vlan_group *) card->vlangrp;
5179 if (card_group) for (i=0;i<VLAN_GROUP_ARRAY_LEN;i++) {
5180 if ((card_group->vlan_devices[i])&&
5181 (card_group->vlan_devices[i]->flags&IFF_UP)) {
5182 if ((vin4_dev=in_dev_get(card_group->
5183 vlan_devices[i]))) {
5184 read_lock(&vin4_dev->lock);
5185 for (im4=vin4_dev->mc_list;im4;im4=im4->next) {
5186 qeth_get_mac_for_ipm(im4->multiaddr,buf,vin4_dev->dev);
5187 ipmanew=(struct qeth_ipm_mac*)kmalloc(
5188 sizeof(struct qeth_ipm_mac),GFP_KERNEL);
5189 if (!ipmanew) {
5190 PRINT_WARN("No memory for IPM address " \
5191 "handling. Multicast VLAN IP %08x" \
5192 "will not be set on %s.\n",
5193 (__u32)im4->multiaddr,
5194 card->dev_name);
5195 QETH_DBF_TEXT2(0,trace,"TOIPMNMM");
5196 } else {
5197 memset(ipmanew,0,sizeof(struct qeth_ipm_mac));
5198 memcpy(ipmanew->mac,buf,OSA_ADDR_LEN);
5199 maddr=im4->multiaddr;
5200 memcpy(&(ipmanew->ip[0]),&maddr,4);
5201 memset(&(ipmanew->ip[4]),0xff,12);
5202 ipmanew->next=NULL;
5203 remove=qeth_add_mc_ifa_to_list(
5204 &card->ip_mc_new_state.ipm_ifa,
5205 ipmanew);
5206 sprintf(dbf_text,"%08x",
5207 *((__u32*)&ipmanew->ip));
5208 QETH_DBF_TEXT4(0,trace,dbf_text);
5209 QETH_DBF_HEX4(0,trace,&ipmanew->mac,
5210 QETH_DBF_TRACE_LEN);
5211 if (remove) {
5212 QETH_DBF_TEXT4(0,trace,"mlrdv4rm");
5213 kfree(ipmanew);
5214 }
5215 }
5216 }
5217 read_unlock(&vin4_dev->lock);
5218 in_dev_put(vin4_dev);
5219 } else {
5220 QETH_DBF_TEXT2(0,trace,"novdhol3");
5221 QETH_DBF_TEXT2(0,trace,card->dev_name);
5222 QETH_DBF_TEXT2(0,trace,card_group->
5223 vlan_devices[i]->name);
5224 }
5225 }
5226 }
5227 }
5228 #endif /* QETH_VLAN */
5229
5230 read_unlock(&in4_dev->lock);
5231 in_dev_put(in4_dev);
5232 }
5233
qeth_get_unique_id(qeth_card_t * card)5234 static void qeth_get_unique_id(qeth_card_t *card)
5235 {
5236 #ifdef QETH_IPV6
5237 #ifdef CONFIG_SHARED_IPV6_CARDS
5238 ipa_cmd_t cmd;
5239 int result;
5240 char dbf_text[15];
5241
5242 if (!qeth_is_supported(IPA_IPv6)) {
5243 card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|
5244 UNIQUE_ID_NOT_BY_CARD;
5245 return;
5246 }
5247 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_CREATE_ADDR,6);
5248
5249 *((__u16*)&cmd.data.create_destroy_addr.unique_id[6])=card->unique_id;
5250
5251 result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE);
5252
5253 if (result) {
5254 card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|
5255 UNIQUE_ID_NOT_BY_CARD;
5256 PRINT_WARN("couldn't get a unique id from the card on irq " \
5257 "x%x (result=x%x), using default id. ipv6 " \
5258 "autoconfig on other lpars may lead to duplicate " \
5259 "ip addresses. please use manually " \
5260 "configured ones.\n",card->irq0,result);
5261 QETH_DBF_TEXT2(0,trace,"unid fld");
5262 sprintf(dbf_text,"%4x%4x",card->irq0,result);
5263 QETH_DBF_TEXT2(0,trace,dbf_text);
5264 } else {
5265 card->unique_id=
5266 *((__u16*)&cmd.data.create_destroy_addr.unique_id[6]);
5267 QETH_DBF_TEXT2(0,setup,"uniqueid");
5268 sprintf(dbf_text,"%4x%4x",card->irq0,card->unique_id);
5269 QETH_DBF_TEXT2(0,setup,dbf_text);
5270 }
5271 #else /* CONFIG_SHARED_IPV6_CARDS */
5272 card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD;
5273 #endif /* CONFIG_SHARED_IPV6_CARDS */
5274 #else /* QETH_IPV6 */
5275 card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD;
5276 #endif /* QETH_IPV6 */
5277 }
5278
qeth_put_unique_id(qeth_card_t * card)5279 static void qeth_put_unique_id(qeth_card_t *card)
5280 {
5281 #ifdef QETH_IPV6
5282 #ifdef CONFIG_SHARED_IPV6_CARDS
5283 ipa_cmd_t cmd;
5284 int result;
5285 char dbf_text[15];
5286
5287 /* is also true, if ipv6 is not supported on the card */
5288 if ((card->unique_id&UNIQUE_ID_NOT_BY_CARD)==UNIQUE_ID_NOT_BY_CARD)
5289 return;
5290
5291 qeth_fill_ipa_cmd(card,&cmd,IPA_CMD_DESTROY_ADDR,6);
5292 *((__u16*)&cmd.data.create_destroy_addr.unique_id[6])=card->unique_id;
5293 memcpy(&cmd.data.create_destroy_addr.unique_id[0],
5294 card->dev->dev_addr,OSA_ADDR_LEN);
5295
5296 result=qeth_send_ipa_cmd(card,&cmd,1,IPA_CMD_STATE);
5297
5298 if (result) {
5299 QETH_DBF_TEXT2(0,trace,"unibkfld");
5300 sprintf(dbf_text,"%4x%4x",card->irq0,result);
5301 QETH_DBF_TEXT2(0,trace,dbf_text);
5302 }
5303 #else /* CONFIG_SHARED_IPV6_CARDS */
5304 card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD;
5305 #endif /* CONFIG_SHARED_IPV6_CARDS */
5306 #else /* QETH_IPV6 */
5307 card->unique_id=UNIQUE_ID_IF_CREATE_ADDR_FAILED|UNIQUE_ID_NOT_BY_CARD;
5308 #endif /* QETH_IPV6 */
5309 }
5310
qeth_do_setadapterparms_stuff(qeth_card_t * card)5311 static void qeth_do_setadapterparms_stuff(qeth_card_t *card)
5312 {
5313 int result;
5314 char dbf_text[15];
5315
5316 if (!qeth_is_supported(IPA_SETADAPTERPARMS)) {
5317 return;
5318 }
5319
5320 sprintf(dbf_text,"stap%4x",card->irq0);
5321 QETH_DBF_TEXT4(0,trace,dbf_text);
5322
5323 result=qeth_send_setadapterparms_query(card);
5324
5325 if (result) {
5326 PRINT_WARN("couldn't set adapter parameters on irq 0x%x: " \
5327 "x%x\n",card->irq0,result);
5328 QETH_DBF_TEXT1(0,trace,"SETADPFL");
5329 sprintf(dbf_text,"%4x%4x",card->irq0,result);
5330 QETH_DBF_TEXT1(1,trace,dbf_text);
5331 return;
5332 }
5333
5334 sprintf(dbf_text,"spap%4x",card->adp_supported);
5335 QETH_DBF_TEXT2(0,trace,dbf_text);
5336
5337 if (qeth_is_adp_supported(IPA_SETADP_ALTER_MAC_ADDRESS)) {
5338 sprintf(dbf_text,"rdmc%4x",card->irq0);
5339 QETH_DBF_TEXT3(0,trace,dbf_text);
5340 QETH_DBF_TEXT2(0,setup,dbf_text);
5341
5342 result=qeth_send_setadapterparms_change_addr(card,
5343 IPA_SETADP_ALTER_MAC_ADDRESS,
5344 CHANGE_ADDR_READ_MAC,card->dev->dev_addr,
5345 OSA_ADDR_LEN);
5346 if (result) {
5347 PRINT_WARN("couldn't get MAC address on " \
5348 "irq 0x%x: x%x\n",card->irq0,result);
5349 QETH_DBF_TEXT1(0,trace,"NOMACADD");
5350 sprintf(dbf_text,"%4x%4x",card->irq0,result);
5351 QETH_DBF_TEXT1(1,trace,dbf_text);
5352 } else {
5353 QETH_DBF_HEX2(0,setup,card->dev->dev_addr,
5354 __max(OSA_ADDR_LEN,QETH_DBF_SETUP_LEN));
5355 QETH_DBF_HEX3(0,trace,card->dev->dev_addr,
5356 __max(OSA_ADDR_LEN,QETH_DBF_TRACE_LEN));
5357 }
5358 }
5359
5360 if ( (card->link_type==QETH_MPC_LINK_TYPE_HSTR) ||
5361 (card->link_type==QETH_MPC_LINK_TYPE_LANE_TR) ) {
5362 sprintf(dbf_text,"hstr%4x",card->irq0);
5363 QETH_DBF_TEXT3(0,trace,dbf_text);
5364
5365 if (qeth_is_adp_supported(IPA_SETADP_SET_BROADCAST_MODE)) {
5366 result=qeth_send_setadapterparms_mode(card,
5367 IPA_SETADP_SET_BROADCAST_MODE,
5368 card->options.broadcast_mode);
5369 if (result) {
5370 PRINT_WARN("couldn't set broadcast mode on " \
5371 "irq 0x%x: x%x\n",
5372 card->irq0,result);
5373 QETH_DBF_TEXT1(0,trace,"STBRDCST");
5374 sprintf(dbf_text,"%4x%4x",card->irq0,result);
5375 QETH_DBF_TEXT1(1,trace,dbf_text);
5376 }
5377 } else if (card->options.broadcast_mode) {
5378 PRINT_WARN("set adapter parameters not available " \
5379 "to set broadcast mode, using ALLRINGS " \
5380 "on irq 0x%x:\n",card->irq0);
5381 sprintf(dbf_text,"NOBC%4x",card->irq0);
5382 QETH_DBF_TEXT1(0,trace,dbf_text);
5383 }
5384
5385 if (qeth_is_adp_supported(IPA_SETADP_SET_BROADCAST_MODE)) {
5386 result=qeth_send_setadapterparms_mode(card,
5387 IPA_SETADP_ALTER_MAC_ADDRESS,
5388 card->options.macaddr_mode);
5389 if (result) {
5390 PRINT_WARN("couldn't set macaddr mode on " \
5391 "irq 0x%x: x%x\n",
5392 card->irq0,result);
5393 QETH_DBF_TEXT1(0,trace,"STMACMOD");
5394 sprintf(dbf_text,"%4x%4x",card->irq0,result);
5395 QETH_DBF_TEXT1(1,trace,dbf_text);
5396 }
5397 } else if (card->options.macaddr_mode) {
5398 PRINT_WARN("set adapter parameters not available " \
5399 "to set macaddr mode, using NONCANONICAL " \
5400 "on irq 0x%x:\n",card->irq0);
5401 sprintf(dbf_text,"NOMA%4x",card->irq0);
5402 QETH_DBF_TEXT1(0,trace,dbf_text);
5403 }
5404 }
5405 }
5406
qeth_softsetup_card(qeth_card_t * card,int wait_for_lock)5407 static int qeth_softsetup_card(qeth_card_t *card,int wait_for_lock)
5408 {
5409 int result;
5410 int use_setip_retries=1;
5411 char dbf_text[15];
5412 int do_a_startlan6=0;
5413
5414 if (wait_for_lock==QETH_WAIT_FOR_LOCK) {
5415 my_spin_lock(&card->softsetup_lock);
5416 } else if (wait_for_lock==QETH_DONT_WAIT_FOR_LOCK) {
5417 if (!spin_trylock(&card->softsetup_lock)) {
5418 return -EAGAIN;
5419 }
5420 } else if (wait_for_lock==QETH_LOCK_ALREADY_HELD) {
5421 use_setip_retries=0; /* we are in recovery and don't want
5422 to repeat setting ips on and on */
5423 } else {
5424 return -EINVAL;
5425 }
5426
5427 qeth_save_dev_flag_state(card);
5428
5429 sprintf(dbf_text,"ssc%c%4x",wait_for_lock?'w':'n',card->irq0);
5430 QETH_DBF_TEXT1(0,trace,dbf_text);
5431
5432 if (!atomic_read(&card->is_softsetup)) {
5433 atomic_set(&card->enable_routing_attempts4,
5434 QETH_ROUTING_ATTEMPTS);
5435 #ifdef QETH_IPV6
5436 atomic_set(&card->enable_routing_attempts6,
5437 QETH_ROUTING_ATTEMPTS);
5438 #endif /* QETH_IPV6 */
5439 if ( (!atomic_read(&card->is_startlaned)) &&
5440 (atomic_read(&card->startlan_attempts)) ) {
5441 atomic_dec(&card->startlan_attempts);
5442 QETH_DBF_TEXT2(0,trace,"startlan");
5443 netif_stop_queue(card->dev);
5444 result=qeth_send_startlan(card,4);
5445 if (result) {
5446 PRINT_WARN("couldn't send STARTLAN on %s " \
5447 "(CHPID 0x%X): 0x%x (%s)\n",
5448 card->dev_name,card->chpid,result,
5449 (result==0xe080)?
5450 "startlan disabled (link " \
5451 "failure -- please check the " \
5452 "network, plug in the cable or " \
5453 "enable the OSA port":
5454 (result==0xf080)?
5455 "startlan disabled (VM: LAN " \
5456 "is offline for functions " \
5457 "requiring LAN access.":
5458 "unknown return code");
5459 sprintf(dbf_text,"stln%4x",result);
5460 QETH_DBF_TEXT2(0,trace,dbf_text);
5461 atomic_set(&card->is_softsetup,0);
5462 atomic_set(&card->is_startlaned,0);
5463 /* do not return an error */
5464 if ((result==0xe080)||(result==0xf080)) {
5465 result=0;
5466 }
5467 goto out;
5468 }
5469 do_a_startlan6=1;
5470 }
5471 netif_wake_queue(card->dev);
5472
5473 qeth_do_setadapterparms_stuff(card);
5474
5475 if (!qeth_is_supported(IPA_ARP_PROCESSING)) {
5476 PRINT_WARN("oops... ARP processing not supported " \
5477 "on %s!\n",card->dev_name);
5478 QETH_DBF_TEXT1(0,trace,"NOarpPRC");
5479 } else {
5480 QETH_DBF_TEXT2(0,trace,"enaARPpr");
5481 result=qeth_send_setassparms_simple_without_data(
5482 card,IPA_ARP_PROCESSING,IPA_CMD_ASS_START);
5483 if (result) {
5484 PRINT_WARN("Could not start ARP processing " \
5485 "assist on %s: 0x%x\n",
5486 card->dev_name,result);
5487 sprintf(dbf_text,"ARPp%4x",result);
5488 QETH_DBF_TEXT2(0,trace,dbf_text);
5489 atomic_set(&card->is_softsetup,0);
5490 goto out;
5491 }
5492 }
5493
5494 if (qeth_is_supported(IPA_IP_FRAGMENTATION)) {
5495 PRINT_INFO("IP fragmentation supported on " \
5496 "%s... :-)\n",card->dev_name);
5497 QETH_DBF_TEXT2(0,trace,"enaipfrg");
5498 result=qeth_send_setassparms_simple_without_data(
5499 card,IPA_IP_FRAGMENTATION,IPA_CMD_ASS_START);
5500 if (result) {
5501 PRINT_WARN("Could not start IP fragmenting " \
5502 "assist on %s: 0x%x, continuing\n",
5503 card->dev_name,result);
5504 sprintf(dbf_text,"IFRG%4x",result);
5505 QETH_DBF_TEXT2(0,trace,dbf_text);
5506 /* go on */
5507 }
5508 }
5509
5510 if (card->options.fake_ll==FAKE_LL) {
5511 if (qeth_is_supported(IPA_SOURCE_MAC_AVAIL)) {
5512 QETH_DBF_TEXT2(0,trace,"enainsrc");
5513 result=qeth_send_setassparms_simple_without_data(
5514 card,IPA_SOURCE_MAC_AVAIL,IPA_CMD_ASS_START);
5515 if (result) {
5516 PRINT_WARN("Could not start " \
5517 "inbound source " \
5518 "assist on %s: 0x%x, " \
5519 "continuing\n",
5520 card->dev_name,result);
5521 sprintf(dbf_text,"INSR%4x",result);
5522 QETH_DBF_TEXT2(0,trace,dbf_text);
5523 /* go on */
5524 }
5525 } else {
5526 PRINT_INFO("Inbound source addresses not " \
5527 "supported on %s\n",card->dev_name);
5528 }
5529 }
5530 #ifdef QETH_VLAN
5531 if (!qeth_is_supported(IPA_FULL_VLAN)) {
5532 PRINT_WARN("VLAN not supported on %s\n",
5533 card->dev_name);
5534 QETH_DBF_TEXT2(0,trace,"vlnotsup");
5535 } else {
5536 result=qeth_send_setassparms_simple_without_data(
5537 card,IPA_VLAN_PRIO,IPA_CMD_ASS_START);
5538 QETH_DBF_TEXT2(0,trace,"enavlan");
5539 if (result) {
5540 PRINT_WARN("Could not start vlan "
5541 "assist on %s: 0x%x, continuing\n",
5542 card->dev_name,result);
5543 sprintf(dbf_text,"VLAN%4x",result);
5544 QETH_DBF_TEXT2(0,trace,dbf_text);
5545 /* go on*/
5546 }
5547 else {
5548 card->dev->features |=
5549 NETIF_F_HW_VLAN_TX |
5550 NETIF_F_HW_VLAN_RX;
5551
5552 }
5553 }
5554 #endif /* QETH_VLAN */
5555
5556 if (!qeth_is_supported(IPA_MULTICASTING)) {
5557 PRINT_WARN("multicasting not supported on %s\n",
5558 card->dev_name);
5559 QETH_DBF_TEXT2(0,trace,"mcnotsup");
5560 } else {
5561 result=qeth_send_setassparms_simple_without_data(
5562 card,IPA_MULTICASTING,IPA_CMD_ASS_START);
5563 QETH_DBF_TEXT2(0,trace,"enamcass");
5564 if (result) {
5565 PRINT_WARN("Could not start multicast "
5566 "assist on %s: 0x%x, continuing\n",
5567 card->dev_name,result);
5568 sprintf(dbf_text,"MCAS%4x",result);
5569 QETH_DBF_TEXT2(0,trace,dbf_text);
5570 /* go on*/
5571 } else {
5572 card->dev->flags|=IFF_MULTICAST;
5573 }
5574 }
5575
5576 if (!qeth_is_supported(IPA_IPv6)) {
5577 QETH_DBF_TEXT2(0,trace,"ipv6ntsp");
5578 PRINT_WARN("IPv6 not supported on %s\n",
5579 card->dev_name);
5580 } else {
5581 if (do_a_startlan6) {
5582 QETH_DBF_TEXT2(0,trace,"startln6");
5583 netif_stop_queue(card->dev);
5584 result=qeth_send_startlan(card,6);
5585 if (result) {
5586 sprintf(dbf_text,"stl6%4x",result);
5587 QETH_DBF_TEXT2(0,trace,dbf_text);
5588 atomic_set(&card->is_softsetup,0);
5589 /* do not return an error */
5590 if ((result==0xe080)||
5591 (result==0xf080)) {
5592 result=0;
5593 }
5594 goto out;
5595 }
5596 }
5597 netif_wake_queue(card->dev);
5598 QETH_DBF_TEXT2(0,trace,"qipassi6");
5599 result=qeth_send_qipassist(card,6);
5600 if (result) {
5601 PRINT_WARN("couldn't send QIPASSIST6 on %s: " \
5602 "0x%x\n",card->dev_name,result);
5603 sprintf(dbf_text,"QIP6%4x",result);
5604 QETH_DBF_TEXT2(0,trace,dbf_text);
5605 atomic_set(&card->is_softsetup,0);
5606 goto out;
5607 }
5608
5609 sprintf(dbf_text,"%8x",card->ipa6_supported);
5610 QETH_DBF_TEXT2(0,trace,dbf_text);
5611 sprintf(dbf_text,"%8x",card->ipa6_enabled);
5612 QETH_DBF_TEXT2(0,trace,dbf_text);
5613 QETH_DBF_TEXT2(0,trace,"enaipv46");
5614 result=qeth_send_setassparms_simple_with_data(
5615 card,IPA_IPv6,IPA_CMD_ASS_START,3);
5616 if (result) {
5617 PRINT_WARN("Could not enable IPv4&6 assist " \
5618 "on %s: " \
5619 "0x%x, continuing\n",
5620 card->dev_name,result);
5621 sprintf(dbf_text,"I46A%4x",result);
5622 QETH_DBF_TEXT2(0,trace,dbf_text);
5623 /* go on */
5624 }
5625 QETH_DBF_TEXT2(0,trace,"enaipv6");
5626 result=qeth_send_setassparms_simple_without_data6(
5627 card,IPA_IPv6,IPA_CMD_ASS_START);
5628 if (result) {
5629 PRINT_WARN("Could not start IPv6 assist " \
5630 "on %s: " \
5631 "0x%x, continuing\n",
5632 card->dev_name,result);
5633 sprintf(dbf_text,"I6AS%4x",result);
5634 QETH_DBF_TEXT2(0,trace,dbf_text);
5635 /* go on */
5636 }
5637 QETH_DBF_TEXT2(0,trace,"enapstr6");
5638 result=qeth_send_setassparms_simple_without_data6(
5639 card,IPA_PASSTHRU,IPA_CMD_ASS_START);
5640 if (result) {
5641 PRINT_WARN("Could not enable passthrough " \
5642 "on %s: " \
5643 "0x%x, continuing\n",
5644 card->dev_name,result);
5645 sprintf(dbf_text,"PSTR%4x",result);
5646 QETH_DBF_TEXT2(0,trace,dbf_text);
5647 /* go on */
5648 }
5649 }
5650
5651 card->broadcast_capable=0;
5652 if (!qeth_is_supported(IPA_FILTERING)) {
5653 QETH_DBF_TEXT2(0,trace,"filtntsp");
5654 PRINT_WARN("Broadcasting not supported on %s\n",
5655 card->dev_name);
5656 } else {
5657 QETH_DBF_TEXT2(0,trace,"enafiltr");
5658 result=qeth_send_setassparms_simple_without_data(
5659 card,IPA_FILTERING,IPA_CMD_ASS_START);
5660 if (result) {
5661 PRINT_WARN("Could not enable broadcast " \
5662 "filtering on %s: " \
5663 "0x%x, continuing\n",
5664 card->dev_name,result);
5665 sprintf(dbf_text,"FLT1%4x",result);
5666 QETH_DBF_TEXT2(0,trace,dbf_text);
5667 goto go_on_filt;
5668 }
5669 result=qeth_send_setassparms_simple_with_data(
5670 card,IPA_FILTERING,IPA_CMD_ASS_CONFIGURE,1);
5671 if (result) {
5672 PRINT_WARN("Could not set up broadcast " \
5673 "filtering on %s: " \
5674 "0x%x, continuing\n",
5675 card->dev_name,result);
5676 sprintf(dbf_text,"FLT2%4x",result);
5677 QETH_DBF_TEXT2(0,trace,dbf_text);
5678 goto go_on_filt;
5679 }
5680 card->dev->flags|=IFF_BROADCAST;
5681 card->broadcast_capable=BROADCAST_WITH_ECHO;
5682
5683 result=qeth_send_setassparms_simple_with_data(
5684 card,IPA_FILTERING,IPA_CMD_ASS_ENABLE,1);
5685 sprintf(dbf_text,"Flt3%4x",result);
5686 QETH_DBF_TEXT2(0,trace,dbf_text);
5687 QETH_DBF_TEXT2(0,setup,dbf_text);
5688 if (!result) {
5689 PRINT_INFO("Broadcast packets will not be " \
5690 "echoed back on %s.\n",
5691 card->dev_name);
5692 card->broadcast_capable=BROADCAST_WITHOUT_ECHO;
5693 }
5694 }
5695 go_on_filt:
5696 if (card->options.checksum_type==HW_CHECKSUMMING) {
5697 if (!qeth_is_supported(IPA_INBOUND_CHECKSUM)) {
5698 PRINT_WARN("Inbound HW checksumming not " \
5699 "supported on %s, continuing " \
5700 "using inbound sw checksumming\n",
5701 card->dev_name);
5702 QETH_DBF_TEXT2(0,trace,"ibckntsp");
5703 card->options.checksum_type=SW_CHECKSUMMING;
5704 } else {
5705 QETH_DBF_TEXT2(0,trace,"ibcksupp");
5706 result=qeth_send_setassparms_simple_without_data(
5707 card,IPA_INBOUND_CHECKSUM,
5708 IPA_CMD_ASS_START);
5709 if (result) {
5710 PRINT_WARN("Could not start inbound " \
5711 "checksumming on %s: " \
5712 "0x%x, " \
5713 "continuing using " \
5714 "inbound sw checksumming\n",
5715 card->dev_name,result);
5716 sprintf(dbf_text,"SIBC%4x",result);
5717 QETH_DBF_TEXT2(0,trace,dbf_text);
5718 card->options.checksum_type=
5719 SW_CHECKSUMMING;
5720 goto go_on_checksum;
5721 }
5722 result=qeth_send_setassparms_simple_with_data(
5723 card,IPA_INBOUND_CHECKSUM,
5724 IPA_CMD_ASS_ENABLE,
5725 card->csum_enable_mask);
5726 if (result) {
5727 PRINT_WARN("Could not enable inbound " \
5728 "checksumming on %s: " \
5729 "0x%x, " \
5730 "continuing using " \
5731 "inbound sw checksumming\n",
5732 card->dev_name,result);
5733 sprintf(dbf_text,"EIBC%4x",result);
5734 QETH_DBF_TEXT2(0,trace,dbf_text);
5735 card->options.checksum_type=
5736 SW_CHECKSUMMING;
5737 goto go_on_checksum;
5738 }
5739 }
5740 }
5741 go_on_checksum:
5742
5743 atomic_set(&card->is_softsetup,1);
5744 }
5745
5746 if (atomic_read(&card->enable_routing_attempts4)) {
5747 if (card->options.routing_type4) {
5748 sprintf(dbf_text,"strtg4%2x",
5749 card->options.routing_type4);
5750 QETH_DBF_TEXT2(0,trace,dbf_text);
5751 result=qeth_send_setrtg(card,card->options.
5752 routing_type4,4);
5753 if (result) {
5754 if (atomic_dec_return(&card->
5755 enable_routing_attempts4)) {
5756 PRINT_WARN("couldn't set up v4 routing type " \
5757 "on %s: 0x%x (%s).\nWill try " \
5758 "next time again.\n",
5759 card->dev_name,result,
5760 ((result==0xe010)||
5761 (result==0xe008))?
5762 "primary already defined":
5763 ((result==0xe011)||
5764 (result==0xe009))?
5765 "secondary already defined":
5766 (result==0xe012)?
5767 "invalid indicator":
5768 "unknown return code");
5769 sprintf(dbf_text,"sRT4%4x",result);
5770 QETH_DBF_TEXT2(0,trace,dbf_text);
5771 atomic_set(&card->rt4fld,1);
5772 } else {
5773 PRINT_WARN("couldn't set up v4 routing type " \
5774 "on %s: 0x%x (%s).\nTrying to " \
5775 "continue without routing.\n",
5776 card->dev_name,result,
5777 ((result==0xe010)||
5778 (result==0xe008))?
5779 "primary already defined":
5780 ((result==0xe011)||
5781 (result==0xe009))?
5782 "secondary already defined":
5783 (result==0xe012)?
5784 "invalid indicator":
5785 "unknown return code");
5786 sprintf(dbf_text,"SRT4%4x",result);
5787 QETH_DBF_TEXT2(0,trace,dbf_text);
5788 atomic_set(&card->rt4fld,1);
5789 }
5790 } else { /* routing set correctly */
5791 atomic_set(&card->enable_routing_attempts4,0);
5792 atomic_set(&card->rt4fld,0);
5793 }
5794 } else {
5795 atomic_set(&card->enable_routing_attempts4,0);
5796 atomic_set(&card->rt4fld,0);
5797 }
5798 }
5799
5800 #ifdef QETH_IPV6
5801 if (atomic_read(&card->enable_routing_attempts6)) {
5802 /* for OSAs that can't do v6 multicast routing, we don't try */
5803 if ( (card->type==QETH_CARD_TYPE_OSAE) &&
5804 ( (card->options.routing_type6&ROUTER_MASK) ==
5805 MULTICAST_ROUTER) &&
5806 (!qeth_is_supported6(IPA_OSA_MC_ROUTER_AVAIL)) ) {
5807 atomic_set(&card->enable_routing_attempts6,0);
5808 atomic_set(&card->rt6fld,0);
5809 } else if (card->options.routing_type6) {
5810 sprintf(dbf_text,"strtg6%2x",
5811 card->options.routing_type6);
5812 QETH_DBF_TEXT2(0,trace,dbf_text);
5813 result=qeth_send_setrtg(card,card->options.
5814 routing_type6,6);
5815 if (result) {
5816 if (atomic_dec_return(&card->
5817 enable_routing_attempts6)) {
5818 PRINT_WARN("couldn't set up v6 routing type " \
5819 "on %s: 0x%x (%s).\nWill try " \
5820 "next time again.\n",
5821 card->dev_name,result,
5822 ((result==0xe010)||
5823 (result==0xe008))?
5824 "primary already defined":
5825 ((result==0xe011)||
5826 (result==0xe009))?
5827 "secondary already defined":
5828 (result==0xe012)?
5829 "invalid indicator":
5830 "unknown return code");
5831 sprintf(dbf_text,"sRT6%4x",result);
5832 QETH_DBF_TEXT2(0,trace,dbf_text);
5833 atomic_set(&card->rt6fld,1);
5834 } else {
5835 PRINT_WARN("couldn't set up v6 routing type " \
5836 "on %s: 0x%x (%s).\nTrying to " \
5837 "continue without routing.\n",
5838 card->dev_name,result,
5839 ((result==0xe010)||
5840 (result==0xe008))?
5841 "primary already defined":
5842 ((result==0xe011)||
5843 (result==0xe009))?
5844 "secondary already defined":
5845 (result==0xe012)?
5846 "invalid indicator":
5847 "unknown return code");
5848 sprintf(dbf_text,"SRT6%4x",result);
5849 QETH_DBF_TEXT2(0,trace,dbf_text);
5850 atomic_set(&card->rt6fld,1);
5851 }
5852 } else { /* routing set correctly */
5853 atomic_set(&card->enable_routing_attempts6,0);
5854 atomic_set(&card->rt6fld,0);
5855 }
5856 } else {
5857 atomic_set(&card->enable_routing_attempts6,0);
5858 atomic_set(&card->rt6fld,0);
5859 }
5860 }
5861 #endif /* QETH_IPV6 */
5862
5863 QETH_DBF_TEXT2(0,trace,"delvipa");
5864 qeth_set_vipas(card,0);
5865 QETH_DBF_TEXT2(0,trace,"toip/ms");
5866 qeth_takeover_ip_ipms(card);
5867 #ifdef QETH_IPV6
5868 qeth_takeover_ip_ipms6(card);
5869 #endif /* QETH_IPV6 */
5870 QETH_DBF_TEXT2(0,trace,"setvipa");
5871 qeth_set_vipas(card,1);
5872
5873 result=qeth_setips(card,use_setip_retries);
5874 if (result) { /* by now, qeth_setips does not return errors */
5875 PRINT_WARN("couldn't set up IPs on %s: 0x%x\n",
5876 card->dev_name,result);
5877 sprintf(dbf_text,"SSIP%4x",result);
5878 QETH_DBF_TEXT2(0,trace,dbf_text);
5879 atomic_set(&card->is_softsetup,0);
5880 goto out;
5881 }
5882
5883 result=qeth_setipms(card,use_setip_retries);
5884 if (result) { /* by now, qeth_setipms does not return errors */
5885 PRINT_WARN("couldn't set up multicast IPs on %s: 0x%x\n",
5886 card->dev_name,result);
5887 sprintf(dbf_text,"ssim%4x",result);
5888 QETH_DBF_TEXT2(0,trace,dbf_text);
5889 atomic_set(&card->is_softsetup,0);
5890 goto out;
5891 }
5892 out:
5893 if (!result) {
5894 netif_wake_queue(card->dev);
5895 }
5896 if (wait_for_lock!=QETH_LOCK_ALREADY_HELD)
5897 my_spin_unlock(&card->softsetup_lock);
5898 return result;
5899 }
5900
qeth_softsetup_thread(void * param)5901 static int qeth_softsetup_thread(void *param)
5902 {
5903 char dbf_text[15];
5904 char name[15];
5905 qeth_card_t *card=(qeth_card_t*)param;
5906
5907 daemonize();
5908
5909 /* set a nice name ... */
5910 sprintf(name, "qethsoftd%04x", card->irq0);
5911 strcpy(current->comm, name);
5912
5913 sprintf(dbf_text,"ssth%4x",card->irq0);
5914 QETH_DBF_TEXT2(0,trace,dbf_text);
5915
5916 atomic_set(&card->softsetup_thread_is_running,1);
5917 for (;;) {
5918 if (atomic_read(&card->shutdown_phase)) goto out;
5919 down_interruptible(&card->softsetup_thread_sem);
5920 sprintf(dbf_text,"ssst%4x",card->irq0);
5921 QETH_DBF_TEXT2(0,trace,dbf_text);
5922 if (atomic_read(&card->shutdown_phase)) goto out;
5923 while (qeth_softsetup_card(card,QETH_DONT_WAIT_FOR_LOCK)
5924 ==-EAGAIN) {
5925 if (atomic_read(&card->shutdown_phase)) goto out;
5926 qeth_wait_nonbusy(QETH_IDLE_WAIT_TIME);
5927 }
5928 sprintf(dbf_text,"sstd%4x",card->irq0);
5929 QETH_DBF_TEXT2(0,trace,dbf_text);
5930 netif_wake_queue(card->dev);
5931 }
5932 out:
5933 atomic_set(&card->softsetup_thread_is_running,0);
5934
5935 sprintf(dbf_text,"lsst%4x",card->irq0);
5936 QETH_DBF_TEXT2(0,trace,dbf_text);
5937
5938 return 0;
5939 }
5940
qeth_softsetup_thread_starter(void * data)5941 static void qeth_softsetup_thread_starter(void *data)
5942 {
5943 char dbf_text[15];
5944 qeth_card_t *card=(qeth_card_t *)data;
5945
5946 sprintf(dbf_text,"ssts%4x",card->irq0);
5947 QETH_DBF_TEXT4(0,trace,dbf_text);
5948 sema_init(&card->softsetup_thread_sem,0);
5949 kernel_thread(qeth_softsetup_thread,card,SIGCHLD);
5950 }
5951
qeth_start_reinit_thread(qeth_card_t * card)5952 static void qeth_start_reinit_thread(qeth_card_t *card)
5953 {
5954 char dbf_text[15];
5955
5956 /* we allow max 2 reinit threads, one could be just about to
5957 * finish and the next would be waiting. another waiting
5958 * reinit_thread is not necessary. */
5959 if (atomic_read(&card->reinit_counter)<2) {
5960 atomic_inc(&card->reinit_counter);
5961 if (atomic_read(&card->shutdown_phase)) {
5962 atomic_dec(&card->reinit_counter);
5963 return;
5964 }
5965 sprintf(dbf_text,"stri%4x",card->irq0);
5966 QETH_DBF_TEXT2(0,trace,dbf_text);
5967 PRINT_STUPID("starting reinit-thread\n");
5968 kernel_thread(qeth_reinit_thread,card,SIGCHLD);
5969 }
5970 }
5971
qeth_recover(void * data)5972 static void qeth_recover(void *data)
5973 {
5974 qeth_card_t *card;
5975 int i;
5976 char dbf_text[15];
5977
5978 card=(qeth_card_t*)data;
5979
5980 sprintf(dbf_text,"recv%4x",card->irq0);
5981 QETH_DBF_TEXT2(0,trace,dbf_text);
5982
5983 if (atomic_compare_and_swap(0,1,&card->in_recovery))
5984 return;
5985
5986 i=atomic_read(&card->problem);
5987
5988 sprintf(dbf_text,"PROB%4x",i);
5989 QETH_DBF_TEXT2(0,trace,dbf_text);
5990
5991 if (i!=PROBLEM_TX_TIMEOUT) {
5992 PRINT_WARN("recovery was scheduled on irq 0x%x (%s) with " \
5993 "problem 0x%x\n",
5994 card->irq0,card->dev_name,i);
5995 }
5996
5997 switch (i) {
5998 case PROBLEM_RECEIVED_IDX_TERMINATE:
5999 if (atomic_read(&card->in_recovery))
6000 atomic_set(&card->break_out,QETH_BREAKOUT_AGAIN);
6001 break;
6002 case PROBLEM_CARD_HAS_STARTLANED:
6003 PRINT_WARN("You are lucky! Somebody either fixed the " \
6004 "network problem, plugged the cable back in " \
6005 "or enabled the OSA port on %s (CHPID 0x%X). " \
6006 "The link has come up.\n",
6007 card->dev_name,card->chpid);
6008 sprintf(dbf_text,"CBIN%4x",i);
6009 QETH_DBF_TEXT1(0,trace,dbf_text);
6010 atomic_set(&card->is_softsetup,0);
6011 qeth_set_dev_flag_running(card);
6012 atomic_set(&card->enable_routing_attempts4,
6013 QETH_ROUTING_ATTEMPTS);
6014 qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa);
6015 #ifdef QETH_IPV6
6016 atomic_set(&card->enable_routing_attempts6,
6017 QETH_ROUTING_ATTEMPTS);
6018 qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa);
6019 #endif /* QETH_IPV6 */
6020 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa);
6021 #ifdef QETH_IPV6
6022 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa);
6023 #endif /* QETH_IPV6 */
6024 qeth_refresh_vipa_states(card);
6025 qeth_start_softsetup_thread(card);
6026 atomic_set(&card->in_recovery,0);
6027 break;
6028 case PROBLEM_RESETTING_EVENT_INDICATOR:
6029 /* we do nothing here */
6030 break;
6031 case PROBLEM_ACTIVATE_CHECK_CONDITION:
6032 case PROBLEM_GENERAL_CHECK:
6033 case PROBLEM_USER_TRIGGERED_RECOVERY:
6034 case PROBLEM_AFFE:
6035 case PROBLEM_MACHINE_CHECK:
6036 case PROBLEM_BAD_SIGA_RESULT:
6037 case PROBLEM_TX_TIMEOUT:
6038 qeth_start_reinit_thread(card);
6039 break;
6040 }
6041 }
6042
qeth_schedule_recovery(qeth_card_t * card)6043 static inline void qeth_schedule_recovery(qeth_card_t *card)
6044 {
6045 if (card) {
6046 INIT_LIST_HEAD(&card->tqueue.list);
6047 card->tqueue.routine=qeth_recover;
6048 card->tqueue.data=card;
6049 card->tqueue.sync=0;
6050 schedule_task(&card->tqueue);
6051 } else {
6052 QETH_DBF_TEXT2(1,trace,"scdnocrd");
6053 PRINT_WARN("recovery requested to be scheduled " \
6054 "with no card!\n");
6055 }
6056 }
6057
qeth_qdio_input_handler(int irq,unsigned int status,unsigned int qdio_error,unsigned int siga_error,unsigned int queue,int first_element,int count,unsigned long card_ptr)6058 static void qeth_qdio_input_handler(int irq,unsigned int status,
6059 unsigned int qdio_error,unsigned int siga_error,
6060 unsigned int queue,
6061 int first_element,int count,
6062 unsigned long card_ptr)
6063 {
6064 struct net_device *dev;
6065 qeth_card_t *card;
6066 int problem;
6067 int sbalf15;
6068 char dbf_text[15]="qinbhnXX";
6069
6070 *((__u16*)(&dbf_text[6]))=(__u16)irq;
6071 QETH_DBF_HEX6(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
6072
6073 card=(qeth_card_t *)card_ptr;
6074
6075 #ifdef QETH_PERFORMANCE_STATS
6076 card->perf_stats.inbound_start_time=NOW;
6077 #endif /* QETH_PERFORMANCE_STATS */
6078 dev=card->dev;
6079
6080 if (status&QDIO_STATUS_LOOK_FOR_ERROR) {
6081 if (status&QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
6082 problem=PROBLEM_ACTIVATE_CHECK_CONDITION;
6083 PRINT_WARN("activate queues on irq 0x%x: " \
6084 "dstat=0x%x, cstat=0x%x\n",irq,
6085 card->devstat2->dstat,
6086 card->devstat2->cstat);
6087 atomic_set(&card->problem,problem);
6088 QETH_DBF_TEXT1(0,trace,"IHACTQCK");
6089 sprintf(dbf_text,"%4x%4x",first_element,count);
6090 QETH_DBF_TEXT1(0,trace,dbf_text);
6091 sprintf(dbf_text,"%4x%4x",queue,status);
6092 QETH_DBF_TEXT1(0,trace,dbf_text);
6093 sprintf(dbf_text,"qscd%4x",card->irq0);
6094 QETH_DBF_TEXT1(1,trace,dbf_text);
6095 qeth_schedule_recovery(card);
6096 return;
6097 }
6098 sbalf15=(card->inbound_qdio_buffers[(first_element+count-1)&
6099 QDIO_MAX_BUFFERS_PER_Q].
6100 element[15].flags)&0xff;
6101 PRINT_STUPID("inbound qdio transfer error on irq 0x%04x. " \
6102 "qdio_error=0x%x (more than one: %c), " \
6103 "siga_error=0x%x (more than one: %c), " \
6104 "sbalf15=x%x, bufno=x%x\n",
6105 irq,qdio_error,
6106 (status&QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR)?
6107 'y':'n',siga_error,
6108 (status&QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR)?
6109 'y':'n',
6110 sbalf15,first_element);
6111 sprintf(dbf_text,"IQTI%4x",card->irq0);
6112 QETH_DBF_TEXT1(0,trace,dbf_text);
6113 QETH_DBF_TEXT1(0,qerr,dbf_text);
6114 sprintf(dbf_text,"%4x%4x",first_element,count);
6115 QETH_DBF_TEXT1(0,trace,dbf_text);
6116 QETH_DBF_TEXT1(0,qerr,dbf_text);
6117 sprintf(dbf_text,"%2x%4x%2x",queue,status,sbalf15);
6118 QETH_DBF_TEXT1(0,trace,dbf_text);
6119 QETH_DBF_TEXT1(0,qerr,dbf_text);
6120 sprintf(dbf_text,"%4x%4x",qdio_error,siga_error);
6121 QETH_DBF_TEXT1(0,trace,dbf_text);
6122 QETH_DBF_TEXT1(0,qerr,dbf_text);
6123 /* we inform about error more detailed in
6124 * qeth_read_in_buffer() */
6125 }
6126
6127 for (;;) {
6128 qeth_get_linux_addrs_for_buffer(card,first_element);
6129 qeth_read_in_buffer(card,first_element);
6130 qeth_queue_input_buffer(card,first_element,
6131 QDIO_FLAG_UNDER_INTERRUPT);
6132 count--;
6133 if (count)
6134 first_element=(first_element+1)&
6135 (QDIO_MAX_BUFFERS_PER_Q-1);
6136 else break;
6137 }
6138 }
6139
qeth_qdio_output_handler(int irq,unsigned int status,unsigned int qdio_error,unsigned int siga_error,unsigned int queue,int first_element,int count,unsigned long card_ptr)6140 static void qeth_qdio_output_handler(int irq,unsigned int status,
6141 unsigned int qdio_error,unsigned int siga_error,
6142 unsigned int queue,
6143 int first_element,int count,
6144 unsigned long card_ptr)
6145 {
6146 qeth_card_t *card;
6147 int mycnt,problem,buffers_used;
6148 int sbalf15;
6149 char dbf_text[15]="qouthnXX";
6150 char dbf_text2[15]="stchdwXX";
6151 int last_pci_hit=0,switch_state;
6152 int last_pci;
6153
6154 *((__u16*)(&dbf_text[6]))=(__u16)irq;
6155 QETH_DBF_HEX6(0,trace,dbf_text,QETH_DBF_TRACE_LEN);
6156
6157 mycnt=count;
6158 card=(qeth_card_t *)card_ptr;
6159
6160 if (status&QDIO_STATUS_LOOK_FOR_ERROR) {
6161 sbalf15=(card->outbound_ringbuffer[queue]->buffer[
6162 (first_element+count-1)&
6163 QDIO_MAX_BUFFERS_PER_Q].element[15].flags)&0xff;
6164 if (status&QDIO_STATUS_ACTIVATE_CHECK_CONDITION) {
6165 problem=PROBLEM_ACTIVATE_CHECK_CONDITION;
6166 PRINT_WARN("activate queues on irq 0x%x: " \
6167 "dstat=0x%x, cstat=0x%x\n",irq,
6168 card->devstat2->dstat,
6169 card->devstat2->cstat);
6170 atomic_set(&card->problem,problem);
6171 QETH_DBF_TEXT1(0,trace,"OHACTQCK");
6172 sprintf(dbf_text,"%4x%4x",first_element,count);
6173 QETH_DBF_TEXT1(0,trace,dbf_text);
6174 sprintf(dbf_text,"%4x%4x",queue,status);
6175 QETH_DBF_TEXT1(0,trace,dbf_text);
6176 sprintf(dbf_text,"qscd%4x",card->irq0);
6177 QETH_DBF_TEXT1(1,trace,dbf_text);
6178 qeth_schedule_recovery(card);
6179 goto out;
6180 }
6181 if ( (siga_error==0x01) ||
6182 (siga_error==(0x02|QDIO_SIGA_ERROR_B_BIT_SET)) ||
6183 (siga_error==0x03) ) {
6184 sprintf(dbf_text,"BS%4x%2x",card->irq0,queue);
6185 QETH_DBF_TEXT2(0,trace,dbf_text);
6186 QETH_DBF_TEXT2(0,qerr,dbf_text);
6187 QETH_DBF_TEXT2(1,setup,dbf_text);
6188 sprintf(dbf_text,"%2x%2x%2x%2x",
6189 first_element+count-1,
6190 siga_error,qdio_error,sbalf15);
6191 QETH_DBF_TEXT2(1,trace,dbf_text);
6192 QETH_DBF_TEXT2(1,qerr,dbf_text);
6193 PRINT_ERR("Outbound queue x%x on irq x%x (%s); " \
6194 "errs: siga: x%x, qdio: x%x, flags15: " \
6195 "x%x. The device will be taken down.\n",
6196 queue,card->irq0,card->dev_name,
6197 siga_error,qdio_error,sbalf15);
6198 netif_stop_queue(card->dev);
6199 qeth_set_dev_flag_norunning(card);
6200 atomic_set(&card->problem,PROBLEM_BAD_SIGA_RESULT);
6201 qeth_schedule_recovery(card);
6202 goto out;
6203 }
6204 PRINT_STUPID("outbound qdio transfer error on irq %04x, " \
6205 "queue=%i. qdio_error=0x%x (more than one: %c)," \
6206 " siga_error=0x%x (more than one: %c), " \
6207 "sbalf15=x%x, bufno=x%x\n",
6208 irq,queue,qdio_error,status&
6209 QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR?'y':'n',
6210 siga_error,status&
6211 QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR?'y':'n',
6212 sbalf15,first_element);
6213 sprintf(dbf_text,"IQTO%4x",card->irq0);
6214 QETH_DBF_TEXT1(0,trace,dbf_text);
6215 QETH_DBF_TEXT1(0,qerr,dbf_text);
6216 sprintf(dbf_text,"%4x%4x",first_element,count);
6217 QETH_DBF_TEXT1(0,trace,dbf_text);
6218 QETH_DBF_TEXT1(0,qerr,dbf_text);
6219 sprintf(dbf_text,"%2x%4x%2x",queue,status,sbalf15);
6220 QETH_DBF_TEXT1(0,trace,dbf_text);
6221 QETH_DBF_TEXT1(0,qerr,dbf_text);
6222 sprintf(dbf_text,"%4x%4x",qdio_error,siga_error);
6223 QETH_DBF_TEXT1(0,trace,dbf_text);
6224 QETH_DBF_TEXT1(0,qerr,dbf_text);
6225 /* we maybe do recovery or dst_link_failures
6226 * in qeth_free_buffer */
6227 }
6228
6229 if (mycnt) {
6230 last_pci=atomic_read(&card->last_pci_pos[queue]);
6231 for (;;) {
6232 qeth_free_buffer(card,queue,first_element,
6233 qdio_error,siga_error);
6234 if (first_element==last_pci) last_pci_hit=1;
6235 mycnt--;
6236 if (mycnt>0)
6237 first_element=(first_element+1)&
6238 (QDIO_MAX_BUFFERS_PER_Q-1);
6239 else break;
6240 }
6241 }
6242
6243 buffers_used=atomic_return_sub(count,
6244 &card->outbound_used_buffers[queue]);
6245
6246 switch (card->send_state[queue]) {
6247 case SEND_STATE_PACK:
6248 switch_state=(atomic_read
6249 (&card->outbound_used_buffers[queue])<=
6250 LOW_WATERMARK_PACK);
6251 /* first_element is the last buffer that we got back
6252 * from OSA */
6253 if (switch_state||last_pci_hit) {
6254 *((__u16*)(&dbf_text2[6]))=card->irq0;
6255 QETH_DBF_HEX3(0,trace,dbf_text2,QETH_DBF_TRACE_LEN);
6256 if (atomic_swap(&card->outbound_ringbuffer_lock
6257 [queue],QETH_LOCK_FLUSH)
6258 ==QETH_LOCK_UNLOCKED) {
6259 /* we stop the queue as we try to not run
6260 * onto the outbound_ringbuffer_lock --
6261 * this will not prevent it totally, but
6262 * reduce it. in high traffic situations,
6263 * it saves around 20us per second, hopefully
6264 * this is amortized by calling netif_... */
6265 netif_stop_queue(card->dev);
6266 qeth_flush_packed_packets
6267 (card,queue,
6268 QDIO_FLAG_UNDER_INTERRUPT);
6269 /* only switch state to non-packing, if
6270 * the amount of used buffers decreased */
6271 if (switch_state)
6272 card->send_state[queue]=
6273 SEND_STATE_DONT_PACK;
6274
6275 /* reset the last_pci position to avoid
6276 * races, when we get close to packing again
6277 * immediately (in order to never loose
6278 * a PCI) */
6279 atomic_set(&card->last_pci_pos[queue],
6280 (-2*QDIO_MAX_BUFFERS_PER_Q));
6281
6282 netif_wake_queue(card->dev);
6283 atomic_set(&card->outbound_ringbuffer_lock[
6284 queue],QETH_LOCK_UNLOCKED);
6285 } /* if the lock was UNLOCKED, we flush ourselves,
6286 otherwise this is done in do_send_packet when
6287 the lock is released */
6288 #ifdef QETH_PERFORMANCE_STATS
6289 card->perf_stats.sc_p_dp++;
6290 #endif /* QETH_PERFORMANCE_STATS */
6291 }
6292 break;
6293 default: break;
6294 }
6295
6296 /* we don't have to start the queue, if it was started already */
6297 if (buffers_used<QDIO_MAX_BUFFERS_PER_Q-1)
6298 return;
6299
6300 out:
6301 netif_wake_queue(card->dev);
6302 }
6303
qeth_interrupt_handler_read(int irq,void * devstat,struct pt_regs * p)6304 static void qeth_interrupt_handler_read(int irq,void *devstat,
6305 struct pt_regs *p)
6306 {
6307 devstat_t *stat;
6308 int cstat,dstat;
6309 int problem;
6310 qeth_card_t *card;
6311 int rqparam;
6312 char dbf_text[15];
6313 int result;
6314
6315 stat=(devstat_t *)devstat;
6316 cstat=stat->cstat;
6317 dstat=stat->dstat;
6318 rqparam=stat->intparm;
6319
6320 sprintf(dbf_text,"rint%4x",irq);
6321 QETH_DBF_TEXT4(0,trace,dbf_text);
6322 sprintf(dbf_text,"%4x%4x",cstat,dstat);
6323 QETH_DBF_TEXT4(0,trace,dbf_text);
6324 sprintf(dbf_text,"%4x",rqparam);
6325 QETH_DBF_TEXT4(0,trace,dbf_text);
6326
6327 if (!rqparam) {
6328 PRINT_STUPID("got unsolicited interrupt in read handler, " \
6329 "irq 0x%x\n",irq);
6330 return;
6331 }
6332
6333 card=qeth_get_card_by_irq(irq);
6334 if (!card) return;
6335
6336 if ((rqparam==CLEAR_STATE) || (stat->flag&DEVSTAT_CLEAR_FUNCTION)) {
6337 atomic_set(&card->clear_succeeded0,1);
6338 return;
6339 }
6340
6341 if ((dstat==0)&&(cstat==0)) return;
6342
6343 if (card->devstat0->flag&DEVSTAT_FLAG_SENSE_AVAIL) {
6344 PRINT_WARN("sense data available on read channel.\n");
6345 HEXDUMP16(WARN,"irb: ",&card->devstat0->ii.irb);
6346 HEXDUMP16(WARN,"sense data: ",&card->devstat0->ii.
6347 sense.data[0]);
6348 sprintf(dbf_text,"RSNS%4x",irq);
6349 QETH_DBF_TEXT1(0,trace,dbf_text);
6350 QETH_DBF_HEX0(0,sense,&card->devstat0->ii.irb,
6351 QETH_DBF_SENSE_LEN);
6352 }
6353
6354 if (cstat!=0) {
6355 PRINT_WARN("got nonzero-nonpci channel status in read_" \
6356 "handler (irq 0x%x, devstat 0x%02x, schstat " \
6357 "0x%02x, rqparam 0x%x)\n",irq,dstat,cstat,rqparam);
6358 }
6359
6360 problem=qeth_get_cards_problem(card,card->dma_stuff->recbuf,
6361 irq,dstat,cstat,rqparam,
6362 (char*)&card->devstat0->ii.irb,
6363 (char*)&card->devstat0->
6364 ii.sense.data[0]);
6365
6366 /* detect errors in dstat here */
6367 if ( (dstat&DEV_STAT_UNIT_EXCEP) || (dstat&DEV_STAT_UNIT_CHECK) ) {
6368 PRINT_WARN("unit check/exception in read_handler " \
6369 "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \
6370 "rqparam 0x%x)\n",irq,dstat,cstat,rqparam);
6371 if (!atomic_read(&card->is_hardsetup)) {
6372 if ((problem)&&(qeth_is_to_recover(card,problem)))
6373 atomic_set(&card->break_out,
6374 QETH_BREAKOUT_AGAIN);
6375 else
6376 atomic_set(&card->break_out,
6377 QETH_BREAKOUT_LEAVE);
6378 goto wakeup_out;
6379 } else goto recover;
6380 }
6381
6382 if (!(dstat&DEV_STAT_CHN_END)) {
6383 PRINT_WARN("didn't get device end in read_handler " \
6384 "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \
6385 "rqparam 0x%x)\n",irq,dstat,cstat,rqparam);
6386 goto wakeup_out;
6387 }
6388
6389 if ( (rqparam==IDX_ACTIVATE_WRITE_STATE) ||
6390 (rqparam==NOP_STATE) ) {
6391 goto wakeup_out;
6392 }
6393
6394 /* at this point, (maybe channel end and) device end has appeared */
6395
6396 /* we don't start the next read until we have examined the buffer. */
6397 if ( (rqparam!=IDX_ACTIVATE_READ_STATE) &&
6398 (rqparam!=IDX_ACTIVATE_WRITE_STATE) )
6399 qeth_issue_next_read(card);
6400
6401 recover:
6402 if (qeth_is_to_recover(card,problem)) {
6403 sprintf(dbf_text,"rscd%4x",card->irq0);
6404 QETH_DBF_TEXT2(1,trace,dbf_text);
6405 qeth_schedule_recovery(card);
6406 goto wakeup_out;
6407 }
6408
6409 if ( (!IS_IPA(card->dma_stuff->recbuf))||
6410 (IS_IPA(card->dma_stuff->recbuf)&&
6411 IS_IPA_REPLY(card->dma_stuff->recbuf)) ) {
6412 /* setup or unknown data */
6413 result = qeth_look_for_arp_data(card);
6414 switch (result) {
6415 case ARP_RETURNCODE_ERROR:
6416 case ARP_RETURNCODE_LASTREPLY:
6417 qeth_wakeup_ioctl(card);
6418 return;
6419 default:
6420 break;
6421 }
6422 }
6423
6424 wakeup_out:
6425 memcpy(card->ipa_buf,card->dma_stuff->recbuf,QETH_BUFSIZE);
6426 qeth_wakeup(card);
6427 }
6428
qeth_interrupt_handler_write(int irq,void * devstat,struct pt_regs * p)6429 static void qeth_interrupt_handler_write(int irq,void *devstat,
6430 struct pt_regs *p)
6431 {
6432 devstat_t *stat;
6433 int cstat,dstat,rqparam;
6434 qeth_card_t *card;
6435 int problem;
6436 char dbf_text[15];
6437
6438 stat = (devstat_t *)devstat;
6439 cstat = stat->cstat;
6440 dstat = stat->dstat;
6441 rqparam=stat->intparm;
6442
6443 sprintf(dbf_text,"wint%4x",irq);
6444 QETH_DBF_TEXT4(0,trace,dbf_text);
6445 sprintf(dbf_text,"%4x%4x",cstat,dstat);
6446 QETH_DBF_TEXT4(0,trace,dbf_text);
6447 sprintf(dbf_text,"%4x",rqparam);
6448 QETH_DBF_TEXT4(0,trace,dbf_text);
6449
6450 if (!rqparam) {
6451 PRINT_STUPID("got unsolicited interrupt in write handler, " \
6452 "irq 0x%x\n",irq);
6453 return;
6454 }
6455
6456 card=qeth_get_card_by_irq(irq);
6457 if (!card) return;
6458
6459 if ((rqparam==CLEAR_STATE) || (stat->flag&DEVSTAT_CLEAR_FUNCTION)) {
6460 atomic_set(&card->clear_succeeded1,1);
6461 goto out;
6462 }
6463
6464 if ((dstat==0)&&(cstat==0)) goto out;
6465
6466 if (card->devstat1->flag&DEVSTAT_FLAG_SENSE_AVAIL) {
6467 PRINT_WARN("sense data available on write channel.\n");
6468 HEXDUMP16(WARN,"irb: ",&card->devstat1->ii.irb);
6469 HEXDUMP16(WARN,"sense data: ",&card->devstat1->ii.
6470 sense.data[0]);
6471 sprintf(dbf_text,"WSNS%4x",irq);
6472 QETH_DBF_TEXT1(0,trace,dbf_text);
6473 QETH_DBF_HEX0(0,sense,&card->devstat1->ii.irb,
6474 QETH_DBF_SENSE_LEN);
6475 }
6476
6477 if (cstat != 0) {
6478 PRINT_WARN("got nonzero channel status in write_handler " \
6479 "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \
6480 "rqparam 0x%x)\n",irq,dstat,cstat,rqparam);
6481 }
6482
6483 problem=qeth_get_cards_problem(card,NULL,
6484 irq,dstat,cstat,rqparam,
6485 (char*)&card->devstat1->ii.irb,
6486 (char*)&card->devstat1->
6487 ii.sense.data[0]);
6488
6489 /* detect errors in dstat here */
6490 if ( (dstat&DEV_STAT_UNIT_EXCEP) || (dstat&DEV_STAT_UNIT_CHECK) ) {
6491 PRINT_WARN("unit check/exception in write_handler " \
6492 "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \
6493 "rqparam 0x%x)\n",irq,dstat,cstat,rqparam);
6494 if (!atomic_read(&card->is_hardsetup)) {
6495 if (problem==PROBLEM_RESETTING_EVENT_INDICATOR) {
6496 atomic_set(&card->break_out,
6497 QETH_BREAKOUT_AGAIN);
6498 qeth_wakeup(card);
6499 goto out;
6500 }
6501 atomic_set(&card->break_out,QETH_BREAKOUT_LEAVE);
6502 goto out;
6503 } else goto recover;
6504 }
6505
6506 if (dstat==DEV_STAT_DEV_END) goto out;
6507
6508 if (!(dstat&DEV_STAT_CHN_END)) {
6509 PRINT_WARN("didn't get device end in write_handler " \
6510 "(irq 0x%x, devstat 0x%02x, schstat 0x%02x, " \
6511 "rqparam 0x%x)\n",irq,dstat,cstat,rqparam);
6512 goto out;
6513 }
6514
6515 recover:
6516 if (qeth_is_to_recover(card,problem)) {
6517 sprintf(dbf_text,"wscd%4x",card->irq1);
6518 QETH_DBF_TEXT2(1,trace,dbf_text);
6519 qeth_schedule_recovery(card);
6520 goto out;
6521 }
6522
6523 /* at this point, (maybe channel end and) device end has appeared */
6524 if ( (rqparam==IDX_ACTIVATE_READ_STATE) ||
6525 (rqparam==IDX_ACTIVATE_WRITE_STATE) ||
6526 (rqparam==NOP_STATE) ) {
6527 qeth_wakeup(card);
6528 goto out;
6529 }
6530
6531 /* well, a write has been done successfully. */
6532
6533 out:
6534 /* all statuses are final statuses on the write channel */
6535 atomic_set(&card->write_busy,0);
6536 }
6537
qeth_interrupt_handler_qdio(int irq,void * devstat,struct pt_regs * p)6538 static void qeth_interrupt_handler_qdio(int irq,void *devstat,
6539 struct pt_regs *p)
6540 {
6541 devstat_t *stat;
6542 int cstat,dstat,rqparam;
6543 char dbf_text[15];
6544
6545 qeth_card_t *card;
6546
6547 stat = (devstat_t *)devstat;
6548 cstat = stat->cstat;
6549 dstat = stat->dstat;
6550 rqparam=stat->intparm;
6551
6552 sprintf(dbf_text,"qint%4x",irq);
6553 QETH_DBF_TEXT4(0,trace,dbf_text);
6554 sprintf(dbf_text,"%4x%4x",cstat,dstat);
6555 QETH_DBF_TEXT4(0,trace,dbf_text);
6556 sprintf(dbf_text,"%4x",rqparam);
6557 QETH_DBF_TEXT4(0,trace,dbf_text);
6558
6559
6560 if (!rqparam) {
6561 PRINT_STUPID("got unsolicited interrupt in qdio handler, " \
6562 "irq 0x%x\n",irq);
6563 return;
6564 }
6565
6566 card=qeth_get_card_by_irq(irq);
6567 if (!card) return;
6568
6569 if ((rqparam==CLEAR_STATE) || (stat->flag&DEVSTAT_CLEAR_FUNCTION)) {
6570 atomic_set(&card->clear_succeeded2,1);
6571 return;
6572 }
6573
6574 if ((dstat==0)&&(cstat==0)) return;
6575
6576 if (card->devstat2->flag&DEVSTAT_FLAG_SENSE_AVAIL) {
6577 PRINT_WARN("sense data available on qdio channel.\n");
6578 HEXDUMP16(WARN,"irb: ",&card->devstat2->ii.irb);
6579 HEXDUMP16(WARN,"sense data: ",&card->devstat2->ii.
6580 sense.data[0]);
6581 sprintf(dbf_text,"QSNS%4x",irq);
6582 QETH_DBF_TEXT1(0,trace,dbf_text);
6583 QETH_DBF_HEX0(0,sense,&card->devstat2->ii.irb,
6584 QETH_DBF_SENSE_LEN);
6585 }
6586
6587 if ( (rqparam==READ_CONF_DATA_STATE) ||
6588 (rqparam==NOP_STATE) ) {
6589 qeth_wakeup(card);
6590 return;
6591 }
6592
6593 if (cstat != 0) {
6594 sprintf(dbf_text,"qchk%4x",irq);
6595 QETH_DBF_TEXT2(0,trace,dbf_text);
6596 sprintf(dbf_text,"%4x%4x",cstat,dstat);
6597 QETH_DBF_TEXT2(0,trace,dbf_text);
6598 sprintf(dbf_text,"%4x",rqparam);
6599 QETH_DBF_TEXT2(0,trace,dbf_text);
6600 PRINT_WARN("got nonzero channel status in qdio_handler " \
6601 "(irq 0x%x, devstat 0x%02x, schstat 0x%02x)\n",
6602 irq,dstat,cstat);
6603 }
6604
6605 if (dstat&~(DEV_STAT_CHN_END|DEV_STAT_DEV_END)) {
6606 PRINT_WARN("got the following dstat on the qdio channel: " \
6607 "irq 0x%x, dstat 0x%02x, cstat 0x%02x, " \
6608 "rqparam=%i\n",
6609 irq,dstat,cstat,rqparam);
6610 }
6611
6612 }
6613
qeth_register_netdev(qeth_card_t * card)6614 static int qeth_register_netdev(qeth_card_t *card)
6615 {
6616 int result;
6617 char dbf_text[15];
6618
6619 sprintf(dbf_text,"rgnd%4x",card->irq0);
6620 QETH_DBF_TEXT3(0,trace,dbf_text);
6621
6622 result=register_netdev(card->dev);
6623
6624 return result;
6625 }
6626
qeth_unregister_netdev(qeth_card_t * card)6627 static void qeth_unregister_netdev(qeth_card_t *card)
6628 {
6629 char dbf_text[15];
6630
6631 sprintf(dbf_text,"nrgn%4x",card->irq0);
6632 QETH_DBF_TEXT3(0,trace,dbf_text);
6633
6634 unregister_netdev(card->dev);
6635 }
6636
qeth_stop(struct net_device * dev)6637 static int qeth_stop(struct net_device *dev)
6638 {
6639 char dbf_text[15];
6640 qeth_card_t *card;
6641
6642 card=(qeth_card_t *)dev->priv;
6643 sprintf(dbf_text,"stop%4x",card->irq0);
6644 QETH_DBF_TEXT2(0,trace,dbf_text);
6645 QETH_DBF_TEXT2(0,setup,dbf_text);
6646
6647 qeth_save_dev_flag_state(card);
6648
6649 netif_stop_queue(dev);
6650 if (atomic_swap(&((qeth_card_t*)dev->priv)->is_open,0)) {
6651 MOD_DEC_USE_COUNT;
6652 }
6653
6654 return 0;
6655 }
6656
qeth_softshutdown(qeth_card_t * card)6657 static void qeth_softshutdown(qeth_card_t *card)
6658 {
6659 char dbf_text[15];
6660
6661 sprintf(dbf_text,"ssht%4x",card->irq0);
6662 QETH_DBF_TEXT3(0,trace,dbf_text);
6663
6664 qeth_send_stoplan(card);
6665 }
6666
qeth_clear_card(qeth_card_t * card,int qdio_clean,int use_halt)6667 static void qeth_clear_card(qeth_card_t *card,int qdio_clean,int use_halt)
6668 {
6669 unsigned long flags0,flags1,flags2;
6670 char dbf_text[15];
6671
6672 sprintf(dbf_text,"clr%c%4x",(qdio_clean)?'q':' ',card->irq0);
6673 QETH_DBF_TEXT3(0,trace,dbf_text);
6674 QETH_DBF_TEXT1(0,setup,dbf_text);
6675
6676 atomic_set(&card->write_busy,0);
6677 if (qdio_clean)
6678 qdio_cleanup(card->irq2,
6679 (card->type==QETH_CARD_TYPE_IQD)?
6680 QDIO_FLAG_CLEANUP_USING_HALT:
6681 QDIO_FLAG_CLEANUP_USING_CLEAR);
6682
6683 if (use_halt) {
6684 atomic_set(&card->clear_succeeded0,0);
6685 atomic_set(&card->clear_succeeded1,0);
6686 atomic_set(&card->clear_succeeded2,0);
6687
6688 s390irq_spin_lock_irqsave(card->irq0,flags0);
6689 halt_IO(card->irq0,CLEAR_STATE,0);
6690 s390irq_spin_unlock_irqrestore(card->irq0,flags0);
6691
6692 s390irq_spin_lock_irqsave(card->irq1,flags1);
6693 halt_IO(card->irq1,CLEAR_STATE,0);
6694 s390irq_spin_unlock_irqrestore(card->irq1,flags1);
6695
6696 s390irq_spin_lock_irqsave(card->irq2,flags2);
6697 halt_IO(card->irq2,CLEAR_STATE,0);
6698 s390irq_spin_unlock_irqrestore(card->irq2,flags2);
6699
6700 if (qeth_wait_for_event(&card->clear_succeeded0,
6701 QETH_CLEAR_TIMEOUT)==-ETIME) {
6702 if (atomic_read(&card->shutdown_phase)!=
6703 QETH_REMOVE_CARD_QUICK) {
6704 PRINT_ERR("Did not get interrupt on halt_IO " \
6705 "on irq 0x%x.\n",card->irq0);
6706 }
6707 }
6708 if (qeth_wait_for_event(&card->clear_succeeded1,
6709 QETH_CLEAR_TIMEOUT)==-ETIME) {
6710 if (atomic_read(&card->shutdown_phase)!=
6711 QETH_REMOVE_CARD_QUICK) {
6712 PRINT_ERR("Did not get interrupt on halt_IO " \
6713 "on irq 0x%x.\n",card->irq1);
6714 }
6715 }
6716 if (qeth_wait_for_event(&card->clear_succeeded2,
6717 QETH_CLEAR_TIMEOUT)==-ETIME) {
6718 if (atomic_read(&card->shutdown_phase)!=
6719 QETH_REMOVE_CARD_QUICK) {
6720 PRINT_ERR("Did not get interrupt on halt_IO " \
6721 "on irq 0x%x.\n",card->irq2);
6722 }
6723 }
6724 }
6725
6726 atomic_set(&card->clear_succeeded0,0);
6727 atomic_set(&card->clear_succeeded1,0);
6728 atomic_set(&card->clear_succeeded2,0);
6729
6730 s390irq_spin_lock_irqsave(card->irq0,flags0);
6731 clear_IO(card->irq0,CLEAR_STATE,0);
6732 s390irq_spin_unlock_irqrestore(card->irq0,flags0);
6733
6734 s390irq_spin_lock_irqsave(card->irq1,flags1);
6735 clear_IO(card->irq1,CLEAR_STATE,0);
6736 s390irq_spin_unlock_irqrestore(card->irq1,flags1);
6737
6738 s390irq_spin_lock_irqsave(card->irq2,flags2);
6739 clear_IO(card->irq2,CLEAR_STATE,0);
6740 s390irq_spin_unlock_irqrestore(card->irq2,flags2);
6741
6742 if (qeth_wait_for_event(&card->clear_succeeded0,
6743 QETH_CLEAR_TIMEOUT)==-ETIME) {
6744 if (atomic_read(&card->shutdown_phase)!=
6745 QETH_REMOVE_CARD_QUICK) {
6746 PRINT_ERR("Did not get interrupt on clear_IO on " \
6747 "irq 0x%x.\n",card->irq0);
6748 }
6749 }
6750 if (qeth_wait_for_event(&card->clear_succeeded1,
6751 QETH_CLEAR_TIMEOUT)==-ETIME) {
6752 if (atomic_read(&card->shutdown_phase)!=
6753 QETH_REMOVE_CARD_QUICK) {
6754 PRINT_ERR("Did not get interrupt on clear_IO on " \
6755 "irq 0x%x.\n",card->irq1);
6756 }
6757 }
6758 if (qeth_wait_for_event(&card->clear_succeeded2,
6759 QETH_CLEAR_TIMEOUT)==-ETIME) {
6760 if (atomic_read(&card->shutdown_phase)!=
6761 QETH_REMOVE_CARD_QUICK) {
6762 PRINT_ERR("Did not get interrupt on clear_IO on " \
6763 "irq 0x%x.\n",card->irq2);
6764 }
6765 }
6766 }
6767
qeth_free_card(qeth_card_t * card)6768 static void qeth_free_card(qeth_card_t *card)
6769 {
6770 int i,j;
6771 char dbf_text[15];
6772 int element_count;
6773 qeth_vipa_entry_t *e,*e2;
6774
6775 if (!card) return;
6776
6777 sprintf(dbf_text,"free%4x",card->irq0);
6778 QETH_DBF_TEXT3(0,trace,dbf_text);
6779 QETH_DBF_TEXT1(0,setup,dbf_text);
6780
6781 my_write_lock(&card->vipa_list_lock);
6782 e=card->vipa_list;
6783 while (e) {
6784 e2=e->next;
6785 kfree(e);
6786 e=e2;
6787 }
6788 my_write_unlock(&card->vipa_list_lock);
6789
6790 element_count=(card->options.memusage==MEMUSAGE_DISCONTIG)?
6791 BUFFER_MAX_ELEMENTS:1;
6792 for (i=0;i<card->options.inbound_buffer_count;i++) {
6793 for (j=0;j<element_count;j++) {
6794 if (card->inbound_buffer_pool_entry[i][j]) {
6795 kfree(card->inbound_buffer_pool_entry[i][j]);
6796 card->inbound_buffer_pool_entry[i][j]=NULL;
6797 }
6798 }
6799 }
6800 for (i=0;i<card->no_queues;i++)
6801 if (card->outbound_ringbuffer[i])
6802 vfree(card->outbound_ringbuffer[i]);
6803
6804 if (card->stats) kfree(card->stats);
6805 if (card->dma_stuff) kfree(card->dma_stuff);
6806 if (card->dev) kfree(card->dev);
6807 if (card->devstat2) kfree(card->devstat2);
6808 if (card->devstat1) kfree(card->devstat1);
6809 if (card->devstat0) kfree(card->devstat0);
6810 vfree(card); /* we checked against NULL already */
6811 }
6812
6813 /* also locked from outside (setup_lock) */
qeth_remove_card_from_list(qeth_card_t * card)6814 static void qeth_remove_card_from_list(qeth_card_t *card)
6815 {
6816 qeth_card_t *cn;
6817 unsigned long flags0,flags1,flags2;
6818 char dbf_text[15];
6819
6820 my_write_lock(&list_lock);
6821 if (!card) {
6822 QETH_DBF_TEXT2(0,trace,"RMCWNOCD");
6823 PRINT_WARN("qeth_remove_card_from_list call with no card!\n");
6824 return;
6825 }
6826
6827 sprintf(dbf_text,"rmcl%4x",card->irq0);
6828 QETH_DBF_TEXT3(0,trace,dbf_text);
6829
6830 /* check first, if card is in list */
6831 if (!firstcard) {
6832 QETH_DBF_TEXT2(0,trace,"NOCRDINL");
6833 PRINT_WARN("qeth_remove_card_from_list called on " \
6834 "empty card list!!\n");
6835 return;
6836 }
6837
6838 s390irq_spin_lock_irqsave(card->irq0,flags0);
6839 s390irq_spin_lock_irqsave(card->irq1,flags1);
6840 s390irq_spin_lock_irqsave(card->irq2,flags2);
6841
6842 if (firstcard==card)
6843 firstcard=card->next;
6844 else {
6845 cn=firstcard;
6846 while (cn->next) {
6847 if (cn->next==card) {
6848 cn->next=card->next;
6849 card->next=NULL;
6850 break;
6851 }
6852 cn = cn->next;
6853 }
6854 }
6855
6856 s390irq_spin_unlock_irqrestore(card->irq2,flags2);
6857 s390irq_spin_unlock_irqrestore(card->irq1,flags1);
6858 s390irq_spin_unlock_irqrestore(card->irq0,flags0);
6859
6860
6861 my_write_unlock(&list_lock);
6862
6863 }
6864
qeth_delete_all_ips(qeth_card_t * card)6865 static void qeth_delete_all_ips(qeth_card_t *card)
6866 {
6867 qeth_vipa_entry_t *e;
6868
6869 if (atomic_read(&card->is_softsetup)) {
6870 qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa);
6871 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa);
6872
6873 #ifdef QETH_IPV6
6874 qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa);
6875 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa);
6876 #endif /* QETH_IPV6 */
6877
6878 my_write_lock(&card->vipa_list_lock);
6879 e=card->vipa_list;
6880 while (e) {
6881 e->state=VIPA_2_B_REMOVED;
6882 e=e->next;
6883 }
6884 my_write_unlock(&card->vipa_list_lock);
6885 qeth_start_softsetup_thread(card);
6886 }
6887 }
6888
qeth_remove_card(qeth_card_t * card,int method)6889 static void qeth_remove_card(qeth_card_t *card,int method)
6890 {
6891 char dbf_text[15];
6892
6893 if (!card) {
6894 return;
6895 }
6896 sprintf(dbf_text,"rmcd%4x",card->irq0);
6897 QETH_DBF_TEXT2(0,trace,dbf_text);
6898 QETH_DBF_TEXT1(0,setup,dbf_text);
6899
6900 if (method==QETH_REMOVE_CARD_PROPER) {
6901 atomic_set(&card->shutdown_phase,QETH_REMOVE_CARD_PROPER);
6902 if (atomic_read(&card->is_open)) {
6903 qeth_stop(card->dev);
6904 qeth_wait_nonbusy(QETH_REMOVE_WAIT_TIME);
6905 }
6906 qeth_delete_all_ips(card);
6907 } else {
6908 atomic_set(&card->shutdown_phase,QETH_REMOVE_CARD_QUICK);
6909 }
6910 atomic_set(&card->write_busy,0);
6911
6912 QETH_DBF_TEXT4(0,trace,"freeskbs");
6913 qeth_free_all_skbs(card);
6914
6915 QETH_DBF_TEXT2(0,trace,"upthrsem");
6916
6917 up(&card->softsetup_thread_sem);
6918 up(&card->reinit_thread_sem);
6919 while ( (atomic_read(&card->softsetup_thread_is_running)) ||
6920 (atomic_read(&card->reinit_counter)) ) {
6921 qeth_wait_nonbusy(QETH_WAIT_FOR_THREAD_TIME);
6922 }
6923
6924 if (method==QETH_REMOVE_CARD_PROPER) {
6925 QETH_DBF_TEXT4(0,trace,"softshut");
6926 qeth_softshutdown(card);
6927 qeth_wait_nonbusy(QETH_REMOVE_WAIT_TIME);
6928 }
6929
6930 atomic_set(&card->is_startlaned,0); /* paranoia, qeth_stop
6931 should prevent
6932 further calls of
6933 hard_start_xmit */
6934
6935 if (atomic_read(&card->is_registered)) {
6936 QETH_DBF_TEXT2(0,trace,"unregdev");
6937 qeth_unregister_netdev(card);
6938 qeth_wait_nonbusy(QETH_REMOVE_WAIT_TIME);
6939 atomic_set(&card->is_registered,0);
6940 }
6941
6942 qeth_put_unique_id(card);
6943
6944 QETH_DBF_TEXT2(0,trace,"clrcard");
6945 if (atomic_read(&card->is_hardsetup)) {
6946 PRINT_STUPID("clearing card %s\n",card->dev_name);
6947 qeth_clear_card(card,1,0);
6948 }
6949
6950 atomic_set(&card->is_hardsetup,0);
6951 atomic_set(&card->is_softsetup,0);
6952
6953
6954 if (card->has_irq>=3) {
6955 QETH_DBF_TEXT2(0,trace,"freeirq2");
6956 chandev_free_irq(card->irq2,card->devstat2);
6957 }
6958 if (card->has_irq>=2) {
6959 QETH_DBF_TEXT2(0,trace,"freeirq1");
6960 chandev_free_irq(card->irq1,card->devstat1);
6961 }
6962 if (card->has_irq>=1) {
6963 QETH_DBF_TEXT2(0,trace,"freeirq0");
6964 chandev_free_irq(card->irq0,card->devstat0);
6965 }
6966 }
6967
qeth_destructor(struct net_device * dev)6968 static void qeth_destructor(struct net_device *dev)
6969 {
6970 char dbf_text[15];
6971 qeth_card_t *card;
6972
6973 card=(qeth_card_t *)(dev->priv);
6974 sprintf(dbf_text,"dstr%4x",card->irq0);
6975 QETH_DBF_TEXT2(0,trace,dbf_text);
6976 }
6977
qeth_set_multicast_list(struct net_device * dev)6978 static void qeth_set_multicast_list(struct net_device *dev)
6979 {
6980 char dbf_text[15];
6981 qeth_card_t *card=dev->priv;
6982
6983 sprintf(dbf_text,"smcl%4x",card->irq0);
6984 QETH_DBF_TEXT2(0,trace,dbf_text);
6985
6986 qeth_start_softsetup_thread(card);
6987 }
6988
qeth_set_mac_address(struct net_device * dev,void * addr)6989 static int qeth_set_mac_address(struct net_device *dev,void *addr)
6990 {
6991 char dbf_text[15];
6992
6993 sprintf(dbf_text,"stmc%4x",((qeth_card_t *)dev->priv)->irq0);
6994 QETH_DBF_TEXT2(0,trace,dbf_text);
6995 return -EOPNOTSUPP;
6996 }
6997
qeth_neigh_setup(struct net_device * dev,struct neigh_parms * np)6998 static int qeth_neigh_setup(struct net_device *dev,struct neigh_parms *np)
6999 {
7000 char dbf_text[15];
7001
7002 sprintf(dbf_text,"ngst%4x",((qeth_card_t *)dev->priv)->irq0);
7003 QETH_DBF_TEXT2(0,trace,dbf_text);
7004 return 0;
7005 }
7006
qeth_generate_tokens(qeth_card_t * card)7007 static void qeth_generate_tokens(qeth_card_t *card)
7008 {
7009 card->token.issuer_rm_w=0x00010103UL;
7010 card->token.cm_filter_w=0x00010108UL;
7011 card->token.cm_connection_w=0x0001010aUL;
7012 card->token.ulp_filter_w=0x0001010bUL;
7013 card->token.ulp_connection_w=0x0001010dUL;
7014 }
7015
qeth_peer_func_level(int level)7016 static int qeth_peer_func_level(int level)
7017 {
7018 if ((level&0xff)==8) return (level&0xff)+0x400;
7019 if ( ((level>>8)&3)==1) return (level&0xff)+0x200;
7020 return level; /* hmmm... don't know what to do with that level. */
7021 }
7022
qeth_idx_activate_read(qeth_card_t * card)7023 static int qeth_idx_activate_read(qeth_card_t *card)
7024 {
7025 int result,result2;
7026 __u16 temp;
7027 unsigned long flags;
7028 char dbf_text[15];
7029
7030 result=result2=0;
7031
7032 memcpy(&card->dma_stuff->write_ccw,WRITE_CCW,sizeof(ccw1_t));
7033 card->dma_stuff->write_ccw.count=IDX_ACTIVATE_SIZE;
7034 card->dma_stuff->write_ccw.cda=
7035 QETH_GET_ADDR(card->dma_stuff->sendbuf);
7036
7037 memcpy(card->dma_stuff->sendbuf,IDX_ACTIVATE_READ,
7038 IDX_ACTIVATE_SIZE);
7039 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(card->dma_stuff->sendbuf),
7040 &card->seqno.trans_hdr,QETH_SEQ_NO_LENGTH);
7041
7042 memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(card->dma_stuff->sendbuf),
7043 &card->token.issuer_rm_w,QETH_MPC_TOKEN_LENGTH);
7044 memcpy(QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->sendbuf),
7045 &card->func_level,2);
7046
7047 temp=card->devno2;
7048 memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(card->dma_stuff->sendbuf),
7049 &temp,2);
7050 temp=(card->cula<<8)+card->unit_addr2;
7051 memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(card->dma_stuff->sendbuf),
7052 &temp,2);
7053
7054 sprintf(dbf_text,"iarw%4x",card->irq0);
7055 QETH_DBF_TEXT2(0,trace,dbf_text);
7056 QETH_DBF_HEX2(0,control,card->dma_stuff->sendbuf,
7057 QETH_DBF_CONTROL_LEN);
7058
7059 s390irq_spin_lock_irqsave(card->irq0,flags);
7060 result=do_IO(card->irq0,&card->dma_stuff->write_ccw,
7061 IDX_ACTIVATE_WRITE_STATE,0,0);
7062 if (result) {
7063 qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO);
7064 result2=do_IO(card->irq0,&card->dma_stuff->write_ccw,
7065 IDX_ACTIVATE_WRITE_STATE,0,0);
7066 sprintf(dbf_text,"IRW1%4x",result);
7067 QETH_DBF_TEXT2(0,trace,dbf_text);
7068 sprintf(dbf_text,"IRW2%4x",result2);
7069 QETH_DBF_TEXT2(0,trace,dbf_text);
7070 PRINT_WARN("qeth_idx_activate_read (write): do_IO returned " \
7071 "%i, next try returns %i\n",result,result2);
7072 }
7073 s390irq_spin_unlock_irqrestore(card->irq0,flags);
7074
7075 if (atomic_read(&card->break_out)) {
7076 QETH_DBF_TEXT3(0,trace,"IARWBRKO");
7077 result=-EIO;
7078 goto exit;
7079 }
7080
7081 if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) {
7082 sprintf(dbf_text,"IRWT%4x",card->irq0);
7083 QETH_DBF_TEXT1(0,trace,dbf_text);
7084 PRINT_ERR("IDX_ACTIVATE(wr) on read channel irq 0x%x: " \
7085 "timeout\n",card->irq0);
7086 result=-EIO;
7087 goto exit;
7088 }
7089
7090 /* start reading on read channel, card->read_ccw is not yet used */
7091 memcpy(&card->dma_stuff->read_ccw,READ_CCW,sizeof(ccw1_t));
7092 card->dma_stuff->read_ccw.count=QETH_BUFSIZE;
7093 card->dma_stuff->read_ccw.cda=QETH_GET_ADDR(card->dma_stuff->recbuf);
7094
7095 s390irq_spin_lock_irqsave(card->irq0,flags);
7096 result2=0;
7097 result=do_IO(card->irq0,&card->dma_stuff->read_ccw,
7098 IDX_ACTIVATE_READ_STATE,0,0);
7099 if (result) {
7100 qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO);
7101 result2=do_IO(card->irq0,&card->dma_stuff->read_ccw,
7102 IDX_ACTIVATE_READ_STATE,0,0);
7103 sprintf(dbf_text,"IRR1%4x",result);
7104 QETH_DBF_TEXT2(0,trace,dbf_text);
7105 sprintf(dbf_text,"IRR2%4x",result2);
7106 QETH_DBF_TEXT2(0,trace,dbf_text);
7107 PRINT_WARN("qeth_idx_activate_read (read): do_IO " \
7108 "returned %i, next try returns %i\n",
7109 result,result2);
7110 }
7111 s390irq_spin_unlock_irqrestore(card->irq0,flags);
7112
7113 if (result2) {
7114 result=result2;
7115 if (result) goto exit;
7116 }
7117
7118 if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) {
7119 sprintf(dbf_text,"IRRT%4x",card->irq0);
7120 QETH_DBF_TEXT1(0,trace,dbf_text);
7121 PRINT_ERR("IDX_ACTIVATE(rd) on read channel irq 0x%x: " \
7122 "timeout\n",card->irq0);
7123 result=-EIO;
7124 goto exit;
7125 }
7126 sprintf(dbf_text,"iarr%4x",card->irq0);
7127 QETH_DBF_TEXT2(0,trace,dbf_text);
7128 QETH_DBF_HEX2(0,control,card->dma_stuff->recbuf,
7129 QETH_DBF_CONTROL_LEN);
7130
7131 if (!(QETH_IS_IDX_ACT_POS_REPLY(card->dma_stuff->recbuf))) {
7132 sprintf(dbf_text,"IRNR%4x",card->irq0);
7133 QETH_DBF_TEXT1(0,trace,dbf_text);
7134 PRINT_ERR("IDX_ACTIVATE on read channel irq 0x%x: negative " \
7135 "reply\n",card->irq0);
7136 result=-EIO;
7137 goto exit;
7138 }
7139
7140 card->portname_required=
7141 ((!QETH_IDX_NO_PORTNAME_REQUIRED(card->dma_stuff->recbuf))&&
7142 (card->type==QETH_CARD_TYPE_OSAE));
7143 /* however, as the portname indication of OSA is wrong, we have to
7144 * do this: */
7145 card->portname_required=(card->type==QETH_CARD_TYPE_OSAE);
7146
7147
7148 memcpy(&temp,QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->recbuf),2);
7149 if (temp!=qeth_peer_func_level(card->func_level)) {
7150 sprintf(dbf_text,"IRFL%4x",card->irq0);
7151 QETH_DBF_TEXT1(0,trace,dbf_text);
7152 sprintf(dbf_text,"%4x%4x",card->func_level,temp);
7153 QETH_DBF_TEXT1(0,trace,dbf_text);
7154 PRINT_WARN("IDX_ACTIVATE on read channel irq 0x%x: " \
7155 "function level mismatch (sent: 0x%x, " \
7156 "received: 0x%x)\n",
7157 card->irq0,card->func_level,temp);
7158 result=-EIO;
7159 }
7160
7161 memcpy(&card->token.issuer_rm_r,
7162 QETH_IDX_ACT_ISSUER_RM_TOKEN(card->dma_stuff->recbuf),
7163 QETH_MPC_TOKEN_LENGTH);
7164
7165 memcpy(&card->level[0],
7166 QETH_IDX_REPLY_LEVEL(card->dma_stuff->recbuf),
7167 QETH_MCL_LENGTH);
7168 exit:
7169 return result;
7170 }
7171
qeth_idx_activate_write(qeth_card_t * card)7172 static int qeth_idx_activate_write(qeth_card_t *card)
7173 {
7174 int result,result2;
7175 __u16 temp;
7176 unsigned long flags;
7177 char dbf_text[15];
7178
7179 result=result2=0;
7180
7181 memcpy(&card->dma_stuff->write_ccw,WRITE_CCW,sizeof(ccw1_t));
7182 card->dma_stuff->write_ccw.count=IDX_ACTIVATE_SIZE;
7183 card->dma_stuff->write_ccw.cda=
7184 QETH_GET_ADDR(card->dma_stuff->sendbuf);
7185
7186 memcpy(card->dma_stuff->sendbuf,IDX_ACTIVATE_WRITE,
7187 IDX_ACTIVATE_SIZE);
7188 memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(card->dma_stuff->sendbuf),
7189 &card->seqno.trans_hdr,QETH_SEQ_NO_LENGTH);
7190 card->seqno.trans_hdr++;
7191
7192 memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(card->dma_stuff->sendbuf),
7193 &card->token.issuer_rm_w,QETH_MPC_TOKEN_LENGTH);
7194 memcpy(QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->sendbuf),
7195 &card->func_level,2);
7196
7197 temp=card->devno2;
7198 memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(card->dma_stuff->sendbuf),
7199 &temp,2);
7200 temp=(card->cula<<8)+card->unit_addr2;
7201 memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(card->dma_stuff->sendbuf),
7202 &temp,2);
7203
7204 sprintf(dbf_text,"iaww%4x",card->irq0);
7205 QETH_DBF_TEXT2(0,trace,dbf_text);
7206 QETH_DBF_HEX2(0,control,card->dma_stuff->sendbuf,
7207 QETH_DBF_CONTROL_LEN);
7208
7209 s390irq_spin_lock_irqsave(card->irq1,flags);
7210 result=do_IO(card->irq1,&card->dma_stuff->write_ccw,
7211 IDX_ACTIVATE_WRITE_STATE,0,0);
7212 if (result) {
7213 qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO);
7214 result2=do_IO(card->irq1,&card->dma_stuff->write_ccw,
7215 IDX_ACTIVATE_WRITE_STATE,0,0);
7216 sprintf(dbf_text,"IWW1%4x",result);
7217 QETH_DBF_TEXT2(0,trace,dbf_text);
7218 sprintf(dbf_text,"IWW2%4x",result2);
7219 QETH_DBF_TEXT2(0,trace,dbf_text);
7220 PRINT_WARN("qeth_idx_activate_write (write): do_IO " \
7221 "returned %i, next try returns %i\n",
7222 result,result2);
7223 }
7224 s390irq_spin_unlock_irqrestore(card->irq1,flags);
7225
7226 if (atomic_read(&card->break_out)) {
7227 QETH_DBF_TEXT3(0,trace,"IAWWBRKO");
7228 result=-EIO;
7229 goto exit;
7230 }
7231
7232 if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) {
7233 sprintf(dbf_text,"IWWT%4x",card->irq0);
7234 QETH_DBF_TEXT1(0,trace,dbf_text);
7235 PRINT_ERR("IDX_ACTIVATE(wr) on write channel irq 0x%x: " \
7236 "timeout\n",card->irq1);
7237 result=-EIO;
7238 goto exit;
7239 }
7240
7241 QETH_DBF_TEXT3(0,trace,"idxawrrd");
7242
7243 /* start one read on write channel */
7244 memcpy(&card->dma_stuff->read_ccw,READ_CCW,sizeof(ccw1_t));
7245 card->dma_stuff->read_ccw.count=QETH_BUFSIZE;
7246
7247 /* recbuf and card->read_ccw is not yet used by any other
7248 read channel program */
7249 card->dma_stuff->read_ccw.cda=QETH_GET_ADDR(card->dma_stuff->recbuf);
7250
7251 s390irq_spin_lock_irqsave(card->irq1,flags);
7252 result2=0;
7253 result=do_IO(card->irq1,&card->dma_stuff->read_ccw,
7254 IDX_ACTIVATE_READ_STATE,0,0);
7255 if (result) {
7256 qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO);
7257 result2=do_IO(card->irq1,&card->dma_stuff->read_ccw,
7258 IDX_ACTIVATE_READ_STATE,0,0);
7259 sprintf(dbf_text,"IWR1%4x",result);
7260 QETH_DBF_TEXT2(0,trace,dbf_text);
7261 sprintf(dbf_text,"IWR2%4x",result2);
7262 QETH_DBF_TEXT2(0,trace,dbf_text);
7263 PRINT_WARN("qeth_idx_activate_write (read): do_IO returned " \
7264 "%i, next try returns %i\n",result,result2);
7265 }
7266
7267 s390irq_spin_unlock_irqrestore(card->irq1,flags);
7268
7269 if (result2) {
7270 result=result2;
7271 if (result) goto exit;
7272 }
7273
7274 if (qeth_sleepon(card,QETH_MPC_TIMEOUT)) {
7275 sprintf(dbf_text,"IWRT%4x",card->irq0);
7276 QETH_DBF_TEXT1(0,trace,dbf_text);
7277 PRINT_ERR("IDX_ACTIVATE(rd) on write channel irq 0x%x: " \
7278 "timeout\n",card->irq1);
7279 result=-EIO;
7280 goto exit;
7281 }
7282 sprintf(dbf_text,"iawr%4x",card->irq0);
7283 QETH_DBF_TEXT2(0,trace,dbf_text);
7284 QETH_DBF_HEX2(0,control,card->dma_stuff->recbuf,
7285 QETH_DBF_CONTROL_LEN);
7286
7287 if (!(QETH_IS_IDX_ACT_POS_REPLY(card->dma_stuff->recbuf))) {
7288 sprintf(dbf_text,"IWNR%4x",card->irq0);
7289 QETH_DBF_TEXT1(0,trace,dbf_text);
7290 PRINT_ERR("IDX_ACTIVATE on write channel irq 0x%x: " \
7291 "negative reply\n",card->irq1);
7292 result=-EIO;
7293 goto exit;
7294 }
7295
7296 memcpy(&temp,QETH_IDX_ACT_FUNC_LEVEL(card->dma_stuff->recbuf),2);
7297 if ((temp&~0x0100)!=qeth_peer_func_level(card->func_level)) {
7298 sprintf(dbf_text,"IWFM%4x",card->irq0);
7299 QETH_DBF_TEXT1(0,trace,dbf_text);
7300 sprintf(dbf_text,"%4x%4x",card->func_level,temp);
7301 QETH_DBF_TEXT1(0,trace,dbf_text);
7302 PRINT_WARN("IDX_ACTIVATE on write channel irq 0x%x: " \
7303 "function level mismatch (sent: 0x%x, " \
7304 "received: 0x%x)\n",
7305 card->irq1,card->func_level,temp);
7306 result=-EIO;
7307 }
7308
7309 exit:
7310 return result;
7311 }
7312
qeth_cm_enable(qeth_card_t * card)7313 static int qeth_cm_enable(qeth_card_t *card)
7314 {
7315 unsigned char *buffer;
7316 int result;
7317 char dbf_text[15];
7318
7319 memcpy(card->send_buf,CM_ENABLE,CM_ENABLE_SIZE);
7320
7321 memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(card->send_buf),
7322 &card->token.issuer_rm_r,QETH_MPC_TOKEN_LENGTH);
7323 memcpy(QETH_CM_ENABLE_FILTER_TOKEN(card->send_buf),
7324 &card->token.cm_filter_w,QETH_MPC_TOKEN_LENGTH);
7325
7326 buffer=qeth_send_control_data(card,card->send_buf,
7327 CM_ENABLE_SIZE,MPC_SETUP_STATE);
7328
7329 if (!buffer) {
7330 QETH_DBF_TEXT2(0,trace,"CME:NOBF");
7331 return -EIO;
7332 }
7333
7334 memcpy(&card->token.cm_filter_r,
7335 QETH_CM_ENABLE_RESP_FILTER_TOKEN(buffer),
7336 QETH_MPC_TOKEN_LENGTH);
7337
7338 result=qeth_check_idx_response(buffer);
7339
7340 sprintf(dbf_text,"cme=%4x",result);
7341 QETH_DBF_TEXT3(0,trace,dbf_text);
7342
7343 return result;
7344 }
7345
qeth_cm_setup(qeth_card_t * card)7346 static int qeth_cm_setup(qeth_card_t *card)
7347 {
7348 unsigned char *buffer;
7349 int result;
7350 char dbf_text[15];
7351
7352 memcpy(card->send_buf,CM_SETUP,CM_SETUP_SIZE);
7353
7354 memcpy(QETH_CM_SETUP_DEST_ADDR(card->send_buf),
7355 &card->token.issuer_rm_r,QETH_MPC_TOKEN_LENGTH);
7356 memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(card->send_buf),
7357 &card->token.cm_connection_w,QETH_MPC_TOKEN_LENGTH);
7358 memcpy(QETH_CM_SETUP_FILTER_TOKEN(card->send_buf),
7359 &card->token.cm_filter_r,QETH_MPC_TOKEN_LENGTH);
7360
7361 buffer=qeth_send_control_data(card,card->send_buf,
7362 CM_SETUP_SIZE,MPC_SETUP_STATE);
7363
7364 if (!buffer) {
7365 QETH_DBF_TEXT2(0,trace,"CMS:NOBF");
7366 return -EIO;
7367 }
7368
7369 memcpy(&card->token.cm_connection_r,
7370 QETH_CM_SETUP_RESP_DEST_ADDR(buffer),
7371 QETH_MPC_TOKEN_LENGTH);
7372
7373 result=qeth_check_idx_response(buffer);
7374
7375 sprintf(dbf_text,"cms=%4x",result);
7376 QETH_DBF_TEXT3(0,trace,dbf_text);
7377
7378 return result;
7379 }
7380
qeth_ulp_enable(qeth_card_t * card)7381 static int qeth_ulp_enable(qeth_card_t *card)
7382 {
7383 unsigned char *buffer;
7384 __u16 mtu,framesize;
7385 __u16 len;
7386 __u8 link_type;
7387 int result;
7388 char dbf_text[15];
7389
7390 memcpy(card->send_buf,ULP_ENABLE,ULP_ENABLE_SIZE);
7391
7392 *(QETH_ULP_ENABLE_LINKNUM(card->send_buf))=(__u8)card->options.portno;
7393
7394 memcpy(QETH_ULP_ENABLE_DEST_ADDR(card->send_buf),
7395 &card->token.cm_connection_r,QETH_MPC_TOKEN_LENGTH);
7396 memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(card->send_buf),
7397 &card->token.ulp_filter_w,QETH_MPC_TOKEN_LENGTH);
7398
7399 memcpy(QETH_ULP_ENABLE_PORTNAME_AND_LL(card->send_buf),
7400 card->options.portname,9);
7401
7402 buffer=qeth_send_control_data(card,card->send_buf,
7403 ULP_ENABLE_SIZE,MPC_SETUP_STATE);
7404
7405 if (!buffer) {
7406 QETH_DBF_TEXT2(0,trace,"ULE:NOBF");
7407 return -EIO;
7408 }
7409
7410 memcpy(&card->token.ulp_filter_r,
7411 QETH_ULP_ENABLE_RESP_FILTER_TOKEN(buffer),
7412 QETH_MPC_TOKEN_LENGTH);
7413
7414 /* to be done before qeth_init_ringbuffers and qeth_init_dev */
7415 if (qeth_get_mtu_out_of_mpc(card->type)) {
7416 memcpy(&framesize,QETH_ULP_ENABLE_RESP_MAX_MTU(buffer),2);
7417 mtu=qeth_get_mtu_outof_framesize(framesize);
7418
7419 sprintf(dbf_text,"ule:%4x",card->irq0);
7420 QETH_DBF_TEXT2(0,trace,dbf_text);
7421 sprintf(dbf_text,"mtu=%4x",mtu);
7422 QETH_DBF_TEXT2(0,trace,dbf_text);
7423
7424 if (!mtu) return -EINVAL;
7425
7426 card->max_mtu=mtu;
7427 card->initial_mtu=mtu;
7428 card->inbound_buffer_size=mtu+2*PAGE_SIZE;
7429 } else {
7430 card->initial_mtu=qeth_get_initial_mtu_for_card(card);
7431 card->max_mtu=qeth_get_max_mtu_for_card(card->type);
7432 card->inbound_buffer_size=DEFAULT_BUFFER_SIZE;
7433 }
7434
7435 memcpy(&len,QETH_ULP_ENABLE_RESP_DIFINFO_LEN(buffer),2);
7436 if (len>=QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
7437 memcpy(&link_type,QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer),1);
7438 card->link_type=link_type;
7439 sprintf(dbf_text,"link=%2x",link_type);
7440 QETH_DBF_TEXT2(0,trace,dbf_text);
7441 } else card->link_type=0;
7442
7443 result=qeth_check_idx_response(buffer);
7444
7445 sprintf(dbf_text,"ule=%4x",result);
7446 QETH_DBF_TEXT3(0,trace,dbf_text);
7447
7448 return result;
7449 }
7450
qeth_ulp_setup(qeth_card_t * card)7451 static int qeth_ulp_setup(qeth_card_t *card)
7452 {
7453 unsigned char *buffer;
7454 __u16 temp;
7455 int result;
7456 char dbf_text[15];
7457
7458 memcpy(card->send_buf,ULP_SETUP,ULP_SETUP_SIZE);
7459
7460 memcpy(QETH_ULP_SETUP_DEST_ADDR(card->send_buf),
7461 &card->token.cm_connection_r,QETH_MPC_TOKEN_LENGTH);
7462 memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(card->send_buf),
7463 &card->token.ulp_connection_w,QETH_MPC_TOKEN_LENGTH);
7464 memcpy(QETH_ULP_SETUP_FILTER_TOKEN(card->send_buf),
7465 &card->token.ulp_filter_r,QETH_MPC_TOKEN_LENGTH);
7466
7467 temp=card->devno2;
7468 memcpy(QETH_ULP_SETUP_CUA(card->send_buf),
7469 &temp,2);
7470 temp=(card->cula<<8)+card->unit_addr2;
7471 memcpy(QETH_ULP_SETUP_REAL_DEVADDR(card->send_buf),
7472 &temp,2);
7473
7474 buffer=qeth_send_control_data(card,card->send_buf,
7475 ULP_SETUP_SIZE,MPC_SETUP_STATE);
7476
7477 if (!buffer) {
7478 QETH_DBF_TEXT2(0,trace,"ULS:NOBF");
7479 return -EIO;
7480 }
7481
7482 memcpy(&card->token.ulp_connection_r,
7483 QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(buffer),
7484 QETH_MPC_TOKEN_LENGTH);
7485
7486 result=qeth_check_idx_response(buffer);
7487
7488 sprintf(dbf_text,"uls=%4x",result);
7489 QETH_DBF_TEXT3(0,trace,dbf_text);
7490
7491 return result;
7492 }
7493
qeth_qdio_establish(qeth_card_t * card)7494 static int qeth_qdio_establish(qeth_card_t *card)
7495 {
7496 int result;
7497 char *adapter_area;
7498 char dbf_text[15];
7499 void **input_array,**output_array,**ptr;
7500 int i,j;
7501 qdio_initialize_t init_data;
7502
7503 adapter_area=vmalloc(QDIO_MAX_BUFFERS_PER_Q*sizeof(char));
7504 if (!adapter_area) return -ENOMEM;
7505
7506 memset(adapter_area,0,QDIO_MAX_BUFFERS_PER_Q*sizeof(char));
7507
7508 adapter_area[0]=_ascebc['P'];
7509 adapter_area[1]=_ascebc['C'];
7510 adapter_area[2]=_ascebc['I'];
7511 adapter_area[3]=_ascebc['T'];
7512 *((unsigned int*)(&adapter_area[4]))=PCI_THRESHOLD_A;
7513 *((unsigned int*)(&adapter_area[8]))=PCI_THRESHOLD_B;
7514 *((unsigned int*)(&adapter_area[12]))=PCI_TIMER_VALUE;
7515
7516 input_array=vmalloc(QDIO_MAX_BUFFERS_PER_Q*sizeof(void*));
7517 if (!input_array) {
7518 vfree(adapter_area);
7519 return -ENOMEM;
7520 }
7521 ptr=input_array;
7522 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
7523 *ptr=(void*)virt_to_phys
7524 (&card->inbound_qdio_buffers[j]);
7525 ptr++;
7526 }
7527
7528 output_array=vmalloc(QDIO_MAX_BUFFERS_PER_Q*sizeof(void*)*
7529 card->no_queues);
7530 if (!output_array) {
7531 vfree(input_array);
7532 vfree(adapter_area);
7533 return -ENOMEM;
7534 }
7535 ptr=output_array;
7536 for (i=0;i<card->no_queues;i++)
7537 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
7538 *ptr=(void*)virt_to_phys
7539 (&card->outbound_ringbuffer[i]->
7540 buffer[j]);
7541 ptr++;
7542 }
7543
7544 init_data.irq=card->irq2;
7545 init_data.q_format=qeth_get_q_format(card->type);
7546 init_data.qib_param_field_format=0;
7547 init_data.qib_param_field=adapter_area;
7548 init_data.input_slib_elements=NULL;
7549 init_data.output_slib_elements=NULL;
7550 init_data.min_input_threshold=card->options.polltime;
7551 init_data.max_input_threshold=card->options.polltime;
7552 init_data.min_output_threshold=QETH_MIN_OUTPUT_THRESHOLD;
7553 init_data.max_output_threshold=QETH_MAX_OUTPUT_THRESHOLD;
7554 init_data.no_input_qs=1;
7555 init_data.no_output_qs=card->no_queues;
7556 init_data.input_handler=qeth_qdio_input_handler;
7557 init_data.output_handler=qeth_qdio_output_handler;
7558 init_data.int_parm=(unsigned long)card;
7559 init_data.flags=QDIO_INBOUND_0COPY_SBALS|
7560 QDIO_OUTBOUND_0COPY_SBALS|
7561 QDIO_USE_OUTBOUND_PCIS;
7562 if (card->do_pfix)
7563 init_data.flags |= QDIO_PFIX;
7564 init_data.input_sbal_addr_array=input_array;
7565 init_data.output_sbal_addr_array=output_array;
7566
7567 result=qdio_initialize(&init_data);
7568
7569 vfree(input_array);
7570 vfree(output_array);
7571 vfree(adapter_area);
7572
7573 sprintf(dbf_text,"qde=%4i",result);
7574 QETH_DBF_TEXT3(0,trace,dbf_text);
7575
7576 return result;
7577 }
7578
qeth_qdio_activate(qeth_card_t * card)7579 static int qeth_qdio_activate(qeth_card_t *card)
7580 {
7581 int result;
7582 char dbf_text[15];
7583
7584 result=qdio_activate(card->irq2,0);
7585
7586 sprintf(dbf_text,"qda=%4x",result);
7587 QETH_DBF_TEXT3(0,trace,dbf_text);
7588
7589 return result;
7590 }
7591
qeth_dm_act(qeth_card_t * card)7592 static int qeth_dm_act(qeth_card_t *card)
7593 {
7594 unsigned char *buffer;
7595 int result;
7596 char dbf_text[15];
7597
7598 memcpy(card->send_buf,DM_ACT,DM_ACT_SIZE);
7599
7600 memcpy(QETH_DM_ACT_DEST_ADDR(card->send_buf),
7601 &card->token.cm_connection_r,QETH_MPC_TOKEN_LENGTH);
7602 memcpy(QETH_DM_ACT_CONNECTION_TOKEN(card->send_buf),
7603 &card->token.ulp_connection_r,QETH_MPC_TOKEN_LENGTH);
7604
7605 buffer=qeth_send_control_data(card,card->send_buf,
7606 DM_ACT_SIZE,MPC_SETUP_STATE);
7607
7608 if (!buffer) {
7609 QETH_DBF_TEXT2(0,trace,"DMA:NOBF");
7610 return -EIO;
7611 }
7612
7613 result=qeth_check_idx_response(buffer);
7614
7615 sprintf(dbf_text,"dma=%4x",result);
7616 QETH_DBF_TEXT3(0,trace,dbf_text);
7617
7618 return result;
7619 }
7620
7621 #if defined(QETH_VLAN)||defined(QETH_IPV6)
qeth_verify_dev(struct net_device * dev)7622 static int qeth_verify_dev(struct net_device *dev)
7623 {
7624 qeth_card_t *tmp;
7625 int result=0;
7626 #ifdef QETH_VLAN
7627 struct vlan_group *vlan_grp;
7628 int i;
7629 #endif
7630
7631 my_read_lock(&list_lock);
7632 tmp=firstcard;
7633 for (;tmp&&(!result);tmp=tmp->next) {
7634 if (atomic_read(&tmp->shutdown_phase))
7635 continue;
7636 if (dev==tmp->dev) {
7637 result=QETH_VERIFY_IS_REAL_DEV;
7638 }
7639 #ifdef QETH_VLAN
7640 /* check all vlan devices */
7641 vlan_grp = (struct vlan_group *) tmp->vlangrp;
7642 if (vlan_grp) {
7643 for (i=0;i<VLAN_GROUP_ARRAY_LEN;i++) {
7644 if (vlan_grp->vlan_devices[i]==dev) {
7645 result=QETH_VERIFY_IS_VLAN_DEV;
7646 }
7647 }
7648 }
7649
7650 #endif
7651 }
7652 my_read_unlock(&list_lock);
7653 return result;
7654 }
7655 #endif /* defined(QETH_VLAN)||defined(QETH_IPV6) */
7656
qeth_verify_card(qeth_card_t * card)7657 static int qeth_verify_card(qeth_card_t *card)
7658 {
7659 qeth_card_t *tmp;
7660 int result=0;
7661
7662 my_read_lock(&list_lock);
7663 tmp=firstcard;
7664 while (tmp) {
7665 if ((card==tmp) && (!atomic_read(&card->shutdown_phase))) {
7666 result=1;
7667 break;
7668 }
7669 tmp=tmp->next;
7670 }
7671 my_read_unlock(&list_lock);
7672 return result;
7673 }
7674
qeth_correct_routing_status(qeth_card_t * card)7675 static void qeth_correct_routing_status(qeth_card_t *card)
7676 {
7677 if (card->type==QETH_CARD_TYPE_IQD) {
7678 /* if it's not a mc router, it's no router */
7679 if ( (card->options.routing_type4 == PRIMARY_ROUTER) ||
7680 (card->options.routing_type4 == SECONDARY_ROUTER)
7681 #ifdef QETH_IPV6
7682 ||
7683 (card->options.routing_type6 == PRIMARY_ROUTER) ||
7684 (card->options.routing_type6 == SECONDARY_ROUTER)
7685 #endif /* QETH_IPV6 */
7686 ) {
7687 PRINT_WARN("routing not applicable, reset " \
7688 "routing status.\n");
7689 card->options.routing_type4=NO_ROUTER;
7690 #ifdef QETH_IPV6
7691 card->options.routing_type6=NO_ROUTER;
7692 #endif /* QETH_IPV6 */
7693 }
7694 card->options.do_prio_queueing=NO_PRIO_QUEUEING;
7695 } else {
7696 /* if it's a mc router, it's no router */
7697 if ( (((!qeth_is_supported(IPA_OSA_MC_ROUTER_AVAIL))&&
7698 card->options.routing_type4 == MULTICAST_ROUTER)) ||
7699 (card->options.routing_type4 == PRIMARY_CONNECTOR) ||
7700 (card->options.routing_type4 == SECONDARY_CONNECTOR)
7701 #ifdef QETH_IPV6
7702 ||
7703 (((!qeth_is_supported(IPA_OSA_MC_ROUTER_AVAIL))&&
7704 card->options.routing_type6 == MULTICAST_ROUTER)) ||
7705 (card->options.routing_type6 == PRIMARY_CONNECTOR) ||
7706 (card->options.routing_type6 == SECONDARY_CONNECTOR)
7707 #endif /* QETH_IPV6 */
7708 ) {
7709 PRINT_WARN("routing not applicable, reset " \
7710 "routing status. (Did you mean " \
7711 "primary_router or secondary_router?)\n");
7712 card->options.routing_type4=NO_ROUTER;
7713 #ifdef QETH_IPV6
7714 card->options.routing_type6=NO_ROUTER;
7715 #endif /* QETH_IPV6 */
7716 }
7717 }
7718 }
7719
7720 #ifdef QETH_IPV6
7721 extern struct neigh_table arp_tbl;
7722 int (*qeth_old_arp_constructor)(struct neighbour *);
7723 static struct neigh_ops arp_direct_ops_template =
7724 {
7725 family: AF_INET,
7726 destructor: NULL,
7727 solicit: NULL,
7728 error_report: NULL,
7729 output: dev_queue_xmit,
7730 connected_output: dev_queue_xmit,
7731 hh_output: dev_queue_xmit,
7732 queue_xmit: dev_queue_xmit
7733 };
7734 /* as we have neighbour structures point to this structure, even
7735 * after our life time, this will stay in memory as a leak */
7736 static struct neigh_ops *arp_direct_ops;
7737
qeth_arp_constructor(struct neighbour * neigh)7738 static int qeth_arp_constructor(struct neighbour *neigh)
7739 {
7740 char dbf_text[15];
7741 struct net_device *dev = neigh->dev;
7742 struct in_device *in_dev = in_dev_get(dev);
7743
7744 if (in_dev == NULL)
7745 return -EINVAL;
7746
7747 QETH_DBF_TEXT4(0,trace,"arpconst");
7748 if (!qeth_verify_dev(dev)) {
7749
7750 in_dev_put(in_dev);
7751 return qeth_old_arp_constructor(neigh);
7752 }
7753
7754 neigh->type = inet_addr_type(*(u32*)neigh->primary_key);
7755 if (in_dev->arp_parms)
7756 neigh->parms = in_dev->arp_parms;
7757
7758 in_dev_put(in_dev);
7759
7760 sprintf(dbf_text,"%08x",ntohl(*((__u32*)(neigh->primary_key))));
7761 QETH_DBF_TEXT4(0,trace,dbf_text);
7762 QETH_DBF_HEX4(0,trace,&neigh,sizeof(void*));
7763
7764 neigh->nud_state = NUD_NOARP;
7765 neigh->ops = arp_direct_ops;
7766 neigh->output = neigh->ops->queue_xmit;
7767 return 0;
7768 }
7769
qeth_hard_header(struct sk_buff * skb,struct net_device * dev,unsigned short type,void * daddr,void * saddr,unsigned len)7770 static int qeth_hard_header(struct sk_buff *skb,struct net_device *dev,
7771 unsigned short type,void *daddr,void *saddr,
7772 unsigned len)
7773 {
7774 qeth_card_t *card;
7775
7776 QETH_DBF_TEXT5(0,trace,"hardhdr");
7777
7778 #ifdef QETH_VLAN
7779 if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV)
7780 card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv;
7781 else
7782 #endif
7783 card=(qeth_card_t*)dev->priv;
7784
7785 return card->hard_header(skb,dev,type,daddr,saddr,len);
7786 }
7787
qeth_header_cache_update(struct hh_cache * hh,struct net_device * dev,unsigned char * haddr)7788 static void qeth_header_cache_update(struct hh_cache *hh,
7789 struct net_device *dev,
7790 unsigned char *haddr)
7791 {
7792 qeth_card_t *card;
7793
7794 card=(qeth_card_t*)dev->priv;
7795 QETH_DBF_TEXT5(0,trace,"hdrcheup");
7796 return card->header_cache_update(hh,dev,haddr);
7797 }
7798
qeth_rebuild_header(struct sk_buff * skb)7799 static int qeth_rebuild_header(struct sk_buff *skb)
7800 {
7801 qeth_card_t *card;
7802 QETH_DBF_TEXT5(0,trace,"rebldhdr");
7803 if (skb->protocol==__constant_htons(ETH_P_IP)) return 0;
7804
7805 #ifdef QETH_VLAN
7806 if (qeth_verify_dev(skb->dev)==QETH_VERIFY_IS_VLAN_DEV)
7807 card = (qeth_card_t *)VLAN_DEV_INFO(skb->dev)->real_dev->priv;
7808 else
7809 #endif
7810 card=(qeth_card_t*)skb->dev->priv;
7811
7812 return card->rebuild_header(skb);
7813 }
7814
qeth_ipv6_init_card(qeth_card_t * card)7815 static void qeth_ipv6_init_card(qeth_card_t *card)
7816 {
7817 card->hard_header=qeth_get_hard_header(card->link_type);
7818 card->rebuild_header=qeth_get_rebuild_header(card->link_type);
7819 card->hard_header_cache=qeth_get_hard_header_cache(card->link_type);
7820 card->header_cache_update=
7821 qeth_get_header_cache_update(card->link_type);
7822 card->type_trans=qeth_get_type_trans(card->link_type);
7823 }
7824 #endif /* QETH_IPV6 */
7825
7826 #ifdef QETH_VLAN
qeth_vlan_rx_register(struct net_device * dev,struct vlan_group * grp)7827 static void qeth_vlan_rx_register(struct net_device *dev,
7828 struct vlan_group *grp)
7829 {
7830 qeth_card_t *card;
7831 card = (qeth_card_t *)dev->priv;
7832 spin_lock_irq(&card->vlan_lock);
7833 card->vlangrp = grp;
7834 spin_unlock_irq(&card->vlan_lock);
7835 }
qeth_vlan_rx_kill_vid(struct net_device * dev,unsigned short vid)7836 static void qeth_vlan_rx_kill_vid(struct net_device *dev,
7837 unsigned short vid)
7838 {
7839 qeth_card_t *card;
7840 card = (qeth_card_t *)dev->priv;
7841 spin_lock_irq(&card->vlan_lock);
7842 if (card->vlangrp)
7843 card->vlangrp->vlan_devices[vid] = NULL;
7844 spin_unlock_irq(&card->vlan_lock);
7845 }
7846
7847 #endif /*QETH_VLAN*/
7848
7849
qeth_tx_timeout(struct net_device * dev)7850 static void qeth_tx_timeout(struct net_device *dev)
7851 {
7852 char dbf_text[15];
7853 qeth_card_t *card;
7854
7855 card=(qeth_card_t *)dev->priv;
7856 sprintf(dbf_text,"XMTO%4x",card->irq0);
7857 QETH_DBF_TEXT2(1,trace,dbf_text);
7858 card->stats->tx_errors++;
7859 atomic_set(&card->problem,PROBLEM_TX_TIMEOUT);
7860 qeth_schedule_recovery(card);
7861 }
7862
qeth_init_dev(struct net_device * dev)7863 static int qeth_init_dev(struct net_device *dev)
7864 {
7865 qeth_card_t *card;
7866 char dbf_text[15];
7867
7868 card=(qeth_card_t *)dev->priv;
7869
7870 sprintf(dbf_text,"inid%4x",card->irq0);
7871 QETH_DBF_TEXT3(0,trace,dbf_text);
7872
7873 dev->tx_timeout=&qeth_tx_timeout;
7874 dev->watchdog_timeo=QETH_TX_TIMEOUT;
7875 dev->open=qeth_open;
7876 dev->stop=qeth_stop;
7877 dev->set_config=qeth_set_config;
7878 dev->hard_start_xmit=qeth_hard_start_xmit;
7879 dev->do_ioctl=qeth_do_ioctl;
7880 dev->get_stats=qeth_get_stats;
7881 dev->change_mtu=qeth_change_mtu;
7882 #ifdef QETH_VLAN
7883 dev->vlan_rx_register = qeth_vlan_rx_register;
7884 dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
7885 #endif
7886
7887 dev->rebuild_header=
7888 #ifdef QETH_IPV6
7889 (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))?
7890 (qeth_get_rebuild_header(card->link_type)?
7891 qeth_rebuild_header:NULL):
7892 #endif /* QETH_IPV6 */
7893 NULL;
7894 dev->hard_header=
7895 #ifdef QETH_IPV6
7896 (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))?
7897 (qeth_get_hard_header(card->link_type)?
7898 qeth_hard_header:NULL):
7899 #else /* QETH_IPV6 */
7900 (card->options.fake_ll==FAKE_LL)?qeth_fake_header:
7901 #endif /* QETH_IPV6 */
7902 NULL;
7903 dev->header_cache_update=
7904 #ifdef QETH_IPV6
7905 (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))?
7906 (qeth_get_header_cache_update(card->link_type)?
7907 qeth_header_cache_update:NULL):
7908 #endif /* QETH_IPV6 */
7909 NULL;
7910 dev->hard_header_cache=
7911 #ifdef QETH_IPV6
7912 (!(qeth_get_additional_dev_flags(card->type)&IFF_NOARP))?
7913 qeth_get_hard_header_cache(card->link_type):
7914 #endif /* QETH_IPV6 */
7915 NULL;
7916 dev->hard_header_parse=NULL;
7917 dev->destructor=qeth_destructor;
7918 dev->set_multicast_list=qeth_set_multicast_list;
7919 dev->set_mac_address=qeth_set_mac_address;
7920 dev->neigh_setup=qeth_neigh_setup;
7921
7922 dev->flags|=qeth_get_additional_dev_flags(card->type);
7923
7924 dev->flags|=(
7925 (card->options.fake_broadcast==FAKE_BROADCAST)||
7926 (card->broadcast_capable)
7927 )?
7928 IFF_BROADCAST:0;
7929
7930 /* is done in hardsetup_card... see comment below
7931 qeth_send_qipassist(card,4);*/
7932
7933 /* that was the old place. one id. we need to make sure, that
7934 * OSA knows about us going to use the same id again, so we
7935 * do that in hardsetup_card every time
7936 qeth_get_unique_id(card);*/
7937
7938 #ifdef CONFIG_SHARED_IPV6_CARDS
7939 dev->features=(card->unique_id&UNIQUE_ID_NOT_BY_CARD)?
7940 0:NETIF_F_SHARED_IPV6;
7941 dev->dev_id=card->unique_id&0xffff;
7942 #endif /* CONFIG_SHARED_IPV6_CARDS */
7943
7944 dev->tx_queue_len=qeth_get_device_tx_q_len(card->type);
7945 dev->hard_header_len=qeth_get_hlen(card->link_type)+
7946 card->options.add_hhlen;
7947 dev->addr_len=OSA_ADDR_LEN; /* is ok for eth, tr, atm lane */
7948 netif_start_queue(dev);
7949
7950 dev->mtu=card->initial_mtu;
7951
7952 #ifdef QETH_IPV6
7953 qeth_ipv6_init_card(card);
7954 #endif /* QETH_IPV6 */
7955
7956 dev_init_buffers(dev);
7957
7958 return 0;
7959 }
7960
qeth_get_unitaddr(qeth_card_t * card)7961 static int qeth_get_unitaddr(qeth_card_t *card)
7962 {
7963 char *prcd;
7964 int result=0;
7965 char dbf_text[15];
7966 int length;
7967
7968 sprintf(dbf_text,"gtua%4x",card->irq0);
7969 QETH_DBF_TEXT2(0,trace,dbf_text);
7970
7971 result = read_conf_data(card->irq2, (void **)&prcd, &length, 0);
7972 if (result) {
7973 sprintf(dbf_text, "rcd%4x", result);
7974 QETH_DBF_TEXT3(0, trace, dbf_text);
7975 PRINT_ERR("read_conf_data for sch %x returned %i\n",
7976 card->irq2, result);
7977 goto exit;
7978 }
7979
7980 card->chpid = prcd[30];
7981 card->unit_addr2 = prcd[31];
7982 card->cula = prcd[63];
7983 /* Don't build queues with diag98 for VM guest lan. */
7984 card->is_guest_lan= ((prcd[0x10]==_ascebc['V']) &&
7985 (prcd[0x11]==_ascebc['M']));
7986 card->do_pfix = (MACHINE_HAS_PFIX) ? (!(card->is_guest_lan)):0;
7987
7988 sprintf(dbf_text,"chpid:%02x",card->chpid);
7989 QETH_DBF_TEXT2(0,trace,dbf_text);
7990 sprintf(dbf_text,"unad2:%02x",card->unit_addr2);
7991 QETH_DBF_TEXT2(0,trace,dbf_text);
7992 sprintf(dbf_text,"cula:%02x",card->cula);
7993 QETH_DBF_TEXT2(0,trace,dbf_text);
7994
7995 result=0;
7996
7997 exit:
7998 return result;
7999 }
8000
qeth_send_nops(qeth_card_t * card)8001 static int qeth_send_nops(qeth_card_t *card)
8002 {
8003 int result,result2;
8004 char dbf_text[15];
8005 int irq;
8006 unsigned long saveflags;
8007
8008 card->dma_stuff->write_ccw.cmd_code=CCW_NOP_CMD;
8009 card->dma_stuff->write_ccw.flags=CCW_FLAG_SLI;
8010 card->dma_stuff->write_ccw.count=CCW_NOP_COUNT;
8011 card->dma_stuff->write_ccw.cda=(unsigned long)NULL;
8012
8013 #define DO_SEND_NOP(subchannel) \
8014 do { \
8015 irq=subchannel; \
8016 sprintf(dbf_text,"snnp%4x",irq); \
8017 QETH_DBF_TEXT3(0,trace,dbf_text); \
8018 \
8019 s390irq_spin_lock_irqsave(irq,saveflags); \
8020 result=do_IO(irq,&card->dma_stuff->write_ccw,NOP_STATE,0,0); \
8021 if (result) { \
8022 qeth_delay_millis(QETH_WAIT_BEFORE_2ND_DOIO); \
8023 result2=do_IO(irq,&card->dma_stuff->write_ccw, \
8024 NOP_STATE,0,0); \
8025 PRINT_WARN("qeth_send_nops on irq 0x%x: do_IO returned %i, " \
8026 "next try returns %i\n", \
8027 irq,result,result2); \
8028 result=result2; \
8029 } \
8030 s390irq_spin_unlock_irqrestore(irq,saveflags); \
8031 \
8032 if (result) goto exit; \
8033 \
8034 if (qeth_sleepon(card,QETH_NOP_TIMEOUT)) { \
8035 QETH_DBF_TEXT2(0,trace,"snnp:tme"); \
8036 result=-EIO; \
8037 goto exit; \
8038 } \
8039 } while (0)
8040
8041 DO_SEND_NOP(card->irq0);
8042 DO_SEND_NOP(card->irq1);
8043 DO_SEND_NOP(card->irq2);
8044
8045 exit:
8046 return result;
8047 }
8048
qeth_clear_card_structures(qeth_card_t * card)8049 static void qeth_clear_card_structures(qeth_card_t *card)
8050 {
8051 int i,j;
8052 char dbf_text[15];
8053
8054 if (!card) {
8055 QETH_DBF_TEXT2(0,trace,"clrCRDnc");
8056 return;
8057 }
8058
8059 sprintf(dbf_text,"clcs%4x",card->irq0);
8060 QETH_DBF_TEXT3(0,trace,dbf_text);
8061
8062 atomic_set(&card->is_startlaned,0);
8063
8064 for (i=0;i<QETH_MAX_QUEUES;i++) {
8065 card->send_state[i]=SEND_STATE_DONT_PACK;
8066 card->outbound_first_free_buffer[i]=0;
8067 atomic_set(&card->outbound_used_buffers[i],0);
8068 atomic_set(&card->outbound_ringbuffer_lock[i],0);
8069
8070 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
8071 card->outbound_buffer_send_state[i][j]=
8072 SEND_STATE_DONT_PACK;
8073 card->send_retries[i][j]=0;
8074
8075 if (i<card->no_queues) {
8076 card->outbound_ringbuffer[i]->
8077 ringbuf_element[j].
8078 next_element_to_fill=0;
8079 card->outbound_bytes_in_buffer[i]=0;
8080 skb_queue_head_init(&card->
8081 outbound_ringbuffer[i]->
8082 ringbuf_element[j].
8083 skb_list);
8084 }
8085 }
8086 }
8087
8088 for (i=0;i<card->options.inbound_buffer_count;i++) {
8089 xchg((int*)&card->inbound_buffer_pool_entry_used[i],
8090 BUFFER_UNUSED);
8091 }
8092
8093 spin_lock_init(&card->requeue_input_lock);
8094 atomic_set(&card->requeue_position,0);
8095 atomic_set(&card->requeue_counter,0);
8096
8097 card->seqno.trans_hdr=0;
8098 card->seqno.pdu_hdr=0;
8099 card->seqno.pdu_hdr_ack=0;
8100 card->seqno.ipa=0;
8101
8102 qeth_clear_ifa4_list(&card->ip_current_state.ip_ifa);
8103 qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa);
8104 qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm_ifa);
8105 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa);
8106
8107 #ifdef QETH_IPV6
8108 qeth_clear_ifa6_list(&card->ip_current_state.ip6_ifa);
8109 qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa);
8110 qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm6_ifa);
8111 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa);
8112 #endif /* QETH_IPV6 */
8113 }
8114
qeth_init_input_buffers(qeth_card_t * card)8115 static void qeth_init_input_buffers(qeth_card_t *card)
8116 {
8117 int i;
8118
8119 /* slowly, slowly (we don't want to enqueue all buffers
8120 * at one time) */
8121 for (i=0;i<QDIO_MAX_BUFFERS_PER_Q;i++) {
8122 atomic_set(&card->inbound_buffer_refcnt[i],1);
8123 }
8124 for (i=0;i<QDIO_MAX_BUFFERS_PER_Q;i++) {
8125 atomic_set(&card->inbound_buffer_refcnt[i],0);
8126 /* only try to queue as many buffers as we have at all */
8127 if (i<card->options.inbound_buffer_count) {
8128 qeth_queue_input_buffer(card,i,0);
8129 }
8130 }
8131 qdio_synchronize(card->irq2,QDIO_FLAG_SYNC_INPUT,0);
8132 }
8133
8134 /* initializes all the structures for a card */
qeth_hardsetup_card(qeth_card_t * card,int in_recovery)8135 static int qeth_hardsetup_card(qeth_card_t *card,int in_recovery)
8136 {
8137 int result,q,breakout;
8138 unsigned long flags;
8139 int laps=QETH_HARDSETUP_LAPS;
8140 int clear_laps;
8141 int cleanup_qdio;
8142 char dbf_text[15];
8143 int i,r;
8144
8145 /* setup name and so on */
8146 atomic_set(&card->shutdown_phase,0);
8147
8148 if (atomic_read(&card->is_hardsetup)) {
8149 sprintf(dbf_text,"hscd%4x",card->irq0);
8150 QETH_DBF_TEXT2(1,trace,dbf_text);
8151 PRINT_ALL("card is already hardsetup.\n");
8152 return 0;
8153 }
8154
8155 cleanup_qdio=in_recovery; /* if we are in recovery, we clean
8156 the qdio stuff up */
8157
8158 my_spin_lock(&card->hardsetup_lock);
8159 atomic_set(&card->write_busy,0);
8160
8161 do {
8162 if (in_recovery) {
8163 PRINT_STUPID("qeth: recovery: quiescing %s...\n",
8164 card->dev_name);
8165 sprintf(dbf_text,"Rqsc%4x",card->irq0);
8166 QETH_DBF_TEXT2(0,trace,dbf_text);
8167 qeth_wait_nonbusy(QETH_QUIESCE_WAIT_BEFORE_CLEAR);
8168 }
8169 clear_laps=QETH_HARDSETUP_CLEAR_LAPS;
8170 do {
8171 if (in_recovery)
8172 PRINT_STUPID("clearing card %s\n",
8173 card->dev_name);
8174 qeth_clear_card(card,cleanup_qdio,
8175 (card->type==QETH_CARD_TYPE_OSAE));
8176 result=qeth_send_nops(card);
8177 breakout=atomic_read(&card->break_out);
8178 } while ( (--clear_laps) && (result) );
8179 if (result) {
8180 goto exit;
8181 }
8182
8183 if (in_recovery) {
8184 PRINT_STUPID("qeth: recovery: still quiescing %s...\n",
8185 card->dev_name);
8186 sprintf(dbf_text,"RQsc%4x",card->irq0);
8187 QETH_DBF_TEXT2(0,trace,dbf_text);
8188 qeth_wait_nonbusy(QETH_QUIESCE_WAIT_AFTER_CLEAR);
8189 } else {
8190 atomic_set(&card->shutdown_phase,0);
8191 }
8192
8193 cleanup_qdio=0; /* qdio was cleaned now, if necessary */
8194
8195 result=qeth_get_unitaddr(card);
8196 if (result) goto exit;
8197
8198 qeth_generate_tokens(card);
8199
8200 #define PRINT_TOKENS do { \
8201 sprintf(dbf_text,"stra "); \
8202 memcpy(&dbf_text[4],&card->seqno.trans_hdr,4); \
8203 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8204 sprintf(dbf_text,"spdu "); \
8205 memcpy(&dbf_text[4],&card->seqno.pdu_hdr,4); \
8206 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8207 sprintf(dbf_text,"spda "); \
8208 memcpy(&dbf_text[4],&card->seqno.pdu_hdr_ack,4); \
8209 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8210 sprintf(dbf_text,"sipa "); \
8211 memcpy(&dbf_text[4],&card->seqno.ipa,4); \
8212 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8213 sprintf(dbf_text,"tisw "); \
8214 memcpy(&dbf_text[4],&card->token.issuer_rm_w,4); \
8215 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8216 sprintf(dbf_text,"tisr "); \
8217 memcpy(&dbf_text[4],&card->token.issuer_rm_r,4); \
8218 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8219 sprintf(dbf_text,"tcfw "); \
8220 memcpy(&dbf_text[4],&card->token.cm_filter_w,4); \
8221 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8222 sprintf(dbf_text,"tcfr "); \
8223 memcpy(&dbf_text[4],&card->token.cm_filter_r,4); \
8224 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8225 sprintf(dbf_text,"tccw "); \
8226 memcpy(&dbf_text[4],&card->token.cm_connection_w,4); \
8227 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8228 sprintf(dbf_text,"tccr "); \
8229 memcpy(&dbf_text[4],&card->token.cm_connection_r,4); \
8230 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8231 sprintf(dbf_text,"tufw "); \
8232 memcpy(&dbf_text[4],&card->token.ulp_filter_w,4); \
8233 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8234 sprintf(dbf_text,"tufr "); \
8235 memcpy(&dbf_text[4],&card->token.ulp_filter_r,4); \
8236 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8237 sprintf(dbf_text,"tucw "); \
8238 memcpy(&dbf_text[4],&card->token.ulp_connection_w,4); \
8239 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8240 sprintf(dbf_text,"tucr "); \
8241 memcpy(&dbf_text[4],&card->token.ulp_connection_r,4); \
8242 QETH_DBF_HEX3(0,trace,dbf_text,QETH_DBF_TRACE_LEN); \
8243 } while (0)
8244 PRINT_TOKENS;
8245
8246 /* card->break_out and problem will be set here to 0
8247 * (in each lap) (there can't be a problem at this
8248 * early time) */
8249 atomic_set(&card->problem,0);
8250 atomic_set(&card->break_out,0);
8251
8252 #define CHECK_ERRORS \
8253 breakout=atomic_read(&card->break_out); \
8254 if (breakout==QETH_BREAKOUT_AGAIN) \
8255 continue; \
8256 else if (breakout==QETH_BREAKOUT_LEAVE) { \
8257 result=-EIO; \
8258 goto exit; \
8259 } \
8260 if (result) goto exit
8261
8262 QETH_DBF_TEXT2(0,trace,"hsidxard");
8263 result=qeth_idx_activate_read(card);
8264 CHECK_ERRORS;
8265
8266 PRINT_TOKENS;
8267 QETH_DBF_TEXT2(0,trace,"hsidxawr");
8268 result=qeth_idx_activate_write(card);
8269 CHECK_ERRORS;
8270
8271 QETH_DBF_TEXT2(0,trace,"hsissurd");
8272 /* from here, there will always be an outstanding read */
8273 s390irq_spin_lock_irqsave(card->irq0,flags);
8274 qeth_issue_next_read(card);
8275 s390irq_spin_unlock_irqrestore(card->irq0,flags);
8276
8277 PRINT_TOKENS;
8278 QETH_DBF_TEXT2(0,trace,"hscmenab");
8279 result=qeth_cm_enable(card);
8280 CHECK_ERRORS;
8281
8282 PRINT_TOKENS;
8283 QETH_DBF_TEXT2(0,trace,"hscmsetu");
8284 result=qeth_cm_setup(card);
8285 CHECK_ERRORS;
8286
8287 PRINT_TOKENS;
8288 QETH_DBF_TEXT2(0,trace,"hsulpena");
8289 result=qeth_ulp_enable(card);
8290 CHECK_ERRORS;
8291
8292 PRINT_TOKENS;
8293 QETH_DBF_TEXT2(0,trace,"hsulpset");
8294 result=qeth_ulp_setup(card);
8295 CHECK_ERRORS;
8296
8297 cleanup_qdio=1;
8298
8299 QETH_DBF_TEXT2(0,trace,"hsqdioes");
8300 result=qeth_qdio_establish(card);
8301 CHECK_ERRORS;
8302
8303 PRINT_TOKENS;
8304 QETH_DBF_TEXT2(0,trace,"hsqdioac");
8305 result=qeth_qdio_activate(card);
8306 CHECK_ERRORS;
8307
8308 PRINT_TOKENS;
8309 QETH_DBF_TEXT2(0,trace,"hsdmact");
8310 result=qeth_dm_act(card);
8311 CHECK_ERRORS;
8312 } while ( (laps--) && (breakout==QETH_BREAKOUT_AGAIN) );
8313 if (breakout==QETH_BREAKOUT_AGAIN) {
8314 sprintf(dbf_text,"hsnr%4x",card->irq0);
8315 QETH_DBF_TEXT2(0,trace,dbf_text);
8316 printk("qeth: recovery not successful on device " \
8317 "0x%X/0x%X/0x%X; giving up.\n",
8318 card->devno0,card->devno1,card->devno2);
8319 result=-EIO;
8320 goto exit;
8321 }
8322
8323 qeth_clear_ifa4_list(&card->ip_current_state.ip_ifa);
8324 qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa);
8325 qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm_ifa);
8326 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa);
8327
8328 #ifdef QETH_IPV6
8329 qeth_clear_ifa6_list(&card->ip_current_state.ip6_ifa);
8330 qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa);
8331 qeth_clear_ifamc_list(&card->ip_mc_current_state.ipm6_ifa);
8332 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa);
8333 #endif /* QETH_IPV6 */
8334
8335 if (!atomic_read(&card->is_registered)) {
8336 card->dev->dev_addr[0]=0; /* we don't know the mac addr yet */
8337 card->dev->dev_addr[1]=0;
8338 card->dev->dev_addr[2]=0;
8339 card->dev->dev_addr[3]=0;
8340 card->dev->dev_addr[4]=0;
8341 card->dev->dev_addr[5]=0;
8342 card->dev->broadcast[0]=card->dev->broadcast[1]=0xff;
8343 card->dev->broadcast[2]=card->dev->broadcast[3]=0xff;
8344 card->dev->broadcast[4]=card->dev->broadcast[5]=0xff;
8345
8346 card->dev->type=qeth_get_arphrd_type(card->type,
8347 card->link_type);
8348
8349 card->dev->init=qeth_init_dev;
8350
8351 if (card->options.memusage==MEMUSAGE_CONTIG) {
8352 card->easy_copy_cap=
8353 qeth_determine_easy_copy_cap(card->type);
8354 } else card->easy_copy_cap=0;
8355 card->ipa_timeout=qeth_get_ipa_timeout(card->type);
8356 }
8357
8358 atomic_set(&card->is_hardsetup,1);
8359 atomic_set(&card->is_softsetup,0);
8360 atomic_set(&card->startlan_attempts,1);
8361
8362 for (q=0;q<card->no_queues;q++)
8363 card->send_state[q]=SEND_STATE_DONT_PACK;
8364
8365 /* here we need to know, whether we should include a value
8366 * into eui-64 address generation */
8367 QETH_DBF_TEXT2(0,trace,"qipassi4");
8368 r=qeth_send_qipassist(card,4);
8369 if (r) {
8370 PRINT_WARN("couldn't send QIPASSIST4 on %s: " \
8371 "0x%x\n",card->dev_name,r);
8372 sprintf(dbf_text,"QIP4%4x",r);
8373 QETH_DBF_TEXT2(0,trace,dbf_text);
8374 }
8375
8376 sprintf(dbf_text,"%8x",card->ipa_supported);
8377 QETH_DBF_TEXT2(0,trace,dbf_text);
8378 sprintf(dbf_text,"%8x",card->ipa_enabled);
8379 QETH_DBF_TEXT2(0,trace,dbf_text);
8380
8381 qeth_correct_routing_status(card);
8382
8383 qeth_get_unique_id(card);
8384
8385 /* print out status */
8386 if (in_recovery) {
8387 qeth_clear_card_structures(card);
8388 qeth_init_input_buffers(card);
8389 QETH_DBF_TEXT1(0,trace,"RECOVSUC");
8390 printk("qeth: recovered device 0x%X/0x%X/0x%X (%s) " \
8391 "successfully.\n",
8392 card->devno0,card->devno1,card->devno2,
8393 card->dev_name);
8394 } else {
8395 QETH_DBF_TEXT2(0,trace,"hrdsetok");
8396
8397 switch (card->type) {
8398 case QETH_CARD_TYPE_OSAE:
8399 /* VM will use a non-zero first character to indicate
8400 * a HiperSockets like reporting of the level
8401 * OSA sets the first character to zero */
8402 if (!card->level[0]) {
8403 sprintf(card->level,"%02x%02x",card->level[2],
8404 card->level[3]);
8405 card->level[QETH_MCL_LENGTH]=0;
8406 break;
8407 } else {
8408 /* fallthrough */
8409 }
8410 case QETH_CARD_TYPE_IQD:
8411 card->level[0]=(char)_ebcasc[(__u8)card->level[0]];
8412 card->level[1]=(char)_ebcasc[(__u8)card->level[1]];
8413 card->level[2]=(char)_ebcasc[(__u8)card->level[2]];
8414 card->level[3]=(char)_ebcasc[(__u8)card->level[3]];
8415 card->level[QETH_MCL_LENGTH]=0;
8416 break;
8417 default:
8418 memset(&card->level[0],0,QETH_MCL_LENGTH+1);
8419 }
8420
8421 sprintf(dbf_text,"lvl:%s",card->level);
8422 QETH_DBF_TEXT2(0,setup,dbf_text);
8423
8424 if (card->portname_required) {
8425 sprintf(dbf_text,"%s",card->options.portname+1);
8426 for (i=0;i<8;i++)
8427 dbf_text[i]=(char)_ebcasc[(__u8)dbf_text[i]];
8428 dbf_text[8]=0;
8429 printk("qeth: Device 0x%X/0x%X/0x%X is a%s " \
8430 "card%s%s%s\n" \
8431 "with link type %s (portname: %s)\n",
8432 card->devno0,card->devno1,card->devno2,
8433 qeth_get_cardname(card->type,
8434 card->is_guest_lan),
8435 (card->level[0])?" (level: ":"",
8436 (card->level[0])?card->level:"",
8437 (card->level[0])?")":"",
8438 qeth_get_link_type_name(card->type,
8439 card->link_type),
8440 dbf_text);
8441 } else {
8442 if (card->options.portname[0]) {
8443 printk("qeth: Device 0x%X/0x%X/0x%X is a%s " \
8444 "card%s%s%s\nwith link type %s " \
8445 "(no portname needed by interface)\n",
8446 card->devno0,card->devno1,card->devno2,
8447 qeth_get_cardname(card->type,
8448 card->is_guest_lan),
8449 (card->level[0])?" (level: ":"",
8450 (card->level[0])?card->level:"",
8451 (card->level[0])?")":"",
8452 qeth_get_link_type_name(card->type,
8453 card->
8454 link_type));
8455 } else {
8456 printk("qeth: Device 0x%X/0x%X/0x%X is a%s " \
8457 "card%s%s%s\nwith link type %s\n",
8458 card->devno0,card->devno1,card->devno2,
8459 qeth_get_cardname(card->type,
8460 card->is_guest_lan),
8461 (card->level[0])?" (level: ":"",
8462 (card->level[0])?card->level:"",
8463 (card->level[0])?")":"",
8464 qeth_get_link_type_name(card->type,
8465 card->
8466 link_type));
8467 }
8468 }
8469 }
8470
8471 exit:
8472 my_spin_unlock(&card->hardsetup_lock);
8473 return result;
8474 }
8475
qeth_reinit_thread(void * param)8476 static int qeth_reinit_thread(void *param)
8477 {
8478 qeth_card_t *card=(qeth_card_t*)param;
8479 int already_registered;
8480 int already_hardsetup;
8481 int retry=QETH_RECOVERY_HARDSETUP_RETRY;
8482 int result;
8483 char dbf_text[15];
8484 char name[15];
8485
8486 sprintf(dbf_text,"RINI%4x",card->irq0);
8487 QETH_DBF_TEXT1(0,trace,dbf_text);
8488
8489 daemonize();
8490
8491 /* set a nice name ... */
8492 sprintf(name, "qethrinid%04x", card->irq0);
8493 strcpy(current->comm, name);
8494
8495 if (atomic_read(&card->shutdown_phase)) goto out_wakeup;
8496 down_interruptible(&card->reinit_thread_sem);
8497 if (atomic_read(&card->shutdown_phase)) goto out_wakeup;
8498
8499 QETH_DBF_TEXT1(0,trace,"ri-gotin");
8500 PRINT_STUPID("entering recovery (reinit) thread for device %s\n",
8501 card->dev_name);
8502
8503 atomic_set(&card->is_startlaned,0);
8504 atomic_set(&card->is_softsetup,0);
8505
8506 my_read_lock(&list_lock);
8507 if (!qeth_verify_card(card)) goto out;
8508 QETH_DBF_TEXT1(0,trace,"ri-vrfd");
8509
8510 atomic_set(&card->write_busy,0);
8511 qeth_set_dev_flag_norunning(card);
8512 already_hardsetup=atomic_read(&card->is_hardsetup);
8513 already_registered=atomic_read(&card->is_registered);
8514 if (already_hardsetup) {
8515 atomic_set(&card->is_hardsetup,0);
8516
8517 if (-1==my_spin_lock_nonbusy(card,&setup_lock)) goto out;
8518 if (atomic_read(&card->shutdown_phase)) goto out_wakeup;
8519
8520 atomic_set(&card->escape_softsetup,1);
8521 if (-1==my_spin_lock_nonbusy(card,&card->softsetup_lock)) {
8522 atomic_set(&card->escape_softsetup,0);
8523 goto out;
8524 }
8525 atomic_set(&card->escape_softsetup,0);
8526 if (atomic_read(&card->shutdown_phase)) {
8527 my_spin_unlock(&card->softsetup_lock);
8528 goto out_wakeup;
8529 }
8530 if (!qeth_verify_card(card)) goto out;
8531
8532 if (already_registered)
8533 netif_stop_queue(card->dev);
8534
8535 qeth_wait_nonbusy(QETH_QUIESCE_NETDEV_TIME);
8536
8537 atomic_set(&card->is_startlaned,0);
8538
8539 QETH_DBF_TEXT1(0,trace,"ri-frskb");
8540 qeth_free_all_skbs(card);
8541 do {
8542 QETH_DBF_TEXT1(0,trace,"ri-hrdst");
8543 result=qeth_hardsetup_card(card,1);
8544 } while (result&&(retry--));
8545
8546 /* tries to remove old ips, that's paranoid, but ok */
8547 qeth_clear_ifa4_list(&card->ip_new_state.ip_ifa);
8548 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm_ifa);
8549
8550 #ifdef QETH_IPV6
8551 qeth_clear_ifa6_list(&card->ip_new_state.ip6_ifa);
8552 qeth_clear_ifamc_list(&card->ip_mc_new_state.ipm6_ifa);
8553 #endif /* QETH_IPV6 */
8554
8555 if (result) {
8556 QETH_DBF_TEXT1(0,trace,"ri-nosuc");
8557 printk("qeth: RECOVERY WAS NOT SUCCESSFUL ON %s " \
8558 "(devnos 0x%X/0x%X/0x%X), GIVING UP, " \
8559 "OUTGOING PACKETS WILL BE DISCARDED!\n",
8560 card->dev_name,card->devno0,
8561 card->devno1,card->devno2);
8562 /* early leave hard_start_xmit! */
8563 atomic_set(&card->is_startlaned,0);
8564 /* show status in /proc/qeth */
8565 atomic_set(&card->is_gone,1);
8566 qeth_snmp_notify();
8567 } else {
8568 QETH_DBF_TEXT1(0,trace,"ri-sftst");
8569 qeth_softsetup_card(card,QETH_LOCK_ALREADY_HELD);
8570 my_spin_unlock(&card->softsetup_lock);
8571
8572 if (!already_registered) {
8573 QETH_DBF_TEXT1(0,trace,"ri-regcd");
8574 qeth_register_netdev(card);
8575 }
8576 qeth_restore_dev_flag_state(card);
8577 atomic_set(&card->is_gone,0);
8578 netif_wake_queue(card->dev);
8579 qeth_snmp_notify();
8580 }
8581 my_spin_unlock(&setup_lock);
8582 }
8583 out:
8584 atomic_set(&card->in_recovery,0);
8585 my_read_unlock(&list_lock);
8586 QETH_DBF_TEXT1(0,trace,"ri-leave");
8587 out_wakeup:
8588 up(&card->reinit_thread_sem);
8589 atomic_dec(&card->reinit_counter);
8590
8591 return 0;
8592 }
8593
qeth_fill_qeth_card_options(qeth_card_t * card)8594 static void qeth_fill_qeth_card_options(qeth_card_t *card)
8595 {
8596 int i;
8597
8598 card->options.portname[0]=0;
8599 for (i=1;i<9;i++)
8600 card->options.portname[i]=_ascebc[' '];
8601 strcpy(card->options.devname," ");
8602 card->options.routing_type4=NO_ROUTER;
8603 #ifdef QETH_IPV6
8604 card->options.routing_type6=NO_ROUTER;
8605 #endif /* QETH_IPV6 */
8606 card->options.portno=0;
8607 card->options.checksum_type=QETH_CHECKSUM_DEFAULT;
8608 card->options.do_prio_queueing=0;
8609 card->options.default_queue=QETH_DEFAULT_QUEUE;
8610 card->options.inbound_buffer_count=DEFAULT_BUFFER_COUNT;
8611 card->options.polltime=QETH_MAX_INPUT_THRESHOLD;
8612 card->options.memusage=MEMUSAGE_DISCONTIG;
8613 card->options.macaddr_mode=MACADDR_NONCANONICAL;
8614 card->options.broadcast_mode=BROADCAST_ALLRINGS;
8615 card->options.fake_broadcast=DONT_FAKE_BROADCAST;
8616 card->options.ena_ipat=ENABLE_TAKEOVER;
8617 card->options.add_hhlen=DEFAULT_ADD_HHLEN;
8618 card->options.fake_ll=DONT_FAKE_LL;
8619 card->options.async_iqd=SYNC_IQD;
8620 }
8621
qeth_alloc_card(void)8622 static qeth_card_t *qeth_alloc_card(void)
8623 {
8624 qeth_card_t *card;
8625
8626 QETH_DBF_TEXT3(0,trace,"alloccrd");
8627 card=(qeth_card_t *)vmalloc(sizeof(qeth_card_t));
8628 if (!card) goto exit_card;
8629 memset(card,0,sizeof(qeth_card_t));
8630 init_waitqueue_head(&card->wait_q);
8631 init_waitqueue_head(&card->ioctl_wait_q);
8632
8633 qeth_fill_qeth_card_options(card);
8634
8635 card->dma_stuff=(qeth_dma_stuff_t*)kmalloc(sizeof(qeth_dma_stuff_t),
8636 GFP_DMA);
8637 if (!card->dma_stuff) goto exit_dma;
8638 memset(card->dma_stuff,0,sizeof(qeth_dma_stuff_t));
8639
8640 card->dma_stuff->recbuf=(char*)kmalloc(QETH_BUFSIZE,GFP_DMA);
8641 if (!card->dma_stuff->recbuf) goto exit_dma1;
8642 memset(card->dma_stuff->recbuf,0,QETH_BUFSIZE);
8643
8644 card->dma_stuff->sendbuf=(char*)kmalloc(QETH_BUFSIZE,GFP_DMA);
8645 if (!card->dma_stuff->sendbuf) goto exit_dma2;
8646 memset(card->dma_stuff->sendbuf,0,QETH_BUFSIZE);
8647
8648 card->dev=(struct net_device *)kmalloc(sizeof(struct net_device),
8649 GFP_KERNEL);
8650 if (!card->dev) goto exit_dev;
8651 memset(card->dev,0,sizeof(struct net_device));
8652
8653 card->stats=(struct net_device_stats *)kmalloc(
8654 sizeof(struct net_device_stats),GFP_KERNEL);
8655 if (!card->stats) goto exit_stats;
8656 memset(card->stats,0,sizeof(struct net_device_stats));
8657
8658 card->devstat0=(devstat_t *)kmalloc(sizeof(devstat_t),GFP_KERNEL);
8659 if (!card->devstat0) goto exit_stats;
8660 memset(card->devstat0,0,sizeof(devstat_t));
8661
8662 card->devstat1=(devstat_t *)kmalloc(sizeof(devstat_t),GFP_KERNEL);
8663 if (!card->devstat1) {
8664 kfree(card->devstat0);
8665 goto exit_stats;
8666 }
8667 memset(card->devstat1,0,sizeof(devstat_t));
8668
8669 card->devstat2=(devstat_t *)kmalloc(sizeof(devstat_t),GFP_KERNEL);
8670 if (!card->devstat2) {
8671 kfree(card->devstat1);
8672 kfree(card->devstat0);
8673 goto exit_stats;
8674 }
8675 memset(card->devstat2,0,sizeof(devstat_t));
8676
8677 spin_lock_init(&card->wait_q_lock);
8678 spin_lock_init(&card->softsetup_lock);
8679 spin_lock_init(&card->hardsetup_lock);
8680 sema_init(&card->ioctl_sem, 1);
8681
8682 #ifdef QETH_VLAN
8683 spin_lock_init(&card->vlan_lock);
8684 card->vlangrp = NULL;
8685 #endif
8686 card->unique_id=0;
8687 sema_init(&card->reinit_thread_sem,0);
8688 up(&card->reinit_thread_sem);
8689
8690 /* setup card stuff */
8691 card->ip_current_state.ip_ifa=NULL;
8692 card->ip_new_state.ip_ifa=NULL;
8693 card->ip_mc_current_state.ipm_ifa=NULL;
8694 card->ip_mc_new_state.ipm_ifa=NULL;
8695
8696 #ifdef QETH_IPV6
8697 card->ip_current_state.ip6_ifa=NULL;
8698 card->ip_new_state.ip6_ifa=NULL;
8699 card->ip_mc_current_state.ipm6_ifa=NULL;
8700 card->ip_mc_new_state.ipm6_ifa=NULL;
8701 #endif /* QETH_IPV6 */
8702
8703 card->csum_enable_mask=IPA_CHECKSUM_DEFAULT_ENABLE_MASK;
8704
8705 /* setup net_device stuff */
8706 card->dev->priv=card;
8707
8708 strncpy(card->dev->name,card->dev_name,IFNAMSIZ);
8709
8710 /* setup net_device_stats stuff */
8711 /* =nothing yet */
8712
8713 /* and return to the sender */
8714 return card;
8715
8716 /* these are quick exits in case of failures of the kmallocs */
8717 exit_stats:
8718 kfree(card->dev);
8719 exit_dev:
8720 kfree(card->dma_stuff->sendbuf);
8721 exit_dma2:
8722 kfree(card->dma_stuff->recbuf);
8723 exit_dma1:
8724 kfree(card->dma_stuff);
8725 exit_dma:
8726 kfree(card);
8727 exit_card:
8728 return NULL;
8729 }
8730
qeth_init_ringbuffers1(qeth_card_t * card)8731 static int qeth_init_ringbuffers1(qeth_card_t *card)
8732 {
8733 int i,j;
8734 char dbf_text[15];
8735
8736 sprintf(dbf_text,"irb1%4x",card->irq0);
8737 QETH_DBF_TEXT3(0,trace,dbf_text);
8738
8739 for (i=0;i<card->no_queues;i++) {
8740 card->outbound_ringbuffer[i]=
8741 vmalloc(sizeof(qeth_ringbuffer_t));
8742 if (!card->outbound_ringbuffer[i]) {
8743 for (j=i-1;j>=0;j--) {
8744 vfree(card->outbound_ringbuffer[j]);
8745 card->outbound_ringbuffer[j]=NULL;
8746 }
8747 return -ENOMEM;
8748 }
8749 memset(card->outbound_ringbuffer[i],0,
8750 sizeof(qeth_ringbuffer_t));
8751 for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++)
8752 skb_queue_head_init(&card->outbound_ringbuffer[i]->
8753 ringbuf_element[j].skb_list);
8754 }
8755
8756 return 0;
8757 }
8758
qeth_init_ringbuffers2(qeth_card_t * card)8759 static int qeth_init_ringbuffers2(qeth_card_t *card)
8760 {
8761 int i,j;
8762 int failed=0;
8763 char dbf_text[15];
8764 int discont_mem,element_count;
8765 long alloc_size;
8766
8767 sprintf(dbf_text,"irb2%4x",card->irq0);
8768 QETH_DBF_TEXT3(0,trace,dbf_text);
8769
8770 discont_mem=(card->options.memusage==MEMUSAGE_DISCONTIG);
8771 element_count=(discont_mem)?BUFFER_MAX_ELEMENTS:1;
8772 alloc_size=(discont_mem)?PAGE_SIZE:BUFFER_SIZE;
8773 if (discont_mem) {
8774 for (i=0;i<card->options.inbound_buffer_count;i++) {
8775 for (j=0;j<element_count;j++) {
8776 card->inbound_buffer_pool_entry[i][j]=
8777 kmalloc(alloc_size,GFP_KERNEL);
8778 if (!card->inbound_buffer_pool_entry[i][j]) {
8779 failed=1;
8780 goto out;
8781 }
8782 }
8783 card->inbound_buffer_pool_entry_used[i]=BUFFER_UNUSED;
8784 }
8785 } else {
8786 for (i=0;i<card->options.inbound_buffer_count;i++) {
8787 card->inbound_buffer_pool_entry[i][0]=
8788 kmalloc(alloc_size,GFP_KERNEL);
8789 if (!card->inbound_buffer_pool_entry[i][0]) failed=1;
8790 for (j=1;j<element_count;j++)
8791 card->inbound_buffer_pool_entry[i][j]=
8792 card->inbound_buffer_pool_entry[i][0]+
8793 PAGE_SIZE*j;
8794 card->inbound_buffer_pool_entry_used[i]=BUFFER_UNUSED;
8795 }
8796 }
8797
8798 out:
8799 if (failed) {
8800 for (i=0;i<card->options.inbound_buffer_count;i++) {
8801 for (j=0;j<QDIO_MAX_ELEMENTS_PER_BUFFER;j++) {
8802 if (card->inbound_buffer_pool_entry[i][j]) {
8803 if (j<element_count) kfree(card->
8804 inbound_buffer_pool_entry
8805 [i][j]);
8806 card->inbound_buffer_pool_entry
8807 [i][j]=NULL;
8808 }
8809 }
8810 }
8811 for (i=0;i<card->no_queues;i++) {
8812 vfree(card->outbound_ringbuffer[i]);
8813 card->outbound_ringbuffer[i]=NULL;
8814 }
8815 return -ENOMEM;
8816 }
8817
8818 spin_lock_init(&card->requeue_input_lock);
8819
8820 return 0;
8821 }
8822
8823 /* also locked from outside (setup_lock) */
qeth_insert_card_into_list(qeth_card_t * card)8824 static void qeth_insert_card_into_list(qeth_card_t *card)
8825 {
8826 char dbf_text[15];
8827
8828 sprintf(dbf_text,"icil%4x",card->irq0);
8829 QETH_DBF_TEXT3(0,trace,dbf_text);
8830
8831 my_write_lock(&list_lock);
8832 card->next=firstcard;
8833 firstcard=card;
8834 my_write_unlock(&list_lock);
8835 }
8836
qeth_determine_card_type(qeth_card_t * card)8837 static int qeth_determine_card_type(qeth_card_t *card)
8838 {
8839 int i=0;
8840 char dbf_text[15];
8841
8842 while (known_devices[i][4]) {
8843 if ( (card->dev_type==known_devices[i][2]) &&
8844 (card->dev_model==known_devices[i][3]) ) {
8845 card->type=known_devices[i][4];
8846 if (card->options.ena_ipat==ENABLE_TAKEOVER)
8847 card->func_level=known_devices[i][6];
8848 else
8849 card->func_level=known_devices[i][7];
8850 card->no_queues=known_devices[i][8];
8851 card->is_multicast_different=known_devices[i][9];
8852 sprintf(dbf_text,"irq %4x",card->irq0);
8853 QETH_DBF_TEXT2(0,setup,dbf_text);
8854 sprintf(dbf_text,"ctyp%4x",card->type);
8855 QETH_DBF_TEXT2(0,setup,dbf_text);
8856 return 0;
8857 }
8858 i++;
8859 }
8860 card->type=QETH_CARD_TYPE_UNKNOWN;
8861 sprintf(dbf_text,"irq %4x",card->irq0);
8862 QETH_DBF_TEXT2(0,setup,dbf_text);
8863 sprintf(dbf_text,"ctypUNKN");
8864 QETH_DBF_TEXT2(0,setup,dbf_text);
8865 PRINT_ERR("unknown card type on irq x%x\n",card->irq0);
8866 return -ENOENT;
8867 }
8868
qeth_getint(char * s,int longint)8869 static int qeth_getint(char *s,int longint)
8870 {
8871 int cnt;
8872 int hex;
8873 int result;
8874 char c;
8875
8876 if (!s) return -1;
8877 hex=((s[0]=='0')&&( (s[1]=='x') || (s[1]=='X') ))?1:0;
8878 cnt=(hex)?2:0; /* start from the first real digit */
8879 if (!(s[cnt])) return -1;
8880 result=0;
8881 while ((c=s[cnt++])) {
8882 if (hex) {
8883 if (isxdigit(c)) result=result*16+qeth_getxdigit(c);
8884 else return -1;
8885 } else {
8886 if (isdigit(c)) result=result*10+c-'0';
8887 else return -1;
8888 }
8889 /* prevent overflow, 0xffff is enough for us */
8890 if (longint) {
8891 if (result>0xfffffff) return -1;
8892 } else {
8893 if (result>0xffff) return -1;
8894 }
8895 }
8896 return result;
8897 }
8898
qeth_setvalue_if_possible(qeth_card_t * card,char * option,int parse_category,int * variable,int value)8899 static int qeth_setvalue_if_possible(qeth_card_t *card,char *option,
8900 int parse_category,
8901 int *variable,int value)
8902 {
8903 int *a_p=0; /* to shut the compiler up */
8904 int routing_already_set_conflict=0;
8905
8906 a_p= &card->options.already_parsed[parse_category];
8907
8908 /* reject a general router statement, if router4 or router6
8909 * have already been set */
8910 if (parse_category==PARSE_ROUTING_TYPE) {
8911 if ( (card->options.already_parsed[PARSE_ROUTING_TYPE4]) ||
8912 (card->options.already_parsed[PARSE_ROUTING_TYPE6]) )
8913 routing_already_set_conflict=1;
8914 }
8915
8916 /* reject a router4 statement, if a general router statement
8917 * has already been set */
8918 if (parse_category==PARSE_ROUTING_TYPE4) {
8919 if ( (card->options.already_parsed[PARSE_ROUTING_TYPE4]) &&
8920 (card->options.already_parsed[PARSE_ROUTING_TYPE6]) )
8921 routing_already_set_conflict=1;
8922 }
8923
8924 /* reject a router6 statement, if a general router statement
8925 * has already been set */
8926 if (parse_category==PARSE_ROUTING_TYPE6) {
8927 if ( (card->options.already_parsed[PARSE_ROUTING_TYPE4]) &&
8928 (card->options.already_parsed[PARSE_ROUTING_TYPE6]) )
8929 routing_already_set_conflict=1;
8930 }
8931
8932 if ( (routing_already_set_conflict) ||
8933 ((parse_category!=-1) && (*a_p)) ) {
8934 PRINT_ERR("parameter %s does not fit to previous " \
8935 "parameters\n",option);
8936 return 0;
8937 }
8938 *a_p=1;
8939 *variable=value;
8940 return 1;
8941 }
8942
8943 /* um... */
8944 #define doit1(a,b,c,d) \
8945 if (!strcmp(option,a)) \
8946 return qeth_setvalue_if_possible(card,option,b,((int*)&c),d)
8947
8948 #define doit2(a,b,c,d,e,f) \
8949 doit1(a,b,c,d) | qeth_setvalue_if_possible(card,option,-1,((int*)&e),f)
8950
8951 /* returns 0, if option could notr be parsed alright */
qeth_parse_option(qeth_card_t * card,char * option)8952 static int qeth_parse_option(qeth_card_t *card,char *option)
8953 {
8954 int i;
8955 int *a_p;
8956
8957 #ifdef QETH_IPV6
8958 doit2("no_router",PARSE_ROUTING_TYPE,
8959 card->options.routing_type4,NO_ROUTER,
8960 card->options.routing_type6,NO_ROUTER);
8961 doit2("primary_router",PARSE_ROUTING_TYPE,
8962 card->options.routing_type4,PRIMARY_ROUTER,
8963 card->options.routing_type6,PRIMARY_ROUTER);
8964 doit2("secondary_router",PARSE_ROUTING_TYPE,
8965 card->options.routing_type4,SECONDARY_ROUTER,
8966 card->options.routing_type6,SECONDARY_ROUTER);
8967 doit2("multicast_router",PARSE_ROUTING_TYPE,
8968 card->options.routing_type4,MULTICAST_ROUTER,
8969 card->options.routing_type6,MULTICAST_ROUTER);
8970 doit2("primary_connector",PARSE_ROUTING_TYPE,
8971 card->options.routing_type4,PRIMARY_CONNECTOR,
8972 card->options.routing_type6,PRIMARY_CONNECTOR);
8973 doit2("secondary_connector",PARSE_ROUTING_TYPE,
8974 card->options.routing_type4,SECONDARY_CONNECTOR,
8975 card->options.routing_type6,SECONDARY_CONNECTOR);
8976 #else /* QETH_IPV6 */
8977 doit1("no_router",PARSE_ROUTING_TYPE,
8978 card->options.routing_type4,NO_ROUTER);
8979 doit1("primary_router",PARSE_ROUTING_TYPE,
8980 card->options.routing_type4,PRIMARY_ROUTER);
8981 doit1("secondary_router",PARSE_ROUTING_TYPE,
8982 card->options.routing_type4,SECONDARY_ROUTER);
8983 doit1("multicast_router",PARSE_ROUTING_TYPE,
8984 card->options.routing_type4,MULTICAST_ROUTER);
8985 doit1("primary_connector",PARSE_ROUTING_TYPE,
8986 card->options.routing_type4,PRIMARY_CONNECTOR);
8987 doit1("secondary_connector",PARSE_ROUTING_TYPE,
8988 card->options.routing_type4,SECONDARY_CONNECTOR);
8989 #endif /* QETH_IPV6 */
8990
8991 doit1("no_router4",PARSE_ROUTING_TYPE4,
8992 card->options.routing_type4,NO_ROUTER);
8993 doit1("primary_router4",PARSE_ROUTING_TYPE4,
8994 card->options.routing_type4,PRIMARY_ROUTER);
8995 doit1("secondary_router4",PARSE_ROUTING_TYPE4,
8996 card->options.routing_type4,SECONDARY_ROUTER);
8997 doit1("multicast_router4",PARSE_ROUTING_TYPE4,
8998 card->options.routing_type4,MULTICAST_ROUTER);
8999 doit1("primary_connector4",PARSE_ROUTING_TYPE4,
9000 card->options.routing_type4,PRIMARY_CONNECTOR);
9001 doit1("secondary_connector4",PARSE_ROUTING_TYPE4,
9002 card->options.routing_type4,SECONDARY_CONNECTOR);
9003
9004 #ifdef QETH_IPV6
9005 doit1("no_router6",PARSE_ROUTING_TYPE6,
9006 card->options.routing_type6,NO_ROUTER);
9007 doit1("primary_router6",PARSE_ROUTING_TYPE6,
9008 card->options.routing_type6,PRIMARY_ROUTER);
9009 doit1("secondary_router6",PARSE_ROUTING_TYPE6,
9010 card->options.routing_type6,SECONDARY_ROUTER);
9011 doit1("multicast_router6",PARSE_ROUTING_TYPE6,
9012 card->options.routing_type6,MULTICAST_ROUTER);
9013 doit1("primary_connector6",PARSE_ROUTING_TYPE6,
9014 card->options.routing_type6,PRIMARY_CONNECTOR);
9015 doit1("secondary_connector6",PARSE_ROUTING_TYPE6,
9016 card->options.routing_type6,SECONDARY_CONNECTOR);
9017 #endif /* QETH_IPV6 */
9018
9019 doit1("sw_checksumming",PARSE_CHECKSUMMING,
9020 card->options.checksum_type,SW_CHECKSUMMING);
9021 doit1("hw_checksumming",PARSE_CHECKSUMMING,
9022 card->options.checksum_type,HW_CHECKSUMMING);
9023 doit1("no_checksumming",PARSE_CHECKSUMMING,
9024 card->options.checksum_type,NO_CHECKSUMMING);
9025
9026 doit1("prio_queueing_prec",PARSE_PRIO_QUEUEING,
9027 card->options.do_prio_queueing,PRIO_QUEUEING_PREC);
9028 doit1("prio_queueing_tos",PARSE_PRIO_QUEUEING,
9029 card->options.do_prio_queueing,PRIO_QUEUEING_TOS);
9030
9031 doit1("mem_discontig",PARSE_MEMUSAGE,
9032 card->options.memusage,MEMUSAGE_DISCONTIG);
9033 doit1("mem_contig",PARSE_MEMUSAGE,
9034 card->options.memusage,MEMUSAGE_CONTIG);
9035
9036 doit1("broadcast_allrings",PARSE_BROADCAST_MODE,
9037 card->options.broadcast_mode,BROADCAST_ALLRINGS);
9038 doit1("broadcast_local",PARSE_BROADCAST_MODE,
9039 card->options.broadcast_mode,BROADCAST_LOCAL);
9040
9041 doit1("macaddr_noncanon",PARSE_MACADDR_MODE,
9042 card->options.macaddr_mode,MACADDR_NONCANONICAL);
9043 doit1("macaddr_canon",PARSE_MACADDR_MODE,
9044 card->options.macaddr_mode,MACADDR_CANONICAL);
9045
9046 doit1("enable_takeover",PARSE_ENA_IPAT,
9047 card->options.ena_ipat,ENABLE_TAKEOVER);
9048 doit1("disable_takeover",PARSE_ENA_IPAT,
9049 card->options.ena_ipat,DISABLE_TAKEOVER);
9050
9051 doit1("fake_broadcast",PARSE_FAKE_BROADCAST,
9052 card->options.fake_broadcast,FAKE_BROADCAST);
9053 doit1("dont_fake_broadcast",PARSE_FAKE_BROADCAST,
9054 card->options.fake_broadcast,DONT_FAKE_BROADCAST);
9055
9056 doit1("fake_ll",PARSE_FAKE_LL,
9057 card->options.fake_ll,FAKE_LL);
9058 doit1("dont_fake_ll",PARSE_FAKE_LL,
9059 card->options.fake_ll,DONT_FAKE_LL);
9060
9061 doit1("sync_hsi",PARSE_ASYNC_IQD,
9062 card->options.async_iqd,SYNC_IQD);
9063 doit1("async_hsi",PARSE_ASYNC_IQD,
9064 card->options.async_iqd,ASYNC_IQD);
9065
9066 doit2("no_prio_queueing:0",PARSE_PRIO_QUEUEING,
9067 card->options.do_prio_queueing,NO_PRIO_QUEUEING,
9068 card->options.default_queue,0);
9069 doit2("no_prio_queueing:1",PARSE_PRIO_QUEUEING,
9070 card->options.do_prio_queueing,NO_PRIO_QUEUEING,
9071 card->options.default_queue,1);
9072 doit2("no_prio_queueing:2",PARSE_PRIO_QUEUEING,
9073 card->options.do_prio_queueing,NO_PRIO_QUEUEING,
9074 card->options.default_queue,2);
9075 doit2("no_prio_queueing:3",PARSE_PRIO_QUEUEING,
9076 card->options.do_prio_queueing,NO_PRIO_QUEUEING,
9077 card->options.default_queue,3);
9078 doit2("no_prio_queueing",PARSE_PRIO_QUEUEING,
9079 card->options.do_prio_queueing,NO_PRIO_QUEUEING,
9080 card->options.default_queue,QETH_DEFAULT_QUEUE);
9081
9082 if (!strncmp(option,"polltime:",9)) {
9083 i=qeth_getint(option+9,1);
9084 if (i==-1) {
9085 PRINT_ERR("parameter %s -- does not contain " \
9086 "a valid number.\n",option);
9087 return 0;
9088 }
9089 return qeth_setvalue_if_possible(card,option,PARSE_POLLTIME,
9090 &card->options.polltime,i);
9091 }
9092
9093 if (!strncmp(option,"port:",5)) {
9094 i=qeth_getint(option+5,0);
9095 if (i==-1) {
9096 PRINT_ERR("parameter %s -- does not contain " \
9097 "a valid number.\n",option);
9098 return 0;
9099 }
9100 if ( (i<0) || (i>MAX_PORTNO) ) {
9101 PRINT_ERR("parameter %s -- out of range\n",
9102 option);
9103 return 0;
9104 }
9105 return qeth_setvalue_if_possible(card,option,PARSE_PORTNO,
9106 &card->options.portno,i);
9107 }
9108
9109 if (!strncmp(option,"add_hhlen:",10)) {
9110 i=qeth_getint(option+10,0);
9111 if (i==-1) {
9112 PRINT_ERR("parameter %s -- does not contain " \
9113 "a valid number.\n",option);
9114 return 0;
9115 }
9116 if ( (i<0) || (i>MAX_ADD_HHLEN) ) {
9117 PRINT_ERR("parameter %s -- out of range\n",
9118 option);
9119 return 0;
9120 }
9121 return qeth_setvalue_if_possible(card,option,PARSE_ADD_HHLEN,
9122 &card->options.add_hhlen,i);
9123 }
9124
9125 if (!strncmp(option,"portname:",9)) {
9126 a_p=&card->options.already_parsed[PARSE_PORTNAME];
9127 if (*a_p) {
9128 PRINT_ERR("parameter %s does not fit to " \
9129 "previous parameters\n",option);
9130 return 0;
9131 }
9132 if ((strlen(option)-9)>8) {
9133 PRINT_ERR("parameter %s -- too long\n",option);
9134 return 0;
9135 }
9136 *a_p=1;
9137 card->options.portname[0]=strlen(option)-9;
9138 /* for beauty reasons: */
9139 for (i=1;i<9;i++)
9140 card->options.portname[i]=' ';
9141 strcpy(card->options.portname+1,option+9);
9142 for (i=1;i<9;i++)
9143 card->options.portname[i]=
9144 _ascebc[(unsigned char)
9145 card->options.portname[i]];
9146 return 1;
9147 }
9148
9149 PRINT_ERR("unknown parameter: %s\n",option);
9150
9151 return 0;
9152 }
9153
qeth_detach_handler(int irq,int status)9154 static void qeth_detach_handler(int irq,int status)
9155 {
9156 qeth_card_t *card;
9157 int remove_method;
9158 char dbf_text[15];
9159
9160 if (irq>=NR_IRQS) {
9161 irq-=NR_IRQS;
9162 remove_method=QETH_REMOVE_CARD_PROPER;
9163 } else {
9164 remove_method=QETH_REMOVE_CARD_QUICK;
9165 }
9166
9167 QETH_DBF_TEXT1(0,trace,"detchhnd");
9168 sprintf(dbf_text,"%4x%4x",irq,status);
9169 QETH_DBF_TEXT1(0,trace,dbf_text);
9170
9171 /* try to get the lock, if we didn't get it (hold by recovery),
9172 * give up initiative to enable others to release the lock */
9173 my_spin_lock_nonbusy(NULL,&setup_lock);
9174
9175 if ((card=qeth_get_card_by_irq(irq))) {
9176 qeth_remove_card(card,remove_method);
9177 }
9178 qeth_snmp_notify();
9179 my_spin_unlock(&setup_lock);
9180 }
9181
qeth_chandev_do_unregister_device(struct net_device * dev,int quick)9182 static void qeth_chandev_do_unregister_device(struct net_device *dev,
9183 int quick)
9184 {
9185 qeth_card_t *card;
9186
9187 card=(qeth_card_t *)dev->priv;
9188
9189 if (quick) {
9190 qeth_detach_handler(card->irq0,0x1234);
9191 } else {
9192 qeth_detach_handler(NR_IRQS+card->irq0,0x1234);
9193 }
9194 }
9195
qeth_chandev_unregister_device(struct net_device * dev)9196 static void qeth_chandev_unregister_device(struct net_device *dev)
9197 {
9198 qeth_chandev_do_unregister_device(dev, 0);
9199 }
9200
qeth_chandev_parse_options(qeth_card_t * card,char * parmstring)9201 static void qeth_chandev_parse_options(qeth_card_t *card,char *parmstring)
9202 {
9203 /* parse options coming from the chandev layer */
9204 char *optionstr;
9205 char *tmp;
9206
9207 QETH_DBF_HEX2(0,misc,parmstring,
9208 qeth_min(QETH_DBF_MISC_LEN,strlen(parmstring)));
9209 tmp = kmalloc ((strlen(parmstring) + 1) * sizeof (char), GFP_KERNEL);
9210 if (tmp) {
9211 memset (tmp, 0, strlen(parmstring) + 1);
9212 memcpy (tmp, parmstring, strlen(parmstring) + 1);
9213 do {
9214 char *end;
9215 int len;
9216 end = strchr (tmp, ',');
9217 if (end == NULL) {
9218 len = strlen (tmp) + 1;
9219 } else {
9220 len = (long) end - (long) tmp + 1;
9221 *end = '\0';
9222 end++;
9223 }
9224
9225 if (len>1) {
9226 optionstr = kmalloc (len * sizeof (char),
9227 GFP_KERNEL);
9228 if (optionstr) {
9229 memset(optionstr,0,len*sizeof(char));
9230 memcpy(optionstr,tmp,len*sizeof(char));
9231
9232 qeth_parse_option(card,optionstr);
9233 kfree(optionstr);
9234 tmp = end;
9235 } else {
9236 PRINT_ERR("Cannot allocate memory " \
9237 "for option parsing!\n");
9238 break;
9239 }
9240 }
9241 } while (tmp != NULL && *tmp != '\0');
9242 } else {
9243 PRINT_ERR("Cannot allocate memory " \
9244 "for option parsing!\n");
9245 }
9246 }
9247
qeth_get_bufcnt_from_memamnt(qeth_card_t * card,__s32 * memamnt)9248 static int qeth_get_bufcnt_from_memamnt(qeth_card_t *card,__s32 *memamnt)
9249 {
9250 int cnt = 0;
9251 int bufsize = BUFFER_SIZE;
9252
9253 if (bufsize == 24576)
9254 bufsize = 32768;
9255 if (bufsize == 40960)
9256 bufsize = 65536;
9257 cnt = (*memamnt)*1024 / bufsize;
9258 cnt = (cnt<BUFCNT_MIN)?BUFCNT_MIN:((cnt>BUFCNT_MAX)?BUFCNT_MAX:cnt);
9259 (*memamnt) = cnt * bufsize/1024;
9260
9261 return cnt;
9262 }
9263
qeth_attach_handler(int irq_to_scan,chandev_probeinfo * probeinfo)9264 static int qeth_attach_handler(int irq_to_scan,chandev_probeinfo *probeinfo)
9265 {
9266 int result = 0;
9267 int irq1,irq2;
9268 unsigned int irq;
9269 int nr;
9270 __u8 mask;
9271 int read_chpid=-1,write_chpid=-2,data_chpid=-3; /* so that it will
9272 fail, if getting
9273 the chpids fails */
9274 qeth_card_t *card;
9275 int success = 0;
9276 char dbf_text[15];
9277 chandev_subchannel_info temp;
9278
9279 QETH_DBF_TEXT2(0,trace,"athandlr");
9280 sprintf(dbf_text,"irq:%4x",irq_to_scan);
9281 QETH_DBF_TEXT2(0,trace,dbf_text);
9282
9283 my_spin_lock_nonbusy(NULL,&setup_lock);
9284
9285 for (nr=0; nr<8; nr++) {
9286 mask = 0x80 >> nr;
9287 if (probeinfo->read.pim & mask) {
9288 read_chpid=probeinfo->read.chpid[nr];
9289 /* we take the first chpid -- well, there's
9290 * usually only one... */
9291 break;
9292 }
9293 }
9294 for (nr=0; nr<8; nr++) {
9295 mask = 0x80 >> nr;
9296 if (probeinfo->write.pim & mask) {
9297 write_chpid=probeinfo->write.chpid[nr];
9298 /* we take the first chpid -- well, there's
9299 * usually only one... */
9300 break;
9301 }
9302 }
9303 for (nr=0; nr<8; nr++) {
9304 mask = 0x80 >> nr;
9305 if (probeinfo->data.pim & mask) {
9306 data_chpid=probeinfo->data.chpid[nr];
9307 /* we take the first chpid -- well, there's
9308 * usually only one... */
9309 break;
9310 }
9311 }
9312 if ((read_chpid!=write_chpid)||(read_chpid!=data_chpid)) {
9313 PRINT_ERR("devices are not on the same CHPID!\n");
9314 goto endloop;
9315 }
9316
9317 /* Try to reorder the devices, if neccessary */
9318 if (probeinfo->read.dev_model == 0x05)
9319 /* No odd/even restr. for IQD */
9320 goto correct_order;
9321 if ((probeinfo->read.devno %2 == 0) &&
9322 (probeinfo->write.devno == probeinfo->read.devno + 1))
9323 goto correct_order;
9324 if ((probeinfo->write.devno %2 == 0) &&
9325 (probeinfo->data.devno == probeinfo->write.devno + 1)) {
9326 temp = probeinfo->read;
9327 probeinfo->read = probeinfo->write;
9328 probeinfo->write = probeinfo->data;
9329 probeinfo->data = temp;
9330 goto correct_order;
9331 }
9332 if ((probeinfo->write.devno %2 == 0) &&
9333 (probeinfo->read.devno == probeinfo->write.devno + 1)) {
9334 temp = probeinfo->read;
9335 probeinfo->read = probeinfo->write;
9336 probeinfo->write = temp;
9337 goto correct_order;
9338 }
9339 if ((probeinfo->read.devno %2 == 0) &&
9340 (probeinfo->data.devno == probeinfo->read.devno + 1)) {
9341 temp = probeinfo->write;
9342 probeinfo->write = probeinfo->data;
9343 probeinfo->data = temp;
9344 goto correct_order;
9345 }
9346 if ((probeinfo->data.devno %2 == 0) &&
9347 (probeinfo->write.devno == probeinfo->data.devno + 1)) {
9348 temp = probeinfo->read;
9349 probeinfo->read = probeinfo->data;
9350 probeinfo->data = temp;
9351 goto correct_order;
9352 }
9353 if ((probeinfo->data.devno %2 == 0) &&
9354 (probeinfo->read.devno == probeinfo->data.devno + 1)) {
9355 temp = probeinfo->read;
9356 probeinfo->read = probeinfo->data;
9357 probeinfo->data = probeinfo->write;
9358 probeinfo->write = temp;
9359 goto correct_order;
9360 }
9361 PRINT_ERR("Failed to reorder devices %04x,%04x,%04x; "
9362 "please check your configuration\n",
9363 probeinfo->read.devno, probeinfo->write.devno,
9364 probeinfo->data.devno);
9365 goto endloop;
9366
9367 correct_order:
9368 irq = probeinfo->read.irq;
9369 irq1 = probeinfo->write.irq;
9370 irq2 = probeinfo->data.irq;
9371
9372 card=qeth_alloc_card();
9373 if (card==NULL) {
9374 QETH_DBF_TEXT2(0,trace,"nocrdmem");
9375 PRINT_ERR("memory structures could not be allocated\n");
9376 goto endloop;
9377 }
9378 card->chpid=read_chpid;
9379
9380 if (probeinfo->port_protocol_no != -1 )
9381 card->options.portno = probeinfo->port_protocol_no;
9382 else
9383 card->options.portno = 0;
9384
9385 qeth_chandev_parse_options(card,probeinfo->parmstr);
9386
9387 card->has_irq=0;
9388 card->irq0=irq;
9389 card->irq1=irq1;
9390 card->irq2=irq2;
9391 card->devno0=probeinfo->read.devno;
9392 card->devno1=probeinfo->write.devno;
9393 card->devno2=probeinfo->data.devno;
9394 card->dev_type=probeinfo->read.dev_type;
9395 card->dev_model=probeinfo->read.dev_model;
9396 atomic_set(&card->is_gone,0);
9397 atomic_set(&card->rt4fld,0);
9398 #ifdef QETH_IPV6
9399 atomic_set(&card->rt6fld,0);
9400 #endif /* QETH_IPV6 */
9401
9402 sprintf(dbf_text,"atch%4x",card->irq0);
9403 QETH_DBF_TEXT1(0,setup,dbf_text);
9404 QETH_DBF_HEX1(0,setup,&card,sizeof(void*));
9405 QETH_DBF_HEX1(0,setup,&card->dev,sizeof(void*));
9406 QETH_DBF_HEX1(0,setup,&card->stats,sizeof(void*));
9407 QETH_DBF_HEX1(0,setup,&card->devstat0,sizeof(void*));
9408 QETH_DBF_HEX1(0,setup,&card->devstat1,sizeof(void*));
9409 QETH_DBF_HEX1(0,setup,&card->devstat2,sizeof(void*));
9410
9411 QETH_DBF_HEX2(0,misc,&card->options,QETH_DBF_MISC_LEN);
9412
9413 if (qeth_determine_card_type(card)) {
9414 qeth_free_card(card);
9415 goto endloop;
9416 }
9417
9418 qeth_insert_card_into_list(card);
9419
9420 QETH_DBF_TEXT3(0,trace,"request0");
9421 /* 0 is irqflags. what is SA_SAMPLE_RANDOM? */
9422 result=chandev_request_irq(irq,(void*)
9423 qeth_interrupt_handler_read,
9424 0,QETH_NAME,card->devstat0);
9425 if (result) goto attach_error;
9426 card->has_irq++;
9427
9428 QETH_DBF_TEXT3(0,trace,"request1");
9429 result=chandev_request_irq(irq1,(void*)
9430 qeth_interrupt_handler_write,
9431 0,QETH_NAME,card->devstat1);
9432 if (result) goto attach_error;
9433 card->has_irq++;
9434
9435 QETH_DBF_TEXT3(0,trace,"request2");
9436 result=chandev_request_irq(irq2,(void*)
9437 qeth_interrupt_handler_qdio,
9438 0,QETH_NAME,card->devstat2);
9439 if (result) goto attach_error;
9440 card->has_irq++;
9441
9442 printk("qeth: Trying to use card with devnos 0x%X/0x%X/0x%X\n",
9443 card->devno0,card->devno1,card->devno2);
9444
9445 result=qeth_init_ringbuffers1(card);
9446 if (result) goto attach_error;
9447
9448 result=qeth_hardsetup_card(card,0);
9449 if (result) goto attach_error;
9450 if (probeinfo->memory_usage_in_k != 0) {
9451 card->options.inbound_buffer_count=
9452 qeth_get_bufcnt_from_memamnt
9453 (card,&probeinfo->memory_usage_in_k);
9454 card->options.memory_usage_in_k=
9455 probeinfo->memory_usage_in_k;
9456 } else {
9457 /* sick... */
9458 probeinfo->memory_usage_in_k=
9459 -card->options.inbound_buffer_count*
9460 BUFFER_SIZE/1024;
9461 }
9462 result=qeth_init_ringbuffers2(card);
9463 if (result) goto attach_error;
9464
9465 success = 1;
9466 goto endloop;
9467
9468 attach_error:
9469 sprintf(dbf_text,"ATER%4x",card->irq0);
9470 QETH_DBF_TEXT2(0,trace,dbf_text);
9471 switch (result) {
9472 case 0:
9473 break;
9474 case -EINVAL:
9475 PRINT_ERR("oops... invalid parameter.\n");
9476 break;
9477 case -EBUSY:
9478 PRINT_WARN("Device is busy!\n");
9479 break;
9480 case -ENODEV:
9481 PRINT_WARN("Device became not operational.\n");
9482 break;
9483 case -ENOMEM:
9484 PRINT_ERR("Not enough kernel memory for operation.\n");
9485 break;
9486 case -EIO:
9487 PRINT_ERR("There were problems in hard-setting up " \
9488 "the card.\n");
9489 break;
9490 case -ETIME:
9491 PRINT_WARN("Timeout on initializing the card.\n");
9492 break;
9493 default:
9494 PRINT_ERR("Unknown error %d in attach_handler.\n",
9495 result);
9496 }
9497 if (result) {
9498 qeth_remove_card(card,QETH_REMOVE_CARD_PROPER);
9499
9500 qeth_remove_card_from_list(card);
9501 QETH_DBF_TEXT4(0,trace,"freecard");
9502 qeth_free_card(card);
9503 }
9504 endloop:
9505
9506 QETH_DBF_TEXT3(0,trace,"leftloop");
9507
9508 if (!success) {
9509 QETH_DBF_TEXT2(0,trace,"noaddcrd");
9510
9511 /* we want to return which problem we had */
9512 result=result?result:-ENODEV;
9513 goto exit;
9514 }
9515
9516
9517 exit:
9518 my_spin_unlock(&setup_lock);
9519
9520 return result;
9521 }
9522
qeth_chandev_msck_notfunc(struct net_device * device,int msck_irq,chandev_msck_status prevstatus,chandev_msck_status newstatus)9523 static void qeth_chandev_msck_notfunc(struct net_device *device,
9524 int msck_irq,
9525 chandev_msck_status prevstatus,
9526 chandev_msck_status newstatus )
9527 {
9528
9529 if (!(device->priv))
9530 return;
9531
9532 if ((prevstatus != chandev_status_good) ||
9533 (prevstatus != chandev_status_all_chans_good)) {
9534 if ((newstatus == chandev_status_good) ||
9535 (newstatus == chandev_status_all_chans_good)) {
9536 qeth_card_t *card = (qeth_card_t *)device->priv;
9537
9538 atomic_set(&card->problem,PROBLEM_MACHINE_CHECK);
9539 atomic_set(&card->write_busy,0);
9540 qeth_schedule_recovery(card);
9541 }
9542 }
9543 if ((newstatus == chandev_status_gone) ||
9544 (newstatus == chandev_status_no_path) ||
9545 (newstatus == chandev_status_not_oper)) {
9546 qeth_card_t *card = (qeth_card_t *)device->priv;
9547
9548 my_read_lock(&list_lock);
9549 if (qeth_verify_card(card)) {
9550 atomic_set(&card->is_startlaned,0);
9551 qeth_set_dev_flag_norunning(card);
9552 /*
9553 * Unfortunately, the chandev layer does not provide
9554 * a possibility to unregister a single device. So
9555 * we mark the card as "gone" to avoid internal
9556 * mishandling.
9557 */
9558 atomic_set(&card->is_gone,1);
9559 /* means, we prevent looping in
9560 * qeth_send_control_data */
9561 atomic_set(&card->write_busy,0);
9562 qeth_snmp_notify();
9563 }
9564 my_read_unlock(&list_lock);
9565 }
9566 }
9567
qeth_chandev_init_netdev(struct net_device * dev,int sizeof_priv)9568 struct net_device *qeth_chandev_init_netdev(struct net_device *dev,
9569 int sizeof_priv)
9570 {
9571
9572 qeth_card_t *card = NULL;
9573 int result;
9574 char dbf_text[15];
9575
9576 if (!dev) {
9577 PRINT_ERR("qeth_chandev_init_netdev called with no device!\n");
9578 goto out;
9579 }
9580
9581 card = (qeth_card_t *)dev->priv;
9582 strcpy(card->dev_name,dev->name);
9583 result=qeth_register_netdev(card);
9584 if (result) {
9585 PRINT_ALL(" register_netdev %s -- rc=%i\n",
9586 ((qeth_card_t*)firstcard->dev->priv)->
9587 dev_name,result);
9588 sprintf(dbf_text,"rgnd%4x",(__u16)result);
9589 QETH_DBF_TEXT2(1,trace,dbf_text);
9590 atomic_set(&card->is_registered,0);
9591 goto out;
9592 }
9593 strcpy(card->dev_name,dev->name);
9594 atomic_set(&card->write_busy,0);
9595 atomic_set(&card->is_registered,1);
9596
9597 result=qeth_softsetup_card(card,QETH_WAIT_FOR_LOCK);
9598
9599 if (!result) {
9600 qeth_init_input_buffers(card);
9601 } else {
9602 QETH_DBF_TEXT2(0,trace,"SSFAILED");
9603 PRINT_WARN("soft-setup of card failed!\n");
9604 }
9605
9606 INIT_LIST_HEAD(&card->tqueue_sst.list);
9607 card->tqueue_sst.routine=qeth_softsetup_thread_starter;
9608 card->tqueue_sst.data=card;
9609 card->tqueue_sst.sync=0;
9610 schedule_task(&card->tqueue_sst);
9611 out:
9612 qeth_snmp_notify();
9613 return dev;
9614
9615 }
9616
qeth_probe(chandev_probeinfo * probeinfo)9617 static int qeth_probe(chandev_probeinfo *probeinfo)
9618 {
9619 int result;
9620 struct net_device *pdevice = NULL;
9621 int sizeof_priv;
9622 qeth_card_t *card;
9623 char *basename = NULL;
9624
9625 result = qeth_attach_handler(probeinfo->read.irq, probeinfo);
9626 if (result)
9627 return result;
9628
9629 sizeof_priv = sizeof(qeth_card_t);
9630 card = qeth_get_card_by_irq(probeinfo->read.irq);
9631
9632 pdevice = card->dev;
9633 basename = (char *)qeth_get_dev_basename(card->type, card->link_type);
9634
9635 pdevice->irq=card->irq0;
9636
9637 if (probeinfo->memory_usage_in_k>=0)
9638 probeinfo->memory_usage_in_k=
9639 -card->options.memory_usage_in_k;
9640 pdevice = chandev_initnetdevice(probeinfo,
9641 card->options.portno,
9642 pdevice,
9643 sizeof_priv,
9644 basename,
9645 qeth_chandev_init_netdev,
9646 qeth_chandev_unregister_device);
9647 if (pdevice) {
9648 return 0;
9649 } else {
9650 qeth_remove_card(card,QETH_REMOVE_CARD_PROPER);
9651 qeth_remove_card_from_list(card);
9652 QETH_DBF_TEXT4(0,trace,"freecard");
9653 qeth_free_card(card);
9654 return -ENODEV;
9655 }
9656
9657 }
9658
qeth_dev_event(struct notifier_block * this,unsigned long event,void * ptr)9659 static int qeth_dev_event(struct notifier_block *this,
9660 unsigned long event,void *ptr)
9661 {
9662 qeth_card_t *card;
9663 struct net_device *dev = (struct net_device *)ptr;
9664 char dbf_text[15];
9665
9666 sprintf(dbf_text,"devevent");
9667 QETH_DBF_TEXT3(0,trace,dbf_text);
9668 QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long));
9669 QETH_DBF_HEX3(0,trace,&dev,sizeof(void*));
9670
9671 #ifdef QETH_VLAN
9672 if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV)
9673 card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv;
9674 else
9675 #endif
9676 card=(qeth_card_t *)dev->priv;
9677 if (qeth_does_card_exist(card)) {
9678 qeth_save_dev_flag_state(card);
9679 switch (event) {
9680 default:
9681 qeth_start_softsetup_thread(card);
9682 break;
9683 }
9684 }
9685
9686 return NOTIFY_DONE;
9687 }
9688
qeth_ip_event(struct notifier_block * this,unsigned long event,void * ptr)9689 static int qeth_ip_event(struct notifier_block *this,
9690 unsigned long event,void *ptr)
9691 {
9692 qeth_card_t *card;
9693 struct in_ifaddr *ifa=(struct in_ifaddr *)ptr;
9694 struct net_device *dev = ifa->ifa_dev->dev;
9695 char dbf_text[15];
9696
9697 sprintf(dbf_text,"ipevent");
9698 QETH_DBF_TEXT3(0,trace,dbf_text);
9699 QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long));
9700 sprintf(dbf_text,"%08x",ifa->ifa_address);
9701 QETH_DBF_TEXT3(0,trace,dbf_text);
9702 sprintf(dbf_text,"%08x",ifa->ifa_mask);
9703 QETH_DBF_TEXT3(0,trace,dbf_text);
9704
9705 #ifdef QETH_VLAN
9706 if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV)
9707 card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv;
9708 else
9709 #endif
9710 card=(qeth_card_t *)dev->priv;
9711 if (qeth_does_card_exist(card)) {
9712 QETH_DBF_HEX3(0,trace,&card,sizeof(void*));
9713 qeth_save_dev_flag_state(card);
9714 qeth_start_softsetup_thread(card);
9715 }
9716
9717 return NOTIFY_DONE;
9718 }
9719
9720 #ifdef QETH_IPV6
qeth_ip6_event(struct notifier_block * this,unsigned long event,void * ptr)9721 static int qeth_ip6_event(struct notifier_block *this,
9722 unsigned long event,void *ptr)
9723 {
9724 qeth_card_t *card;
9725 struct inet6_ifaddr *ifa=(struct inet6_ifaddr *)ptr;
9726 struct net_device *dev = ifa->idev->dev;
9727 char dbf_text[15];
9728
9729 sprintf(dbf_text,"ip6event");
9730 QETH_DBF_TEXT3(0,trace,dbf_text);
9731 QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long));
9732 QETH_DBF_HEX3(0,trace,ifa->addr.s6_addr,QETH_DBF_TRACE_LEN);
9733 QETH_DBF_HEX3(0,trace,ifa->addr.s6_addr+QETH_DBF_TRACE_LEN,
9734 QETH_DBF_TRACE_LEN);
9735
9736 #ifdef QETH_VLAN
9737 if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV)
9738 card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv;
9739 else
9740 #endif
9741 card=(qeth_card_t *)dev->priv;
9742
9743 if (qeth_does_card_exist(card)) {
9744 QETH_DBF_HEX3(0,trace,&card,sizeof(void*));
9745 qeth_save_dev_flag_state(card);
9746 qeth_start_softsetup_thread(card);
9747 }
9748
9749 return NOTIFY_DONE;
9750 }
9751
9752 static int
qeth_multicast6_event(struct notifier_block * this,unsigned long event,void * ptr)9753 qeth_multicast6_event(struct notifier_block *this,
9754 unsigned long event, void *ptr)
9755 {
9756 qeth_card_t *card;
9757 struct ifmcaddr6 *mc = (struct ifmcaddr6 *) ptr;
9758 struct net_device *dev = mc->idev->dev;
9759 char dbf_text[15];
9760
9761 sprintf(dbf_text,"mc6event");
9762 QETH_DBF_TEXT3(0,trace,dbf_text);
9763 QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long));
9764 #ifdef QETH_VLAN
9765 if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV)
9766 card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv;
9767 else
9768 #endif
9769 card=(qeth_card_t *)dev->priv;
9770 if (qeth_does_card_exist(card)) {
9771 QETH_DBF_HEX3(0,trace,&card,sizeof(void*));
9772 qeth_save_dev_flag_state(card);
9773 qeth_start_softsetup_thread(card);
9774 }
9775
9776 return NOTIFY_DONE;
9777 }
9778
9779 #endif /* QETH_IPV6 */
9780
9781 static int
qeth_multicast_event(struct notifier_block * this,unsigned long event,void * ptr)9782 qeth_multicast_event(struct notifier_block *this,
9783 unsigned long event, void *ptr)
9784 {
9785 qeth_card_t *card;
9786 struct ip_mc_list *mc = (struct ip_mc_list *) ptr;
9787 struct net_device *dev = mc->interface->dev;
9788 char dbf_text[15];
9789
9790 sprintf(dbf_text,"mc4event");
9791 QETH_DBF_TEXT3(0,trace,dbf_text);
9792 QETH_DBF_HEX3(0,trace,&event,sizeof(unsigned long));
9793 #ifdef QETH_VLAN
9794 if (qeth_verify_dev(dev)==QETH_VERIFY_IS_VLAN_DEV)
9795 card = (qeth_card_t *)VLAN_DEV_INFO(dev)->real_dev->priv;
9796 else
9797 #endif
9798 card=(qeth_card_t *)dev->priv;
9799 if (qeth_does_card_exist(card)) {
9800 QETH_DBF_HEX3(0,trace,&card,sizeof(void*));
9801 qeth_save_dev_flag_state(card);
9802 qeth_start_softsetup_thread(card);
9803 }
9804
9805 return NOTIFY_DONE;
9806 }
9807
qeth_reboot_event(struct notifier_block * this,unsigned long event,void * ptr)9808 static int qeth_reboot_event(struct notifier_block *this,
9809 unsigned long event,void *ptr)
9810 {
9811 qeth_card_t *card;
9812
9813 my_read_lock(&list_lock);
9814 if (firstcard) {
9815 card = firstcard;
9816 clear_another_one:
9817 if (card->has_irq) {
9818 if (card->type==QETH_CARD_TYPE_IQD) {
9819 halt_IO(card->irq2,0,0);
9820 clear_IO(card->irq0,0,0);
9821 clear_IO(card->irq1,0,0);
9822 clear_IO(card->irq2,0,0);
9823 } else {
9824 clear_IO(card->irq2,0,0);
9825 clear_IO(card->irq0,0,0);
9826 clear_IO(card->irq1,0,0);
9827 }
9828 }
9829 if (card->next) {
9830 card = card->next;
9831 goto clear_another_one;
9832 }
9833 }
9834 my_read_unlock(&list_lock);
9835
9836 return 0;
9837 }
9838
9839 static struct notifier_block qeth_dev_notifier = {
9840 qeth_dev_event,
9841 0
9842 };
9843
9844 static struct notifier_block qeth_ip_notifier = {
9845 qeth_ip_event,
9846 0
9847 };
9848
9849 #ifdef QETH_IPV6
9850 static struct notifier_block qeth_ip6_notifier = {
9851 qeth_ip6_event,
9852 0
9853 };
9854 #endif /* QETH_IPV6 */
9855
9856 static struct notifier_block qeth_reboot_notifier = {
9857 qeth_reboot_event,
9858 0
9859 };
9860
qeth_register_notifiers(void)9861 static void qeth_register_notifiers(void)
9862 {
9863 int r;
9864
9865 QETH_DBF_TEXT5(0,trace,"regnotif");
9866 /* register to be notified on events */
9867 r=register_netdevice_notifier(&qeth_dev_notifier);
9868
9869 r=register_inetaddr_notifier(&qeth_ip_notifier);
9870 #ifdef QETH_IPV6
9871 r=register_inet6addr_notifier(&qeth_ip6_notifier);
9872 #endif /* QETH_IPV6 */
9873 r=register_reboot_notifier(&qeth_reboot_notifier);
9874 }
9875
9876 #ifdef MODULE
qeth_unregister_notifiers(void)9877 static void qeth_unregister_notifiers(void)
9878 {
9879 int r;
9880
9881 QETH_DBF_TEXT5(0,trace,"unregnot");
9882 r=unregister_netdevice_notifier(&qeth_dev_notifier);
9883 r=unregister_inetaddr_notifier(&qeth_ip_notifier);
9884 #ifdef QETH_IPV6
9885 r=unregister_inet6addr_notifier(&qeth_ip6_notifier);
9886 #endif /* QETH_IPV6 */
9887 r=unregister_reboot_notifier(&qeth_reboot_notifier);
9888 }
9889 #endif /* MODULE */
9890
qeth_procfile_open(struct inode * inode,struct file * file)9891 static int qeth_procfile_open(struct inode *inode, struct file *file)
9892 {
9893 int length=0;
9894 qeth_card_t *card;
9895 char checksum_str[5],queueing_str[14],router_str[8],bufsize_str[4];
9896 char *buffer;
9897 int rc=0;
9898 int size;
9899 tempinfo_t *info;
9900
9901 MOD_INC_USE_COUNT;
9902 info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
9903 if (info == NULL) {
9904 PRINT_WARN("No memory available for data\n");
9905 MOD_DEC_USE_COUNT;
9906 return -ENOMEM;
9907 } else {
9908 file->private_data = (void *) info;
9909 }
9910
9911 /* lock all the stuff */
9912 my_read_lock(&list_lock);
9913 card=firstcard;
9914 size=200; /* 2 lines plus some sanity space */
9915 while (card) {
9916 size+=90; /* if device name is > 10 chars, (should never
9917 happen...), we'll need that */
9918 card=card->next;
9919 }
9920
9921 buffer=info->data = (char *) vmalloc (size);
9922 if (info->data == NULL) {
9923 PRINT_WARN("No memory available for data\n");
9924 vfree (info);
9925 rc=-ENOMEM;
9926 MOD_DEC_USE_COUNT;
9927 goto out;
9928 }
9929
9930 QETH_DBF_TEXT2(0,trace,"procread");
9931 length+=sprintf(buffer+length,
9932 "devnos (hex) CHPID " \
9933 "device cardtype port chksum prio-q'ing " \
9934 "rtr fsz C cnt\n");
9935 length+=sprintf(buffer+length,
9936 "-------------- --- ----" \
9937 "------ -------------- -- -- ---------- " \
9938 "--- --- - ---\n");
9939 card=firstcard;
9940 while (card) {
9941 strcpy(checksum_str,
9942 (card->options.checksum_type==SW_CHECKSUMMING)?"SW":
9943 (card->options.checksum_type==HW_CHECKSUMMING)?"HW":
9944 "no");
9945 if (card->options.do_prio_queueing==NO_PRIO_QUEUEING) {
9946 sprintf(queueing_str,"always_q_%i",
9947 card->options.default_queue);
9948 } else {
9949 strcpy(queueing_str,(card->options.do_prio_queueing
9950 ==PRIO_QUEUEING_PREC)?"by_prec.":
9951 "by_ToS");
9952 }
9953
9954 /* a '+' in the routing indicator means, that broadcast
9955 * packets are not echoed back to the sender */
9956 #ifdef QETH_IPV6
9957 if (atomic_read(&card->rt4fld) ||
9958 atomic_read(&card->rt6fld))
9959 strcpy(router_str, "FLD");
9960 #else /* QETH_IPV6 */
9961 if (atomic_read(&card->rt4fld))
9962 strcpy(router_str, "FLD");
9963 #endif /* QETH_IPV6 */
9964 else if ( ((card->options.routing_type4&ROUTER_MASK)==
9965 PRIMARY_ROUTER)
9966 #ifdef QETH_IPV6
9967 &&
9968 ( ((card->options.routing_type6&ROUTER_MASK)==
9969 PRIMARY_ROUTER)||
9970 (!qeth_is_supported(IPA_IPv6)) )
9971 #endif /* QETH_IPV6 */
9972 ) {
9973 strcpy(router_str,"pri");
9974 } else
9975 if ( ((card->options.routing_type4&ROUTER_MASK)==
9976 SECONDARY_ROUTER)
9977 #ifdef QETH_IPV6
9978 &&
9979 ( ((card->options.routing_type6&ROUTER_MASK)==
9980 SECONDARY_ROUTER)||
9981 (!qeth_is_supported(IPA_IPv6)) )
9982 #endif /* QETH_IPV6 */
9983 ) {
9984 strcpy(router_str,"sec");
9985 } else
9986 if ( ((card->options.routing_type4&ROUTER_MASK)==
9987 MULTICAST_ROUTER)
9988 #ifdef QETH_IPV6
9989 &&
9990 ( ((card->options.routing_type6&ROUTER_MASK)==
9991 MULTICAST_ROUTER)||
9992 (!qeth_is_supported(IPA_IPv6)) )
9993 #endif /* QETH_IPV6 */
9994 ) {
9995 if (card->broadcast_capable==BROADCAST_WITHOUT_ECHO)
9996 strcpy(router_str,"mc+");
9997 else
9998 strcpy(router_str,"mc");
9999 } else
10000 if ( ((card->options.routing_type4&ROUTER_MASK)==
10001 PRIMARY_CONNECTOR)
10002 #ifdef QETH_IPV6
10003 &&
10004 ( ((card->options.routing_type6&ROUTER_MASK)==
10005 PRIMARY_CONNECTOR)||
10006 (!qeth_is_supported(IPA_IPv6)) )
10007 #endif /* QETH_IPV6 */
10008 ) {
10009 if (card->broadcast_capable==BROADCAST_WITHOUT_ECHO)
10010 strcpy(router_str,"p+c");
10011 else
10012 strcpy(router_str,"p.c");
10013 } else
10014 if ( ((card->options.routing_type4&ROUTER_MASK)==
10015 SECONDARY_CONNECTOR)
10016 #ifdef QETH_IPV6
10017 &&
10018 ( ((card->options.routing_type6&ROUTER_MASK)==
10019 SECONDARY_CONNECTOR)||
10020 (!qeth_is_supported(IPA_IPv6)) )
10021 #endif /* QETH_IPV6 */
10022 ) {
10023 if (card->broadcast_capable==BROADCAST_WITHOUT_ECHO)
10024 strcpy(router_str,"s+c");
10025 else
10026 strcpy(router_str,"s.c");
10027 } else
10028 if ( ((card->options.routing_type4&ROUTER_MASK)==
10029 NO_ROUTER)
10030 #ifdef QETH_IPV6
10031 &&
10032 ( ((card->options.routing_type6&ROUTER_MASK)==
10033 NO_ROUTER)||
10034 (!qeth_is_supported(IPA_IPv6)) )
10035 #endif /* QETH_IPV6 */
10036 ) {
10037 strcpy(router_str,"no");
10038 } else {
10039 strcpy(router_str,"mix");
10040 }
10041 strcpy(bufsize_str,
10042 (BUFFER_SIZE==16384)?"16k":
10043 (BUFFER_SIZE==24576)?"24k":
10044 (BUFFER_SIZE==32768)?"32k":
10045 (BUFFER_SIZE==40960)?"40k":
10046 "64k");
10047 if (atomic_read(&card->is_gone)) {
10048 length+=sprintf(buffer+length,
10049 "%04X/%04X/%04X x%02X %10s %14s %2i"
10050 " +++ CARD IS GONE +++\n",
10051 card->devno0,card->devno1,card->devno2,
10052 card->chpid,
10053 card->dev_name,
10054 qeth_get_cardname_short
10055 (card->type,card->link_type,
10056 card->is_guest_lan),
10057 card->options.portno);
10058 } else if (!atomic_read(&card->is_startlaned)) {
10059 length+=sprintf(buffer+length,
10060 "%04X/%04X/%04X x%02X %10s %14s %2i"
10061 " +++ CABLE PULLED +++\n",
10062 card->devno0,card->devno1,card->devno2,
10063 card->chpid,
10064 card->dev_name,
10065 qeth_get_cardname_short
10066 (card->type,card->link_type,
10067 card->is_guest_lan),
10068 card->options.portno);
10069 } else {
10070 length+=sprintf(buffer+length,
10071 "%04X/%04X/%04X x%02X %10s %14s %2i" \
10072 " %2s %10s %3s %3s %c %3i\n",
10073 card->devno0,card->devno1,card->devno2,
10074 card->chpid,card->dev_name,
10075 qeth_get_cardname_short
10076 (card->type,card->link_type,
10077 card->is_guest_lan),
10078 card->options.portno,
10079 checksum_str,
10080 queueing_str,router_str,bufsize_str,
10081 (card->options.memusage==
10082 MEMUSAGE_CONTIG)?'c':' ',
10083 card->options.inbound_buffer_count);
10084 }
10085 card=card->next;
10086 }
10087
10088 out:
10089 info->len=length;
10090 /* unlock all the stuff */
10091 my_read_unlock(&list_lock);
10092 return rc;
10093 }
10094
qeth_find_card(char * buffer,int len)10095 static qeth_card_t *qeth_find_card(char *buffer,int len)
10096 {
10097 qeth_card_t *card;
10098 int devnamelen;
10099
10100 my_read_lock(&list_lock);
10101 card=firstcard;
10102 while (card) {
10103 devnamelen=0;
10104 while ( (devnamelen<DEV_NAME_LEN) &&
10105 ( (card->dev_name[devnamelen]!=' ') &&
10106 (card->dev_name[devnamelen]!=0) &&
10107 (card->dev_name[devnamelen]!='\n') ) ) {
10108 devnamelen++;
10109 }
10110 if ((!strncmp(card->dev_name,buffer,
10111 qeth_min(len,DEV_NAME_LEN)))&&
10112 (devnamelen==len) &&
10113 (!atomic_read(&card->shutdown_phase))) break;
10114 card=card->next;
10115 }
10116 my_read_unlock(&list_lock);
10117
10118 return card;
10119 }
10120
qeth_get_next_token(char * buffer,int * token_len,int * pos,int * end_pos,int count)10121 static int qeth_get_next_token(char *buffer,int *token_len,
10122 int *pos,int *end_pos,int count)
10123 {
10124 *token_len=0;
10125 *end_pos=*pos;
10126 if (*end_pos>=count) return 0;
10127 if (!buffer[*end_pos]) return 0;
10128 for (;;) {
10129 if ( (buffer[*end_pos]!=' ') &&
10130 (buffer[*end_pos]!='\t') &&
10131 (buffer[*end_pos]!='\n') &&
10132 (buffer[*end_pos]!='\r') &&
10133 (buffer[*end_pos]!=0) &&
10134 (*end_pos<count) ) {
10135 *end_pos=(*end_pos)+1;
10136 *token_len=(*token_len)+1;
10137 }
10138 else break;
10139 }
10140 return 1;
10141 }
10142
qeth_skip_whitespace(char * buffer,int * pos,int count)10143 static void qeth_skip_whitespace(char *buffer,int *pos,int count)
10144 {
10145 for (;;) {
10146 if (*pos>=count) return;
10147 if ((buffer[*pos]==' ')||
10148 (buffer[*pos]=='\t')||
10149 (buffer[*pos]=='\n')||
10150 (buffer[*pos]=='\r')) *pos=(*pos)+1;
10151 else return;
10152 }
10153 }
10154
10155 #define CHECK_MISSING_PARAMETER do { \
10156 pos=end_pos; \
10157 if (!qeth_get_next_token(buffer,&token_len,&pos,&end_pos,user_len)) { \
10158 PRINT_WARN("paramter missing on procfile input, " \
10159 "ignoring input!\n"); \
10160 goto out; \
10161 } \
10162 card=qeth_find_card(buffer+pos,token_len); \
10163 if (!card) { \
10164 PRINT_WARN("paramter invalid on procfile input, " \
10165 "ignoring input!\n"); \
10166 goto out; \
10167 } \
10168 } while (0)
10169
qeth_procfile_write(struct file * file,const char * user_buffer,size_t user_len,loff_t * offset)10170 static ssize_t qeth_procfile_write(struct file *file,
10171 const char *user_buffer,
10172 size_t user_len,loff_t *offset)
10173 {
10174 qeth_card_t *card;
10175 char *buffer;
10176 int token_len;
10177 int pos=0,end_pos;
10178 char dbf_text[15];
10179
10180 if (*offset) return user_len;
10181 buffer=vmalloc(__max(user_len+1,QETH_DBF_MISC_LEN));
10182 if (buffer == NULL)
10183 return -ENOMEM;
10184 memset(buffer,0,user_len+1);
10185
10186 if (copy_from_user(buffer, user_buffer, user_len)) {
10187 vfree (buffer);
10188 return -EFAULT;
10189 }
10190
10191 QETH_DBF_TEXT2(0,trace,"procwrit");
10192 QETH_DBF_TEXT2(0,misc,buffer);
10193
10194 if (!qeth_get_next_token(buffer,&token_len,&pos,&end_pos,user_len))
10195 goto out;
10196 qeth_skip_whitespace(buffer,&end_pos,user_len);
10197
10198 if (!strncmp(buffer+pos,"recover",token_len)) {
10199 CHECK_MISSING_PARAMETER;
10200 sprintf(dbf_text,"UTRC%4x",card->irq0);
10201 QETH_DBF_TEXT2(0,trace,dbf_text);
10202 atomic_set(&card->problem,
10203 PROBLEM_USER_TRIGGERED_RECOVERY);
10204 qeth_schedule_recovery(card);
10205
10206 } else if (!strncmp(buffer+pos,"remember",token_len)) {
10207 CHECK_MISSING_PARAMETER;
10208 sprintf(dbf_text,"remb%4x",card->irq0);
10209 QETH_DBF_TEXT2(0,trace,dbf_text);
10210 card->save_state_flag=1;
10211
10212 } else if (!strncmp(buffer+pos,"forget",token_len)) {
10213 CHECK_MISSING_PARAMETER;
10214 sprintf(dbf_text,"forg%4x",card->irq0);
10215 QETH_DBF_TEXT2(0,trace,dbf_text);
10216 card->save_state_flag=0;
10217 } else if (!strncmp(buffer+pos,"primary_router",token_len)) {
10218 CHECK_MISSING_PARAMETER;
10219 sprintf(dbf_text,"prir%4x",card->irq0);
10220 QETH_DBF_TEXT2(0,trace,dbf_text);
10221
10222 card->options.routing_type4=PRIMARY_ROUTER|
10223 RESET_ROUTING_FLAG;
10224 #ifdef QETH_IPV6
10225 card->options.routing_type6=PRIMARY_ROUTER|
10226 RESET_ROUTING_FLAG;
10227 #endif /* QETH_IPV6 */
10228 qeth_correct_routing_status(card);
10229 atomic_set(&card->enable_routing_attempts4,
10230 QETH_ROUTING_ATTEMPTS);
10231 #ifdef QETH_IPV6
10232 atomic_set(&card->enable_routing_attempts6,
10233 QETH_ROUTING_ATTEMPTS);
10234 #endif /* QETH_IPV6 */
10235 qeth_start_softsetup_thread(card);
10236 } else if (!strncmp(buffer+pos,"primary_router4",token_len)) {
10237 CHECK_MISSING_PARAMETER;
10238 sprintf(dbf_text,"pri4%4x",card->irq0);
10239 QETH_DBF_TEXT2(0,trace,dbf_text);
10240
10241 card->options.routing_type4=PRIMARY_ROUTER|
10242 RESET_ROUTING_FLAG;
10243 qeth_correct_routing_status(card);
10244 atomic_set(&card->enable_routing_attempts4,
10245 QETH_ROUTING_ATTEMPTS);
10246 qeth_start_softsetup_thread(card);
10247 #ifdef QETH_IPV6
10248 } else if (!strncmp(buffer+pos,"primary_router6",token_len)) {
10249 CHECK_MISSING_PARAMETER;
10250 sprintf(dbf_text,"pri6%4x",card->irq0);
10251 QETH_DBF_TEXT2(0,trace,dbf_text);
10252
10253 card->options.routing_type6=PRIMARY_ROUTER|
10254 RESET_ROUTING_FLAG;
10255 qeth_correct_routing_status(card);
10256 atomic_set(&card->enable_routing_attempts6,
10257 QETH_ROUTING_ATTEMPTS);
10258 qeth_start_softsetup_thread(card);
10259 #endif /* QETH_IPV6 */
10260 } else if (!strncmp(buffer+pos,"secondary_router",token_len)) {
10261 CHECK_MISSING_PARAMETER;
10262 sprintf(dbf_text,"secr%4x",card->irq0);
10263 QETH_DBF_TEXT2(0,trace,dbf_text);
10264
10265 card->options.routing_type4=SECONDARY_ROUTER|
10266 RESET_ROUTING_FLAG;
10267 #ifdef QETH_IPV6
10268 card->options.routing_type6=SECONDARY_ROUTER|
10269 RESET_ROUTING_FLAG;
10270 #endif /* QETH_IPV6 */
10271 qeth_correct_routing_status(card);
10272 atomic_set(&card->enable_routing_attempts4,
10273 QETH_ROUTING_ATTEMPTS);
10274 #ifdef QETH_IPV6
10275 atomic_set(&card->enable_routing_attempts6,
10276 QETH_ROUTING_ATTEMPTS);
10277 #endif /* QETH_IPV6 */
10278 qeth_start_softsetup_thread(card);
10279 } else if (!strncmp(buffer+pos,"secondary_router4",token_len)) {
10280 CHECK_MISSING_PARAMETER;
10281 sprintf(dbf_text,"sec4%4x",card->irq0);
10282 QETH_DBF_TEXT2(0,trace,dbf_text);
10283
10284 card->options.routing_type4=SECONDARY_ROUTER|
10285 RESET_ROUTING_FLAG;
10286 qeth_correct_routing_status(card);
10287 atomic_set(&card->enable_routing_attempts4,
10288 QETH_ROUTING_ATTEMPTS);
10289 qeth_start_softsetup_thread(card);
10290 #ifdef QETH_IPV6
10291 } else if (!strncmp(buffer+pos,"secondary_router6",token_len)) {
10292 CHECK_MISSING_PARAMETER;
10293 sprintf(dbf_text,"sec6%4x",card->irq0);
10294 QETH_DBF_TEXT2(0,trace,dbf_text);
10295
10296 card->options.routing_type6=SECONDARY_ROUTER|
10297 RESET_ROUTING_FLAG;
10298 qeth_correct_routing_status(card);
10299 atomic_set(&card->enable_routing_attempts6,
10300 QETH_ROUTING_ATTEMPTS);
10301 qeth_start_softsetup_thread(card);
10302 #endif /* QETH_IPV6 */
10303 } else if (!strncmp(buffer+pos,"multicast_router",token_len)) {
10304 CHECK_MISSING_PARAMETER;
10305 sprintf(dbf_text,"mcr %4x",card->irq0);
10306 QETH_DBF_TEXT2(0,trace,dbf_text);
10307
10308 card->options.routing_type4=MULTICAST_ROUTER|
10309 RESET_ROUTING_FLAG;
10310 #ifdef QETH_IPV6
10311 card->options.routing_type6=MULTICAST_ROUTER|
10312 RESET_ROUTING_FLAG;
10313 #endif /* QETH_IPV6 */
10314 qeth_correct_routing_status(card);
10315 atomic_set(&card->enable_routing_attempts4,
10316 QETH_ROUTING_ATTEMPTS);
10317 #ifdef QETH_IPV6
10318 atomic_set(&card->enable_routing_attempts6,
10319 QETH_ROUTING_ATTEMPTS);
10320 #endif /* QETH_IPV6 */
10321 qeth_start_softsetup_thread(card);
10322 } else if (!strncmp(buffer+pos,"multicast_router4",token_len)) {
10323 CHECK_MISSING_PARAMETER;
10324 sprintf(dbf_text,"mcr4%4x",card->irq0);
10325 QETH_DBF_TEXT2(0,trace,dbf_text);
10326
10327 card->options.routing_type4=MULTICAST_ROUTER|
10328 RESET_ROUTING_FLAG;
10329 qeth_correct_routing_status(card);
10330 atomic_set(&card->enable_routing_attempts4,
10331 QETH_ROUTING_ATTEMPTS);
10332 qeth_start_softsetup_thread(card);
10333 #ifdef QETH_IPV6
10334 } else if (!strncmp(buffer+pos,"multicast_router6",token_len)) {
10335 CHECK_MISSING_PARAMETER;
10336 sprintf(dbf_text,"mcr6%4x",card->irq0);
10337 QETH_DBF_TEXT2(0,trace,dbf_text);
10338
10339 card->options.routing_type6=MULTICAST_ROUTER|
10340 RESET_ROUTING_FLAG;
10341 qeth_correct_routing_status(card);
10342 atomic_set(&card->enable_routing_attempts6,
10343 QETH_ROUTING_ATTEMPTS);
10344 qeth_start_softsetup_thread(card);
10345 #endif /* QETH_IPV6 */
10346 } else if (!strncmp(buffer+pos,"primary_connector",token_len)) {
10347 CHECK_MISSING_PARAMETER;
10348 sprintf(dbf_text,"prc %4x",card->irq0);
10349 QETH_DBF_TEXT2(0,trace,dbf_text);
10350
10351 card->options.routing_type4=PRIMARY_CONNECTOR|
10352 RESET_ROUTING_FLAG;
10353 #ifdef QETH_IPV6
10354 card->options.routing_type6=PRIMARY_CONNECTOR|
10355 RESET_ROUTING_FLAG;
10356 #endif /* QETH_IPV6 */
10357 qeth_correct_routing_status(card);
10358 atomic_set(&card->enable_routing_attempts4,
10359 QETH_ROUTING_ATTEMPTS);
10360 #ifdef QETH_IPV6
10361 atomic_set(&card->enable_routing_attempts6,
10362 QETH_ROUTING_ATTEMPTS);
10363 #endif /* QETH_IPV6 */
10364 qeth_start_softsetup_thread(card);
10365 } else if (!strncmp(buffer+pos,"primary_connector4",token_len)) {
10366 CHECK_MISSING_PARAMETER;
10367 sprintf(dbf_text,"prc4%4x",card->irq0);
10368 QETH_DBF_TEXT2(0,trace,dbf_text);
10369
10370 card->options.routing_type4=PRIMARY_CONNECTOR|
10371 RESET_ROUTING_FLAG;
10372 qeth_correct_routing_status(card);
10373 atomic_set(&card->enable_routing_attempts4,
10374 QETH_ROUTING_ATTEMPTS);
10375 qeth_start_softsetup_thread(card);
10376 #ifdef QETH_IPV6
10377 } else if (!strncmp(buffer+pos,"primary_connector6",token_len)) {
10378 CHECK_MISSING_PARAMETER;
10379 sprintf(dbf_text,"prc6%4x",card->irq0);
10380 QETH_DBF_TEXT2(0,trace,dbf_text);
10381
10382 card->options.routing_type6=PRIMARY_CONNECTOR|
10383 RESET_ROUTING_FLAG;
10384 qeth_correct_routing_status(card);
10385 atomic_set(&card->enable_routing_attempts6,
10386 QETH_ROUTING_ATTEMPTS);
10387 qeth_start_softsetup_thread(card);
10388 #endif /* QETH_IPV6 */
10389 } else if (!strncmp(buffer+pos,"secondary_connector",token_len)) {
10390 CHECK_MISSING_PARAMETER;
10391 sprintf(dbf_text,"scc %4x",card->irq0);
10392 QETH_DBF_TEXT2(0,trace,dbf_text);
10393
10394 card->options.routing_type4=SECONDARY_CONNECTOR|
10395 RESET_ROUTING_FLAG;
10396 #ifdef QETH_IPV6
10397 card->options.routing_type6=SECONDARY_CONNECTOR|
10398 RESET_ROUTING_FLAG;
10399 #endif /* QETH_IPV6 */
10400 qeth_correct_routing_status(card);
10401 atomic_set(&card->enable_routing_attempts4,
10402 QETH_ROUTING_ATTEMPTS);
10403 #ifdef QETH_IPV6
10404 atomic_set(&card->enable_routing_attempts6,
10405 QETH_ROUTING_ATTEMPTS);
10406 #endif /* QETH_IPV6 */
10407 qeth_start_softsetup_thread(card);
10408 } else if (!strncmp(buffer+pos,"secondary_connector4",token_len)) {
10409 CHECK_MISSING_PARAMETER;
10410 sprintf(dbf_text,"scc4%4x",card->irq0);
10411 QETH_DBF_TEXT2(0,trace,dbf_text);
10412
10413 card->options.routing_type4=SECONDARY_CONNECTOR|
10414 RESET_ROUTING_FLAG;
10415 qeth_correct_routing_status(card);
10416 atomic_set(&card->enable_routing_attempts4,
10417 QETH_ROUTING_ATTEMPTS);
10418 qeth_start_softsetup_thread(card);
10419 #ifdef QETH_IPV6
10420 } else if (!strncmp(buffer+pos,"secondary_connector6",token_len)) {
10421 CHECK_MISSING_PARAMETER;
10422 sprintf(dbf_text,"scc6%4x",card->irq0);
10423 QETH_DBF_TEXT2(0,trace,dbf_text);
10424
10425 card->options.routing_type6=SECONDARY_CONNECTOR|
10426 RESET_ROUTING_FLAG;
10427 qeth_correct_routing_status(card);
10428 atomic_set(&card->enable_routing_attempts6,
10429 QETH_ROUTING_ATTEMPTS);
10430 qeth_start_softsetup_thread(card);
10431 #endif /* QETH_IPV6 */
10432 } else if (!strncmp(buffer+pos,"no_router",token_len)) {
10433 CHECK_MISSING_PARAMETER;
10434 sprintf(dbf_text,"nor %4x",card->irq0);
10435 QETH_DBF_TEXT2(0,trace,dbf_text);
10436
10437 card->options.routing_type4=NO_ROUTER|
10438 RESET_ROUTING_FLAG;
10439 #ifdef QETH_IPV6
10440 card->options.routing_type6=NO_ROUTER|
10441 RESET_ROUTING_FLAG;
10442 #endif /* QETH_IPV6 */
10443 atomic_set(&card->enable_routing_attempts4,
10444 QETH_ROUTING_ATTEMPTS);
10445 #ifdef QETH_IPV6
10446 atomic_set(&card->enable_routing_attempts6,
10447 QETH_ROUTING_ATTEMPTS);
10448 #endif /* QETH_IPV6 */
10449 qeth_start_softsetup_thread(card);
10450 } else if (!strncmp(buffer+pos,"no_router4",token_len)) {
10451 CHECK_MISSING_PARAMETER;
10452 sprintf(dbf_text,"nor4%4x",card->irq0);
10453 QETH_DBF_TEXT2(0,trace,dbf_text);
10454
10455 card->options.routing_type4=NO_ROUTER|
10456 RESET_ROUTING_FLAG;
10457 atomic_set(&card->enable_routing_attempts4,
10458 QETH_ROUTING_ATTEMPTS);
10459 qeth_start_softsetup_thread(card);
10460 #ifdef QETH_IPV6
10461 } else if (!strncmp(buffer+pos,"no_router6",token_len)) {
10462 CHECK_MISSING_PARAMETER;
10463 sprintf(dbf_text,"nor6%4x",card->irq0);
10464 QETH_DBF_TEXT2(0,trace,dbf_text);
10465
10466 card->options.routing_type6=NO_ROUTER|
10467 RESET_ROUTING_FLAG;
10468 atomic_set(&card->enable_routing_attempts6,
10469 QETH_ROUTING_ATTEMPTS);
10470 qeth_start_softsetup_thread(card);
10471 #endif /* QETH_IPV6 */
10472 } else {
10473 PRINT_WARN("unknown command input in procfile\n");
10474 }
10475 #undef CHECK_MISSING_PARAMETER
10476 out:
10477
10478 *offset = *offset + user_len;
10479 vfree(buffer);
10480
10481 return user_len;
10482 }
10483
10484 #define _OUTP_IT(x...) c+=sprintf(buffer+c,x)
10485
10486 #ifdef QETH_PERFORMANCE_STATS
qeth_perf_procfile_read(char * buffer,char ** buffer_location,off_t offset,int buffer_length,int * eof,void * data)10487 static int qeth_perf_procfile_read(char *buffer,char **buffer_location,
10488 off_t offset,int buffer_length,int *eof,
10489 void *data)
10490 {
10491 int c=0;
10492 qeth_card_t *card;
10493 /* we are always called with buffer_length=4k, so we all
10494 deliver on the first read */
10495 if (offset>0) return 0;
10496
10497 QETH_DBF_TEXT2(0,trace,"perfpfrd");
10498
10499 card=firstcard;
10500
10501 while (card) {
10502 _OUTP_IT("For card with devnos 0x%X/0x%X/0x%X (%s):\n",
10503 card->devno0,card->devno1,card->devno2,
10504 card->dev_name);
10505 _OUTP_IT(" Skb's/buffers received : %i/%i\n",
10506 card->perf_stats.skbs_rec,
10507 card->perf_stats.bufs_rec);
10508 _OUTP_IT(" Skb's/buffers sent : %i/%i\n",
10509 card->perf_stats.skbs_sent,
10510 card->perf_stats.bufs_sent);
10511 _OUTP_IT("\n");
10512 _OUTP_IT(" Skb's/buffers sent without packing : %i/%i\n",
10513 card->perf_stats.skbs_sent_dont_pack,
10514 card->perf_stats.bufs_sent_dont_pack);
10515 _OUTP_IT(" Skb's/buffers sent with packing : %i/%i\n",
10516 card->perf_stats.skbs_sent_pack,
10517 card->perf_stats.bufs_sent_pack);
10518 _OUTP_IT("\n");
10519 _OUTP_IT(" Packing state changes no pkg.->packing : %i/%i\n",
10520 card->perf_stats.sc_dp_p,
10521 card->perf_stats.sc_p_dp);
10522 _OUTP_IT(" Current buffer usage (outbound q's) : " \
10523 "%i/%i/%i/%i\n",
10524 atomic_read(&card->outbound_used_buffers[0]),
10525 atomic_read(&card->outbound_used_buffers[1]),
10526 atomic_read(&card->outbound_used_buffers[2]),
10527 atomic_read(&card->outbound_used_buffers[3]));
10528 _OUTP_IT("\n");
10529 _OUTP_IT(" Inbound time (in us) : %i\n",
10530 card->perf_stats.inbound_time);
10531 _OUTP_IT(" Inbound cnt : %i\n",
10532 card->perf_stats.inbound_cnt);
10533 _OUTP_IT(" Outbound time (in us, incl QDIO) : %i\n",
10534 card->perf_stats.outbound_time);
10535 _OUTP_IT(" Outbound cnt : %i\n",
10536 card->perf_stats.outbound_cnt);
10537 _OUTP_IT(" Watermarks: L/H=%i/%i\n",
10538 LOW_WATERMARK_PACK,HIGH_WATERMARK_PACK);
10539 _OUTP_IT("\n");
10540
10541 card=card->next;
10542 }
10543
10544 return c;
10545 }
10546
10547 static struct proc_dir_entry *qeth_perf_proc_file;
10548
10549 #endif /* QETH_PERFORMANCE_STATS */
10550
qeth_ipato_procfile_open(struct inode * inode,struct file * file)10551 static int qeth_ipato_procfile_open(struct inode *inode, struct file *file)
10552 {
10553 char text[33];
10554 ipato_entry_t *ipato_entry;
10555 qeth_card_t *card;
10556 qeth_vipa_entry_t *vipa_entry;
10557 int rc=0;
10558 tempinfo_t *info;
10559 int size;
10560 char entry_type[5];
10561
10562 MOD_INC_USE_COUNT;
10563 info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
10564 if (info == NULL) {
10565 PRINT_WARN("No memory available for data\n");
10566 return -ENOMEM;
10567 } else {
10568 file->private_data = (void *) info;
10569 }
10570 info->len=0;
10571
10572 QETH_DBF_TEXT2(0,trace,"ipatorea");
10573 /* lock all the stuff */
10574 my_spin_lock(&ipato_list_lock);
10575 my_read_lock(&list_lock);
10576
10577 size=64; /* for inv4/6 etc. */
10578
10579 ipato_entry=ipato_entries;
10580 while (ipato_entry) {
10581 ipato_entry=ipato_entry->next;
10582 size+=64;
10583 }
10584 card=firstcard;
10585 while (card) {
10586 my_read_lock(&card->vipa_list_lock);
10587 vipa_entry=card->vipa_list;
10588 while (vipa_entry) {
10589 vipa_entry=vipa_entry->next;
10590 size+=64;
10591 }
10592 /*my_read_unlock(&card->vipa_list_lock); don't unlock it here*/
10593 card=card->next;
10594 }
10595 info->data = (char *) vmalloc (size);
10596 if (info->data == NULL) {
10597 PRINT_WARN("No memory available for data\n");
10598 vfree (info);
10599 rc=-ENOMEM;
10600 goto out;
10601 }
10602
10603 #define _IOUTP_IT(x...) info->len+=sprintf(info->data+info->len,x)
10604 if (ipato_inv4)
10605 _IOUTP_IT("inv4\n");
10606 ipato_entry=ipato_entries;
10607 text[8]=0;
10608 while (ipato_entry) {
10609 if (ipato_entry->version==4) {
10610 qeth_convert_addr_to_text(4,ipato_entry->addr,text);
10611 _IOUTP_IT("add4 %s/%i%s%s\n",text,
10612 ipato_entry->mask_bits,
10613 ipato_entry->dev_name[0]?":":"",
10614 ipato_entry->dev_name[0]?
10615 ipato_entry->dev_name:"");
10616 }
10617 ipato_entry=ipato_entry->next;
10618 }
10619
10620 if (ipato_inv6)
10621 _IOUTP_IT("inv6\n");
10622 ipato_entry=ipato_entries;
10623 text[32]=0;
10624 while (ipato_entry) {
10625 if (ipato_entry->version==6) {
10626 qeth_convert_addr_to_text(6,ipato_entry->addr,text);
10627 _IOUTP_IT("add6 %s/%i%s%s\n",text,
10628 ipato_entry->mask_bits,
10629 ipato_entry->dev_name[0]?":":"",
10630 ipato_entry->dev_name[0]?
10631 ipato_entry->dev_name:"");
10632 }
10633 ipato_entry=ipato_entry->next;
10634 }
10635 card=firstcard;
10636 while (card) {
10637 vipa_entry=card->vipa_list;
10638 while (vipa_entry) {
10639 strcpy(entry_type,(vipa_entry->flag==
10640 IPA_SETIP_VIPA_FLAGS)?
10641 "vipa":"rxip");
10642 if (vipa_entry->version==4) {
10643 _IOUTP_IT("add_%s4 %02x%02x%02x%02x:%s\n",
10644 entry_type,
10645 vipa_entry->ip[0],
10646 vipa_entry->ip[1],
10647 vipa_entry->ip[2],
10648 vipa_entry->ip[3],
10649 card->dev_name);
10650 } else {
10651 _IOUTP_IT("add_%s6 %02x%02x%02x%02x" \
10652 "%02x%02x%02x%02x" \
10653 "%02x%02x%02x%02x" \
10654 "%02x%02x%02x%02x:%s\n",
10655 entry_type,
10656 vipa_entry->ip[0],
10657 vipa_entry->ip[1],
10658 vipa_entry->ip[2],
10659 vipa_entry->ip[3],
10660 vipa_entry->ip[4],
10661 vipa_entry->ip[5],
10662 vipa_entry->ip[6],
10663 vipa_entry->ip[7],
10664 vipa_entry->ip[8],
10665 vipa_entry->ip[9],
10666 vipa_entry->ip[10],
10667 vipa_entry->ip[11],
10668 vipa_entry->ip[12],
10669 vipa_entry->ip[13],
10670 vipa_entry->ip[14],
10671 vipa_entry->ip[15],
10672 card->dev_name);
10673 }
10674 vipa_entry=vipa_entry->next;
10675 }
10676 card=card->next;
10677 }
10678 out:
10679 /* unlock all the stuff */
10680 card=firstcard;
10681 while (card) {
10682 /*my_read_lock(&card->vipa_list_lock); don't lock it here */
10683 my_read_unlock(&card->vipa_list_lock);
10684 card=card->next;
10685 }
10686 my_read_unlock(&list_lock);
10687 my_spin_unlock(&ipato_list_lock);
10688
10689 return rc;
10690 }
10691
qeth_procfile_read(struct file * file,char * user_buf,size_t user_len,loff_t * offset)10692 static ssize_t qeth_procfile_read(struct file *file,char *user_buf,
10693 size_t user_len,loff_t * offset)
10694 {
10695 loff_t len;
10696 tempinfo_t *p_info = (tempinfo_t *) file->private_data;
10697 loff_t n = *offset;
10698 unsigned long pos = n;
10699
10700 if (pos != n || pos >= p_info->len) {
10701 return 0;
10702 } else {
10703 len = __min(user_len, (p_info->len - pos));
10704 if (copy_to_user (user_buf, &(p_info->data[pos]), len))
10705 return -EFAULT;
10706 *offset = pos + len;
10707 return len;
10708 }
10709 }
10710
10711 /* ATT: this is also the procfile release function for the ipato
10712 * procfs entry */
qeth_procfile_release(struct inode * inode,struct file * file)10713 static int qeth_procfile_release(struct inode *inode,struct file *file)
10714 {
10715 tempinfo_t *p_info = (tempinfo_t *) file->private_data;
10716 struct list_head *l,*n;
10717 struct qeth_notify_list *n_entry;
10718
10719 if (p_info) {
10720 if (p_info->data)
10721 vfree (p_info->data);
10722 vfree (p_info);
10723 }
10724 /*remove task-entry to notify from list */
10725 spin_lock(¬ify_lock);
10726 list_for_each_safe(l, n, ¬ify_list) {
10727 n_entry = list_entry(l, struct qeth_notify_list, list);
10728 if (n_entry->task == current) {
10729 list_del(&n_entry->list);
10730 kfree(n_entry);
10731 }
10732 }
10733 spin_unlock(¬ify_lock);
10734 MOD_DEC_USE_COUNT;
10735 return 0;
10736 }
10737
qeth_ipato_procfile_write(struct file * file,const char * user_buffer,size_t user_len,loff_t * offset)10738 static ssize_t qeth_ipato_procfile_write(struct file *file,
10739 const char *user_buffer,
10740 size_t user_len,loff_t *offset)
10741 {
10742 int add,version;
10743 char text[33];
10744 __u8 addr[16];
10745 int len,i,flag;
10746 int mask_bits;
10747 char *buffer;
10748 int dev_name_there;
10749 char *dev_name_ptr;
10750 qeth_card_t *card;
10751 #define BUFFER_LEN (10+32+1+5+1+DEV_NAME_LEN+1)
10752
10753 if (*offset) return user_len;
10754 buffer=vmalloc(__max(__max(user_len+1,BUFFER_LEN),QETH_DBF_MISC_LEN));
10755
10756 if (buffer == NULL)
10757 return -ENOMEM;
10758 /* BUFFER_LEN=command incl. blank+addr+slash+mask_bits+
10759 * colon+DEV_NAME_LEN+zero */
10760 memset(buffer,0,BUFFER_LEN);
10761
10762 if (copy_from_user(buffer, user_buffer, user_len)) {
10763 vfree (buffer);
10764 return -EFAULT;
10765 }
10766
10767 QETH_DBF_TEXT2(0,trace,"ipatowri");
10768 QETH_DBF_TEXT2(0,misc,buffer);
10769 if (!strncmp(buffer,"inv4",4)) {
10770 ipato_inv4=1-ipato_inv4;
10771 goto out;
10772 }
10773 if (!strncmp(buffer,"inv6",4)) {
10774 ipato_inv6=1-ipato_inv6;
10775 goto out;
10776 }
10777 if ( (!strncmp(buffer,"add4 ",5)) ||
10778 (!strncmp(buffer,"add6 ",5)) ||
10779 (!strncmp(buffer,"del4 ",5)) ||
10780 (!strncmp(buffer,"del6 ",5)) ) {
10781 text[8]=0;
10782 text[32]=0;
10783 add=!strncmp(buffer,"add",3);
10784 version=(buffer[3]=='4')?4:6;
10785 len=(version==4)?8:32;
10786 strncpy(text,buffer+5,len);
10787 if (qeth_convert_text_to_addr(version,text,addr)) {
10788 PRINT_ERR("error in parsing ipato information " \
10789 "(addr)\n");
10790 goto out;
10791 }
10792 strncpy(text,buffer+5+len+1,10);
10793 /* we prepare mask_bits for qeth_getints */
10794 dev_name_there=0;
10795 for (i=5+len+1;i<BUFFER_LEN;i++) {
10796 if (*(buffer+i)=='\n') {
10797 *(buffer+i)=0;
10798 break;
10799 }
10800 if (*(buffer+i)==':') {
10801 *(buffer+i)=0; /* so that qeth_getint works */
10802 dev_name_there=i;
10803 break;
10804 }
10805 if (*(buffer+i)==0)
10806 break;
10807 }
10808 mask_bits=qeth_getint(buffer+5+len+1,0);
10809 if ((mask_bits<0)||(mask_bits>((version==4)?32:128))) {
10810 PRINT_ERR("error in parsing ipato information " \
10811 "(mask bits)\n");
10812 goto out;
10813 }
10814 if (dev_name_there) {
10815 dev_name_ptr=buffer+dev_name_there+1;
10816 /* wipe out the linefeed */
10817 for (i=dev_name_there+1;
10818 i<dev_name_there+1+DEV_NAME_LEN+1;i++)
10819 if (*(buffer+i)=='\n') *(buffer+i)=0;
10820 } else
10821 dev_name_ptr=NULL;
10822
10823 if (add)
10824 qeth_add_ipato_entry(version,addr,mask_bits,
10825 dev_name_ptr);
10826 else
10827 qeth_del_ipato_entry(version,addr,mask_bits,
10828 dev_name_ptr);
10829 goto out;
10830 }
10831 if ( (!strncmp(buffer,"add_vipa4 ",10)) ||
10832 (!strncmp(buffer,"add_rxip4 ",10)) ||
10833 (!strncmp(buffer,"add_vipa6 ",10)) ||
10834 (!strncmp(buffer,"add_rxip6 ",10)) ||
10835 (!strncmp(buffer,"del_vipa4 ",10)) ||
10836 (!strncmp(buffer,"del_rxip4 ",10)) ||
10837 (!strncmp(buffer,"del_vipa6 ",10)) ||
10838 (!strncmp(buffer,"del_rxip6 ",10)) ) {
10839 text[8]=0;
10840 text[32]=0;
10841 add=!strncmp(buffer,"add",3);
10842 flag=(!strncmp(buffer+4,"vipa",4))?IPA_SETIP_VIPA_FLAGS:
10843 IPA_SETIP_TAKEOVER_FLAGS;
10844 version=(buffer[8]=='4')?4:6;
10845 len=(version==4)?8:32;
10846 strncpy(text,buffer+10,len);
10847 if (qeth_convert_text_to_addr(version,text,addr)) {
10848 PRINT_ERR("error in parsing vipa/rxip information " \
10849 "(addr)\n");
10850 goto out;
10851 }
10852 if (*(buffer+10+len)!=':') {
10853 PRINT_ERR("error in parsing vipa/rxip information " \
10854 "(no interface)\n");
10855 goto out;
10856 }
10857 /* interface name is at buffer+10+len+1 */
10858 /* wipe out the \n */
10859 for (i=10+len+1;i<10+len+1+DEV_NAME_LEN+1;i++)
10860 if (*(buffer+i)=='\n') *(buffer+i)=0;
10861 card=qeth_get_card_by_name(buffer+10+len+1);
10862 if (!card) {
10863 PRINT_ERR("error in parsing vipa/rxip information " \
10864 "(unknown interface)\n");
10865 goto out;
10866 }
10867 if (add)
10868 i=qeth_add_vipa_entry(card,version,addr,flag);
10869 else
10870 i=qeth_del_vipa_entry(card,version,addr,flag);
10871 if (!i) qeth_start_softsetup_thread(card);
10872 goto out;
10873 }
10874 PRINT_ERR("unknown ipato information command\n");
10875 out:
10876 vfree(buffer);
10877 *offset = user_len;
10878 #undef BUFFER_LEN
10879 return user_len;
10880 }
10881
qeth_snmp_register(struct task_struct * p,unsigned long arg)10882 static int qeth_snmp_register(struct task_struct *p, unsigned long arg)
10883 {
10884 struct qeth_notify_list *n_entry;
10885 struct list_head *l;
10886 QETH_DBF_TEXT5(0,trace,"snmpreg");
10887
10888 /*check first if entry already exists*/
10889
10890 spin_lock(¬ify_lock);
10891 list_for_each(l, ¬ify_list) {
10892 n_entry = list_entry(l, struct qeth_notify_list, list);
10893 if (n_entry->task == p) {
10894 n_entry->signum = (int) arg;
10895 goto reg_out;
10896 }
10897
10898 }
10899 spin_unlock(¬ify_lock);
10900 n_entry = (struct qeth_notify_list *)
10901 kmalloc(sizeof(struct qeth_notify_list),GFP_KERNEL);
10902 if (!n_entry)
10903 return -ENOMEM;
10904 n_entry->task = p;
10905 n_entry->signum = (int) arg;
10906 spin_lock(¬ify_lock);
10907 list_add(&n_entry->list,¬ify_list);
10908 reg_out:
10909 spin_unlock(¬ify_lock);
10910 return 0;
10911 }
10912
qeth_procfile_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)10913 static int qeth_procfile_ioctl(struct inode *inode, struct file *file,
10914 unsigned int cmd, unsigned long arg)
10915 {
10916
10917 int result;
10918
10919 switch (cmd) {
10920 case QETH_IOCPROC_REGISTER:
10921 if ( (arg > 0) && (arg < 32) )
10922 result = qeth_snmp_register(current,arg);
10923 else
10924 result = -EINVAL;
10925 break;
10926 default:
10927 result = -EOPNOTSUPP;
10928 }
10929 return result;
10930 };
10931
10932 static struct file_operations qeth_procfile_fops =
10933 {
10934 ioctl:qeth_procfile_ioctl,
10935 read:qeth_procfile_read,
10936 write:qeth_procfile_write,
10937 open:qeth_procfile_open,
10938 release:qeth_procfile_release,
10939 };
10940
10941 static struct proc_dir_entry *qeth_proc_file;
10942
10943 static struct file_operations qeth_ipato_procfile_fops =
10944 {
10945 read:qeth_procfile_read, /* same as above! */
10946 write:qeth_ipato_procfile_write,
10947 open:qeth_ipato_procfile_open,
10948 release:qeth_procfile_release /* same as above! */
10949 };
10950
10951 static struct proc_dir_entry *qeth_ipato_proc_file;
10952
qeth_add_procfs_entries(void)10953 static void qeth_add_procfs_entries(void)
10954 {
10955 proc_file_registration=0;
10956 qeth_proc_file=create_proc_entry(QETH_PROCFILE_NAME,
10957 S_IFREG|0644,&proc_root);
10958 if (qeth_proc_file) {
10959 qeth_proc_file->proc_fops = &qeth_procfile_fops;
10960 } else proc_file_registration=-1;
10961
10962 if (proc_file_registration)
10963 PRINT_WARN("was not able to register proc-file (%i).\n",
10964 proc_file_registration);
10965 proc_ipato_file_registration=0;
10966 qeth_ipato_proc_file=create_proc_entry(QETH_IPA_PROCFILE_NAME,
10967 S_IFREG|0644,&proc_root);
10968 if (qeth_ipato_proc_file) {
10969 qeth_ipato_proc_file->proc_fops = &qeth_ipato_procfile_fops;
10970 } else proc_ipato_file_registration=-1;
10971
10972 if (proc_ipato_file_registration)
10973 PRINT_WARN("was not able to register ipato-proc-file (%i).\n",
10974 proc_ipato_file_registration);
10975
10976 #ifdef QETH_PERFORMANCE_STATS
10977 proc_perf_file_registration=0;
10978 qeth_perf_proc_file=create_proc_entry(QETH_PERF_PROCFILE_NAME,
10979 S_IFREG|0444,&proc_root);
10980 if (qeth_perf_proc_file) {
10981 qeth_perf_proc_file->read_proc=&qeth_perf_procfile_read;
10982 } else proc_perf_file_registration=-1;
10983
10984 if (proc_perf_file_registration)
10985 PRINT_WARN("was not able to register perf. proc-file (%i).\n",
10986 proc_perf_file_registration);
10987 #endif /* QETH_PERFORMANCE_STATS */
10988 }
10989
10990 #ifdef MODULE
qeth_remove_procfs_entries(void)10991 static void qeth_remove_procfs_entries(void)
10992 {
10993 if (!proc_file_registration) /* means if it went ok earlier */
10994 remove_proc_entry(QETH_PROCFILE_NAME,&proc_root);
10995
10996 if (!proc_ipato_file_registration) /* means if it went ok earlier */
10997 remove_proc_entry(QETH_IPA_PROCFILE_NAME,&proc_root);
10998
10999 #ifdef QETH_PERFORMANCE_STATS
11000 if (!proc_perf_file_registration) /* means if it went ok earlier */
11001 remove_proc_entry(QETH_PERF_PROCFILE_NAME,&proc_root);
11002 #endif /* QETH_PERFORMANCE_STATS */
11003 }
11004 #endif /* MODULE */
11005
qeth_unregister_dbf_views(void)11006 static void qeth_unregister_dbf_views(void)
11007 {
11008 if (qeth_dbf_setup)
11009 debug_unregister(qeth_dbf_setup);
11010 if (qeth_dbf_qerr)
11011 debug_unregister(qeth_dbf_qerr);
11012 if (qeth_dbf_sense)
11013 debug_unregister(qeth_dbf_sense);
11014 if (qeth_dbf_misc)
11015 debug_unregister(qeth_dbf_misc);
11016 if (qeth_dbf_data)
11017 debug_unregister(qeth_dbf_data);
11018 if (qeth_dbf_control)
11019 debug_unregister(qeth_dbf_control);
11020 if (qeth_dbf_trace)
11021 debug_unregister(qeth_dbf_trace);
11022 }
11023
qeth_chandev_shutdown(struct net_device * dev)11024 static int qeth_chandev_shutdown(struct net_device *dev)
11025 {
11026
11027 qeth_card_t* card;
11028
11029 card = (qeth_card_t *)dev->priv;
11030
11031 my_spin_lock(&setup_lock);
11032
11033 qeth_remove_card_from_list(card);
11034 QETH_DBF_TEXT4(0,trace,"freecard");
11035 qeth_free_card(card);
11036
11037 my_spin_unlock(&setup_lock);
11038
11039 return 0;
11040
11041 }
11042
11043 #ifdef QETH_IPV6
qeth_ipv6_init(void)11044 static int qeth_ipv6_init(void)
11045 {
11046 qeth_old_arp_constructor=arp_tbl.constructor;
11047 write_lock(&arp_tbl.lock);
11048 arp_tbl.constructor=qeth_arp_constructor;
11049 write_unlock(&arp_tbl.lock);
11050
11051 /* generate the memory leak here */
11052 arp_direct_ops=(struct neigh_ops*)
11053 kmalloc(sizeof(struct neigh_ops),GFP_KERNEL);
11054 if (!arp_direct_ops)
11055 return -ENOMEM;
11056
11057 memcpy(arp_direct_ops,&arp_direct_ops_template,
11058 sizeof(struct neigh_ops));
11059 return 0;
11060 }
11061
qeth_ipv6_uninit(void)11062 static void qeth_ipv6_uninit(void)
11063 {
11064 write_lock(&arp_tbl.lock);
11065 arp_tbl.constructor=qeth_old_arp_constructor;
11066 write_unlock(&arp_tbl.lock);
11067 }
11068 #endif /* QETH_IPV6 */
11069
qeth_get_internal_functions(void)11070 static void qeth_get_internal_functions(void)
11071 {
11072 struct net_device dev;
11073 ether_setup(&dev);
11074 qeth_my_eth_header=dev.hard_header;
11075 qeth_my_eth_rebuild_header=dev.rebuild_header;
11076 qeth_my_eth_header_cache=dev.hard_header_cache;
11077 qeth_my_eth_header_cache_update=dev.header_cache_update;
11078 qeth_my_eth_header=dev.hard_header;
11079 #ifdef CONFIG_TR
11080 tr_setup(&dev);
11081 qeth_my_tr_header=dev.hard_header;
11082 qeth_my_tr_rebuild_header=dev.rebuild_header;
11083 #endif /* CONFIG_TR */
11084 }
11085
11086 #ifdef MODULE
init_module(void)11087 int init_module(void)
11088 #else /* MODULE */
11089 static int __init qeth_init(void)
11090 #endif /* MODULE */
11091 {
11092 int result;
11093 #ifdef MODULE
11094 void *ptr;
11095 #endif /* MODULE */
11096
11097 int unregister_from_chandev=0;
11098 int cards_found;
11099
11100 qeth_eyecatcher();
11101
11102 printk("qeth: loading %s\n",version);
11103
11104 #ifdef MODULE
11105 global_stay_in_mem = chandev_persist(chandev_type_qeth);
11106 #endif /* MODULE */
11107
11108 /*SNMP init stuff*/
11109 spin_lock_init(¬ify_lock);
11110 INIT_LIST_HEAD(¬ify_list);
11111
11112 spin_lock_init(&setup_lock);
11113
11114 spin_lock_init(&ipato_list_lock);
11115
11116 qeth_get_internal_functions();
11117
11118 qeth_alloc_spare_bufs();
11119
11120 #ifdef QETH_IPV6
11121 if (qeth_ipv6_init()) goto oom;
11122 #endif /* QETH_IPV6 */
11123
11124 qeth_dbf_setup=debug_register(QETH_DBF_SETUP_NAME,
11125 QETH_DBF_SETUP_INDEX,
11126 QETH_DBF_SETUP_NR_AREAS,
11127 QETH_DBF_SETUP_LEN);
11128 if (!qeth_dbf_setup) goto oom;
11129
11130 debug_register_view(qeth_dbf_setup,&debug_hex_ascii_view);
11131 debug_set_level(qeth_dbf_setup,QETH_DBF_SETUP_LEVEL);
11132
11133 qeth_dbf_misc=debug_register(QETH_DBF_MISC_NAME,
11134 QETH_DBF_MISC_INDEX,
11135 QETH_DBF_MISC_NR_AREAS,
11136 QETH_DBF_MISC_LEN);
11137 if (!qeth_dbf_misc) goto oom;
11138
11139 debug_register_view(qeth_dbf_misc,&debug_hex_ascii_view);
11140 debug_set_level(qeth_dbf_misc,QETH_DBF_MISC_LEVEL);
11141
11142 qeth_dbf_data=debug_register(QETH_DBF_DATA_NAME,
11143 QETH_DBF_DATA_INDEX,
11144 QETH_DBF_DATA_NR_AREAS,
11145 QETH_DBF_DATA_LEN);
11146 if (!qeth_dbf_data) goto oom;
11147
11148 debug_register_view(qeth_dbf_data,&debug_hex_ascii_view);
11149 debug_set_level(qeth_dbf_data,QETH_DBF_DATA_LEVEL);
11150
11151 qeth_dbf_control=debug_register(QETH_DBF_CONTROL_NAME,
11152 QETH_DBF_CONTROL_INDEX,
11153 QETH_DBF_CONTROL_NR_AREAS,
11154 QETH_DBF_CONTROL_LEN);
11155 if (!qeth_dbf_control) goto oom;
11156
11157 debug_register_view(qeth_dbf_control,&debug_hex_ascii_view);
11158 debug_set_level(qeth_dbf_control,QETH_DBF_CONTROL_LEVEL);
11159
11160 qeth_dbf_sense=debug_register(QETH_DBF_SENSE_NAME,
11161 QETH_DBF_SENSE_INDEX,
11162 QETH_DBF_SENSE_NR_AREAS,
11163 QETH_DBF_SENSE_LEN);
11164 if (!qeth_dbf_sense) goto oom;
11165
11166 debug_register_view(qeth_dbf_sense,&debug_hex_ascii_view);
11167 debug_set_level(qeth_dbf_sense,QETH_DBF_SENSE_LEVEL);
11168
11169 qeth_dbf_qerr=debug_register(QETH_DBF_QERR_NAME,
11170 QETH_DBF_QERR_INDEX,
11171 QETH_DBF_QERR_NR_AREAS,
11172 QETH_DBF_QERR_LEN);
11173 if (!qeth_dbf_qerr) goto oom;
11174
11175 debug_register_view(qeth_dbf_qerr,&debug_hex_ascii_view);
11176 debug_set_level(qeth_dbf_qerr,QETH_DBF_QERR_LEVEL);
11177
11178 qeth_dbf_trace=debug_register(QETH_DBF_TRACE_NAME,
11179 QETH_DBF_TRACE_INDEX,
11180 QETH_DBF_TRACE_NR_AREAS,
11181 QETH_DBF_TRACE_LEN);
11182 if (!qeth_dbf_trace) goto oom;
11183
11184 debug_register_view(qeth_dbf_trace,&debug_hex_ascii_view);
11185 debug_set_level(qeth_dbf_trace,QETH_DBF_TRACE_LEVEL);
11186
11187 cards_found = chandev_register_and_probe
11188 (qeth_probe,(chandev_shutdownfunc)qeth_chandev_shutdown,
11189 (chandev_msck_notification_func)qeth_chandev_msck_notfunc,
11190 chandev_type_qeth);
11191 if (cards_found>0)
11192 result=0;
11193 else if (cards_found<0) {
11194 result=cards_found;
11195 global_stay_in_mem=0;
11196 } else result=-ENODEV;
11197
11198 unregister_from_chandev=(cards_found>=0);
11199 if ((result)&&(global_stay_in_mem)) {
11200 result=0;
11201 }
11202
11203 #ifdef MODULE
11204 QETH_DBF_TEXT0(0,setup,"initmodl");
11205 ptr=&init_module;
11206 QETH_DBF_HEX0(0,setup,&ptr,sizeof(void*));
11207 #endif /* MODULE */
11208
11209 if (!result) {
11210 qeth_register_notifiers();
11211 qeth_add_procfs_entries();
11212 } else {
11213 /* don't call it with shutdown -- there was not device
11214 * initialized or an internal problem in chandev, better
11215 * have him not try to call us */
11216 if (unregister_from_chandev)
11217 chandev_unregister(qeth_probe,0);
11218 qeth_unregister_dbf_views();
11219 #ifdef QETH_IPV6
11220 qeth_ipv6_uninit();
11221 #endif /* QETH_IPV6 */
11222 qeth_free_all_spare_bufs();
11223 }
11224
11225 return result;
11226 oom:
11227 PRINT_ERR("not enough memory for dbf. Will not load module.\n");
11228 result=-ENOMEM;
11229 #ifdef QETH_IPV6
11230 qeth_ipv6_uninit();
11231 #endif /* QETH_IPV6 */
11232 qeth_unregister_dbf_views();
11233 qeth_free_all_spare_bufs();
11234 return result;
11235 }
11236
11237 #ifdef MODULE
cleanup_module(void)11238 void cleanup_module(void)
11239 {
11240 #ifdef QETH_IPV6
11241 qeth_ipv6_uninit();
11242 #endif /* QETH_IPV6 */
11243 qeth_unregister_notifiers();
11244
11245 qeth_remove_procfs_entries();
11246
11247 QETH_DBF_TEXT1(0,trace,"cleanup.");
11248
11249 chandev_unregister(qeth_probe, 1 );
11250
11251 qeth_free_all_spare_bufs();
11252
11253 qeth_unregister_dbf_views();
11254
11255 printk("qeth: %s: module removed\n",version);
11256 }
11257 EXPORT_SYMBOL(qeth_eyecatcher); /* yeah, i know, could be outside of
11258 the ifdef */
11259 #else /* MODULE */
11260 __initcall(qeth_init);
11261 #endif /* MODULE */
11262