Import 2.3.99pre6-5
[davej-history.git] / drivers / net / wan / sdla_fr.c
blobd7a246dd99667c632d263b05e6c2f8d50643b24a
1 /*****************************************************************************
2 * sdla_fr.c WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module.
4 * Author(s): Nenad Corbic <ncorbic@sangoma.com>
5 * Gideon Hack
7 * Copyright: (c) 1995-1999 Sangoma Technologies Inc.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 * ============================================================================
14 * Feb 28, 2000 Jeff Garzik o softnet updates
15 * Nov 08, 1999 Nenad Corbic o Combined all debug UDP calls into one function
16 * o Removed the ARP support. This has to be done
17 * in the next version.
18 * o Only a Node can implement NO signalling.
19 * Initialize DLCI during if_open() if NO
20 * signalling.
21 * o Took out IPX support, implement in next
22 * version
23 * Sep 29, 1999 Nenad Corbic o Added SMP support and changed the update
24 * function to use timer interrupt.
25 * o Fixed the CIR bug: Set the value of BC
26 * to CIR when the CIR is enabled.
27 * o Updated comments, statistics and tracing.
28 * Jun 02, 1999 Gideon Hack o Updated for S514 support.
29 * Sep 18, 1998 Jaspreet Singh o Updated for 2.2.X kernels.
30 * Jul 31, 1998 Jaspreet Singh o Removed wpf_poll routine. The channel/DLCI
31 * status is received through an event interrupt.
32 * Jul 08, 1998 David Fong o Added inverse ARP support.
33 * Mar 26, 1997 Jaspreet Singh o Returning return codes for failed UDP cmds.
34 * Jan 28, 1997 Jaspreet Singh o Improved handling of inactive DLCIs.
35 * Dec 30, 1997 Jaspreet Singh o Replaced dev_tint() with mark_bh(NET_BH)
36 * Dec 16, 1997 Jaspreet Singh o Implemented Multiple IPX support.
37 * Nov 26, 1997 Jaspreet Singh o Improved load sharing with multiple boards
38 * o Added Cli() to protect enabling of interrupts
39 * while polling is called.
40 * Nov 24, 1997 Jaspreet Singh o Added counters to avoid enabling of interrupts
41 * when they have been disabled by another
42 * interface or routine (eg. wpf_poll).
43 * Nov 06, 1997 Jaspreet Singh o Added INTR_TEST_MODE to avoid polling
44 * routine disable interrupts during interrupt
45 * testing.
46 * Oct 20, 1997 Jaspreet Singh o Added hooks in for Router UP time.
47 * Oct 16, 1997 Jaspreet Singh o The critical flag is used to maintain flow
48 * control by avoiding RACE conditions. The
49 * cli() and restore_flags() are taken out.
50 * The fr_channel structure is appended for
51 * Driver Statistics.
52 * Oct 15, 1997 Farhan Thawar o updated if_send() and receive for IPX
53 * Aug 29, 1997 Farhan Thawar o Removed most of the cli() and sti()
54 * o Abstracted the UDP management stuff
55 * o Now use tbusy and critical more intelligently
56 * Jul 21, 1997 Jaspreet Singh o Can configure T391, T392, N391, N392 & N393
57 * through router.conf.
58 * o Protected calls to sdla_peek() by adDing
59 * save_flags(), cli() and restore_flags().
60 * o Added error message for Inactive DLCIs in
61 * fr_event() and update_chan_state().
62 * o Fixed freeing up of buffers using kfree()
63 * when packets are received.
64 * Jul 07, 1997 Jaspreet Singh o Added configurable TTL for UDP packets
65 * o Added ability to discard multicast and
66 * broadcast source addressed packets
67 * Jun 27, 1997 Jaspreet Singh o Added FT1 monitor capabilities
68 * New case (0x44) statement in if_send routine
69 * Added a global variable rCount to keep track
70 * of FT1 status enabled on the board.
71 * May 29, 1997 Jaspreet Singh o Fixed major Flow Control Problem
72 * With multiple boards a problem was seen where
73 * the second board always stopped transmitting
74 * packet after running for a while. The code
75 * got into a stage where the interrupts were
76 * disabled and dev->tbusy was set to 1.
77 * This caused the If_send() routine to get into
78 * the if clause for it(0,dev->tbusy)
79 * forever.
80 * The code got into this stage due to an
81 * interrupt occuring within the if clause for
82 * set_bit(0,dev->tbusy). Since an interrupt
83 * disables furhter transmit interrupt and
84 * makes dev->tbusy = 0, this effect was undone
85 * by making dev->tbusy = 1 in the if clause.
86 * The Fix checks to see if Transmit interrupts
87 * are disabled then do not make dev->tbusy = 1
88 * Introduced a global variable: int_occur and
89 * added tx_int_enabled in the wan_device
90 * structure.
91 * May 21, 1997 Jaspreet Singh o Fixed UDP Management for multiple
92 * boards.
94 * Apr 25, 1997 Farhan Thawar o added UDP Management stuff
95 * o fixed bug in if_send() and tx_intr() to
96 * sleep and wakeup all devices
97 * Mar 11, 1997 Farhan Thawar Version 3.1.1
98 * o fixed (+1) bug in fr508_rx_intr()
99 * o changed if_send() to return 0 if
100 * wandev.critical() is true
101 * o free socket buffer in if_send() if
102 * returning 0
103 * o added tx_intr() routine
104 * Jan 30, 1997 Gene Kozin Version 3.1.0
105 * o implemented exec() entry point
106 * o fixed a bug causing driver configured as
107 * a FR switch to be stuck in WAN_
108 * mode
109 * Jan 02, 1997 Gene Kozin Initial version.
110 *****************************************************************************/
112 #include <linux/config.h>
113 #include <linux/kernel.h> /* printk(), and other useful stuff */
114 #include <linux/stddef.h> /* offsetof(), etc. */
115 #include <linux/errno.h> /* return codes */
116 #include <linux/string.h> /* inline memset(), etc. */
117 #include <linux/malloc.h> /* kmalloc(), kfree() */
118 #include <linux/wanrouter.h> /* WAN router definitions */
119 #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
120 #include <linux/if_arp.h> /* ARPHRD_* defines */
121 #include <asm/byteorder.h> /* htons(), etc. */
122 #include <asm/io.h> /* for inb(), outb(), etc. */
123 #include <linux/time.h> /* for do_gettimeofday */
124 #include <linux/in.h> /* sockaddr_in */
125 #include <linux/inet.h> /* in_ntoa(), etc... */
126 #include <asm/uaccess.h>
127 #include <linux/inetdevice.h>
128 #include <linux/ip.h>
129 #include <net/route.h> /* Dynamic Route Creation */
130 #include <linux/if.h>
132 #include <linux/sdla_fr.h> /* frame relay firmware API definitions */
134 /****** Defines & Macros ****************************************************/
136 #define MAX_CMD_RETRY 10 /* max number of firmware retries */
138 #define FR_HEADER_LEN 8 /* max encapsulation header size */
139 #define FR_CHANNEL_MTU 1500 /* unfragmented logical channel MTU */
141 /* Q.922 frame types */
142 #define Q922_UI 0x03 /* Unnumbered Info frame */
143 #define Q922_XID 0xAF
145 /* DLCI configured or not */
146 #define DLCI_NOT_CONFIGURED 0x00
147 #define DLCI_CONFIG_PENDING 0x01
148 #define DLCI_CONFIGURED 0x02
150 /* CIR enabled or not */
151 #define CIR_ENABLED 0x00
152 #define CIR_DISABLED 0x01
154 #define WANPIPE 0x00
155 #define API 0x01
156 #define FRAME_RELAY_API 1
158 #define TX_TIMEOUT (5*HZ)
160 /* For handle_IPXWAN() */
161 #define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b)))
163 /****** Data Structures *****************************************************/
165 /* This is an extention of the 'struct net_device' we create for each network
166 * interface to keep the rest of channel-specific data.
168 typedef struct fr_channel
170 /* This member must be first. */
171 struct net_device *slave; /* WAN slave */
173 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
174 unsigned dlci_configured ; /* check whether configured or not */
175 unsigned cir_status; /* check whether CIR enabled or not */
176 unsigned dlci; /* logical channel number */
177 unsigned cir; /* committed information rate */
178 unsigned bc; /* committed burst size */
179 unsigned be; /* excess burst size */
180 unsigned mc; /* multicast support on or off */
181 unsigned tx_int_status; /* Transmit Interrupt Status */
182 unsigned short pkt_length; /* Packet Length */
183 unsigned long router_start_time;/* Router start time in seconds */
184 unsigned long tick_counter; /* counter for transmit time out */
185 char dev_pending_devtint; /* interface pending dev_tint() */
186 char state; /* channel state */
187 void *dlci_int_interface; /* pointer to the DLCI Interface */
188 unsigned long IB_addr; /* physical address of Interface Byte */
189 unsigned long state_tick; /* time of the last state change */
190 unsigned char enable_IPX; /* Enable/Disable the use of IPX */
191 unsigned long network_number; /* Internal Network Number for IPX*/
192 sdla_t *card; /* -> owner */
193 unsigned route_flag; /* Add/Rem dest addr in route tables */
194 unsigned inarp; /* Inverse Arp Request status */
195 int inarp_interval; /* Time between InArp Requests */
196 unsigned long inarp_tick; /* InArp jiffies tick counter */
197 struct net_device_stats ifstats; /* interface statistics */
198 if_send_stat_t drvstats_if_send;
199 rx_intr_stat_t drvstats_rx_intr;
200 pipe_mgmt_stat_t drvstats_gen;
202 unsigned char usedby; /* Used by WANPIPE or API */
204 unsigned long router_up_time;
206 unsigned short transmit_length;
207 char transmit_buffer[FR_MAX_NO_DATA_BYTES_IN_FRAME];
208 } fr_channel_t;
210 /* Route Flag options */
211 #define NO_ROUTE 0x00
212 #define ADD_ROUTE 0x01
213 #define ROUTE_ADDED 0x02
214 #define REMOVE_ROUTE 0x03
216 /* inarp options */
217 #define INARP_NONE 0x00
218 #define INARP_REQUEST 0x01
219 #define INARP_CONFIGURED 0x02
221 /* reasons for enabling the timer interrupt on the adapter */
222 #define TMR_INT_ENABLED_UDP 0x01
223 #define TMR_INT_ENABLED_UPDATE 0x02
226 typedef struct dlci_status
228 unsigned short dlci PACKED;
229 unsigned char state PACKED;
230 } dlci_status_t;
232 typedef struct dlci_IB_mapping
234 unsigned short dlci PACKED;
235 unsigned long addr_value PACKED;
236 } dlci_IB_mapping_t;
238 /* This structure is used for DLCI list Tx interrupt mode. It is used to
239 enable interrupt bit and set the packet length for transmission
241 typedef struct fr_dlci_interface
243 unsigned char gen_interrupt PACKED;
244 unsigned short packet_length PACKED;
245 unsigned char reserved PACKED;
246 } fr_dlci_interface_t;
248 /* variable for keeping track of enabling/disabling FT1 monitor status */
249 static int rCount = 0;
251 extern int ip_rt_ioctl(unsigned int, void *);
252 extern void disable_irq(unsigned int);
253 extern void enable_irq(unsigned int);
255 /* variable for keeping track of number of interrupts generated during
256 * interrupt test routine
258 static int Intr_test_counter;
259 /****** Function Prototypes *************************************************/
261 /* WAN link driver entry points. These are called by the WAN router module. */
262 static int update(wan_device_t *wandev);
263 static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf);
264 static int del_if(wan_device_t *wandev, struct net_device *dev);
266 /* WANPIPE-specific entry points */
267 static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data);
269 /* Network device interface */
270 static int if_init(struct net_device *dev);
271 static int if_open(struct net_device *dev);
272 static int if_close(struct net_device *dev);
273 static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len);
274 static int if_rebuild_hdr(struct sk_buff *skb);
275 static int if_send(struct sk_buff *skb, struct net_device *dev);
276 static void if_tx_timeout (struct net_device *dev);
277 static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
278 struct sk_buff *skb);
279 static struct net_device_stats *if_stats(struct net_device *dev);
281 /* Interrupt handlers */
282 static void fr_isr(sdla_t *card);
283 static void rx_intr(sdla_t *card);
284 static void tx_intr(sdla_t *card);
285 static void timer_intr(sdla_t *card);
286 static void spur_intr(sdla_t *card);
288 /* Frame relay firmware interface functions */
289 static int fr_read_version(sdla_t *card, char *str);
290 static int fr_configure(sdla_t *card, fr_conf_t *conf);
291 static int fr_dlci_configure(sdla_t *card, fr_dlc_conf_t *conf, unsigned dlci);
292 static int fr_init_dlci (sdla_t *card, fr_channel_t *chan);
293 static int fr_set_intr_mode (sdla_t *card, unsigned mode, unsigned mtu, unsigned short timeout);
294 static int fr_comm_enable(sdla_t *card);
295 static int fr_comm_disable(sdla_t *card);
296 static int fr_get_err_stats(sdla_t *card);
297 static int fr_get_stats(sdla_t *card);
298 static int fr_add_dlci(sdla_t *card, int dlci);
299 static int fr_activate_dlci(sdla_t *card, int dlci);
300 static int fr_delete_dlci (sdla_t* card, int dlci);
301 static int fr_issue_isf(sdla_t *card, int isf);
302 static int fr_send(sdla_t *card, int dlci, unsigned char attr, int len,
303 void *buf);
305 /* Firmware asynchronous event handlers */
306 static int fr_event(sdla_t *card, int event, fr_mbox_t *mbox);
307 static int fr_modem_failure(sdla_t *card, fr_mbox_t *mbox);
308 static int fr_dlci_change(sdla_t *card, fr_mbox_t *mbox);
310 /* Miscellaneous functions */
311 static int update_chan_state(struct net_device *dev);
312 static void set_chan_state(struct net_device *dev, int state);
313 static struct net_device *find_channel(sdla_t *card, unsigned dlci);
314 static int is_tx_ready(sdla_t *card, fr_channel_t *chan);
315 static unsigned int dec_to_uint(unsigned char *str, int len);
316 static int reply_udp( unsigned char *data, unsigned int mbox_len );
318 static int intr_test( sdla_t* card );
319 static void init_chan_statistics( fr_channel_t* chan );
320 static void init_global_statistics( sdla_t* card );
321 static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan );
322 static void setup_for_delayed_transmit(struct net_device* dev, void* buf,
323 unsigned len);
326 /* Inverse ARP and Dynamic routing functions */
327 int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device *dev);
328 int is_arp(void *buf);
329 int send_inarp_request(sdla_t *card, struct net_device *dev);
331 /* Udp management functions */
332 static int process_udp_mgmt_pkt(sdla_t *card);
333 static int udp_pkt_type( struct sk_buff *skb, sdla_t *card );
334 static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card,
335 struct sk_buff *skb, int dlci);
337 /* IPX functions */
338 static void switch_net_numbers(unsigned char *sendpacket,
339 unsigned long network_number, unsigned char incoming);
341 static int handle_IPXWAN(unsigned char *sendpacket, char *devname,
342 unsigned char enable_IPX, unsigned long network_number);
344 /* Lock Functions: SMP supported */
345 void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags);
346 void s508_s514_lock(sdla_t *card, unsigned long *smp_flags);
348 unsigned short calc_checksum (char *, int);
351 /****** Public Functions ****************************************************/
353 /*============================================================================
354 * Frame relay protocol initialization routine.
356 * This routine is called by the main WANPIPE module during setup. At this
357 * point adapter is completely initialized and firmware is running.
358 * o read firmware version (to make sure it's alive)
359 * o configure adapter
360 * o initialize protocol-specific fields of the adapter data space.
362 * Return: 0 o.k.
363 * < 0 failure.
365 int wpf_init(sdla_t *card, wandev_conf_t *conf)
368 int err;
370 union
372 char str[80];
373 fr_conf_t cfg;
374 } u;
375 fr_buf_info_t* buf_info;
376 int i;
378 /* Verify configuration ID */
379 if (conf->config_id != WANCONFIG_FR) {
381 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
382 card->devname, conf->config_id);
383 return -EINVAL;
387 /* Initialize protocol-specific fields of adapter data space */
388 switch (card->hw.fwid) {
390 case SFID_FR508:
391 card->mbox = (void*)(card->hw.dpmbase +
392 FR508_MBOX_OFFS);
393 card->flags = (void*)(card->hw.dpmbase +
394 FR508_FLAG_OFFS);
395 if(card->hw.type == SDLA_S514) {
396 card->mbox += FR_MB_VECTOR;
397 card->flags += FR_MB_VECTOR;
399 card->isr = &fr_isr;
400 break;
402 default:
403 return -EINVAL;
406 /* Read firmware version. Note that when adapter initializes, it
407 * clears the mailbox, so it may appear that the first command was
408 * executed successfully when in fact it was merely erased. To work
409 * around this, we execute the first command twice.
412 if (fr_read_version(card, NULL) || fr_read_version(card, u.str))
413 return -EIO;
415 printk(KERN_INFO "%s: running frame relay firmware v%s\n",
416 card->devname, u.str);
418 /* Adjust configuration */
419 conf->mtu += FR_HEADER_LEN;
420 conf->mtu = (conf->mtu >= MIN_LGTH_FR_DATA_CFG) ?
421 min(conf->mtu, FR_MAX_NO_DATA_BYTES_IN_FRAME) :
422 FR_CHANNEL_MTU + FR_HEADER_LEN;
424 conf->bps = min(conf->bps, 2048000);
426 /* Initialze the configuration structure sent to the board to zero */
427 memset(&u.cfg, 0, sizeof(u.cfg));
429 memset(card->u.f.dlci_to_dev_map, 0, sizeof(card->u.f.dlci_to_dev_map));
431 /* Configure adapter firmware */
433 u.cfg.mtu = conf->mtu;
434 u.cfg.kbps = conf->bps / 1000;
436 u.cfg.cir_fwd = u.cfg.cir_bwd = 16;
437 u.cfg.bc_fwd = u.cfg.bc_bwd = 16;
439 u.cfg.options = 0x0000;
440 printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname);
442 switch (conf->u.fr.signalling) {
444 case WANOPT_FR_ANSI:
445 u.cfg.options = 0x0000;
446 break;
448 case WANOPT_FR_Q933:
449 u.cfg.options |= 0x0200;
450 break;
452 case WANOPT_FR_LMI:
453 u.cfg.options |= 0x0400;
454 break;
456 case WANOPT_NO:
457 u.cfg.options |= 0x0800;
458 break;
459 default:
460 printk(KERN_INFO "%s: Illegal Signalling option\n",
461 card->wandev.name);
462 return -EINVAL;
466 card->wandev.signalling = conf->u.fr.signalling;
468 if (conf->station == WANOPT_CPE) {
471 if (conf->u.fr.signalling == WANOPT_NO){
472 printk(KERN_INFO
473 "%s: ERROR - For NO signalling, station must be set to Node!",
474 card->devname);
475 return -EINVAL;
478 u.cfg.station = 0;
479 u.cfg.options |= 0x8000; /* auto config DLCI */
480 card->u.f.dlci_num = 0;
482 } else {
484 u.cfg.station = 1; /* switch emulation mode */
486 /* For switch emulation we have to create a list of dlci(s)
487 * that will be sent to be global SET_DLCI_CONFIGURATION
488 * command in fr_configure() routine.
491 card->u.f.dlci_num = min(max(conf->u.fr.dlci_num, 1), 100);
493 for ( i = 0; i < card->u.f.dlci_num; i++) {
495 card->u.f.node_dlci[i] = (unsigned short)
496 conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16;
501 if (conf->clocking == WANOPT_INTERNAL)
502 u.cfg.port |= 0x0001;
504 if (conf->interface == WANOPT_RS232)
505 u.cfg.port |= 0x0002;
507 if (conf->u.fr.t391)
508 u.cfg.t391 = min(conf->u.fr.t391, 30);
509 else
510 u.cfg.t391 = 5;
512 if (conf->u.fr.t392)
513 u.cfg.t392 = min(conf->u.fr.t392, 30);
514 else
515 u.cfg.t392 = 15;
517 if (conf->u.fr.n391)
518 u.cfg.n391 = min(conf->u.fr.n391, 255);
519 else
520 u.cfg.n391 = 2;
522 if (conf->u.fr.n392)
523 u.cfg.n392 = min(conf->u.fr.n392, 10);
524 else
525 u.cfg.n392 = 3;
527 if (conf->u.fr.n393)
528 u.cfg.n393 = min(conf->u.fr.n393, 10);
529 else
530 u.cfg.n393 = 4;
532 if (fr_configure(card, &u.cfg))
533 return -EIO;
535 if (card->hw.type == SDLA_S514) {
537 buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR +
538 FR508_RXBC_OFFS);
540 card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase);
542 card->u.f.rxmb_base =
543 (void*)(buf_info->rse_base + card->hw.dpmbase);
545 card->u.f.rxmb_last =
546 (void*)(buf_info->rse_base +
547 (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) +
548 card->hw.dpmbase);
551 else {
552 buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS);
554 card->rxmb = (void*)(buf_info->rse_next -
555 FR_MB_VECTOR + card->hw.dpmbase);
557 card->u.f.rxmb_base =
558 (void*)(buf_info->rse_base -
559 FR_MB_VECTOR + card->hw.dpmbase);
561 card->u.f.rxmb_last =
562 (void*)(buf_info->rse_base +
563 (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) -
564 FR_MB_VECTOR + card->hw.dpmbase);
567 card->u.f.rx_base = buf_info->buf_base;
568 card->u.f.rx_top = buf_info->buf_top;
570 card->u.f.tx_interrupts_pending = 0;
572 card->wandev.mtu = conf->mtu;
573 card->wandev.bps = conf->bps;
574 card->wandev.interface = conf->interface;
575 card->wandev.clocking = conf->clocking;
576 card->wandev.station = conf->station;
577 card->poll = NULL;
578 card->exec = &wpf_exec;
579 card->wandev.update = &update;
580 card->wandev.new_if = &new_if;
581 card->wandev.del_if = &del_if;
582 card->wandev.state = WAN_DISCONNECTED;
583 card->wandev.ttl = conf->ttl;
584 card->wandev.udp_port = conf->udp_port;
586 /* Intialize global statistics for a card */
587 init_global_statistics( card );
589 card->TracingEnabled = 0;
591 /* Interrupt Test */
592 Intr_test_counter = 0;
593 card->intr_mode = INTR_TEST_MODE;
594 err = intr_test( card );
596 if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
597 printk(
598 "%s: Interrupt Test Failed, Counter: %i\n",
599 card->devname, Intr_test_counter);
600 printk( "Please choose another interrupt\n");
601 err = -EIO;
602 return err;
605 printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n",
606 card->devname, Intr_test_counter);
609 return 0;
612 /******* WAN Device Driver Entry Points *************************************/
614 /*============================================================================
615 * Update device status & statistics.
617 static int update (wan_device_t* wandev)
619 volatile sdla_t* card;
620 unsigned long timeout;
621 fr508_flags_t* flags;
623 /* sanity checks */
624 if ((wandev == NULL) || (wandev->private == NULL))
625 return -EFAULT;
627 if (wandev->state == WAN_UNCONFIGURED)
628 return -ENODEV;
630 if (test_bit(1, (void*)&wandev->critical))
631 return -EAGAIN;
633 card = wandev->private;
634 flags = card->flags;
637 card->u.f.update_comms_stats = 1;
638 card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
639 flags->imask |= FR_INTR_TIMER;
640 timeout = jiffies;
641 for(;;) {
642 if(card->u.f.update_comms_stats == 0)
643 break;
644 if ((jiffies - timeout) > (1 * HZ)){
645 card->u.f.update_comms_stats = 0;
646 return -EAGAIN;
649 return 0;
652 /*============================================================================
653 * Create new logical channel.
654 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
655 * handled.
656 * o parse media- and hardware-specific configuration
657 * o make sure that a new channel can be created
658 * o allocate resources, if necessary
659 * o prepare network device structure for registaration.
661 * Return: 0 o.k.
662 * < 0 failure (channel will not be created)
664 static int new_if (wan_device_t* wandev, struct net_device* dev, wanif_conf_t* conf)
666 sdla_t* card = wandev->private;
667 fr_channel_t* chan;
668 int dlci = 0;
669 int err = 0;
671 if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
673 printk(KERN_INFO "%s: invalid interface name!\n",
674 card->devname);
675 return -EINVAL;
678 /* allocate and initialize private data */
679 chan = kmalloc(sizeof(fr_channel_t), GFP_KERNEL);
681 if (chan == NULL)
682 return -ENOMEM;
684 memset(chan, 0, sizeof(fr_channel_t));
685 strcpy(chan->name, conf->name);
686 chan->card = card;
688 /* verify media address */
689 if (is_digit(conf->addr[0])) {
691 dlci = dec_to_uint(conf->addr, 0);
693 if (dlci && (dlci <= HIGHEST_VALID_DLCI)) {
695 chan->dlci = dlci;
697 } else {
699 printk(KERN_ERR
700 "%s: invalid DLCI %u on interface %s!\n",
701 wandev->name, dlci, chan->name);
702 err = -EINVAL;
705 } else {
706 printk(KERN_ERR
707 "%s: invalid media address on interface %s!\n",
708 wandev->name, chan->name);
709 err = -EINVAL;
712 /* Setup wanpipe as a router (WANPIPE) or as an API */
713 if(strcmp(conf->usedby, "WANPIPE") == 0){
714 printk(KERN_INFO "%s: Running in WANPIPE mode %s\n",
715 wandev->name, chan->name);
716 chan->usedby = WANPIPE;
718 } else if(strcmp(conf->usedby, "API") == 0){
720 #ifdef FRAME_RELAY_API
721 chan->usedby = API;
722 printk(KERN_INFO "%s: Running in API mode %s\n",
723 wandev->name, chan->name);
724 #else
725 printk(KERN_INFO "%s: API Mode is not supported !\n",
726 wandev->name);
727 printk(KERN_INFO
728 "%s: API patch can be obtained from Sangoma Tech.\n",
729 wandev->name);
730 err = -EINVAL;
731 #endif
734 if (err) {
736 kfree(chan);
737 return err;
740 card->u.f.dlci_to_dev_map[dlci] = dev;
742 /* place cir,be,bc and other channel specific information into the
743 * chan structure
745 if (conf->cir) {
747 chan->cir = max( 1, min( conf->cir, 512 ) );
748 chan->cir_status = CIR_ENABLED;
751 /* If CIR is enabled, force BC to equal CIR
752 * this solves number of potential problems if CIR is
753 * set and BC is not
755 chan->bc = chan->cir;
757 if (conf->be){
758 chan->be = max( 0, min( conf->be, 511) );
759 }else{
760 conf->be = 0;
763 printk (KERN_INFO "%s: CIR enabled for DLCI %i \n",
764 wandev->name,chan->dlci);
765 printk (KERN_INFO "%s: CIR = %i ; BC = %i ; BE = %i\n",
766 wandev->name,chan->cir,chan->bc,chan->be);
769 }else{
770 chan->cir_status = CIR_DISABLED;
771 printk (KERN_INFO "%s: CIR disabled for DLCI %i\n",
772 wandev->name,chan->dlci);
775 chan->mc = conf->mc;
777 /* FIXME: ARP is not supported by this frame relay verson */
778 if (conf->inarp == WANOPT_YES){
779 printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support ARPs\n",
780 card->devname);
782 //chan->inarp = conf->inarp ? INARP_REQUEST : INARP_NONE;
783 //chan->inarp_interval = conf->inarp_interval ? conf->inarp_interval : 10;
784 kfree(chan);
785 return -EINVAL;
786 }else{
787 chan->inarp = INARP_NONE;
788 chan->inarp_interval = 10;
791 chan->dlci_configured = DLCI_NOT_CONFIGURED;
794 /*FIXME: IPX disabled in this WANPIPE version */
795 if (conf->enable_IPX == WANOPT_YES){
796 printk(KERN_INFO "%s: ERROR - This version of WANPIPE doesn't support IPX\n",
797 card->devname);
798 kfree(chan);
799 return -EINVAL;
800 }else{
801 chan->enable_IPX = WANOPT_NO;
804 if (conf->network_number){
805 chan->network_number = conf->network_number;
806 }else{
807 chan->network_number = 0xDEADBEEF;
810 chan->route_flag = NO_ROUTE;
812 init_chan_statistics(chan);
814 chan->transmit_length = 0;
816 /* prepare network device data space for registration */
817 dev->name = chan->name;
818 dev->init = &if_init;
819 dev->priv = chan;
822 /* Enable Interrupts and Communications */
823 if (!wandev->new_if_cnt){
824 fr508_flags_t* flags = card->flags;
826 wandev->new_if_cnt++;
829 If you enable comms and then set ints, you get a Tx int as you
830 perform the SET_INT_TRIGGERS command. So, we only set int
831 triggers and then adjust the interrupt mask (to disable Tx ints)
832 before enabling comms.
834 if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY |
835 FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) ,
836 card->wandev.mtu, 0)) {
837 kfree(chan);
838 return -EIO;
841 flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER);
843 if (fr_comm_enable(card)) {
844 kfree(chan);
845 return -EIO;
847 wanpipe_set_state(card, WAN_CONNECTED);
850 return 0;
853 /*============================================================================
854 * Delete logical channel.
856 static int del_if (wan_device_t* wandev, struct net_device* dev)
858 sdla_t *card = wandev->private;
860 /* Execute shutdown very first time we enter del_if */
862 if (!wandev->del_if_cnt) {
863 wandev->del_if_cnt++;
864 wanpipe_set_state(card, WAN_DISCONNECTED);
865 fr_set_intr_mode(card, 0, 0, 0);
866 fr_comm_disable(card);
869 if (dev->priv) {
870 kfree(dev->priv);
871 dev->priv = NULL;
874 return 0;
877 /****** WANPIPE-specific entry points ***************************************/
879 /*============================================================================
880 * Execute adapter interface command.
882 static int wpf_exec (struct sdla* card, void* u_cmd, void* u_data)
884 fr_mbox_t* mbox = card->mbox;
885 int retry = MAX_CMD_RETRY;
886 int err, len;
887 fr_cmd_t cmd;
889 if(copy_from_user((void*)&cmd, u_cmd, sizeof(cmd)))
890 return -EFAULT;
892 /* execute command */
895 memcpy(&mbox->cmd, &cmd, sizeof(cmd));
897 if (cmd.length){
898 if( copy_from_user((void*)&mbox->data, u_data, cmd.length))
899 return -EFAULT;
902 if (sdla_exec(mbox))
903 err = mbox->cmd.result;
905 else return -EIO;
907 } while (err && retry-- && fr_event(card, err, mbox));
909 /* return result */
910 if (copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(fr_cmd_t)))
911 return -EFAULT;
913 len = mbox->cmd.length;
915 if (len && u_data && !copy_to_user(u_data, (void*)&mbox->data, len))
916 return -EFAULT;
917 return 0;
921 /****** Network Device Interface ********************************************/
923 /*============================================================================
924 * Initialize Linux network interface.
926 * This routine is called only once for each interface, during Linux network
927 * interface registration. Returning anything but zero will fail interface
928 * registration.
930 static int if_init (struct net_device* dev)
932 fr_channel_t* chan = dev->priv;
933 sdla_t* card = chan->card;
934 wan_device_t* wandev = &card->wandev;
936 /* Initialize device driver entry points */
937 dev->open = &if_open;
938 dev->stop = &if_close;
939 dev->hard_header = &if_header;
940 dev->rebuild_header = &if_rebuild_hdr;
941 dev->hard_start_xmit = &if_send;
942 dev->get_stats = &if_stats;
943 dev->tx_timeout = &if_tx_timeout;
944 dev->watchdog_timeo = TX_TIMEOUT;
946 /* Initialize media-specific parameters */
947 dev->type = ARPHRD_DLCI; /* ARP h/w type */
948 dev->flags |= IFF_POINTOPOINT;
950 /* Enable Multicast addressing */
951 if (chan->mc == WANOPT_YES){
952 dev->flags |= IFF_MULTICAST;
955 dev->mtu = wandev->mtu - FR_HEADER_LEN;
956 /* For an API, the maximum number of bytes that the stack will pass
957 to the driver is (dev->mtu + dev->hard_header_len). So, adjust the
958 mtu so that a frame of maximum size can be transmitted by the API.
960 if(chan->usedby == API) {
961 dev->mtu += (sizeof(api_tx_hdr_t) - FR_HEADER_LEN);
964 dev->hard_header_len = FR_HEADER_LEN;/* media header length */
965 dev->addr_len = 2; /* hardware address length */
966 *(unsigned short*)dev->dev_addr = htons(chan->dlci);
968 /* Initialize hardware parameters (just for reference) */
969 dev->irq = wandev->irq;
970 dev->dma = wandev->dma;
971 dev->base_addr = wandev->ioport;
972 dev->mem_start = wandev->maddr;
973 dev->mem_end = wandev->maddr + wandev->msize - 1;
975 /* Set transmit buffer queue length */
976 dev->tx_queue_len = 100;
978 /* Initialize socket buffers */
979 dev_init_buffers(dev);
981 set_chan_state(dev, WAN_DISCONNECTED);
982 return 0;
985 /*============================================================================
986 * Open network interface.
987 * o if this is the first open, then enable communications and interrupts.
988 * o prevent module from unloading by incrementing use count
990 * Return 0 if O.k. or errno.
992 static int if_open (struct net_device* dev)
994 fr_channel_t* chan = dev->priv;
995 sdla_t* card = chan->card;
996 int err = 0;
997 struct timeval tv;
999 if (netif_running(dev))
1000 return -EBUSY; /* only one open is allowed */
1002 if (test_and_set_bit(1, (void*)&card->wandev.critical))
1003 return -EAGAIN;
1006 /* If signalling is set to NO, then setup
1007 * DLCI addresses right away. Don't have to wait for
1008 * link to connect.
1010 if (card->wandev.signalling == WANOPT_NO){
1011 printk(KERN_INFO "%s: Signalling set to NO: Mapping DLCI's\n",
1012 card->wandev.name);
1013 if (fr_init_dlci(card,chan)){
1014 return -EAGAIN;
1018 if (card->wandev.station == WANOPT_CPE) {
1020 /* CPE: issue full status enquiry */
1021 fr_issue_isf(card, FR_ISF_FSE);
1023 } else { /* FR switch: activate DLCI(s) */
1025 /* For Switch emulation we have to ADD and ACTIVATE
1026 * the DLCI(s) that were configured with the SET_DLCI_
1027 * CONFIGURATION command. Add and Activate will fail if
1028 * DLCI specified is not included in the list.
1030 * Also If_open is called once for each interface. But
1031 * it does not get in here for all the interface. So
1032 * we have to pass the entire list of DLCI(s) to add
1033 * activate routines.
1036 fr_add_dlci(card, chan->dlci);
1037 fr_activate_dlci(card, chan->dlci);
1040 netif_start_queue(dev);
1041 wanpipe_open(card);
1042 update_chan_state(dev);
1043 do_gettimeofday( &tv );
1044 chan->router_start_time = tv.tv_sec;
1045 clear_bit(1, (void*)&card->wandev.critical);
1046 return err;
1049 /*============================================================================
1050 * Close network interface.
1051 * o if this is the last open, then disable communications and interrupts.
1052 * o reset flags.
1054 static int if_close (struct net_device* dev)
1056 fr_channel_t* chan = dev->priv;
1057 sdla_t* card = chan->card;
1059 if (test_and_set_bit(1, (void*)&card->wandev.critical))
1060 return -EAGAIN;
1062 netif_stop_queue(dev);
1063 wanpipe_close(card);
1064 if (card->wandev.station == WANOPT_NODE) {
1065 fr_delete_dlci (card,chan->dlci);
1068 clear_bit(1, (void*)&card->wandev.critical);
1069 return 0;
1072 /*============================================================================
1073 * Build media header.
1074 * o encapsulate packet according to encapsulation type.
1076 * The trick here is to put packet type (Ethertype) into 'protocol' field of
1077 * the socket buffer, so that we don't forget it. If encapsulation fails,
1078 * set skb->protocol to 0 and discard packet later.
1080 * Return: media header length.
1082 static int if_header (struct sk_buff* skb, struct net_device* dev,
1083 unsigned short type, void* daddr, void* saddr, unsigned len)
1085 int hdr_len = 0;
1087 skb->protocol = type;
1088 hdr_len = wanrouter_encapsulate(skb, dev);
1090 if (hdr_len < 0) {
1091 hdr_len = 0;
1092 skb->protocol = 0;
1094 skb_push(skb, 1);
1095 skb->data[0] = Q922_UI;
1096 ++hdr_len;
1097 return hdr_len;
1100 /*============================================================================
1101 * Re-build media header.
1103 * Return: 1 physical address resolved.
1104 * 0 physical address not resolved
1106 static int if_rebuild_hdr (struct sk_buff* skb)
1108 struct net_device *dev = skb->dev;
1109 fr_channel_t* chan = dev->priv;
1110 sdla_t* card = chan->card;
1112 printk(KERN_INFO "%s: rebuild_header() called for interface %s!\n",
1113 card->devname, dev->name);
1114 return 1;
1118 /*============================================================================
1119 * Handle transmit timeout event from netif watchdog
1121 static void if_tx_timeout (struct net_device *dev)
1123 fr_channel_t* chan = dev->priv;
1125 /* If our device stays busy for at least 5 seconds then we will
1126 * kick start the device by making dev->tbusy = 0. We expect
1127 * that our device never stays busy more than 5 seconds. So this
1128 * is only used as a last resort.
1131 chan->drvstats_if_send.if_send_tbusy++;
1132 ++chan->ifstats.collisions;
1134 printk (KERN_INFO "%s: Transmit timed out\n", chan->name);
1135 chan->drvstats_if_send.if_send_tbusy_timeout++;
1136 netif_start_queue (dev);
1141 /*============================================================================
1142 * Send a packet on a network interface.
1143 * o set tbusy flag (marks start of the transmission) to block a timer-based
1144 * transmit from overlapping.
1145 * o set critical flag when accessing board.
1146 * o check link state. If link is not up, then drop the packet.
1147 * o check channel status. If it's down then initiate a call.
1148 * o pass a packet to corresponding WAN device.
1149 * o free socket buffer
1151 * Return: 0 complete (socket buffer must be freed)
1152 * non-0 packet may be re-transmitted (tbusy must be set)
1154 * Notes:
1155 * 1. This routine is called either by the protocol stack or by the "net
1156 * bottom half" (with interrupts enabled).
1157 * 2. Setting tbusy flag will inhibit further transmit requests from the
1158 * protocol stack and can be used for flow control with protocol layer.
1160 static int if_send (struct sk_buff* skb, struct net_device* dev)
1162 fr_channel_t* chan = dev->priv;
1163 sdla_t* card = chan->card;
1164 int err;
1165 unsigned char *sendpacket;
1166 fr508_flags_t* adptr_flags = card->flags;
1167 int udp_type, send_data;
1168 unsigned long smp_flags=0;
1169 void* data;
1170 unsigned len;
1172 chan->drvstats_if_send.if_send_entry++;
1174 if (skb == NULL) {
1175 /* if we get here, some higher layer thinks we've missed an
1176 * tx-done interrupt.
1178 printk(KERN_INFO "%s: interface %s got kicked!\n",
1179 card->devname, dev->name);
1180 chan->drvstats_if_send.if_send_skb_null ++;
1181 netif_wake_queue(dev);
1182 return 0;
1185 /* We must set the 'tbusy' flag if we already have a packet queued for
1186 transmission in the transmit interrupt handler. However, we must
1187 ensure that the transmit interrupt does not reset the 'tbusy' flag
1188 just before we set it, as this will result in a "transmit timeout".
1190 set_bit(2, (void*)&card->wandev.critical);
1191 if(chan->transmit_length) {
1192 netif_stop_queue(dev);
1193 chan->tick_counter = jiffies;
1194 clear_bit(2, (void*)&card->wandev.critical);
1195 return 1;
1197 clear_bit(2, (void*)&card->wandev.critical);
1199 data = skb->data;
1200 sendpacket = skb->data;
1201 len = skb->len;
1203 udp_type = udp_pkt_type(skb, card);
1205 if(udp_type != UDP_INVALID_TYPE) {
1206 if(store_udp_mgmt_pkt(udp_type, UDP_PKT_FRM_STACK, card, skb,
1207 chan->dlci)) {
1208 adptr_flags->imask |= FR_INTR_TIMER;
1209 if (udp_type == UDP_FPIPE_TYPE){
1210 chan->drvstats_if_send.
1211 if_send_PIPE_request ++;
1214 return 0;
1217 if((chan->usedby == API) && (len <= sizeof(api_tx_hdr_t))) {
1218 //FIXME: increment some error statistic
1219 dev_kfree_skb(skb);
1220 return 0;
1223 //FIXME: can we do better than sendpacket[2]?
1224 if ((chan->usedby == WANPIPE) && (sendpacket[2] == 0x45)) {
1225 /* check to see if the source IP address is a broadcast or */
1226 /* multicast IP address */
1227 if(chk_bcast_mcast_addr(card, dev, skb))
1228 return 0;
1231 /* Lock the 508 card: SMP Supported */
1232 s508_s514_lock(card,&smp_flags);
1234 if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
1235 chan->drvstats_if_send.if_send_critical_non_ISR ++;
1236 chan->ifstats.tx_dropped ++;
1237 printk(KERN_INFO "%s Critical in IF_SEND %02X\n",
1238 card->devname, card->wandev.critical);
1239 dev_kfree_skb(skb);
1240 /* Unlock the 508 card */
1241 s508_s514_unlock(card,&smp_flags);
1242 return 0;
1245 if (card->wandev.state != WAN_CONNECTED) {
1246 chan->drvstats_if_send.if_send_wan_disconnected ++;
1247 ++chan->ifstats.tx_dropped;
1248 ++card->wandev.stats.tx_dropped;
1250 } else if (chan->state != WAN_CONNECTED) {
1251 chan->drvstats_if_send.if_send_dlci_disconnected ++;
1252 /* Critical area on 514, since disabl_irq is not used
1253 * thus, interrupt would execute a command at
1254 * the same time as if_send.
1256 set_bit(1, (void*)&card->wandev.critical);
1257 update_chan_state(dev);
1258 clear_bit(1, (void*)&card->wandev.critical);
1259 ++chan->ifstats.tx_dropped;
1260 ++card->wandev.stats.tx_dropped;
1262 } else if (!is_tx_ready(card, chan)) {
1263 setup_for_delayed_transmit(dev, data, len);
1264 chan->drvstats_if_send.if_send_no_bfrs++;
1265 } else {
1266 send_data = 1;
1267 //FIXME: IPX is not implemented in this version of Frame Relay ?
1268 if((chan->usedby == WANPIPE) &&
1269 sendpacket[1] == 0x00 &&
1270 sendpacket[2] == 0x80 &&
1271 sendpacket[6] == 0x81 &&
1272 sendpacket[7] == 0x37) {
1274 if( chan->enable_IPX ) {
1275 switch_net_numbers(sendpacket,
1276 chan->network_number, 0);
1277 } else {
1278 //FIXME: Take this out when IPX is fixed
1279 printk(KERN_INFO
1280 "%s: WARNING: Unsupported IPX data in send, packet dropped\n",
1281 card->devname);
1282 send_data = 0;
1286 if (send_data) {
1287 unsigned char attr = 0;
1289 /* For an API transmission, get rid of the API header */
1290 if (chan->usedby == API) {
1291 api_tx_hdr_t* api_tx_hdr;
1292 api_tx_hdr = (api_tx_hdr_t*)&skb->data[0x00];
1293 attr = api_tx_hdr->attr;
1294 data += sizeof(api_tx_hdr_t);
1295 len -= sizeof(api_tx_hdr_t);
1298 err = fr_send(card, chan->dlci, attr, len, data);
1299 if (err) {
1300 switch(err) {
1301 case FRRES_CIR_OVERFLOW:
1302 case FRRES_BUFFER_OVERFLOW:
1303 setup_for_delayed_transmit(dev, data,
1304 len);
1305 chan->drvstats_if_send.
1306 if_send_adptr_bfrs_full ++;
1307 break;
1308 default:
1309 chan->drvstats_if_send.
1310 if_send_dlci_disconnected ++;
1311 ++chan->ifstats.tx_dropped;
1312 ++card->wandev.stats.tx_dropped;
1313 break;
1315 } else {
1316 chan->drvstats_if_send.
1317 if_send_bfr_passed_to_adptr++;
1318 ++chan->ifstats.tx_packets;
1319 ++card->wandev.stats.tx_packets;
1320 chan->ifstats.tx_bytes += len;
1321 card->wandev.stats.tx_bytes += len;
1326 if (!netif_queue_stopped(dev))
1327 dev_kfree_skb(skb);
1329 clear_bit(0, (void*)&card->wandev.critical);
1331 s508_s514_unlock(card,&smp_flags);
1333 return (netif_queue_stopped(dev));
1338 /*============================================================================
1339 * Setup so that a frame can be transmitted on the occurence of a transmit
1340 * interrupt.
1342 static void setup_for_delayed_transmit (struct net_device* dev, void* buf,
1343 unsigned len)
1345 fr_channel_t* chan = dev->priv;
1346 sdla_t* card = chan->card;
1347 fr508_flags_t* adptr_flags = card->flags;
1348 fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface;
1350 if(chan->transmit_length) {
1351 printk(KERN_INFO "%s: Big mess in setup_for_del...\n",
1352 card->devname);
1353 return;
1356 if(len > FR_MAX_NO_DATA_BYTES_IN_FRAME) {
1357 //FIXME: increment some statistic */
1358 return;
1361 chan->transmit_length = len;
1362 memcpy(chan->transmit_buffer, buf, len);
1364 dlci_interface->gen_interrupt |= FR_INTR_TXRDY;
1365 dlci_interface->packet_length = len;
1366 adptr_flags->imask |= FR_INTR_TXRDY;
1368 card->u.f.tx_interrupts_pending ++;
1372 /*============================================================================
1373 * Check to see if the packet to be transmitted contains a broadcast or
1374 * multicast source IP address.
1375 * Return 0 if not broadcast/multicast address, otherwise return 1.
1378 static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
1379 struct sk_buff *skb)
1381 u32 src_ip_addr;
1382 u32 broadcast_ip_addr = 0;
1383 struct in_device *in_dev;
1384 fr_channel_t* chan = dev->priv;
1386 /* read the IP source address from the outgoing packet */
1387 src_ip_addr = *(u32 *)(skb->data + 14);
1389 /* read the IP broadcast address for the device */
1390 in_dev = dev->ip_ptr;
1391 if(in_dev != NULL) {
1392 struct in_ifaddr *ifa= in_dev->ifa_list;
1393 if(ifa != NULL)
1394 broadcast_ip_addr = ifa->ifa_broadcast;
1395 else
1396 return 0;
1399 /* check if the IP Source Address is a Broadcast address */
1400 if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) { printk(KERN_INFO
1401 "%s: Broadcast Source Address silently discarded\n",
1402 card->devname);
1403 dev_kfree_skb(skb);
1404 ++ chan->ifstats.tx_dropped;
1405 return 1;
1408 /* check if the IP Source Address is a Multicast address */
1409 if((chan->mc == WANOPT_NO) && (ntohl(src_ip_addr) >= 0xE0000001) &&
1410 (ntohl(src_ip_addr) <= 0xFFFFFFFE)) {
1411 printk(KERN_INFO
1412 "%s: Multicast Source Address silently discarded\n",
1413 card->devname);
1414 dev_kfree_skb(skb);
1415 ++ chan->ifstats.tx_dropped;
1416 return 1;
1419 return 0;
1422 /*============================================================================
1423 * Reply to UDP Management system.
1424 * Return nothing.
1426 static int reply_udp( unsigned char *data, unsigned int mbox_len )
1428 unsigned short len, udp_length, temp, ip_length;
1429 unsigned long ip_temp;
1430 int even_bound = 0;
1433 fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)data;
1435 /* Set length of packet */
1436 len = sizeof(fr_encap_hdr_t)+
1437 sizeof(ip_pkt_t)+
1438 sizeof(udp_pkt_t)+
1439 sizeof(wp_mgmt_t)+
1440 sizeof(cblock_t)+
1441 mbox_len;
1444 /* fill in UDP reply */
1445 fr_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
1447 /* fill in UDP length */
1448 udp_length = sizeof(udp_pkt_t)+
1449 sizeof(wp_mgmt_t)+
1450 sizeof(cblock_t)+
1451 mbox_len;
1454 /* put it on an even boundary */
1455 if ( udp_length & 0x0001 ) {
1456 udp_length += 1;
1457 len += 1;
1458 even_bound = 1;
1461 temp = (udp_length<<8)|(udp_length>>8);
1462 fr_udp_pkt->udp_pkt.udp_length = temp;
1464 /* swap UDP ports */
1465 temp = fr_udp_pkt->udp_pkt.udp_src_port;
1466 fr_udp_pkt->udp_pkt.udp_src_port =
1467 fr_udp_pkt->udp_pkt.udp_dst_port;
1468 fr_udp_pkt->udp_pkt.udp_dst_port = temp;
1472 /* add UDP pseudo header */
1473 temp = 0x1100;
1474 *((unsigned short *)
1475 (fr_udp_pkt->data+mbox_len+even_bound)) = temp;
1476 temp = (udp_length<<8)|(udp_length>>8);
1477 *((unsigned short *)
1478 (fr_udp_pkt->data+mbox_len+even_bound+2)) = temp;
1480 /* calculate UDP checksum */
1481 fr_udp_pkt->udp_pkt.udp_checksum = 0;
1483 fr_udp_pkt->udp_pkt.udp_checksum =
1484 calc_checksum(&data[UDP_OFFSET+sizeof(fr_encap_hdr_t)],
1485 udp_length+UDP_OFFSET);
1487 /* fill in IP length */
1488 ip_length = udp_length + sizeof(ip_pkt_t);
1489 temp = (ip_length<<8)|(ip_length>>8);
1490 fr_udp_pkt->ip_pkt.total_length = temp;
1492 /* swap IP addresses */
1493 ip_temp = fr_udp_pkt->ip_pkt.ip_src_address;
1494 fr_udp_pkt->ip_pkt.ip_src_address =
1495 fr_udp_pkt->ip_pkt.ip_dst_address;
1496 fr_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
1499 /* fill in IP checksum */
1500 fr_udp_pkt->ip_pkt.hdr_checksum = 0;
1501 fr_udp_pkt->ip_pkt.hdr_checksum =
1502 calc_checksum(&data[sizeof(fr_encap_hdr_t)],
1503 sizeof(ip_pkt_t));
1505 return len;
1506 } /* reply_udp */
1508 unsigned short calc_checksum (char *data, int len)
1510 unsigned short temp;
1511 unsigned long sum=0;
1512 int i;
1514 for( i = 0; i <len; i+=2 ) {
1515 memcpy(&temp,&data[i],2);
1516 sum += (unsigned long)temp;
1519 while (sum >> 16 ) {
1520 sum = (sum & 0xffffUL) + (sum >> 16);
1523 temp = (unsigned short)sum;
1524 temp = ~temp;
1526 if( temp == 0 )
1527 temp = 0xffff;
1529 return temp;
1533 If incoming is 0 (outgoing)- if the net numbers is ours make it 0
1534 if incoming is 1 - if the net number is 0 make it ours
1537 static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming)
1539 unsigned long pnetwork_number;
1541 pnetwork_number = (unsigned long)((sendpacket[14] << 24) +
1542 (sendpacket[15] << 16) + (sendpacket[16] << 8) +
1543 sendpacket[17]);
1545 if (!incoming) {
1546 /* If the destination network number is ours, make it 0 */
1547 if( pnetwork_number == network_number) {
1548 sendpacket[14] = sendpacket[15] = sendpacket[16] =
1549 sendpacket[17] = 0x00;
1551 } else {
1552 /* If the incoming network is 0, make it ours */
1553 if( pnetwork_number == 0) {
1554 sendpacket[14] = (unsigned char)(network_number >> 24);
1555 sendpacket[15] = (unsigned char)((network_number &
1556 0x00FF0000) >> 16);
1557 sendpacket[16] = (unsigned char)((network_number &
1558 0x0000FF00) >> 8);
1559 sendpacket[17] = (unsigned char)(network_number &
1560 0x000000FF);
1565 pnetwork_number = (unsigned long)((sendpacket[26] << 24) +
1566 (sendpacket[27] << 16) + (sendpacket[28] << 8) +
1567 sendpacket[29]);
1569 if( !incoming ) {
1570 /* If the source network is ours, make it 0 */
1571 if( pnetwork_number == network_number) {
1572 sendpacket[26] = sendpacket[27] = sendpacket[28] =
1573 sendpacket[29] = 0x00;
1575 } else {
1576 /* If the source network is 0, make it ours */
1577 if( pnetwork_number == 0 ) {
1578 sendpacket[26] = (unsigned char)(network_number >> 24);
1579 sendpacket[27] = (unsigned char)((network_number &
1580 0x00FF0000) >> 16);
1581 sendpacket[28] = (unsigned char)((network_number &
1582 0x0000FF00) >> 8);
1583 sendpacket[29] = (unsigned char)(network_number &
1584 0x000000FF);
1587 } /* switch_net_numbers */
1589 /*============================================================================
1590 * Get ethernet-style interface statistics.
1591 * Return a pointer to struct enet_statistics.
1593 static struct enet_statistics* if_stats (struct net_device* dev)
1595 fr_channel_t* chan = dev->priv;
1597 if(chan == NULL)
1598 return NULL;
1600 return &chan->ifstats;
1603 /****** Interrupt Handlers **************************************************/
1605 /*============================================================================
1606 * S508 frame relay interrupt service routine.
1608 static void fr_isr (sdla_t* card)
1610 fr508_flags_t* flags = card->flags;
1611 char *ptr = &flags->iflag;
1612 int i,err;
1613 fr_mbox_t* mbox = card->mbox;
1615 /* This flag prevents nesting of interrupts. See sdla_isr() routine
1616 * in sdlamain.c.
1618 card->in_isr = 1;
1620 ++card->statistics.isr_entry;
1622 if(test_bit(1, (void*)&card->wandev.critical)) {
1623 card->wandev.critical = 0;
1624 flags->iflag = 0;
1625 card->in_isr = 0;
1626 return;
1629 if(card->hw.type != SDLA_S514) {
1630 if (test_and_set_bit(0, (void*)&card->wandev.critical)) {
1631 printk(KERN_INFO "%s: Critical while in ISR (0x%02X)\n",
1632 card->devname, card->wandev.critical);
1633 ++card->statistics.isr_already_critical;
1634 card->in_isr = 0;
1635 return;
1639 switch (flags->iflag) {
1641 case FR_INTR_RXRDY: /* receive interrupt */
1642 ++card->statistics.isr_rx;
1643 rx_intr(card);
1644 break;
1647 case FR_INTR_TXRDY: /* transmit interrupt */
1648 ++ card->statistics.isr_tx;
1649 tx_intr(card);
1650 break;
1652 case FR_INTR_READY:
1653 Intr_test_counter++;
1654 ++card->statistics.isr_intr_test;
1655 break;
1657 case FR_INTR_DLC: /* Event interrupt occured */
1658 mbox->cmd.command = FR_READ_STATUS;
1659 mbox->cmd.length = 0;
1660 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
1661 if (err)
1662 fr_event(card, err, mbox);
1663 break;
1665 case FR_INTR_TIMER: /* Timer interrupt */
1666 timer_intr(card);
1667 break;
1669 default:
1670 ++card->statistics.isr_spurious;
1671 spur_intr(card);
1672 printk(KERN_INFO "%s: Interrupt Type 0x%02X!\n",
1673 card->devname, flags->iflag);
1675 printk(KERN_INFO "%s: ID Bytes = ",card->devname);
1676 for(i = 0; i < 8; i ++)
1677 printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
1678 printk(KERN_INFO "\n");
1680 break;
1683 card->in_isr = 0;
1684 flags->iflag = 0;
1685 if(card->hw.type != SDLA_S514)
1686 clear_bit(0, (void*)&card->wandev.critical);
1691 /*============================================================================
1692 * Receive interrupt handler.
1693 * When a receive interrupt occurs do the following:
1694 * 1- Find the structure for the dlci that the interrupt occured on
1695 * 2- If it doesn't exist then print appropriate msg and goto step 8.
1696 * 3- If it exist then copy data to a skb.
1697 * 4- If skb contains Sangoma UDP data then process them
1698 * 5- If skb contains IPXWAN data then send IPXWAN reply packets
1699 * 6- If skb contains Inverse Arp data then send Inv Arp replies
1700 * 7- If skb contains any other data then decapsulate the packet and
1701 * send it to the stack.
1702 * 8- Release the receive element and update receive pointers on the board
1704 static void rx_intr (sdla_t* card)
1706 fr_rx_buf_ctl_t* frbuf = card->rxmb;
1707 fr508_flags_t* flags = card->flags;
1708 fr_channel_t* chan;
1709 char *ptr = &flags->iflag;
1710 struct sk_buff* skb;
1711 struct net_device* dev;
1712 void* buf;
1713 unsigned dlci, len, offs, len_incl_hdr;
1714 int i, udp_type;
1716 if (frbuf->flag != 0x01) {
1718 printk(KERN_INFO
1719 "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
1720 card->devname, (unsigned)frbuf, frbuf->flag);
1722 printk(KERN_INFO "%s: ID Bytes = ",card->devname);
1723 for(i = 0; i < 8; i ++)
1724 printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
1725 printk(KERN_INFO "\n");
1727 ++card->statistics.rx_intr_corrupt_rx_bfr;
1728 return;
1731 len = frbuf->length;
1732 dlci = frbuf->dlci;
1733 offs = frbuf->offset;
1735 /* Find network interface for this packet */
1736 dev = find_channel(card, dlci);
1738 if (dev == NULL) {
1740 /* unconfigured DLCI, so discard packet */
1741 printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n",
1742 card->devname, dlci);
1743 ++card->statistics.rx_intr_on_orphaned_DLCI;
1745 } else {
1746 chan = dev->priv;
1748 skb = dev_alloc_skb(len);
1750 if (!netif_running(dev) || (skb == NULL)) {
1751 ++chan->ifstats.rx_dropped;
1753 if(netif_running(dev)) {
1755 printk(KERN_INFO
1756 "%s: no socket buffers available!\n",
1757 card->devname);
1758 chan->drvstats_rx_intr.rx_intr_no_socket ++;
1760 } else
1761 chan->drvstats_rx_intr.
1762 rx_intr_dev_not_started ++;
1763 } else {
1764 /* Copy data to the socket buffer */
1765 if ((offs + len) > card->u.f.rx_top + 1) {
1766 unsigned tmp = card->u.f.rx_top - offs + 1;
1768 buf = skb_put(skb, tmp);
1769 sdla_peek(&card->hw, offs, buf, tmp);
1770 offs = card->u.f.rx_base;
1771 len -= tmp;
1774 buf = skb_put(skb, len);
1775 sdla_peek(&card->hw, offs, buf, len);
1777 udp_type = udp_pkt_type( skb, card );
1779 if(udp_type != UDP_INVALID_TYPE) {
1780 if(store_udp_mgmt_pkt(udp_type,
1781 UDP_PKT_FRM_NETWORK, card, skb, dlci)) {
1782 flags->imask |= FR_INTR_TIMER;
1783 if (udp_type == UDP_FPIPE_TYPE){
1784 chan->drvstats_rx_intr.
1785 rx_intr_PIPE_request ++;
1790 else if (chan->usedby == API) {
1791 api_rx_hdr_t* api_rx_hdr;
1792 chan->drvstats_rx_intr.
1793 rx_intr_bfr_passed_to_stack ++;
1794 chan->ifstats.rx_packets ++;
1795 card->wandev.stats.rx_packets ++;
1796 chan->ifstats.rx_bytes += skb->len;
1797 card->wandev.stats.rx_bytes += skb->len;
1799 skb_push(skb, sizeof(api_rx_hdr_t));
1800 api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];
1801 api_rx_hdr->attr = frbuf->attr;
1802 api_rx_hdr->time_stamp = frbuf->tmstamp;
1803 skb->protocol = htons(0x16);
1804 skb->pkt_type = PACKET_HOST;
1805 /* Pass it up the protocol stack */
1806 skb->dev = dev;
1807 skb->mac.raw = skb->data;
1808 netif_rx(skb);
1810 } else if (handle_IPXWAN(skb->data,chan->name,
1811 chan->enable_IPX, chan->network_number)) {
1812 if (chan->enable_IPX) {
1813 fr_send(card, dlci, 0, skb->len,
1814 skb->data);
1816 dev_kfree_skb(skb);
1818 /*FIXME: Fix the ARPS in next release
1820 } else if (is_arp(skb->data)) {
1821 if (process_ARP((arphdr_1490_t *)skb->data, card, dev)) {
1822 printk (KERN_INFO "%s: Error processing ARP Packet.\n", card->devname);
1824 dev_kfree_skb(skb);
1827 } else if ( skb->data[0] != 0x03) {
1828 printk(KERN_INFO "%s: Non IETF packet discarded.\n", card->devname);
1829 dev_kfree_skb(skb);
1831 } else {
1833 len_incl_hdr = skb->len;
1834 /* Decapsulate packet and pass it up the
1835 protocol stack */
1836 skb->dev = dev;
1838 /* remove hardware header */
1839 buf = skb_pull(skb, 1);
1841 if (!wanrouter_type_trans(skb, dev)) {
1843 /* can't decapsulate packet */
1844 dev_kfree_skb(skb);
1845 chan->drvstats_rx_intr.
1846 rx_intr_bfr_not_passed_to_stack ++;
1847 ++ chan->ifstats.rx_errors;
1848 ++ card->wandev.stats.rx_errors;
1850 } else {
1851 netif_rx(skb);
1852 chan->drvstats_rx_intr.
1853 rx_intr_bfr_passed_to_stack ++;
1854 ++ chan->ifstats.rx_packets;
1855 ++ card->wandev.stats.rx_packets;
1856 chan->ifstats.rx_bytes += len_incl_hdr;
1857 card->wandev.stats.rx_bytes +=
1858 len_incl_hdr;
1864 /* Release buffer element and calculate a pointer to the next one */
1865 frbuf->flag = 0;
1866 card->rxmb = ++frbuf;
1867 if ((void*)frbuf > card->u.f.rxmb_last)
1868 card->rxmb = card->u.f.rxmb_base;
1872 /*============================================================================
1873 * Transmit interrupt handler.
1875 static void tx_intr(sdla_t *card)
1877 fr508_flags_t* flags = card->flags;
1878 fr_tx_buf_ctl_t* bctl;
1879 struct net_device* dev = card->wandev.dev;
1880 fr_channel_t* chan;
1882 if(card->hw.type == SDLA_S514){
1883 bctl = (void*)(flags->tse_offs + card->hw.dpmbase);
1884 }else{
1885 bctl = (void*)(flags->tse_offs - FR_MB_VECTOR +
1886 card->hw.dpmbase);
1889 /* Find the structure and make it unbusy */
1890 dev = find_channel(card, flags->dlci);
1891 chan = dev->priv;
1893 if(!chan->transmit_length) {
1894 printk(KERN_INFO "%s: tx int error - transmit length zero\n",
1895 card->wandev.name);
1896 return;
1899 /* If the 'if_send()' procedure is currently checking the 'tbusy'
1900 status, then we cannot transmit. Instead, we configure the microcode
1901 so as to re-issue this transmit interrupt at a later stage.
1903 if (test_bit(2, (void*)&card->wandev.critical)) {
1904 fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface;
1905 bctl->flag = 0xA0;
1906 dlci_interface->gen_interrupt |= FR_INTR_TXRDY;
1907 printk(KERN_INFO "%s: TX Interrupt Detected busy if_send\n",card->devname);
1909 } else {
1910 bctl->dlci = flags->dlci;
1911 bctl->length = chan->transmit_length;
1912 sdla_poke(&card->hw, bctl->offset, chan->transmit_buffer,
1913 chan->transmit_length);
1914 bctl->flag = 0xC0;
1916 ++chan->ifstats.tx_packets;
1917 ++card->wandev.stats.tx_packets;
1918 chan->ifstats.tx_bytes += chan->transmit_length;
1919 card->wandev.stats.tx_bytes += chan->transmit_length;
1920 chan->transmit_length = 0;
1922 /* if any other interfaces have transmit interrupts pending, */
1923 /* do not disable the global transmit interrupt */
1924 if(!(-- card->u.f.tx_interrupts_pending))
1925 flags->imask &= ~FR_INTR_TXRDY;
1927 netif_wake_queue (dev);
1932 /*============================================================================
1933 * Timer interrupt handler.
1934 FIXME: update comments as we modify the code
1935 * The timer interrupt is used for three purposes:
1936 * 1) Processing udp calls from 'fpipemon'.
1937 * 2) Processing update calls from /proc file system
1938 * 2) Reading board-level statistics for updating the proc file system.
1939 * 3) Sending inverse ARP request packets.
1941 static void timer_intr(sdla_t *card)
1943 fr508_flags_t* flags = card->flags;
1945 if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UDP) {
1946 if(card->u.f.udp_type == UDP_FPIPE_TYPE) {
1947 if(process_udp_mgmt_pkt(card)) {
1948 card->u.f.timer_int_enabled &=
1949 ~TMR_INT_ENABLED_UDP;
1954 if(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
1955 fr_get_err_stats(card);
1956 fr_get_stats(card);
1957 card->u.f.update_comms_stats = 0;
1958 card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE;
1962 //FIXME: Fix the dynamic IP addressing
1964 goto L4;
1966 // Used to send inarp request at given interval
1967 if (card->wandev.state == WAN_CONNECTED) {
1968 int num_remaining = 0;
1970 dev = card->wandev.dev;
1971 while (dev) {
1972 fr_channel_t *chan = dev->priv;
1974 if (chan->inarp == INARP_REQUEST &&
1975 chan->state == WAN_CONNECTED) {
1976 num_remaining++;
1978 if ((jiffies - chan->inarp_tick) > (chan->inarp_interval * HZ)) {
1979 send_inarp_request(card,dev);
1980 chan->inarp_tick = jiffies;
1983 dev = chan->slave;
1985 if (!num_remaining) { // no more to process
1986 flags->imask &= ~FR_INTR_TIMER;
1992 if(!card->u.f.timer_int_enabled)
1993 flags->imask &= ~FR_INTR_TIMER;
1997 /*============================================================================
1998 * Spurious interrupt handler.
1999 * o print a warning
2000 * o
2002 static void spur_intr (sdla_t* card)
2004 printk(KERN_INFO "%s: spurious interrupt!\n", card->devname);
2007 //FIXME: Fix the IPX in next version
2008 /*===========================================================================
2009 * Return 0 for non-IPXWAN packet
2010 * 1 for IPXWAN packet or IPX is not enabled!
2011 * FIXME: Use a IPX structure here not offsets
2013 static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number)
2015 int i;
2017 if( sendpacket[1] == 0x00 &&
2018 sendpacket[2] == 0x80 &&
2019 sendpacket[6] == 0x81 &&
2020 sendpacket[7] == 0x37) {
2022 /* It's an IPX packet */
2023 if(!enable_IPX) {
2024 /* Return 1 so we don't pass it up the stack. */
2025 //FIXME: Take this out when IPX is fixed
2026 printk (KERN_INFO
2027 "%s: WARNING: Unsupported IPX packet received and dropped\n",
2028 devname);
2029 return 1;
2031 } else {
2032 /* It's not IPX so return and pass it up the stack. */
2033 return 0;
2036 if( sendpacket[24] == 0x90 &&
2037 sendpacket[25] == 0x04)
2039 /* It's IPXWAN */
2041 if( sendpacket[10] == 0x02 &&
2042 sendpacket[42] == 0x00)
2044 /* It's a timer request packet */
2045 printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname);
2047 /* Go through the routing options and answer no to every
2048 * option except Unnumbered RIP/SAP
2050 for(i = 49; sendpacket[i] == 0x00; i += 5)
2052 /* 0x02 is the option for Unnumbered RIP/SAP */
2053 if( sendpacket[i + 4] != 0x02)
2055 sendpacket[i + 1] = 0;
2059 /* Skip over the extended Node ID option */
2060 if( sendpacket[i] == 0x04 )
2062 i += 8;
2065 /* We also want to turn off all header compression opt.
2067 for(; sendpacket[i] == 0x80 ;)
2069 sendpacket[i + 1] = 0;
2070 i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;
2073 /* Set the packet type to timer response */
2074 sendpacket[42] = 0x01;
2076 printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname);
2078 else if( sendpacket[42] == 0x02 )
2080 /* This is an information request packet */
2081 printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname);
2083 /* Set the packet type to information response */
2084 sendpacket[42] = 0x03;
2086 /* Set the router name */
2087 sendpacket[59] = 'F';
2088 sendpacket[60] = 'P';
2089 sendpacket[61] = 'I';
2090 sendpacket[62] = 'P';
2091 sendpacket[63] = 'E';
2092 sendpacket[64] = '-';
2093 sendpacket[65] = CVHexToAscii(network_number >> 28);
2094 sendpacket[66] = CVHexToAscii((network_number & 0x0F000000)>> 24);
2095 sendpacket[67] = CVHexToAscii((network_number & 0x00F00000)>> 20);
2096 sendpacket[68] = CVHexToAscii((network_number & 0x000F0000)>> 16);
2097 sendpacket[69] = CVHexToAscii((network_number & 0x0000F000)>> 12);
2098 sendpacket[70] = CVHexToAscii((network_number & 0x00000F00)>> 8);
2099 sendpacket[71] = CVHexToAscii((network_number & 0x000000F0)>> 4);
2100 sendpacket[72] = CVHexToAscii(network_number & 0x0000000F);
2101 for(i = 73; i < 107; i+= 1)
2103 sendpacket[i] = 0;
2106 printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname);
2108 else
2110 printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname);
2111 return 0;
2114 /* Set the WNodeID to our network address */
2115 sendpacket[43] = (unsigned char)(network_number >> 24);
2116 sendpacket[44] = (unsigned char)((network_number & 0x00FF0000) >> 16);
2117 sendpacket[45] = (unsigned char)((network_number & 0x0000FF00) >> 8);
2118 sendpacket[46] = (unsigned char)(network_number & 0x000000FF);
2120 return 1;
2123 /* If we get here, its an IPX-data packet so it'll get passed up the
2124 * stack.
2125 * switch the network numbers
2127 switch_net_numbers(sendpacket, network_number ,1);
2128 return 0;
2130 /*============================================================================
2131 * Process Route.
2132 * This routine is called as a polling routine to dynamically add/delete routes
2133 * negotiated by inverse ARP. It is in this "task" because we don't want routes
2134 * to be added while in interrupt context.
2137 static void process_route (sdla_t* card)
2139 struct net_device* dev;
2140 struct in_device *in_dev;
2141 struct rtentry route;
2142 int err = 0;
2143 mm_segment_t fs;
2146 /* Dynamic Route adding/removing */
2147 dev = card->wandev.dev;
2148 while (dev) {
2149 fr_channel_t *chan = dev->priv;
2151 if (chan->route_flag == ADD_ROUTE ||
2152 chan->route_flag == REMOVE_ROUTE ) {
2153 fs = get_fs();
2155 in_dev = dev->ip_ptr;
2157 if( in_dev != NULL && in_dev->ifa_list != NULL) {
2158 memset(&route, 0, sizeof(route));
2159 route.rt_dev = dev->name;
2160 route.rt_flags = 0;
2162 ((struct sockaddr_in *) &(route.rt_dst)) ->
2163 sin_addr.s_addr=in_dev->ifa_list->ifa_address;
2164 ((struct sockaddr_in *) &(route.rt_dst)) ->
2165 sin_family = AF_INET;
2166 ((struct sockaddr_in *) &(route.rt_genmask)) ->
2167 sin_addr.s_addr = 0xFFFFFFFF;
2168 ((struct sockaddr_in *) &(route.rt_genmask)) ->
2169 sin_family = AF_INET;
2171 switch(chan->route_flag) {
2173 case ADD_ROUTE:
2174 set_fs(get_ds()); /* get user space block */
2175 err = ip_rt_ioctl( SIOCADDRT, &route);
2176 set_fs(fs); /* restore old block */
2178 if (err) {
2179 printk(KERN_INFO "%s: Adding of route failed. Error: %d\n", card->devname,err);
2180 printk(KERN_INFO "%s: Address: %s\n",
2181 chan->name,
2182 in_ntoa(in_dev->ifa_list->ifa_address) );
2183 } else {
2184 chan->route_flag = ROUTE_ADDED;
2186 break;
2188 case REMOVE_ROUTE:
2189 set_fs(get_ds()); /* get user space block */
2190 err = ip_rt_ioctl( SIOCDELRT, &route);
2191 set_fs(fs); /* restore old block */
2193 if (err) {
2194 printk(KERN_INFO "%s: Deleting of route failed. Error: %d\n", card->devname,err);
2195 printk(KERN_INFO "%s: Address: %s\n",
2196 dev->name,in_ntoa(in_dev->ifa_list->ifa_address) );
2197 } else {
2198 printk(KERN_INFO "%s: Removed route.\n",
2199 chan->name);
2200 chan->route_flag = NO_ROUTE;
2202 break;
2203 } /* Case Statement */
2205 } /* If ADD/DELETE ROUTE */
2207 dev = chan->slave;
2208 } /* Device 'While' Loop */
2210 card->poll = NULL;
2215 /****** Frame Relay Firmware-Specific Functions *****************************/
2217 /*============================================================================
2218 * Read firmware code version.
2219 * o fill string str with firmware version info.
2221 static int fr_read_version (sdla_t* card, char* str)
2223 fr_mbox_t* mbox = card->mbox;
2224 int retry = MAX_CMD_RETRY;
2225 int err;
2229 mbox->cmd.command = FR_READ_CODE_VERSION;
2230 mbox->cmd.length = 0;
2231 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2232 } while (err && retry-- && fr_event(card, err, mbox));
2234 if (!err && str) {
2235 int len = mbox->cmd.length;
2236 memcpy(str, mbox->data, len);
2237 str[len] = '\0';
2239 return err;
2242 /*============================================================================
2243 * Set global configuration.
2245 static int fr_configure (sdla_t* card, fr_conf_t *conf)
2247 fr_mbox_t* mbox = card->mbox;
2248 int retry = MAX_CMD_RETRY;
2249 int dlci_num = card->u.f.dlci_num;
2250 int err, i;
2254 memcpy(mbox->data, conf, sizeof(fr_conf_t));
2256 if (dlci_num) for (i = 0; i < dlci_num; ++i)
2257 ((fr_conf_t*)mbox->data)->dlci[i] =
2258 card->u.f.node_dlci[i];
2260 mbox->cmd.command = FR_SET_CONFIG;
2261 mbox->cmd.length =
2262 sizeof(fr_conf_t) + dlci_num * sizeof(short);
2264 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2266 } while (err && retry-- && fr_event(card, err, mbox));
2268 return err;
2271 /*============================================================================
2272 * Set DLCI configuration.
2274 static int fr_dlci_configure (sdla_t* card, fr_dlc_conf_t *conf, unsigned dlci)
2276 fr_mbox_t* mbox = card->mbox;
2277 int retry = MAX_CMD_RETRY;
2278 int err;
2282 memcpy(mbox->data, conf, sizeof(fr_dlc_conf_t));
2283 mbox->cmd.dlci = (unsigned short) dlci;
2284 mbox->cmd.command = FR_SET_CONFIG;
2285 mbox->cmd.length = sizeof(fr_dlc_conf_t);
2286 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2287 } while (err && retry--);
2289 return err;
2291 /*============================================================================
2292 * Set interrupt mode.
2294 static int fr_set_intr_mode (sdla_t* card, unsigned mode, unsigned mtu,
2295 unsigned short timeout)
2297 fr_mbox_t* mbox = card->mbox;
2298 fr508_intr_ctl_t* ictl = (void*)mbox->data;
2299 int retry = MAX_CMD_RETRY;
2300 int err;
2304 memset(ictl, 0, sizeof(fr508_intr_ctl_t));
2305 ictl->mode = mode;
2306 ictl->tx_len = mtu;
2307 ictl->irq = card->hw.irq;
2309 /* indicate timeout on timer */
2310 if (mode & 0x20) ictl->timeout = timeout;
2312 mbox->cmd.length = sizeof(fr508_intr_ctl_t);
2313 mbox->cmd.command = FR_SET_INTR_MODE;
2314 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2316 } while (err && retry-- && fr_event(card, err, mbox));
2318 return err;
2321 /*============================================================================
2322 * Enable communications.
2324 static int fr_comm_enable (sdla_t* card)
2326 fr_mbox_t* mbox = card->mbox;
2327 int retry = MAX_CMD_RETRY;
2328 int err;
2332 mbox->cmd.command = FR_COMM_ENABLE;
2333 mbox->cmd.length = 0;
2334 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2335 } while (err && retry-- && fr_event(card, err, mbox));
2337 return err;
2340 /*============================================================================
2341 * Disable communications.
2343 static int fr_comm_disable (sdla_t* card)
2345 fr_mbox_t* mbox = card->mbox;
2346 int retry = MAX_CMD_RETRY;
2347 int err;
2351 mbox->cmd.command = FR_COMM_DISABLE;
2352 mbox->cmd.length = 0;
2353 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2354 } while (err && retry-- && fr_event(card, err, mbox));
2356 retry = MAX_CMD_RETRY;
2358 do {
2359 mbox->cmd.command = FR_SET_MODEM_STATUS;
2360 mbox->cmd.length = 1;
2361 mbox->data[0] = 0;
2362 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2363 } while (err && retry-- && fr_event(card, err, mbox));
2365 return err;
2368 /*============================================================================
2369 * Get communications error statistics.
2371 static int fr_get_err_stats (sdla_t* card)
2373 fr_mbox_t* mbox = card->mbox;
2374 int retry = MAX_CMD_RETRY;
2375 int err;
2380 mbox->cmd.command = FR_READ_ERROR_STATS;
2381 mbox->cmd.length = 0;
2382 mbox->cmd.dlci = 0;
2383 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2384 } while (err && retry-- && fr_event(card, err, mbox));
2386 if (!err) {
2387 fr_comm_stat_t* stats = (void*)mbox->data;
2388 card->wandev.stats.rx_over_errors = stats->rx_overruns;
2389 card->wandev.stats.rx_crc_errors = stats->rx_bad_crc;
2390 card->wandev.stats.rx_missed_errors = stats->rx_aborts;
2391 card->wandev.stats.rx_length_errors = stats->rx_too_long;
2392 card->wandev.stats.tx_aborted_errors = stats->tx_aborts;
2396 return err;
2399 /*============================================================================
2400 * Get statistics.
2402 static int fr_get_stats (sdla_t* card)
2404 fr_mbox_t* mbox = card->mbox;
2405 int retry = MAX_CMD_RETRY;
2406 int err;
2411 mbox->cmd.command = FR_READ_STATISTICS;
2412 mbox->cmd.length = 0;
2413 mbox->cmd.dlci = 0;
2414 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2415 } while (err && retry-- && fr_event(card, err, mbox));
2417 if (!err) {
2418 fr_link_stat_t* stats = (void*)mbox->data;
2419 card->wandev.stats.rx_frame_errors = stats->rx_bad_format;
2420 card->wandev.stats.rx_dropped =
2421 stats->rx_dropped + stats->rx_dropped2;
2424 return err;
2427 /*============================================================================
2428 * Add DLCI(s) (Access Node only!).
2429 * This routine will perform the ADD_DLCIs command for the specified DLCI.
2431 static int fr_add_dlci (sdla_t* card, int dlci)
2433 fr_mbox_t* mbox = card->mbox;
2434 int retry = MAX_CMD_RETRY;
2435 int err;
2439 unsigned short* dlci_list = (void*)mbox->data;
2441 mbox->cmd.length = sizeof(short);
2442 dlci_list[0] = dlci;
2443 mbox->cmd.command = FR_ADD_DLCI;
2444 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2446 } while (err && retry-- && fr_event(card, err, mbox));
2448 return err;
2451 /*============================================================================
2452 * Activate DLCI(s) (Access Node only!).
2453 * This routine will perform the ACTIVATE_DLCIs command with a DLCI number.
2455 static int fr_activate_dlci (sdla_t* card, int dlci)
2457 fr_mbox_t* mbox = card->mbox;
2458 int retry = MAX_CMD_RETRY;
2459 int err;
2463 unsigned short* dlci_list = (void*)mbox->data;
2465 mbox->cmd.length = sizeof(short);
2466 dlci_list[0] = dlci;
2467 mbox->cmd.command = FR_ACTIVATE_DLCI;
2468 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2470 } while (err && retry-- && fr_event(card, err, mbox));
2472 return err;
2475 /*============================================================================
2476 * Delete DLCI(s) (Access Node only!).
2477 * This routine will perform the DELETE_DLCIs command with a DLCI number.
2479 static int fr_delete_dlci (sdla_t* card, int dlci)
2481 fr_mbox_t* mbox = card->mbox;
2482 int retry = MAX_CMD_RETRY;
2483 int err;
2487 unsigned short* dlci_list = (void*)mbox->data;
2489 mbox->cmd.length = sizeof(short);
2490 dlci_list[0] = dlci;
2491 mbox->cmd.command = FR_DELETE_DLCI;
2492 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2494 } while (err && retry-- && fr_event(card, err, mbox));
2496 return err;
2501 /*============================================================================
2502 * Issue in-channel signalling frame.
2504 static int fr_issue_isf (sdla_t* card, int isf)
2506 fr_mbox_t* mbox = card->mbox;
2507 int retry = MAX_CMD_RETRY;
2508 int err;
2512 mbox->data[0] = isf;
2513 mbox->cmd.length = 1;
2514 mbox->cmd.command = FR_ISSUE_IS_FRAME;
2515 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2516 } while (err && retry-- && fr_event(card, err, mbox));
2518 return err;
2521 /*============================================================================
2522 * Send a frame on a selected DLCI.
2524 static int fr_send (sdla_t* card, int dlci, unsigned char attr, int len,
2525 void *buf)
2527 fr_mbox_t* mbox = card->mbox + 0x800;
2528 int retry = MAX_CMD_RETRY;
2529 int err;
2533 mbox->cmd.dlci = dlci;
2534 mbox->cmd.attr = attr;
2535 mbox->cmd.length = len;
2536 mbox->cmd.command = FR_WRITE;
2537 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2538 } while (err && retry-- && fr_event(card, err, mbox));
2540 if (!err) {
2542 fr_tx_buf_ctl_t* frbuf;
2544 if(card->hw.type == SDLA_S514)
2545 frbuf = (void*)(*(unsigned long*)mbox->data +
2546 card->hw.dpmbase);
2547 else
2548 frbuf = (void*)(*(unsigned long*)mbox->data -
2549 FR_MB_VECTOR + card->hw.dpmbase);
2551 sdla_poke(&card->hw, frbuf->offset, buf, len);
2552 frbuf->flag = 0x01;
2555 return err;
2558 /****** Firmware Asynchronous Event Handlers ********************************/
2560 /*============================================================================
2561 * Main asyncronous event/error handler.
2562 * This routine is called whenever firmware command returns non-zero
2563 * return code.
2565 * Return zero if previous command has to be cancelled.
2567 static int fr_event (sdla_t *card, int event, fr_mbox_t* mbox)
2569 fr508_flags_t* flags = card->flags;
2570 char *ptr = &flags->iflag;
2571 int i;
2573 switch (event) {
2575 case FRRES_MODEM_FAILURE:
2576 return fr_modem_failure(card, mbox);
2578 case FRRES_CHANNEL_DOWN:
2580 struct net_device *dev;
2582 /* Remove all routes from associated DLCI's */
2583 dev = card->wandev.dev;
2584 while (dev) {
2585 fr_channel_t *chan = dev->priv;
2586 if (chan->route_flag == ROUTE_ADDED) {
2587 chan->route_flag = REMOVE_ROUTE;
2588 card->poll = &process_route;
2591 if (chan->inarp == INARP_CONFIGURED) {
2592 chan->inarp = INARP_REQUEST;
2595 dev = chan->slave;
2598 wanpipe_set_state(card, WAN_DISCONNECTED);
2599 return 1;
2602 case FRRES_CHANNEL_UP:
2604 struct net_device *dev;
2605 int num_requests = 0;
2607 /* Remove all routes from associated DLCI's */
2608 dev = card->wandev.dev;
2609 while (dev) {
2610 fr_channel_t *chan = dev->priv;
2611 if( chan->inarp == INARP_REQUEST ){
2612 num_requests++;
2613 chan->inarp_tick = jiffies;
2615 dev = chan->slave;
2618 /* Allow timer interrupts */
2619 if (num_requests) flags->imask |= 0x20;
2620 wanpipe_set_state(card, WAN_CONNECTED);
2621 return 1;
2624 case FRRES_DLCI_CHANGE:
2625 return fr_dlci_change(card, mbox);
2627 case FRRES_DLCI_MISMATCH:
2628 printk(KERN_INFO "%s: DLCI list mismatch!\n",
2629 card->devname);
2630 return 1;
2632 case CMD_TIMEOUT:
2633 printk(KERN_ERR "%s: command 0x%02X timed out!\n",
2634 card->devname, mbox->cmd.command);
2635 printk(KERN_INFO "%s: ID Bytes = ",card->devname);
2636 for(i = 0; i < 8; i ++)
2637 printk(KERN_INFO "0x%02X ", *(ptr + 0x18 + i));
2638 printk(KERN_INFO "\n");
2640 break;
2642 case FRRES_DLCI_INACTIVE:
2643 break;
2645 case FRRES_CIR_OVERFLOW:
2646 break;
2647 case FRRES_BUFFER_OVERFLOW:
2648 break;
2649 default:
2650 printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"
2651 , card->devname, mbox->cmd.command, event);
2654 return 0;
2657 /*============================================================================
2658 * Handle modem error.
2660 * Return zero if previous command has to be cancelled.
2662 static int fr_modem_failure (sdla_t *card, fr_mbox_t* mbox)
2664 printk(KERN_INFO "%s: physical link down! (modem error 0x%02X)\n",
2665 card->devname, mbox->data[0]);
2667 switch (mbox->cmd.command){
2668 case FR_WRITE:
2670 case FR_READ:
2671 return 0;
2674 return 1;
2677 /*============================================================================
2678 * Handle DLCI status change.
2680 * Return zero if previous command has to be cancelled.
2682 static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox)
2684 dlci_status_t* status = (void*)mbox->data;
2685 int cnt = mbox->cmd.length / sizeof(dlci_status_t);
2686 fr_channel_t *chan;
2687 struct net_device* dev2;
2690 for (; cnt; --cnt, ++status) {
2692 unsigned short dlci= status->dlci;
2693 struct net_device* dev = find_channel(card, dlci);
2695 if (dev == NULL){
2696 printk(KERN_INFO
2697 "%s: CPE contains unconfigured DLCI= %d\n",
2698 card->devname, dlci);
2700 printk(KERN_INFO
2701 "%s: unconfigured DLCI %d reported by network\n"
2702 , card->devname, dlci);
2704 }else{
2705 if (status->state == FR_LINK_INOPER) {
2706 printk(KERN_INFO
2707 "%s: DLCI %u is inactive!\n",
2708 card->devname, dlci);
2710 if (dev && netif_running(dev))
2711 set_chan_state(dev, WAN_DISCONNECTED);
2714 if (status->state & FR_DLCI_DELETED) {
2716 printk(KERN_INFO
2717 "%s: DLCI %u has been deleted!\n",
2718 card->devname, dlci);
2720 if (dev && netif_running(dev)) {
2721 fr_channel_t *chan = dev->priv;
2723 if (chan->route_flag == ROUTE_ADDED) {
2724 chan->route_flag = REMOVE_ROUTE;
2725 card->poll = &process_route;
2728 if (chan->inarp == INARP_CONFIGURED) {
2729 chan->inarp = INARP_REQUEST;
2732 set_chan_state(dev, WAN_DISCONNECTED);
2735 } else if (status->state & FR_DLCI_ACTIVE) {
2737 chan = dev->priv;
2739 /* This flag is used for configuring specific
2740 DLCI(s) when they become active.
2742 chan->dlci_configured = DLCI_CONFIG_PENDING;
2744 if (dev && netif_running(dev))
2745 set_chan_state(dev, WAN_CONNECTED);
2751 dev2 = card->wandev.dev;
2752 while (dev2) {
2753 chan = dev2->priv;
2755 if (chan->dlci_configured == DLCI_CONFIG_PENDING) {
2756 if (fr_init_dlci(card, chan)){
2757 return 1;
2761 dev2 = chan->slave;
2763 return 1;
2767 static int fr_init_dlci (sdla_t *card, fr_channel_t *chan)
2769 fr_dlc_conf_t cfg;
2770 fr508_flags_t* flags = card->flags;
2772 memset(&cfg, 0, sizeof(cfg));
2774 if ( chan->cir_status == CIR_DISABLED) {
2776 cfg.cir_fwd = cfg.cir_bwd = 16;
2777 cfg.bc_fwd = cfg.bc_bwd = 16;
2778 cfg.conf_flags = 0x0001;
2780 }else if (chan->cir_status == CIR_ENABLED) {
2782 cfg.cir_fwd = cfg.cir_bwd = chan->cir;
2783 cfg.bc_fwd = cfg.bc_bwd = chan->bc;
2784 cfg.be_fwd = cfg.be_bwd = chan->be;
2785 cfg.conf_flags = 0x0000;
2788 if (fr_dlci_configure( card, &cfg , chan->dlci)){
2789 printk(KERN_INFO
2790 "%s: DLCI Configure failed for %d\n",
2791 card->devname, chan->dlci);
2792 return 1;
2795 chan->dlci_configured = DLCI_CONFIGURED;
2797 /* Allow timer interrupts */
2798 if( chan->inarp == INARP_REQUEST && card->wandev.state == WAN_CONNECTED) {
2799 chan->inarp_tick = jiffies;
2800 flags->imask |= 0x20;
2803 /* Read the interface byte mapping into the channel
2804 structure.
2806 read_DLCI_IB_mapping( card, chan );
2808 return 0;
2810 /******* Miscellaneous ******************************************************/
2812 /*============================================================================
2813 * Update channel state.
2815 static int update_chan_state (struct net_device* dev)
2817 fr_channel_t* chan = dev->priv;
2818 sdla_t* card = chan->card;
2819 fr_mbox_t* mbox = card->mbox;
2820 int retry = MAX_CMD_RETRY;
2821 int err;
2825 mbox->cmd.command = FR_LIST_ACTIVE_DLCI;
2826 mbox->cmd.length = 0;
2827 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
2828 } while (err && retry-- && fr_event(card, err, mbox));
2830 if (!err) {
2832 unsigned short* list = (void*)mbox->data;
2833 int cnt = mbox->cmd.length / sizeof(short);
2835 for (; cnt; --cnt, ++list) {
2837 if (*list == chan->dlci) {
2838 set_chan_state(dev, WAN_CONNECTED);
2839 break;
2844 return err;
2847 /*============================================================================
2848 * Set channel state.
2850 static void set_chan_state (struct net_device* dev, int state)
2852 fr_channel_t* chan = dev->priv;
2853 sdla_t* card = chan->card;
2854 unsigned long flags;
2856 save_flags(flags);
2857 cli();
2859 if (chan->state != state) {
2861 switch (state) {
2863 case WAN_CONNECTED:
2864 printk(KERN_INFO
2865 "%s: Interface %s: DLCI %d connected\n",
2866 card->devname, dev->name, chan->dlci);
2867 break;
2869 case WAN_CONNECTING:
2870 printk(KERN_INFO
2871 "%s: Interface %s: DLCI %d connecting\n",
2872 card->devname, dev->name, chan->dlci);
2873 break;
2875 case WAN_DISCONNECTED:
2876 printk (KERN_INFO
2877 "%s: Interface %s: DLCI %d disconnected!\n",
2878 card->devname, dev->name, chan->dlci);
2879 break;
2882 chan->state = state;
2885 chan->state_tick = jiffies;
2886 restore_flags(flags);
2889 /*============================================================================
2890 * Find network device by its channel number.
2892 static struct net_device* find_channel (sdla_t* card, unsigned dlci)
2894 if(dlci > HIGHEST_VALID_DLCI)
2895 return NULL;
2897 return(card->u.f.dlci_to_dev_map[dlci]);
2900 /*============================================================================
2901 * Check to see if a frame can be sent. If no transmit buffers available,
2902 * enable transmit interrupts.
2904 * Return: 1 - Tx buffer(s) available
2905 * 0 - no buffers available
2907 static int is_tx_ready (sdla_t* card, fr_channel_t* chan)
2909 unsigned char sb;
2911 if(card->hw.type == SDLA_S514)
2912 return 1;
2914 sb = inb(card->hw.port);
2915 if (sb & 0x02)
2916 return 1;
2918 return 0;
2921 /*============================================================================
2922 * Convert decimal string to unsigned integer.
2923 * If len != 0 then only 'len' characters of the string are converted.
2925 static unsigned int dec_to_uint (unsigned char* str, int len)
2927 unsigned val;
2929 if (!len)
2930 len = strlen(str);
2932 for (val = 0; len && is_digit(*str); ++str, --len)
2933 val = (val * 10) + (*str - (unsigned)'0');
2935 return val;
2940 /*=============================================================================
2941 * Store a UDP management packet for later processing.
2944 static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card,
2945 struct sk_buff *skb, int dlci)
2947 int udp_pkt_stored = 0;
2949 if(!card->u.f.udp_pkt_lgth &&(skb->len <= MAX_LGTH_UDP_MGNT_PKT)){
2950 card->u.f.udp_pkt_lgth = skb->len;
2951 card->u.f.udp_type = udp_type;
2952 card->u.f.udp_pkt_src = udp_pkt_src;
2953 card->u.f.udp_dlci = dlci;
2954 memcpy(card->u.f.udp_pkt_data, skb->data, skb->len);
2955 card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UDP;
2956 udp_pkt_stored = 1;
2958 }else{
2959 printk(KERN_INFO "ERROR: UDP packet not stored for DLCI %d\n",
2960 dlci);
2963 dev_kfree_skb(skb);
2965 return(udp_pkt_stored);
2969 /*==============================================================================
2970 * Process UDP call of type FPIPE8ND
2972 static int process_udp_mgmt_pkt(sdla_t* card)
2975 int c_retry = MAX_CMD_RETRY;
2976 unsigned char *buf;
2977 unsigned char frames;
2978 unsigned int len;
2979 unsigned short buffer_length;
2980 struct sk_buff *new_skb;
2981 fr_mbox_t* mbox = card->mbox;
2982 int err;
2983 struct timeval tv;
2984 int udp_mgmt_req_valid = 1;
2985 struct net_device* dev;
2986 fr_channel_t* chan;
2987 fr_udp_pkt_t *fr_udp_pkt;
2988 unsigned short num_trc_els;
2989 fr_trc_el_t* ptr_trc_el;
2990 fr_trc_el_t trc_el;
2991 fpipemon_trc_t* fpipemon_trc;
2993 char udp_pkt_src = card->u.f.udp_pkt_src;
2994 int dlci = card->u.f.udp_dlci;
2996 /* Find network interface for this packet */
2997 dev = find_channel(card, dlci);
2998 chan = dev->priv;
3000 /* If the UDP packet is from the network, we are going to have to
3001 transmit a response. Before doing so, we must check to see that
3002 we are not currently transmitting a frame (in 'if_send()') and
3003 that we are not already in a 'delayed transmit' state.
3005 if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
3006 if (test_bit(0, (void*)&card->wandev.critical) ||
3007 test_bit(2, (void*)&card->wandev.critical)) {
3008 return 0;
3010 if((netif_queue_stopped(dev)) || (card->u.f.tx_interrupts_pending)) {
3011 return 0;
3015 fr_udp_pkt = (fr_udp_pkt_t *)card->u.f.udp_pkt_data;
3017 switch(fr_udp_pkt->cblock.command) {
3019 case FPIPE_ENABLE_TRACING:
3020 case FPIPE_DISABLE_TRACING:
3021 case FPIPE_GET_TRACE_INFO:
3022 case FR_SET_FT1_MODE:
3023 if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
3024 chan->drvstats_gen.
3025 UDP_PIPE_mgmt_direction_err ++;
3026 udp_mgmt_req_valid = 0;
3027 break;
3030 default:
3031 break;
3034 if(!udp_mgmt_req_valid) {
3035 /* set length to 0 */
3036 fr_udp_pkt->cblock.length = 0;
3037 /* set return code */
3038 fr_udp_pkt->cblock.result = 0xCD;
3039 } else {
3041 switch(fr_udp_pkt->cblock.command) {
3043 case FPIPE_ENABLE_TRACING:
3044 if(!card->TracingEnabled) {
3045 do {
3046 mbox->cmd.command = FR_SET_TRACE_CONFIG;
3047 mbox->cmd.length = 1;
3048 mbox->cmd.dlci = 0x00;
3049 mbox->data[0] = fr_udp_pkt->data[0] |
3050 RESET_TRC;
3051 err = sdla_exec(mbox) ?
3052 mbox->cmd.result : CMD_TIMEOUT;
3053 } while (err && c_retry-- && fr_event(card, err,
3054 mbox));
3056 if(err) {
3057 card->TracingEnabled = 0;
3058 /* set the return code */
3059 fr_udp_pkt->cblock.result =
3060 mbox->cmd.result;
3061 mbox->cmd.length = 0;
3062 break;
3065 sdla_peek(&card->hw, NO_TRC_ELEMENTS_OFF,
3066 &num_trc_els, 2);
3067 sdla_peek(&card->hw, BASE_TRC_ELEMENTS_OFF,
3068 &card->u.f.trc_el_base, 4);
3069 card->u.f.curr_trc_el = card->u.f.trc_el_base;
3070 card->u.f.trc_el_last = card->u.f.curr_trc_el +
3071 ((num_trc_els - 1) *
3072 sizeof(fr_trc_el_t));
3074 /* Calculate the maximum trace data area in */
3075 /* the UDP packet */
3076 card->u.f.trc_bfr_space=(MAX_LGTH_UDP_MGNT_PKT -
3077 sizeof(fr_encap_hdr_t) -
3078 sizeof(ip_pkt_t) -
3079 sizeof(udp_pkt_t) -
3080 sizeof(wp_mgmt_t) -
3081 sizeof(cblock_t));
3083 /* set return code */
3084 fr_udp_pkt->cblock.result = 0;
3086 } else {
3087 /* set return code to line trace already
3088 enabled */
3089 fr_udp_pkt->cblock.result = 1;
3092 mbox->cmd.length = 0;
3093 card->TracingEnabled = 1;
3094 break;
3097 case FPIPE_DISABLE_TRACING:
3098 if(card->TracingEnabled) {
3100 do {
3101 mbox->cmd.command = FR_SET_TRACE_CONFIG;
3102 mbox->cmd.length = 1;
3103 mbox->cmd.dlci = 0x00;
3104 mbox->data[0] = ~ACTIVATE_TRC;
3105 err = sdla_exec(mbox) ?
3106 mbox->cmd.result : CMD_TIMEOUT;
3107 } while (err && c_retry-- && fr_event(card, err, mbox));
3110 /* set return code */
3111 fr_udp_pkt->cblock.result = 0;
3112 mbox->cmd.length = 0;
3113 card->TracingEnabled = 0;
3114 break;
3116 case FPIPE_GET_TRACE_INFO:
3118 /* Line trace cannot be performed on the 502 */
3119 if(!card->TracingEnabled) {
3120 /* set return code */
3121 fr_udp_pkt->cblock.result = 1;
3122 mbox->cmd.length = 0;
3123 break;
3126 (void *)ptr_trc_el = card->u.f.curr_trc_el;
3128 buffer_length = 0;
3129 fr_udp_pkt->data[0x00] = 0x00;
3131 for(frames = 0; frames < MAX_FRMS_TRACED; frames ++) {
3133 sdla_peek(&card->hw, (unsigned long)ptr_trc_el,
3134 (void *)&trc_el.flag,
3135 sizeof(fr_trc_el_t));
3136 if(trc_el.flag == 0x00) {
3137 break;
3139 if((card->u.f.trc_bfr_space - buffer_length)
3140 < sizeof(fpipemon_trc_hdr_t)) {
3141 fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
3142 break;
3145 fpipemon_trc =
3146 (fpipemon_trc_t *)&fr_udp_pkt->data[buffer_length];
3147 fpipemon_trc->fpipemon_trc_hdr.status =
3148 trc_el.attr;
3149 fpipemon_trc->fpipemon_trc_hdr.tmstamp =
3150 trc_el.tmstamp;
3151 fpipemon_trc->fpipemon_trc_hdr.length =
3152 trc_el.length;
3154 if(!trc_el.offset || !trc_el.length) {
3156 fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00;
3158 }else if((trc_el.length + sizeof(fpipemon_trc_hdr_t) + 1) >
3159 (card->u.f.trc_bfr_space - buffer_length)){
3161 fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00;
3162 fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
3164 }else {
3165 fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x01;
3166 sdla_peek(&card->hw, trc_el.offset,
3167 fpipemon_trc->data,
3168 trc_el.length);
3171 trc_el.flag = 0x00;
3172 sdla_poke(&card->hw, (unsigned long)ptr_trc_el,
3173 &trc_el.flag, 1);
3175 ptr_trc_el ++;
3176 if((void *)ptr_trc_el > card->u.f.trc_el_last)
3177 (void*)ptr_trc_el = card->u.f.trc_el_base;
3179 buffer_length += sizeof(fpipemon_trc_hdr_t);
3180 if(fpipemon_trc->fpipemon_trc_hdr.data_passed) {
3181 buffer_length += trc_el.length;
3184 if(fr_udp_pkt->data[0x00] & MORE_TRC_DATA) {
3185 break;
3189 if(frames == MAX_FRMS_TRACED) {
3190 fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
3193 card->u.f.curr_trc_el = (void *)ptr_trc_el;
3195 /* set the total number of frames passed */
3196 fr_udp_pkt->data[0x00] |=
3197 ((frames << 1) & (MAX_FRMS_TRACED << 1));
3199 /* set the data length and return code */
3200 fr_udp_pkt->cblock.length = mbox->cmd.length = buffer_length;
3201 fr_udp_pkt->cblock.result = 0;
3202 break;
3204 case FPIPE_FT1_READ_STATUS:
3205 sdla_peek(&card->hw, 0xF020,
3206 &fr_udp_pkt->data[0x00] , 2);
3207 fr_udp_pkt->cblock.length = 2;
3208 fr_udp_pkt->cblock.result = 0;
3209 break;
3211 case FPIPE_FLUSH_DRIVER_STATS:
3212 init_chan_statistics(chan);
3213 init_global_statistics(card);
3214 mbox->cmd.length = 0;
3215 break;
3217 case FPIPE_ROUTER_UP_TIME:
3218 do_gettimeofday(&tv);
3219 chan->router_up_time = tv.tv_sec -
3220 chan->router_start_time;
3221 *(unsigned long *)&fr_udp_pkt->data =
3222 chan->router_up_time;
3223 mbox->cmd.length = 4;
3224 break;
3227 case FR_FT1_STATUS_CTRL:
3228 if(fr_udp_pkt->data[0] == 1) {
3229 if(rCount++ != 0 ){
3230 fr_udp_pkt->cblock.result = 0;
3231 mbox->cmd.length = 1;
3232 break;
3236 /* Disable FT1 MONITOR STATUS */
3237 if(fr_udp_pkt->data[0] == 0) {
3238 if( --rCount != 0) {
3239 fr_udp_pkt->cblock.result = 0;
3240 mbox->cmd.length = 1;
3241 break;
3245 case FPIPE_DRIVER_STAT_IFSEND:
3246 memcpy(fr_udp_pkt->data,
3247 &chan->drvstats_if_send.if_send_entry,
3248 sizeof(if_send_stat_t));
3249 mbox->cmd.length = sizeof(if_send_stat_t);
3250 break;
3252 case FPIPE_DRIVER_STAT_INTR:
3253 memcpy(fr_udp_pkt->data,
3254 &card->statistics.isr_entry,
3255 sizeof(global_stats_t));
3256 memcpy(&fr_udp_pkt->data[sizeof(global_stats_t)],
3257 &chan->drvstats_rx_intr.rx_intr_no_socket,
3258 sizeof(rx_intr_stat_t));
3259 mbox->cmd.length = sizeof(global_stats_t) +
3260 sizeof(rx_intr_stat_t);
3261 break;
3263 case FPIPE_DRIVER_STAT_GEN:
3264 memcpy(fr_udp_pkt->data,
3265 &chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err,
3266 sizeof(pipe_mgmt_stat_t));
3268 memcpy(&fr_udp_pkt->data[sizeof(pipe_mgmt_stat_t)],
3269 &card->statistics, sizeof(global_stats_t));
3271 fr_udp_pkt->cblock.result = 0;
3272 fr_udp_pkt->cblock.length = sizeof(global_stats_t)+
3273 sizeof(rx_intr_stat_t);
3274 mbox->cmd.length = fr_udp_pkt->cblock.length;
3275 break;
3277 default:
3278 do {
3279 memcpy(&mbox->cmd,
3280 &fr_udp_pkt->cblock.command,
3281 sizeof(fr_cmd_t));
3282 if(mbox->cmd.length) {
3283 memcpy(&mbox->data,
3284 (char *)fr_udp_pkt->data,
3285 mbox->cmd.length);
3288 err = sdla_exec(mbox) ? mbox->cmd.result :
3289 CMD_TIMEOUT;
3290 } while (err && c_retry-- && fr_event(card, err, mbox));
3292 if(!err)
3293 chan->drvstats_gen.
3294 UDP_PIPE_mgmt_adptr_cmnd_OK ++;
3295 else
3296 chan->drvstats_gen.
3297 UDP_PIPE_mgmt_adptr_cmnd_timeout ++;
3299 /* copy the result back to our buffer */
3300 memcpy(&fr_udp_pkt->cblock.command,
3301 &mbox->cmd, sizeof(fr_cmd_t));
3303 if(mbox->cmd.length) {
3304 memcpy(&fr_udp_pkt->data,
3305 &mbox->data, mbox->cmd.length);
3310 /* Fill UDP TTL */
3311 fr_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
3312 len = reply_udp(card->u.f.udp_pkt_data, mbox->cmd.length);
3314 if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
3316 err = fr_send(card, dlci, 0, len, card->u.f.udp_pkt_data);
3317 if (err)
3318 chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_passed ++;
3319 else
3320 chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_failed ++;
3321 } else {
3322 /* Allocate socket buffer */
3323 if((new_skb = dev_alloc_skb(len)) != NULL) {
3325 /* copy data into new_skb */
3326 buf = skb_put(new_skb, len);
3327 memcpy(buf, card->u.f.udp_pkt_data, len);
3329 /* Decapsulate packet and pass it up the protocol
3330 stack */
3331 new_skb->dev = dev;
3332 buf = skb_pull(new_skb, 1); /* remove hardware header*/
3334 if(!wanrouter_type_trans(new_skb, dev)) {
3336 chan->drvstats_gen.
3337 UDP_PIPE_mgmt_not_passed_to_stack ++;
3338 /* can't decapsulate packet */
3339 dev_kfree_skb(new_skb);
3340 } else {
3341 chan->drvstats_gen.
3342 UDP_PIPE_mgmt_passed_to_stack ++;
3343 netif_rx(new_skb);
3346 } else {
3347 chan->drvstats_gen.UDP_PIPE_mgmt_no_socket ++;
3348 printk(KERN_INFO
3349 "%s: UDP mgmt cmnd, no socket buffers available!\n",
3350 card->devname);
3354 card->u.f.udp_pkt_lgth = 0;
3356 return 1;
3359 /*==============================================================================
3360 * Send Inverse ARP Request
3363 int send_inarp_request(sdla_t *card, struct net_device *dev)
3365 arphdr_1490_t *ArpPacket;
3366 arphdr_fr_t *arphdr;
3367 fr_channel_t *chan = dev->priv;
3368 struct in_device *in_dev;
3370 in_dev = dev->ip_ptr;
3372 if(in_dev != NULL ) {
3374 ArpPacket = kmalloc(sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t), GFP_ATOMIC);
3375 /* SNAP Header indicating ARP */
3376 ArpPacket->control = 0x03;
3377 ArpPacket->pad = 0x00;
3378 ArpPacket->NLPID = 0x80;
3379 ArpPacket->OUI[0] = 0;
3380 ArpPacket->OUI[1] = 0;
3381 ArpPacket->OUI[2] = 0;
3382 ArpPacket->PID = 0x0608;
3384 arphdr = (arphdr_fr_t *)(ArpPacket + 1); // Go to ARP Packet
3386 /* InARP request */
3387 arphdr->ar_hrd = 0x0F00; /* Frame Relay HW type */
3388 arphdr->ar_pro = 0x0008; /* IP Protocol */
3389 arphdr->ar_hln = 2; /* HW addr length */
3390 arphdr->ar_pln = 4; /* IP addr length */
3391 arphdr->ar_op = htons(0x08); /* InARP Request */
3392 arphdr->ar_sha = 0; /* src HW DLCI - Doesn't matter */
3393 if(in_dev->ifa_list != NULL)
3394 arphdr->ar_sip = in_dev->ifa_list->ifa_local; /* Local Address */else
3395 arphdr->ar_sip = 0;
3396 arphdr->ar_tha = 0; /* dst HW DLCI - Doesn't matter */
3397 arphdr->ar_tip = 0; /* Remote Address -- what we want */
3399 printk(KERN_INFO "%s: Sending InARP request on DLCI %d.\n", card->devname, chan->dlci);
3400 fr_send(card, chan->dlci, 0,
3401 sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t),
3402 (void *)ArpPacket);
3403 kfree(ArpPacket);
3406 return 1;
3410 /*==============================================================================
3411 * Check packet for ARP Type
3414 int is_arp(void *buf)
3416 arphdr_1490_t *arphdr = (arphdr_1490_t *)buf;
3418 if (arphdr->pad == 0x00 &&
3419 arphdr->NLPID == 0x80 &&
3420 arphdr->PID == 0x0608)
3421 return 1;
3422 else return 0;
3425 /*==============================================================================
3426 * Process ARP Packet Type
3429 int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device* dev)
3432 arphdr_fr_t *arphdr = (arphdr_fr_t *)(ArpPacket + 1); /* Skip header */
3433 fr_rx_buf_ctl_t* frbuf = card->rxmb;
3434 struct in_device *in_dev;
3437 in_dev = dev->ip_ptr;
3438 if( in_dev != NULL && in_dev->ifa_list != NULL) {
3439 switch (ntohs(arphdr->ar_op)) {
3441 case 0x08: // Inverse ARP request -- Send Reply, add route.
3443 /* Check for valid Address */
3444 printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Req\n", ((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
3446 if ((in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) {
3447 printk(KERN_INFO "%s: Invalid PtP address. InARP ignored.\n", card->devname);
3448 printk(KERN_INFO "mask %X\n", in_dev->ifa_list->ifa_mask);
3449 printk(KERN_INFO "local %X\n", in_dev->ifa_list->ifa_local);
3450 return -1;
3453 if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) {
3454 printk(KERN_INFO "%s: Local addr = PtP addr. InARP ignored.\n", card->devname);
3455 return -1;
3458 arphdr->ar_op = htons(0x09); /* InARP Reply */
3460 /* Set addresses */
3461 arphdr->ar_tip = arphdr->ar_sip;
3462 arphdr->ar_sip = in_dev->ifa_list->ifa_local;
3464 fr_send(card, frbuf->dlci, 0, frbuf->length, (void *)ArpPacket);
3466 /* Modify Point-to-Point Address */
3468 struct ifreq if_info;
3469 struct sockaddr_in *if_data;
3470 mm_segment_t fs = get_fs();
3471 int err;
3473 /* Set remote addresses */
3474 memset(&if_info, 0, sizeof(if_info));
3475 strcpy(if_info.ifr_name, dev->name);
3477 set_fs(get_ds()); /* get user space block */
3479 if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr;
3480 if_data->sin_addr.s_addr = arphdr->ar_tip;
3481 if_data->sin_family = AF_INET;
3482 err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
3484 set_fs(fs); /* restore old block */
3487 /* Add Route Flag */
3488 /* The route will be added in the polling routine so
3489 that it is not interrupt context. */
3491 ((fr_channel_t *) dev->priv)->route_flag = ADD_ROUTE;
3492 card->poll = &process_route;
3494 break;
3496 case 0x09: // Inverse ARP reply
3498 /* Check for valid Address */
3499 printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Reply\n", ((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
3501 if ((in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) {
3502 printk(KERN_INFO "%s: Invalid PtP address. InARP ignored.\n", card->devname);
3503 return -1;
3506 if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) {
3507 printk(KERN_INFO "%s: Local addr = PtP addr. InARP ignored.\n", card->devname);
3508 return -1;
3511 /* Modify Point-to-Point Address */
3513 struct ifreq if_info;
3514 struct sockaddr_in *if_data;
3515 mm_segment_t fs = get_fs();
3516 int err;
3518 /* Set remote addresses */
3519 memset(&if_info, 0, sizeof(if_info));
3520 strcpy(if_info.ifr_name, dev->name);
3522 set_fs(get_ds()); /* get user space block */
3524 if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr;
3525 if_data->sin_addr.s_addr = arphdr->ar_sip;
3526 if_data->sin_family = AF_INET;
3527 err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
3529 set_fs(fs); /* restore old block */
3532 /* Add Route Flag */
3533 /* The route will be added in the polling routine so
3534 that it is not interrupt context. */
3536 ((fr_channel_t *) dev->priv)->route_flag = ADD_ROUTE;
3537 ((fr_channel_t *) dev->priv)->inarp = INARP_CONFIGURED;
3538 card->poll = &process_route;
3540 break;
3541 default: // ARP's and RARP's -- Shouldn't happen.
3545 return 0;
3549 /*==============================================================================
3550 * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR_
3551 * TEST_COUNTER times.
3553 static int intr_test( sdla_t* card )
3555 fr_mbox_t* mb = card->mbox;
3556 int err,i;
3558 /* The critical flag is unset here because we want to get into the
3559 ISR without the flag already set. The If_open sets the flag.
3561 clear_bit(1, (void*)&card->wandev.critical);
3563 err = fr_set_intr_mode(card, FR_INTR_READY, card->wandev.mtu, 0 );
3565 if (err == CMD_OK) {
3567 for ( i = 0; i < MAX_INTR_TEST_COUNTER; i++ ) {
3568 /* Run command READ_CODE_VERSION */
3569 mb->cmd.length = 0;
3570 mb->cmd.command = FR_READ_CODE_VERSION;
3571 err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
3572 if (err != CMD_OK)
3573 fr_event(card, err, mb);
3576 } else {
3577 return err;
3580 err = fr_set_intr_mode( card, 0, card->wandev.mtu, 0 );
3582 if( err != CMD_OK )
3583 return err;
3585 set_bit(1, (void*)&card->wandev.critical);
3586 return 0;
3589 /*==============================================================================
3590 * Determine what type of UDP call it is. FPIPE8ND ?
3592 static int udp_pkt_type( struct sk_buff *skb, sdla_t* card )
3594 fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)skb->data;
3596 if((fr_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
3597 (fr_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45) &&
3598 (fr_udp_pkt->udp_pkt.udp_dst_port ==
3599 ntohs(card->wandev.udp_port)) &&
3600 (fr_udp_pkt->wp_mgmt.request_reply ==
3601 UDPMGMT_REQUEST)) {
3602 if(!strncmp(fr_udp_pkt->wp_mgmt.signature,
3603 UDPMGMT_FPIPE_SIGNATURE, 8))
3604 return UDP_FPIPE_TYPE;
3607 return UDP_INVALID_TYPE;
3611 /*==============================================================================
3612 * Initializes the Statistics values in the fr_channel structure.
3614 void init_chan_statistics( fr_channel_t* chan)
3616 memset(&chan->drvstats_if_send.if_send_entry, 0,
3617 sizeof(if_send_stat_t));
3618 memset(&chan->drvstats_rx_intr.rx_intr_no_socket, 0,
3619 sizeof(rx_intr_stat_t));
3620 memset(&chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err, 0,
3621 sizeof(pipe_mgmt_stat_t));
3624 /*==============================================================================
3625 * Initializes the Statistics values in the Sdla_t structure.
3627 void init_global_statistics( sdla_t* card )
3629 /* Intialize global statistics for a card */
3630 memset(&card->statistics.isr_entry, 0, sizeof(global_stats_t));
3633 static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan )
3635 fr_mbox_t* mbox = card->mbox;
3636 int retry = MAX_CMD_RETRY;
3637 dlci_IB_mapping_t* result;
3638 int err, counter, found;
3640 do {
3641 mbox->cmd.command = FR_READ_DLCI_IB_MAPPING;
3642 mbox->cmd.length = 0;
3643 err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
3644 } while (err && retry-- && fr_event(card, err, mbox));
3646 if( mbox->cmd.result != 0){
3647 printk(KERN_INFO "%s: Read DLCI IB Mapping failed\n",
3648 chan->name);
3651 counter = mbox->cmd.length / sizeof(dlci_IB_mapping_t);
3652 result = (void *)mbox->data;
3654 found = 0;
3655 for (; counter; --counter, ++result) {
3656 if ( result->dlci == chan->dlci ) {
3657 chan->IB_addr = result->addr_value;
3658 if(card->hw.type == SDLA_S514){
3659 chan->dlci_int_interface =
3660 (void*)(card->hw.dpmbase +
3661 chan->IB_addr);
3662 }else{
3663 chan->dlci_int_interface =
3664 (void*)(card->hw.dpmbase +
3665 (chan->IB_addr & 0x00001FFF));
3668 found = 1;
3669 break;
3672 if (!found)
3673 printk( KERN_INFO "%s: DLCI %d not found by IB MAPPING cmd\n",
3674 card->devname, chan->dlci);
3677 void s508_s514_lock(sdla_t *card, unsigned long *smp_flags)
3680 if (card->hw.type != SDLA_S514){
3681 #ifdef CONFIG_SMP
3682 spin_lock_irqsave(&card->lock, *smp_flags);
3683 #else
3684 disable_irq(card->hw.irq);
3685 #endif
3687 #ifdef CONFIG_SMP
3688 else{
3689 spin_lock(&card->lock);
3691 #endif
3694 void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags)
3696 if (card->hw.type != SDLA_S514){
3697 #ifdef CONFIG_SMP
3698 spin_unlock_irqrestore(&card->lock, *smp_flags);
3699 #else
3700 enable_irq(card->hw.irq);
3701 #endif
3703 #ifdef CONFIG_SMP
3704 else{
3705 spin_unlock(&card->lock);
3707 #endif
3711 /****** End *****************************************************************/