diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/wan/farsync.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/net/wan/farsync.c')
-rw-r--r-- | drivers/net/wan/farsync.c | 2712 |
1 files changed, 2712 insertions, 0 deletions
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c new file mode 100644 index 000000000000..7575b799ce53 --- /dev/null +++ b/drivers/net/wan/farsync.c | |||
@@ -0,0 +1,2712 @@ | |||
1 | /* | ||
2 | * FarSync WAN driver for Linux (2.6.x kernel version) | ||
3 | * | ||
4 | * Actually sync driver for X.21, V.35 and V.24 on FarSync T-series cards | ||
5 | * | ||
6 | * Copyright (C) 2001-2004 FarSite Communications Ltd. | ||
7 | * www.farsite.co.uk | ||
8 | * | ||
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 | * Author: R.J.Dunlop <bob.dunlop@farsite.co.uk> | ||
15 | * Maintainer: Kevin Curtis <kevin.curtis@farsite.co.uk> | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/version.h> | ||
21 | #include <linux/pci.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/if.h> | ||
25 | #include <linux/hdlc.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <asm/uaccess.h> | ||
28 | |||
29 | #include "farsync.h" | ||
30 | |||
31 | /* | ||
32 | * Module info | ||
33 | */ | ||
34 | MODULE_AUTHOR("R.J.Dunlop <bob.dunlop@farsite.co.uk>"); | ||
35 | MODULE_DESCRIPTION("FarSync T-Series WAN driver. FarSite Communications Ltd."); | ||
36 | MODULE_LICENSE("GPL"); | ||
37 | |||
38 | /* Driver configuration and global parameters | ||
39 | * ========================================== | ||
40 | */ | ||
41 | |||
42 | /* Number of ports (per card) and cards supported | ||
43 | */ | ||
44 | #define FST_MAX_PORTS 4 | ||
45 | #define FST_MAX_CARDS 32 | ||
46 | |||
47 | /* Default parameters for the link | ||
48 | */ | ||
49 | #define FST_TX_QUEUE_LEN 100 /* At 8Mbps a longer queue length is | ||
50 | * useful, the syncppp module forces | ||
51 | * this down assuming a slower line I | ||
52 | * guess. | ||
53 | */ | ||
54 | #define FST_TXQ_DEPTH 16 /* This one is for the buffering | ||
55 | * of frames on the way down to the card | ||
56 | * so that we can keep the card busy | ||
57 | * and maximise throughput | ||
58 | */ | ||
59 | #define FST_HIGH_WATER_MARK 12 /* Point at which we flow control | ||
60 | * network layer */ | ||
61 | #define FST_LOW_WATER_MARK 8 /* Point at which we remove flow | ||
62 | * control from network layer */ | ||
63 | #define FST_MAX_MTU 8000 /* Huge but possible */ | ||
64 | #define FST_DEF_MTU 1500 /* Common sane value */ | ||
65 | |||
66 | #define FST_TX_TIMEOUT (2*HZ) | ||
67 | |||
68 | #ifdef ARPHRD_RAWHDLC | ||
69 | #define ARPHRD_MYTYPE ARPHRD_RAWHDLC /* Raw frames */ | ||
70 | #else | ||
71 | #define ARPHRD_MYTYPE ARPHRD_HDLC /* Cisco-HDLC (keepalives etc) */ | ||
72 | #endif | ||
73 | |||
74 | /* | ||
75 | * Modules parameters and associated varaibles | ||
76 | */ | ||
77 | int fst_txq_low = FST_LOW_WATER_MARK; | ||
78 | int fst_txq_high = FST_HIGH_WATER_MARK; | ||
79 | int fst_max_reads = 7; | ||
80 | int fst_excluded_cards = 0; | ||
81 | int fst_excluded_list[FST_MAX_CARDS]; | ||
82 | |||
83 | module_param(fst_txq_low, int, 0); | ||
84 | module_param(fst_txq_high, int, 0); | ||
85 | module_param(fst_max_reads, int, 0); | ||
86 | module_param(fst_excluded_cards, int, 0); | ||
87 | module_param_array(fst_excluded_list, int, NULL, 0); | ||
88 | |||
89 | /* Card shared memory layout | ||
90 | * ========================= | ||
91 | */ | ||
92 | #pragma pack(1) | ||
93 | |||
94 | /* This information is derived in part from the FarSite FarSync Smc.h | ||
95 | * file. Unfortunately various name clashes and the non-portability of the | ||
96 | * bit field declarations in that file have meant that I have chosen to | ||
97 | * recreate the information here. | ||
98 | * | ||
99 | * The SMC (Shared Memory Configuration) has a version number that is | ||
100 | * incremented every time there is a significant change. This number can | ||
101 | * be used to check that we have not got out of step with the firmware | ||
102 | * contained in the .CDE files. | ||
103 | */ | ||
104 | #define SMC_VERSION 24 | ||
105 | |||
106 | #define FST_MEMSIZE 0x100000 /* Size of card memory (1Mb) */ | ||
107 | |||
108 | #define SMC_BASE 0x00002000L /* Base offset of the shared memory window main | ||
109 | * configuration structure */ | ||
110 | #define BFM_BASE 0x00010000L /* Base offset of the shared memory window DMA | ||
111 | * buffers */ | ||
112 | |||
113 | #define LEN_TX_BUFFER 8192 /* Size of packet buffers */ | ||
114 | #define LEN_RX_BUFFER 8192 | ||
115 | |||
116 | #define LEN_SMALL_TX_BUFFER 256 /* Size of obsolete buffs used for DOS diags */ | ||
117 | #define LEN_SMALL_RX_BUFFER 256 | ||
118 | |||
119 | #define NUM_TX_BUFFER 2 /* Must be power of 2. Fixed by firmware */ | ||
120 | #define NUM_RX_BUFFER 8 | ||
121 | |||
122 | /* Interrupt retry time in milliseconds */ | ||
123 | #define INT_RETRY_TIME 2 | ||
124 | |||
125 | /* The Am186CH/CC processors support a SmartDMA mode using circular pools | ||
126 | * of buffer descriptors. The structure is almost identical to that used | ||
127 | * in the LANCE Ethernet controllers. Details available as PDF from the | ||
128 | * AMD web site: http://www.amd.com/products/epd/processors/\ | ||
129 | * 2.16bitcont/3.am186cxfa/a21914/21914.pdf | ||
130 | */ | ||
131 | struct txdesc { /* Transmit descriptor */ | ||
132 | volatile u16 ladr; /* Low order address of packet. This is a | ||
133 | * linear address in the Am186 memory space | ||
134 | */ | ||
135 | volatile u8 hadr; /* High order address. Low 4 bits only, high 4 | ||
136 | * bits must be zero | ||
137 | */ | ||
138 | volatile u8 bits; /* Status and config */ | ||
139 | volatile u16 bcnt; /* 2s complement of packet size in low 15 bits. | ||
140 | * Transmit terminal count interrupt enable in | ||
141 | * top bit. | ||
142 | */ | ||
143 | u16 unused; /* Not used in Tx */ | ||
144 | }; | ||
145 | |||
146 | struct rxdesc { /* Receive descriptor */ | ||
147 | volatile u16 ladr; /* Low order address of packet */ | ||
148 | volatile u8 hadr; /* High order address */ | ||
149 | volatile u8 bits; /* Status and config */ | ||
150 | volatile u16 bcnt; /* 2s complement of buffer size in low 15 bits. | ||
151 | * Receive terminal count interrupt enable in | ||
152 | * top bit. | ||
153 | */ | ||
154 | volatile u16 mcnt; /* Message byte count (15 bits) */ | ||
155 | }; | ||
156 | |||
157 | /* Convert a length into the 15 bit 2's complement */ | ||
158 | /* #define cnv_bcnt(len) (( ~(len) + 1 ) & 0x7FFF ) */ | ||
159 | /* Since we need to set the high bit to enable the completion interrupt this | ||
160 | * can be made a lot simpler | ||
161 | */ | ||
162 | #define cnv_bcnt(len) (-(len)) | ||
163 | |||
164 | /* Status and config bits for the above */ | ||
165 | #define DMA_OWN 0x80 /* SmartDMA owns the descriptor */ | ||
166 | #define TX_STP 0x02 /* Tx: start of packet */ | ||
167 | #define TX_ENP 0x01 /* Tx: end of packet */ | ||
168 | #define RX_ERR 0x40 /* Rx: error (OR of next 4 bits) */ | ||
169 | #define RX_FRAM 0x20 /* Rx: framing error */ | ||
170 | #define RX_OFLO 0x10 /* Rx: overflow error */ | ||
171 | #define RX_CRC 0x08 /* Rx: CRC error */ | ||
172 | #define RX_HBUF 0x04 /* Rx: buffer error */ | ||
173 | #define RX_STP 0x02 /* Rx: start of packet */ | ||
174 | #define RX_ENP 0x01 /* Rx: end of packet */ | ||
175 | |||
176 | /* Interrupts from the card are caused by various events which are presented | ||
177 | * in a circular buffer as several events may be processed on one physical int | ||
178 | */ | ||
179 | #define MAX_CIRBUFF 32 | ||
180 | |||
181 | struct cirbuff { | ||
182 | u8 rdindex; /* read, then increment and wrap */ | ||
183 | u8 wrindex; /* write, then increment and wrap */ | ||
184 | u8 evntbuff[MAX_CIRBUFF]; | ||
185 | }; | ||
186 | |||
187 | /* Interrupt event codes. | ||
188 | * Where appropriate the two low order bits indicate the port number | ||
189 | */ | ||
190 | #define CTLA_CHG 0x18 /* Control signal changed */ | ||
191 | #define CTLB_CHG 0x19 | ||
192 | #define CTLC_CHG 0x1A | ||
193 | #define CTLD_CHG 0x1B | ||
194 | |||
195 | #define INIT_CPLT 0x20 /* Initialisation complete */ | ||
196 | #define INIT_FAIL 0x21 /* Initialisation failed */ | ||
197 | |||
198 | #define ABTA_SENT 0x24 /* Abort sent */ | ||
199 | #define ABTB_SENT 0x25 | ||
200 | #define ABTC_SENT 0x26 | ||
201 | #define ABTD_SENT 0x27 | ||
202 | |||
203 | #define TXA_UNDF 0x28 /* Transmission underflow */ | ||
204 | #define TXB_UNDF 0x29 | ||
205 | #define TXC_UNDF 0x2A | ||
206 | #define TXD_UNDF 0x2B | ||
207 | |||
208 | #define F56_INT 0x2C | ||
209 | #define M32_INT 0x2D | ||
210 | |||
211 | #define TE1_ALMA 0x30 | ||
212 | |||
213 | /* Port physical configuration. See farsync.h for field values */ | ||
214 | struct port_cfg { | ||
215 | u16 lineInterface; /* Physical interface type */ | ||
216 | u8 x25op; /* Unused at present */ | ||
217 | u8 internalClock; /* 1 => internal clock, 0 => external */ | ||
218 | u8 transparentMode; /* 1 => on, 0 => off */ | ||
219 | u8 invertClock; /* 0 => normal, 1 => inverted */ | ||
220 | u8 padBytes[6]; /* Padding */ | ||
221 | u32 lineSpeed; /* Speed in bps */ | ||
222 | }; | ||
223 | |||
224 | /* TE1 port physical configuration */ | ||
225 | struct su_config { | ||
226 | u32 dataRate; | ||
227 | u8 clocking; | ||
228 | u8 framing; | ||
229 | u8 structure; | ||
230 | u8 interface; | ||
231 | u8 coding; | ||
232 | u8 lineBuildOut; | ||
233 | u8 equalizer; | ||
234 | u8 transparentMode; | ||
235 | u8 loopMode; | ||
236 | u8 range; | ||
237 | u8 txBufferMode; | ||
238 | u8 rxBufferMode; | ||
239 | u8 startingSlot; | ||
240 | u8 losThreshold; | ||
241 | u8 enableIdleCode; | ||
242 | u8 idleCode; | ||
243 | u8 spare[44]; | ||
244 | }; | ||
245 | |||
246 | /* TE1 Status */ | ||
247 | struct su_status { | ||
248 | u32 receiveBufferDelay; | ||
249 | u32 framingErrorCount; | ||
250 | u32 codeViolationCount; | ||
251 | u32 crcErrorCount; | ||
252 | u32 lineAttenuation; | ||
253 | u8 portStarted; | ||
254 | u8 lossOfSignal; | ||
255 | u8 receiveRemoteAlarm; | ||
256 | u8 alarmIndicationSignal; | ||
257 | u8 spare[40]; | ||
258 | }; | ||
259 | |||
260 | /* Finally sling all the above together into the shared memory structure. | ||
261 | * Sorry it's a hodge podge of arrays, structures and unused bits, it's been | ||
262 | * evolving under NT for some time so I guess we're stuck with it. | ||
263 | * The structure starts at offset SMC_BASE. | ||
264 | * See farsync.h for some field values. | ||
265 | */ | ||
266 | struct fst_shared { | ||
267 | /* DMA descriptor rings */ | ||
268 | struct rxdesc rxDescrRing[FST_MAX_PORTS][NUM_RX_BUFFER]; | ||
269 | struct txdesc txDescrRing[FST_MAX_PORTS][NUM_TX_BUFFER]; | ||
270 | |||
271 | /* Obsolete small buffers */ | ||
272 | u8 smallRxBuffer[FST_MAX_PORTS][NUM_RX_BUFFER][LEN_SMALL_RX_BUFFER]; | ||
273 | u8 smallTxBuffer[FST_MAX_PORTS][NUM_TX_BUFFER][LEN_SMALL_TX_BUFFER]; | ||
274 | |||
275 | u8 taskStatus; /* 0x00 => initialising, 0x01 => running, | ||
276 | * 0xFF => halted | ||
277 | */ | ||
278 | |||
279 | u8 interruptHandshake; /* Set to 0x01 by adapter to signal interrupt, | ||
280 | * set to 0xEE by host to acknowledge interrupt | ||
281 | */ | ||
282 | |||
283 | u16 smcVersion; /* Must match SMC_VERSION */ | ||
284 | |||
285 | u32 smcFirmwareVersion; /* 0xIIVVRRBB where II = product ID, VV = major | ||
286 | * version, RR = revision and BB = build | ||
287 | */ | ||
288 | |||
289 | u16 txa_done; /* Obsolete completion flags */ | ||
290 | u16 rxa_done; | ||
291 | u16 txb_done; | ||
292 | u16 rxb_done; | ||
293 | u16 txc_done; | ||
294 | u16 rxc_done; | ||
295 | u16 txd_done; | ||
296 | u16 rxd_done; | ||
297 | |||
298 | u16 mailbox[4]; /* Diagnostics mailbox. Not used */ | ||
299 | |||
300 | struct cirbuff interruptEvent; /* interrupt causes */ | ||
301 | |||
302 | u32 v24IpSts[FST_MAX_PORTS]; /* V.24 control input status */ | ||
303 | u32 v24OpSts[FST_MAX_PORTS]; /* V.24 control output status */ | ||
304 | |||
305 | struct port_cfg portConfig[FST_MAX_PORTS]; | ||
306 | |||
307 | u16 clockStatus[FST_MAX_PORTS]; /* lsb: 0=> present, 1=> absent */ | ||
308 | |||
309 | u16 cableStatus; /* lsb: 0=> present, 1=> absent */ | ||
310 | |||
311 | u16 txDescrIndex[FST_MAX_PORTS]; /* transmit descriptor ring index */ | ||
312 | u16 rxDescrIndex[FST_MAX_PORTS]; /* receive descriptor ring index */ | ||
313 | |||
314 | u16 portMailbox[FST_MAX_PORTS][2]; /* command, modifier */ | ||
315 | u16 cardMailbox[4]; /* Not used */ | ||
316 | |||
317 | /* Number of times the card thinks the host has | ||
318 | * missed an interrupt by not acknowledging | ||
319 | * within 2mS (I guess NT has problems) | ||
320 | */ | ||
321 | u32 interruptRetryCount; | ||
322 | |||
323 | /* Driver private data used as an ID. We'll not | ||
324 | * use this as I'd rather keep such things | ||
325 | * in main memory rather than on the PCI bus | ||
326 | */ | ||
327 | u32 portHandle[FST_MAX_PORTS]; | ||
328 | |||
329 | /* Count of Tx underflows for stats */ | ||
330 | u32 transmitBufferUnderflow[FST_MAX_PORTS]; | ||
331 | |||
332 | /* Debounced V.24 control input status */ | ||
333 | u32 v24DebouncedSts[FST_MAX_PORTS]; | ||
334 | |||
335 | /* Adapter debounce timers. Don't touch */ | ||
336 | u32 ctsTimer[FST_MAX_PORTS]; | ||
337 | u32 ctsTimerRun[FST_MAX_PORTS]; | ||
338 | u32 dcdTimer[FST_MAX_PORTS]; | ||
339 | u32 dcdTimerRun[FST_MAX_PORTS]; | ||
340 | |||
341 | u32 numberOfPorts; /* Number of ports detected at startup */ | ||
342 | |||
343 | u16 _reserved[64]; | ||
344 | |||
345 | u16 cardMode; /* Bit-mask to enable features: | ||
346 | * Bit 0: 1 enables LED identify mode | ||
347 | */ | ||
348 | |||
349 | u16 portScheduleOffset; | ||
350 | |||
351 | struct su_config suConfig; /* TE1 Bits */ | ||
352 | struct su_status suStatus; | ||
353 | |||
354 | u32 endOfSmcSignature; /* endOfSmcSignature MUST be the last member of | ||
355 | * the structure and marks the end of shared | ||
356 | * memory. Adapter code initializes it as | ||
357 | * END_SIG. | ||
358 | */ | ||
359 | }; | ||
360 | |||
361 | /* endOfSmcSignature value */ | ||
362 | #define END_SIG 0x12345678 | ||
363 | |||
364 | /* Mailbox values. (portMailbox) */ | ||
365 | #define NOP 0 /* No operation */ | ||
366 | #define ACK 1 /* Positive acknowledgement to PC driver */ | ||
367 | #define NAK 2 /* Negative acknowledgement to PC driver */ | ||
368 | #define STARTPORT 3 /* Start an HDLC port */ | ||
369 | #define STOPPORT 4 /* Stop an HDLC port */ | ||
370 | #define ABORTTX 5 /* Abort the transmitter for a port */ | ||
371 | #define SETV24O 6 /* Set V24 outputs */ | ||
372 | |||
373 | /* PLX Chip Register Offsets */ | ||
374 | #define CNTRL_9052 0x50 /* Control Register */ | ||
375 | #define CNTRL_9054 0x6c /* Control Register */ | ||
376 | |||
377 | #define INTCSR_9052 0x4c /* Interrupt control/status register */ | ||
378 | #define INTCSR_9054 0x68 /* Interrupt control/status register */ | ||
379 | |||
380 | /* 9054 DMA Registers */ | ||
381 | /* | ||
382 | * Note that we will be using DMA Channel 0 for copying rx data | ||
383 | * and Channel 1 for copying tx data | ||
384 | */ | ||
385 | #define DMAMODE0 0x80 | ||
386 | #define DMAPADR0 0x84 | ||
387 | #define DMALADR0 0x88 | ||
388 | #define DMASIZ0 0x8c | ||
389 | #define DMADPR0 0x90 | ||
390 | #define DMAMODE1 0x94 | ||
391 | #define DMAPADR1 0x98 | ||
392 | #define DMALADR1 0x9c | ||
393 | #define DMASIZ1 0xa0 | ||
394 | #define DMADPR1 0xa4 | ||
395 | #define DMACSR0 0xa8 | ||
396 | #define DMACSR1 0xa9 | ||
397 | #define DMAARB 0xac | ||
398 | #define DMATHR 0xb0 | ||
399 | #define DMADAC0 0xb4 | ||
400 | #define DMADAC1 0xb8 | ||
401 | #define DMAMARBR 0xac | ||
402 | |||
403 | #define FST_MIN_DMA_LEN 64 | ||
404 | #define FST_RX_DMA_INT 0x01 | ||
405 | #define FST_TX_DMA_INT 0x02 | ||
406 | #define FST_CARD_INT 0x04 | ||
407 | |||
408 | /* Larger buffers are positioned in memory at offset BFM_BASE */ | ||
409 | struct buf_window { | ||
410 | u8 txBuffer[FST_MAX_PORTS][NUM_TX_BUFFER][LEN_TX_BUFFER]; | ||
411 | u8 rxBuffer[FST_MAX_PORTS][NUM_RX_BUFFER][LEN_RX_BUFFER]; | ||
412 | }; | ||
413 | |||
414 | /* Calculate offset of a buffer object within the shared memory window */ | ||
415 | #define BUF_OFFSET(X) (BFM_BASE + offsetof(struct buf_window, X)) | ||
416 | |||
417 | #pragma pack() | ||
418 | |||
419 | /* Device driver private information | ||
420 | * ================================= | ||
421 | */ | ||
422 | /* Per port (line or channel) information | ||
423 | */ | ||
424 | struct fst_port_info { | ||
425 | struct net_device *dev; /* Device struct - must be first */ | ||
426 | struct fst_card_info *card; /* Card we're associated with */ | ||
427 | int index; /* Port index on the card */ | ||
428 | int hwif; /* Line hardware (lineInterface copy) */ | ||
429 | int run; /* Port is running */ | ||
430 | int mode; /* Normal or FarSync raw */ | ||
431 | int rxpos; /* Next Rx buffer to use */ | ||
432 | int txpos; /* Next Tx buffer to use */ | ||
433 | int txipos; /* Next Tx buffer to check for free */ | ||
434 | int start; /* Indication of start/stop to network */ | ||
435 | /* | ||
436 | * A sixteen entry transmit queue | ||
437 | */ | ||
438 | int txqs; /* index to get next buffer to tx */ | ||
439 | int txqe; /* index to queue next packet */ | ||
440 | struct sk_buff *txq[FST_TXQ_DEPTH]; /* The queue */ | ||
441 | int rxqdepth; | ||
442 | }; | ||
443 | |||
444 | /* Per card information | ||
445 | */ | ||
446 | struct fst_card_info { | ||
447 | char __iomem *mem; /* Card memory mapped to kernel space */ | ||
448 | char __iomem *ctlmem; /* Control memory for PCI cards */ | ||
449 | unsigned int phys_mem; /* Physical memory window address */ | ||
450 | unsigned int phys_ctlmem; /* Physical control memory address */ | ||
451 | unsigned int irq; /* Interrupt request line number */ | ||
452 | unsigned int nports; /* Number of serial ports */ | ||
453 | unsigned int type; /* Type index of card */ | ||
454 | unsigned int state; /* State of card */ | ||
455 | spinlock_t card_lock; /* Lock for SMP access */ | ||
456 | unsigned short pci_conf; /* PCI card config in I/O space */ | ||
457 | /* Per port info */ | ||
458 | struct fst_port_info ports[FST_MAX_PORTS]; | ||
459 | struct pci_dev *device; /* Information about the pci device */ | ||
460 | int card_no; /* Inst of the card on the system */ | ||
461 | int family; /* TxP or TxU */ | ||
462 | int dmarx_in_progress; | ||
463 | int dmatx_in_progress; | ||
464 | unsigned long int_count; | ||
465 | unsigned long int_time_ave; | ||
466 | void *rx_dma_handle_host; | ||
467 | dma_addr_t rx_dma_handle_card; | ||
468 | void *tx_dma_handle_host; | ||
469 | dma_addr_t tx_dma_handle_card; | ||
470 | struct sk_buff *dma_skb_rx; | ||
471 | struct fst_port_info *dma_port_rx; | ||
472 | struct fst_port_info *dma_port_tx; | ||
473 | int dma_len_rx; | ||
474 | int dma_len_tx; | ||
475 | int dma_txpos; | ||
476 | int dma_rxpos; | ||
477 | }; | ||
478 | |||
479 | /* Convert an HDLC device pointer into a port info pointer and similar */ | ||
480 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) | ||
481 | #define port_to_dev(P) ((P)->dev) | ||
482 | |||
483 | |||
484 | /* | ||
485 | * Shared memory window access macros | ||
486 | * | ||
487 | * We have a nice memory based structure above, which could be directly | ||
488 | * mapped on i386 but might not work on other architectures unless we use | ||
489 | * the readb,w,l and writeb,w,l macros. Unfortunately these macros take | ||
490 | * physical offsets so we have to convert. The only saving grace is that | ||
491 | * this should all collapse back to a simple indirection eventually. | ||
492 | */ | ||
493 | #define WIN_OFFSET(X) ((long)&(((struct fst_shared *)SMC_BASE)->X)) | ||
494 | |||
495 | #define FST_RDB(C,E) readb ((C)->mem + WIN_OFFSET(E)) | ||
496 | #define FST_RDW(C,E) readw ((C)->mem + WIN_OFFSET(E)) | ||
497 | #define FST_RDL(C,E) readl ((C)->mem + WIN_OFFSET(E)) | ||
498 | |||
499 | #define FST_WRB(C,E,B) writeb ((B), (C)->mem + WIN_OFFSET(E)) | ||
500 | #define FST_WRW(C,E,W) writew ((W), (C)->mem + WIN_OFFSET(E)) | ||
501 | #define FST_WRL(C,E,L) writel ((L), (C)->mem + WIN_OFFSET(E)) | ||
502 | |||
503 | /* | ||
504 | * Debug support | ||
505 | */ | ||
506 | #if FST_DEBUG | ||
507 | |||
508 | static int fst_debug_mask = { FST_DEBUG }; | ||
509 | |||
510 | /* Most common debug activity is to print something if the corresponding bit | ||
511 | * is set in the debug mask. Note: this uses a non-ANSI extension in GCC to | ||
512 | * support variable numbers of macro parameters. The inverted if prevents us | ||
513 | * eating someone else's else clause. | ||
514 | */ | ||
515 | #define dbg(F,fmt,A...) if ( ! ( fst_debug_mask & (F))) \ | ||
516 | ; \ | ||
517 | else \ | ||
518 | printk ( KERN_DEBUG FST_NAME ": " fmt, ## A ) | ||
519 | |||
520 | #else | ||
521 | #define dbg(X...) /* NOP */ | ||
522 | #endif | ||
523 | |||
524 | /* Printing short cuts | ||
525 | */ | ||
526 | #define printk_err(fmt,A...) printk ( KERN_ERR FST_NAME ": " fmt, ## A ) | ||
527 | #define printk_warn(fmt,A...) printk ( KERN_WARNING FST_NAME ": " fmt, ## A ) | ||
528 | #define printk_info(fmt,A...) printk ( KERN_INFO FST_NAME ": " fmt, ## A ) | ||
529 | |||
530 | /* | ||
531 | * PCI ID lookup table | ||
532 | */ | ||
533 | static struct pci_device_id fst_pci_dev_id[] __devinitdata = { | ||
534 | {PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_T2P, PCI_ANY_ID, | ||
535 | PCI_ANY_ID, 0, 0, FST_TYPE_T2P}, | ||
536 | |||
537 | {PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_T4P, PCI_ANY_ID, | ||
538 | PCI_ANY_ID, 0, 0, FST_TYPE_T4P}, | ||
539 | |||
540 | {PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_T1U, PCI_ANY_ID, | ||
541 | PCI_ANY_ID, 0, 0, FST_TYPE_T1U}, | ||
542 | |||
543 | {PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_T2U, PCI_ANY_ID, | ||
544 | PCI_ANY_ID, 0, 0, FST_TYPE_T2U}, | ||
545 | |||
546 | {PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_T4U, PCI_ANY_ID, | ||
547 | PCI_ANY_ID, 0, 0, FST_TYPE_T4U}, | ||
548 | |||
549 | {PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_TE1, PCI_ANY_ID, | ||
550 | PCI_ANY_ID, 0, 0, FST_TYPE_TE1}, | ||
551 | |||
552 | {PCI_VENDOR_ID_FARSITE, PCI_DEVICE_ID_FARSITE_TE1C, PCI_ANY_ID, | ||
553 | PCI_ANY_ID, 0, 0, FST_TYPE_TE1}, | ||
554 | {0,} /* End */ | ||
555 | }; | ||
556 | |||
557 | MODULE_DEVICE_TABLE(pci, fst_pci_dev_id); | ||
558 | |||
559 | /* | ||
560 | * Device Driver Work Queues | ||
561 | * | ||
562 | * So that we don't spend too much time processing events in the | ||
563 | * Interrupt Service routine, we will declare a work queue per Card | ||
564 | * and make the ISR schedule a task in the queue for later execution. | ||
565 | * In the 2.4 Kernel we used to use the immediate queue for BH's | ||
566 | * Now that they are gone, tasklets seem to be much better than work | ||
567 | * queues. | ||
568 | */ | ||
569 | |||
570 | static void do_bottom_half_tx(struct fst_card_info *card); | ||
571 | static void do_bottom_half_rx(struct fst_card_info *card); | ||
572 | static void fst_process_tx_work_q(unsigned long work_q); | ||
573 | static void fst_process_int_work_q(unsigned long work_q); | ||
574 | |||
575 | DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0); | ||
576 | DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0); | ||
577 | |||
578 | struct fst_card_info *fst_card_array[FST_MAX_CARDS]; | ||
579 | spinlock_t fst_work_q_lock; | ||
580 | u64 fst_work_txq; | ||
581 | u64 fst_work_intq; | ||
582 | |||
583 | static void | ||
584 | fst_q_work_item(u64 * queue, int card_index) | ||
585 | { | ||
586 | unsigned long flags; | ||
587 | u64 mask; | ||
588 | |||
589 | /* | ||
590 | * Grab the queue exclusively | ||
591 | */ | ||
592 | spin_lock_irqsave(&fst_work_q_lock, flags); | ||
593 | |||
594 | /* | ||
595 | * Making an entry in the queue is simply a matter of setting | ||
596 | * a bit for the card indicating that there is work to do in the | ||
597 | * bottom half for the card. Note the limitation of 64 cards. | ||
598 | * That ought to be enough | ||
599 | */ | ||
600 | mask = 1 << card_index; | ||
601 | *queue |= mask; | ||
602 | spin_unlock_irqrestore(&fst_work_q_lock, flags); | ||
603 | } | ||
604 | |||
605 | static void | ||
606 | fst_process_tx_work_q(unsigned long /*void **/work_q) | ||
607 | { | ||
608 | unsigned long flags; | ||
609 | u64 work_txq; | ||
610 | int i; | ||
611 | |||
612 | /* | ||
613 | * Grab the queue exclusively | ||
614 | */ | ||
615 | dbg(DBG_TX, "fst_process_tx_work_q\n"); | ||
616 | spin_lock_irqsave(&fst_work_q_lock, flags); | ||
617 | work_txq = fst_work_txq; | ||
618 | fst_work_txq = 0; | ||
619 | spin_unlock_irqrestore(&fst_work_q_lock, flags); | ||
620 | |||
621 | /* | ||
622 | * Call the bottom half for each card with work waiting | ||
623 | */ | ||
624 | for (i = 0; i < FST_MAX_CARDS; i++) { | ||
625 | if (work_txq & 0x01) { | ||
626 | if (fst_card_array[i] != NULL) { | ||
627 | dbg(DBG_TX, "Calling tx bh for card %d\n", i); | ||
628 | do_bottom_half_tx(fst_card_array[i]); | ||
629 | } | ||
630 | } | ||
631 | work_txq = work_txq >> 1; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | static void | ||
636 | fst_process_int_work_q(unsigned long /*void **/work_q) | ||
637 | { | ||
638 | unsigned long flags; | ||
639 | u64 work_intq; | ||
640 | int i; | ||
641 | |||
642 | /* | ||
643 | * Grab the queue exclusively | ||
644 | */ | ||
645 | dbg(DBG_INTR, "fst_process_int_work_q\n"); | ||
646 | spin_lock_irqsave(&fst_work_q_lock, flags); | ||
647 | work_intq = fst_work_intq; | ||
648 | fst_work_intq = 0; | ||
649 | spin_unlock_irqrestore(&fst_work_q_lock, flags); | ||
650 | |||
651 | /* | ||
652 | * Call the bottom half for each card with work waiting | ||
653 | */ | ||
654 | for (i = 0; i < FST_MAX_CARDS; i++) { | ||
655 | if (work_intq & 0x01) { | ||
656 | if (fst_card_array[i] != NULL) { | ||
657 | dbg(DBG_INTR, | ||
658 | "Calling rx & tx bh for card %d\n", i); | ||
659 | do_bottom_half_rx(fst_card_array[i]); | ||
660 | do_bottom_half_tx(fst_card_array[i]); | ||
661 | } | ||
662 | } | ||
663 | work_intq = work_intq >> 1; | ||
664 | } | ||
665 | } | ||
666 | |||
667 | /* Card control functions | ||
668 | * ====================== | ||
669 | */ | ||
670 | /* Place the processor in reset state | ||
671 | * | ||
672 | * Used to be a simple write to card control space but a glitch in the latest | ||
673 | * AMD Am186CH processor means that we now have to do it by asserting and de- | ||
674 | * asserting the PLX chip PCI Adapter Software Reset. Bit 30 in CNTRL register | ||
675 | * at offset 9052_CNTRL. Note the updates for the TXU. | ||
676 | */ | ||
677 | static inline void | ||
678 | fst_cpureset(struct fst_card_info *card) | ||
679 | { | ||
680 | unsigned char interrupt_line_register; | ||
681 | unsigned long j = jiffies + 1; | ||
682 | unsigned int regval; | ||
683 | |||
684 | if (card->family == FST_FAMILY_TXU) { | ||
685 | if (pci_read_config_byte | ||
686 | (card->device, PCI_INTERRUPT_LINE, &interrupt_line_register)) { | ||
687 | dbg(DBG_ASS, | ||
688 | "Error in reading interrupt line register\n"); | ||
689 | } | ||
690 | /* | ||
691 | * Assert PLX software reset and Am186 hardware reset | ||
692 | * and then deassert the PLX software reset but 186 still in reset | ||
693 | */ | ||
694 | outw(0x440f, card->pci_conf + CNTRL_9054 + 2); | ||
695 | outw(0x040f, card->pci_conf + CNTRL_9054 + 2); | ||
696 | /* | ||
697 | * We are delaying here to allow the 9054 to reset itself | ||
698 | */ | ||
699 | j = jiffies + 1; | ||
700 | while (jiffies < j) | ||
701 | /* Do nothing */ ; | ||
702 | outw(0x240f, card->pci_conf + CNTRL_9054 + 2); | ||
703 | /* | ||
704 | * We are delaying here to allow the 9054 to reload its eeprom | ||
705 | */ | ||
706 | j = jiffies + 1; | ||
707 | while (jiffies < j) | ||
708 | /* Do nothing */ ; | ||
709 | outw(0x040f, card->pci_conf + CNTRL_9054 + 2); | ||
710 | |||
711 | if (pci_write_config_byte | ||
712 | (card->device, PCI_INTERRUPT_LINE, interrupt_line_register)) { | ||
713 | dbg(DBG_ASS, | ||
714 | "Error in writing interrupt line register\n"); | ||
715 | } | ||
716 | |||
717 | } else { | ||
718 | regval = inl(card->pci_conf + CNTRL_9052); | ||
719 | |||
720 | outl(regval | 0x40000000, card->pci_conf + CNTRL_9052); | ||
721 | outl(regval & ~0x40000000, card->pci_conf + CNTRL_9052); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | /* Release the processor from reset | ||
726 | */ | ||
727 | static inline void | ||
728 | fst_cpurelease(struct fst_card_info *card) | ||
729 | { | ||
730 | if (card->family == FST_FAMILY_TXU) { | ||
731 | /* | ||
732 | * Force posted writes to complete | ||
733 | */ | ||
734 | (void) readb(card->mem); | ||
735 | |||
736 | /* | ||
737 | * Release LRESET DO = 1 | ||
738 | * Then release Local Hold, DO = 1 | ||
739 | */ | ||
740 | outw(0x040e, card->pci_conf + CNTRL_9054 + 2); | ||
741 | outw(0x040f, card->pci_conf + CNTRL_9054 + 2); | ||
742 | } else { | ||
743 | (void) readb(card->ctlmem); | ||
744 | } | ||
745 | } | ||
746 | |||
747 | /* Clear the cards interrupt flag | ||
748 | */ | ||
749 | static inline void | ||
750 | fst_clear_intr(struct fst_card_info *card) | ||
751 | { | ||
752 | if (card->family == FST_FAMILY_TXU) { | ||
753 | (void) readb(card->ctlmem); | ||
754 | } else { | ||
755 | /* Poke the appropriate PLX chip register (same as enabling interrupts) | ||
756 | */ | ||
757 | outw(0x0543, card->pci_conf + INTCSR_9052); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | /* Enable card interrupts | ||
762 | */ | ||
763 | static inline void | ||
764 | fst_enable_intr(struct fst_card_info *card) | ||
765 | { | ||
766 | if (card->family == FST_FAMILY_TXU) { | ||
767 | outl(0x0f0c0900, card->pci_conf + INTCSR_9054); | ||
768 | } else { | ||
769 | outw(0x0543, card->pci_conf + INTCSR_9052); | ||
770 | } | ||
771 | } | ||
772 | |||
773 | /* Disable card interrupts | ||
774 | */ | ||
775 | static inline void | ||
776 | fst_disable_intr(struct fst_card_info *card) | ||
777 | { | ||
778 | if (card->family == FST_FAMILY_TXU) { | ||
779 | outl(0x00000000, card->pci_conf + INTCSR_9054); | ||
780 | } else { | ||
781 | outw(0x0000, card->pci_conf + INTCSR_9052); | ||
782 | } | ||
783 | } | ||
784 | |||
785 | /* Process the result of trying to pass a received frame up the stack | ||
786 | */ | ||
787 | static void | ||
788 | fst_process_rx_status(int rx_status, char *name) | ||
789 | { | ||
790 | switch (rx_status) { | ||
791 | case NET_RX_SUCCESS: | ||
792 | { | ||
793 | /* | ||
794 | * Nothing to do here | ||
795 | */ | ||
796 | break; | ||
797 | } | ||
798 | |||
799 | case NET_RX_CN_LOW: | ||
800 | { | ||
801 | dbg(DBG_ASS, "%s: Receive Low Congestion\n", name); | ||
802 | break; | ||
803 | } | ||
804 | |||
805 | case NET_RX_CN_MOD: | ||
806 | { | ||
807 | dbg(DBG_ASS, "%s: Receive Moderate Congestion\n", name); | ||
808 | break; | ||
809 | } | ||
810 | |||
811 | case NET_RX_CN_HIGH: | ||
812 | { | ||
813 | dbg(DBG_ASS, "%s: Receive High Congestion\n", name); | ||
814 | break; | ||
815 | } | ||
816 | |||
817 | case NET_RX_DROP: | ||
818 | { | ||
819 | dbg(DBG_ASS, "%s: Received packet dropped\n", name); | ||
820 | break; | ||
821 | } | ||
822 | } | ||
823 | } | ||
824 | |||
825 | /* Initilaise DMA for PLX 9054 | ||
826 | */ | ||
827 | static inline void | ||
828 | fst_init_dma(struct fst_card_info *card) | ||
829 | { | ||
830 | /* | ||
831 | * This is only required for the PLX 9054 | ||
832 | */ | ||
833 | if (card->family == FST_FAMILY_TXU) { | ||
834 | pci_set_master(card->device); | ||
835 | outl(0x00020441, card->pci_conf + DMAMODE0); | ||
836 | outl(0x00020441, card->pci_conf + DMAMODE1); | ||
837 | outl(0x0, card->pci_conf + DMATHR); | ||
838 | } | ||
839 | } | ||
840 | |||
841 | /* Tx dma complete interrupt | ||
842 | */ | ||
843 | static void | ||
844 | fst_tx_dma_complete(struct fst_card_info *card, struct fst_port_info *port, | ||
845 | int len, int txpos) | ||
846 | { | ||
847 | struct net_device *dev = port_to_dev(port); | ||
848 | struct net_device_stats *stats = hdlc_stats(dev); | ||
849 | |||
850 | /* | ||
851 | * Everything is now set, just tell the card to go | ||
852 | */ | ||
853 | dbg(DBG_TX, "fst_tx_dma_complete\n"); | ||
854 | FST_WRB(card, txDescrRing[port->index][txpos].bits, | ||
855 | DMA_OWN | TX_STP | TX_ENP); | ||
856 | stats->tx_packets++; | ||
857 | stats->tx_bytes += len; | ||
858 | dev->trans_start = jiffies; | ||
859 | } | ||
860 | |||
861 | /* | ||
862 | * Mark it for our own raw sockets interface | ||
863 | */ | ||
864 | static unsigned short farsync_type_trans(struct sk_buff *skb, | ||
865 | struct net_device *dev) | ||
866 | { | ||
867 | skb->dev = dev; | ||
868 | skb->mac.raw = skb->data; | ||
869 | skb->pkt_type = PACKET_HOST; | ||
870 | return htons(ETH_P_CUST); | ||
871 | } | ||
872 | |||
873 | /* Rx dma complete interrupt | ||
874 | */ | ||
875 | static void | ||
876 | fst_rx_dma_complete(struct fst_card_info *card, struct fst_port_info *port, | ||
877 | int len, struct sk_buff *skb, int rxp) | ||
878 | { | ||
879 | struct net_device *dev = port_to_dev(port); | ||
880 | struct net_device_stats *stats = hdlc_stats(dev); | ||
881 | int pi; | ||
882 | int rx_status; | ||
883 | |||
884 | dbg(DBG_TX, "fst_rx_dma_complete\n"); | ||
885 | pi = port->index; | ||
886 | memcpy(skb_put(skb, len), card->rx_dma_handle_host, len); | ||
887 | |||
888 | /* Reset buffer descriptor */ | ||
889 | FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN); | ||
890 | |||
891 | /* Update stats */ | ||
892 | stats->rx_packets++; | ||
893 | stats->rx_bytes += len; | ||
894 | |||
895 | /* Push upstream */ | ||
896 | dbg(DBG_RX, "Pushing the frame up the stack\n"); | ||
897 | if (port->mode == FST_RAW) | ||
898 | skb->protocol = farsync_type_trans(skb, dev); | ||
899 | else | ||
900 | skb->protocol = hdlc_type_trans(skb, dev); | ||
901 | rx_status = netif_rx(skb); | ||
902 | fst_process_rx_status(rx_status, port_to_dev(port)->name); | ||
903 | if (rx_status == NET_RX_DROP) | ||
904 | stats->rx_dropped++; | ||
905 | dev->last_rx = jiffies; | ||
906 | } | ||
907 | |||
908 | /* | ||
909 | * Receive a frame through the DMA | ||
910 | */ | ||
911 | static inline void | ||
912 | fst_rx_dma(struct fst_card_info *card, unsigned char *skb, | ||
913 | unsigned char *mem, int len) | ||
914 | { | ||
915 | /* | ||
916 | * This routine will setup the DMA and start it | ||
917 | */ | ||
918 | |||
919 | dbg(DBG_RX, "In fst_rx_dma %p %p %d\n", skb, mem, len); | ||
920 | if (card->dmarx_in_progress) { | ||
921 | dbg(DBG_ASS, "In fst_rx_dma while dma in progress\n"); | ||
922 | } | ||
923 | |||
924 | outl((unsigned long) skb, card->pci_conf + DMAPADR0); /* Copy to here */ | ||
925 | outl((unsigned long) mem, card->pci_conf + DMALADR0); /* from here */ | ||
926 | outl(len, card->pci_conf + DMASIZ0); /* for this length */ | ||
927 | outl(0x00000000c, card->pci_conf + DMADPR0); /* In this direction */ | ||
928 | |||
929 | /* | ||
930 | * We use the dmarx_in_progress flag to flag the channel as busy | ||
931 | */ | ||
932 | card->dmarx_in_progress = 1; | ||
933 | outb(0x03, card->pci_conf + DMACSR0); /* Start the transfer */ | ||
934 | } | ||
935 | |||
936 | /* | ||
937 | * Send a frame through the DMA | ||
938 | */ | ||
939 | static inline void | ||
940 | fst_tx_dma(struct fst_card_info *card, unsigned char *skb, | ||
941 | unsigned char *mem, int len) | ||
942 | { | ||
943 | /* | ||
944 | * This routine will setup the DMA and start it. | ||
945 | */ | ||
946 | |||
947 | dbg(DBG_TX, "In fst_tx_dma %p %p %d\n", skb, mem, len); | ||
948 | if (card->dmatx_in_progress) { | ||
949 | dbg(DBG_ASS, "In fst_tx_dma while dma in progress\n"); | ||
950 | } | ||
951 | |||
952 | outl((unsigned long) skb, card->pci_conf + DMAPADR1); /* Copy from here */ | ||
953 | outl((unsigned long) mem, card->pci_conf + DMALADR1); /* to here */ | ||
954 | outl(len, card->pci_conf + DMASIZ1); /* for this length */ | ||
955 | outl(0x000000004, card->pci_conf + DMADPR1); /* In this direction */ | ||
956 | |||
957 | /* | ||
958 | * We use the dmatx_in_progress to flag the channel as busy | ||
959 | */ | ||
960 | card->dmatx_in_progress = 1; | ||
961 | outb(0x03, card->pci_conf + DMACSR1); /* Start the transfer */ | ||
962 | } | ||
963 | |||
964 | /* Issue a Mailbox command for a port. | ||
965 | * Note we issue them on a fire and forget basis, not expecting to see an | ||
966 | * error and not waiting for completion. | ||
967 | */ | ||
968 | static void | ||
969 | fst_issue_cmd(struct fst_port_info *port, unsigned short cmd) | ||
970 | { | ||
971 | struct fst_card_info *card; | ||
972 | unsigned short mbval; | ||
973 | unsigned long flags; | ||
974 | int safety; | ||
975 | |||
976 | card = port->card; | ||
977 | spin_lock_irqsave(&card->card_lock, flags); | ||
978 | mbval = FST_RDW(card, portMailbox[port->index][0]); | ||
979 | |||
980 | safety = 0; | ||
981 | /* Wait for any previous command to complete */ | ||
982 | while (mbval > NAK) { | ||
983 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
984 | schedule_timeout(1); | ||
985 | spin_lock_irqsave(&card->card_lock, flags); | ||
986 | |||
987 | if (++safety > 2000) { | ||
988 | printk_err("Mailbox safety timeout\n"); | ||
989 | break; | ||
990 | } | ||
991 | |||
992 | mbval = FST_RDW(card, portMailbox[port->index][0]); | ||
993 | } | ||
994 | if (safety > 0) { | ||
995 | dbg(DBG_CMD, "Mailbox clear after %d jiffies\n", safety); | ||
996 | } | ||
997 | if (mbval == NAK) { | ||
998 | dbg(DBG_CMD, "issue_cmd: previous command was NAK'd\n"); | ||
999 | } | ||
1000 | |||
1001 | FST_WRW(card, portMailbox[port->index][0], cmd); | ||
1002 | |||
1003 | if (cmd == ABORTTX || cmd == STARTPORT) { | ||
1004 | port->txpos = 0; | ||
1005 | port->txipos = 0; | ||
1006 | port->start = 0; | ||
1007 | } | ||
1008 | |||
1009 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1010 | } | ||
1011 | |||
1012 | /* Port output signals control | ||
1013 | */ | ||
1014 | static inline void | ||
1015 | fst_op_raise(struct fst_port_info *port, unsigned int outputs) | ||
1016 | { | ||
1017 | outputs |= FST_RDL(port->card, v24OpSts[port->index]); | ||
1018 | FST_WRL(port->card, v24OpSts[port->index], outputs); | ||
1019 | |||
1020 | if (port->run) | ||
1021 | fst_issue_cmd(port, SETV24O); | ||
1022 | } | ||
1023 | |||
1024 | static inline void | ||
1025 | fst_op_lower(struct fst_port_info *port, unsigned int outputs) | ||
1026 | { | ||
1027 | outputs = ~outputs & FST_RDL(port->card, v24OpSts[port->index]); | ||
1028 | FST_WRL(port->card, v24OpSts[port->index], outputs); | ||
1029 | |||
1030 | if (port->run) | ||
1031 | fst_issue_cmd(port, SETV24O); | ||
1032 | } | ||
1033 | |||
1034 | /* | ||
1035 | * Setup port Rx buffers | ||
1036 | */ | ||
1037 | static void | ||
1038 | fst_rx_config(struct fst_port_info *port) | ||
1039 | { | ||
1040 | int i; | ||
1041 | int pi; | ||
1042 | unsigned int offset; | ||
1043 | unsigned long flags; | ||
1044 | struct fst_card_info *card; | ||
1045 | |||
1046 | pi = port->index; | ||
1047 | card = port->card; | ||
1048 | spin_lock_irqsave(&card->card_lock, flags); | ||
1049 | for (i = 0; i < NUM_RX_BUFFER; i++) { | ||
1050 | offset = BUF_OFFSET(rxBuffer[pi][i][0]); | ||
1051 | |||
1052 | FST_WRW(card, rxDescrRing[pi][i].ladr, (u16) offset); | ||
1053 | FST_WRB(card, rxDescrRing[pi][i].hadr, (u8) (offset >> 16)); | ||
1054 | FST_WRW(card, rxDescrRing[pi][i].bcnt, cnv_bcnt(LEN_RX_BUFFER)); | ||
1055 | FST_WRW(card, rxDescrRing[pi][i].mcnt, LEN_RX_BUFFER); | ||
1056 | FST_WRB(card, rxDescrRing[pi][i].bits, DMA_OWN); | ||
1057 | } | ||
1058 | port->rxpos = 0; | ||
1059 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1060 | } | ||
1061 | |||
1062 | /* | ||
1063 | * Setup port Tx buffers | ||
1064 | */ | ||
1065 | static void | ||
1066 | fst_tx_config(struct fst_port_info *port) | ||
1067 | { | ||
1068 | int i; | ||
1069 | int pi; | ||
1070 | unsigned int offset; | ||
1071 | unsigned long flags; | ||
1072 | struct fst_card_info *card; | ||
1073 | |||
1074 | pi = port->index; | ||
1075 | card = port->card; | ||
1076 | spin_lock_irqsave(&card->card_lock, flags); | ||
1077 | for (i = 0; i < NUM_TX_BUFFER; i++) { | ||
1078 | offset = BUF_OFFSET(txBuffer[pi][i][0]); | ||
1079 | |||
1080 | FST_WRW(card, txDescrRing[pi][i].ladr, (u16) offset); | ||
1081 | FST_WRB(card, txDescrRing[pi][i].hadr, (u8) (offset >> 16)); | ||
1082 | FST_WRW(card, txDescrRing[pi][i].bcnt, 0); | ||
1083 | FST_WRB(card, txDescrRing[pi][i].bits, 0); | ||
1084 | } | ||
1085 | port->txpos = 0; | ||
1086 | port->txipos = 0; | ||
1087 | port->start = 0; | ||
1088 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1089 | } | ||
1090 | |||
1091 | /* TE1 Alarm change interrupt event | ||
1092 | */ | ||
1093 | static void | ||
1094 | fst_intr_te1_alarm(struct fst_card_info *card, struct fst_port_info *port) | ||
1095 | { | ||
1096 | u8 los; | ||
1097 | u8 rra; | ||
1098 | u8 ais; | ||
1099 | |||
1100 | los = FST_RDB(card, suStatus.lossOfSignal); | ||
1101 | rra = FST_RDB(card, suStatus.receiveRemoteAlarm); | ||
1102 | ais = FST_RDB(card, suStatus.alarmIndicationSignal); | ||
1103 | |||
1104 | if (los) { | ||
1105 | /* | ||
1106 | * Lost the link | ||
1107 | */ | ||
1108 | if (netif_carrier_ok(port_to_dev(port))) { | ||
1109 | dbg(DBG_INTR, "Net carrier off\n"); | ||
1110 | netif_carrier_off(port_to_dev(port)); | ||
1111 | } | ||
1112 | } else { | ||
1113 | /* | ||
1114 | * Link available | ||
1115 | */ | ||
1116 | if (!netif_carrier_ok(port_to_dev(port))) { | ||
1117 | dbg(DBG_INTR, "Net carrier on\n"); | ||
1118 | netif_carrier_on(port_to_dev(port)); | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | if (los) | ||
1123 | dbg(DBG_INTR, "Assert LOS Alarm\n"); | ||
1124 | else | ||
1125 | dbg(DBG_INTR, "De-assert LOS Alarm\n"); | ||
1126 | if (rra) | ||
1127 | dbg(DBG_INTR, "Assert RRA Alarm\n"); | ||
1128 | else | ||
1129 | dbg(DBG_INTR, "De-assert RRA Alarm\n"); | ||
1130 | |||
1131 | if (ais) | ||
1132 | dbg(DBG_INTR, "Assert AIS Alarm\n"); | ||
1133 | else | ||
1134 | dbg(DBG_INTR, "De-assert AIS Alarm\n"); | ||
1135 | } | ||
1136 | |||
1137 | /* Control signal change interrupt event | ||
1138 | */ | ||
1139 | static void | ||
1140 | fst_intr_ctlchg(struct fst_card_info *card, struct fst_port_info *port) | ||
1141 | { | ||
1142 | int signals; | ||
1143 | |||
1144 | signals = FST_RDL(card, v24DebouncedSts[port->index]); | ||
1145 | |||
1146 | if (signals & (((port->hwif == X21) || (port->hwif == X21D)) | ||
1147 | ? IPSTS_INDICATE : IPSTS_DCD)) { | ||
1148 | if (!netif_carrier_ok(port_to_dev(port))) { | ||
1149 | dbg(DBG_INTR, "DCD active\n"); | ||
1150 | netif_carrier_on(port_to_dev(port)); | ||
1151 | } | ||
1152 | } else { | ||
1153 | if (netif_carrier_ok(port_to_dev(port))) { | ||
1154 | dbg(DBG_INTR, "DCD lost\n"); | ||
1155 | netif_carrier_off(port_to_dev(port)); | ||
1156 | } | ||
1157 | } | ||
1158 | } | ||
1159 | |||
1160 | /* Log Rx Errors | ||
1161 | */ | ||
1162 | static void | ||
1163 | fst_log_rx_error(struct fst_card_info *card, struct fst_port_info *port, | ||
1164 | unsigned char dmabits, int rxp, unsigned short len) | ||
1165 | { | ||
1166 | struct net_device *dev = port_to_dev(port); | ||
1167 | struct net_device_stats *stats = hdlc_stats(dev); | ||
1168 | |||
1169 | /* | ||
1170 | * Increment the appropriate error counter | ||
1171 | */ | ||
1172 | stats->rx_errors++; | ||
1173 | if (dmabits & RX_OFLO) { | ||
1174 | stats->rx_fifo_errors++; | ||
1175 | dbg(DBG_ASS, "Rx fifo error on card %d port %d buffer %d\n", | ||
1176 | card->card_no, port->index, rxp); | ||
1177 | } | ||
1178 | if (dmabits & RX_CRC) { | ||
1179 | stats->rx_crc_errors++; | ||
1180 | dbg(DBG_ASS, "Rx crc error on card %d port %d\n", | ||
1181 | card->card_no, port->index); | ||
1182 | } | ||
1183 | if (dmabits & RX_FRAM) { | ||
1184 | stats->rx_frame_errors++; | ||
1185 | dbg(DBG_ASS, "Rx frame error on card %d port %d\n", | ||
1186 | card->card_no, port->index); | ||
1187 | } | ||
1188 | if (dmabits == (RX_STP | RX_ENP)) { | ||
1189 | stats->rx_length_errors++; | ||
1190 | dbg(DBG_ASS, "Rx length error (%d) on card %d port %d\n", | ||
1191 | len, card->card_no, port->index); | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | /* Rx Error Recovery | ||
1196 | */ | ||
1197 | static void | ||
1198 | fst_recover_rx_error(struct fst_card_info *card, struct fst_port_info *port, | ||
1199 | unsigned char dmabits, int rxp, unsigned short len) | ||
1200 | { | ||
1201 | int i; | ||
1202 | int pi; | ||
1203 | |||
1204 | pi = port->index; | ||
1205 | /* | ||
1206 | * Discard buffer descriptors until we see the start of the | ||
1207 | * next frame. Note that for long frames this could be in | ||
1208 | * a subsequent interrupt. | ||
1209 | */ | ||
1210 | i = 0; | ||
1211 | while ((dmabits & (DMA_OWN | RX_STP)) == 0) { | ||
1212 | FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN); | ||
1213 | rxp = (rxp+1) % NUM_RX_BUFFER; | ||
1214 | if (++i > NUM_RX_BUFFER) { | ||
1215 | dbg(DBG_ASS, "intr_rx: Discarding more bufs" | ||
1216 | " than we have\n"); | ||
1217 | break; | ||
1218 | } | ||
1219 | dmabits = FST_RDB(card, rxDescrRing[pi][rxp].bits); | ||
1220 | dbg(DBG_ASS, "DMA Bits of next buffer was %x\n", dmabits); | ||
1221 | } | ||
1222 | dbg(DBG_ASS, "There were %d subsequent buffers in error\n", i); | ||
1223 | |||
1224 | /* Discard the terminal buffer */ | ||
1225 | if (!(dmabits & DMA_OWN)) { | ||
1226 | FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN); | ||
1227 | rxp = (rxp+1) % NUM_RX_BUFFER; | ||
1228 | } | ||
1229 | port->rxpos = rxp; | ||
1230 | return; | ||
1231 | |||
1232 | } | ||
1233 | |||
1234 | /* Rx complete interrupt | ||
1235 | */ | ||
1236 | static void | ||
1237 | fst_intr_rx(struct fst_card_info *card, struct fst_port_info *port) | ||
1238 | { | ||
1239 | unsigned char dmabits; | ||
1240 | int pi; | ||
1241 | int rxp; | ||
1242 | int rx_status; | ||
1243 | unsigned short len; | ||
1244 | struct sk_buff *skb; | ||
1245 | struct net_device *dev = port_to_dev(port); | ||
1246 | struct net_device_stats *stats = hdlc_stats(dev); | ||
1247 | |||
1248 | /* Check we have a buffer to process */ | ||
1249 | pi = port->index; | ||
1250 | rxp = port->rxpos; | ||
1251 | dmabits = FST_RDB(card, rxDescrRing[pi][rxp].bits); | ||
1252 | if (dmabits & DMA_OWN) { | ||
1253 | dbg(DBG_RX | DBG_INTR, "intr_rx: No buffer port %d pos %d\n", | ||
1254 | pi, rxp); | ||
1255 | return; | ||
1256 | } | ||
1257 | if (card->dmarx_in_progress) { | ||
1258 | return; | ||
1259 | } | ||
1260 | |||
1261 | /* Get buffer length */ | ||
1262 | len = FST_RDW(card, rxDescrRing[pi][rxp].mcnt); | ||
1263 | /* Discard the CRC */ | ||
1264 | len -= 2; | ||
1265 | if (len == 0) { | ||
1266 | /* | ||
1267 | * This seems to happen on the TE1 interface sometimes | ||
1268 | * so throw the frame away and log the event. | ||
1269 | */ | ||
1270 | printk_err("Frame received with 0 length. Card %d Port %d\n", | ||
1271 | card->card_no, port->index); | ||
1272 | /* Return descriptor to card */ | ||
1273 | FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN); | ||
1274 | |||
1275 | rxp = (rxp+1) % NUM_RX_BUFFER; | ||
1276 | port->rxpos = rxp; | ||
1277 | return; | ||
1278 | } | ||
1279 | |||
1280 | /* Check buffer length and for other errors. We insist on one packet | ||
1281 | * in one buffer. This simplifies things greatly and since we've | ||
1282 | * allocated 8K it shouldn't be a real world limitation | ||
1283 | */ | ||
1284 | dbg(DBG_RX, "intr_rx: %d,%d: flags %x len %d\n", pi, rxp, dmabits, len); | ||
1285 | if (dmabits != (RX_STP | RX_ENP) || len > LEN_RX_BUFFER - 2) { | ||
1286 | fst_log_rx_error(card, port, dmabits, rxp, len); | ||
1287 | fst_recover_rx_error(card, port, dmabits, rxp, len); | ||
1288 | return; | ||
1289 | } | ||
1290 | |||
1291 | /* Allocate SKB */ | ||
1292 | if ((skb = dev_alloc_skb(len)) == NULL) { | ||
1293 | dbg(DBG_RX, "intr_rx: can't allocate buffer\n"); | ||
1294 | |||
1295 | stats->rx_dropped++; | ||
1296 | |||
1297 | /* Return descriptor to card */ | ||
1298 | FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN); | ||
1299 | |||
1300 | rxp = (rxp+1) % NUM_RX_BUFFER; | ||
1301 | port->rxpos = rxp; | ||
1302 | return; | ||
1303 | } | ||
1304 | |||
1305 | /* | ||
1306 | * We know the length we need to receive, len. | ||
1307 | * It's not worth using the DMA for reads of less than | ||
1308 | * FST_MIN_DMA_LEN | ||
1309 | */ | ||
1310 | |||
1311 | if ((len < FST_MIN_DMA_LEN) || (card->family == FST_FAMILY_TXP)) { | ||
1312 | memcpy_fromio(skb_put(skb, len), | ||
1313 | card->mem + BUF_OFFSET(rxBuffer[pi][rxp][0]), | ||
1314 | len); | ||
1315 | |||
1316 | /* Reset buffer descriptor */ | ||
1317 | FST_WRB(card, rxDescrRing[pi][rxp].bits, DMA_OWN); | ||
1318 | |||
1319 | /* Update stats */ | ||
1320 | stats->rx_packets++; | ||
1321 | stats->rx_bytes += len; | ||
1322 | |||
1323 | /* Push upstream */ | ||
1324 | dbg(DBG_RX, "Pushing frame up the stack\n"); | ||
1325 | if (port->mode == FST_RAW) | ||
1326 | skb->protocol = farsync_type_trans(skb, dev); | ||
1327 | else | ||
1328 | skb->protocol = hdlc_type_trans(skb, dev); | ||
1329 | rx_status = netif_rx(skb); | ||
1330 | fst_process_rx_status(rx_status, port_to_dev(port)->name); | ||
1331 | if (rx_status == NET_RX_DROP) { | ||
1332 | stats->rx_dropped++; | ||
1333 | } | ||
1334 | dev->last_rx = jiffies; | ||
1335 | } else { | ||
1336 | card->dma_skb_rx = skb; | ||
1337 | card->dma_port_rx = port; | ||
1338 | card->dma_len_rx = len; | ||
1339 | card->dma_rxpos = rxp; | ||
1340 | fst_rx_dma(card, (char *) card->rx_dma_handle_card, | ||
1341 | (char *) BUF_OFFSET(rxBuffer[pi][rxp][0]), len); | ||
1342 | } | ||
1343 | if (rxp != port->rxpos) { | ||
1344 | dbg(DBG_ASS, "About to increment rxpos by more than 1\n"); | ||
1345 | dbg(DBG_ASS, "rxp = %d rxpos = %d\n", rxp, port->rxpos); | ||
1346 | } | ||
1347 | rxp = (rxp+1) % NUM_RX_BUFFER; | ||
1348 | port->rxpos = rxp; | ||
1349 | } | ||
1350 | |||
1351 | /* | ||
1352 | * The bottom halfs to the ISR | ||
1353 | * | ||
1354 | */ | ||
1355 | |||
1356 | static void | ||
1357 | do_bottom_half_tx(struct fst_card_info *card) | ||
1358 | { | ||
1359 | struct fst_port_info *port; | ||
1360 | int pi; | ||
1361 | int txq_length; | ||
1362 | struct sk_buff *skb; | ||
1363 | unsigned long flags; | ||
1364 | struct net_device *dev; | ||
1365 | struct net_device_stats *stats; | ||
1366 | |||
1367 | /* | ||
1368 | * Find a free buffer for the transmit | ||
1369 | * Step through each port on this card | ||
1370 | */ | ||
1371 | |||
1372 | dbg(DBG_TX, "do_bottom_half_tx\n"); | ||
1373 | for (pi = 0, port = card->ports; pi < card->nports; pi++, port++) { | ||
1374 | if (!port->run) | ||
1375 | continue; | ||
1376 | |||
1377 | dev = port_to_dev(port); | ||
1378 | stats = hdlc_stats(dev); | ||
1379 | while (! | ||
1380 | (FST_RDB(card, txDescrRing[pi][port->txpos].bits) & | ||
1381 | DMA_OWN) | ||
1382 | && !(card->dmatx_in_progress)) { | ||
1383 | /* | ||
1384 | * There doesn't seem to be a txdone event per-se | ||
1385 | * We seem to have to deduce it, by checking the DMA_OWN | ||
1386 | * bit on the next buffer we think we can use | ||
1387 | */ | ||
1388 | spin_lock_irqsave(&card->card_lock, flags); | ||
1389 | if ((txq_length = port->txqe - port->txqs) < 0) { | ||
1390 | /* | ||
1391 | * This is the case where one has wrapped and the | ||
1392 | * maths gives us a negative number | ||
1393 | */ | ||
1394 | txq_length = txq_length + FST_TXQ_DEPTH; | ||
1395 | } | ||
1396 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1397 | if (txq_length > 0) { | ||
1398 | /* | ||
1399 | * There is something to send | ||
1400 | */ | ||
1401 | spin_lock_irqsave(&card->card_lock, flags); | ||
1402 | skb = port->txq[port->txqs]; | ||
1403 | port->txqs++; | ||
1404 | if (port->txqs == FST_TXQ_DEPTH) { | ||
1405 | port->txqs = 0; | ||
1406 | } | ||
1407 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
1408 | /* | ||
1409 | * copy the data and set the required indicators on the | ||
1410 | * card. | ||
1411 | */ | ||
1412 | FST_WRW(card, txDescrRing[pi][port->txpos].bcnt, | ||
1413 | cnv_bcnt(skb->len)); | ||
1414 | if ((skb->len < FST_MIN_DMA_LEN) | ||
1415 | || (card->family == FST_FAMILY_TXP)) { | ||
1416 | /* Enqueue the packet with normal io */ | ||
1417 | memcpy_toio(card->mem + | ||
1418 | BUF_OFFSET(txBuffer[pi] | ||
1419 | [port-> | ||
1420 | txpos][0]), | ||
1421 | skb->data, skb->len); | ||
1422 | FST_WRB(card, | ||
1423 | txDescrRing[pi][port->txpos]. | ||
1424 | bits, | ||
1425 | DMA_OWN | TX_STP | TX_ENP); | ||
1426 | stats->tx_packets++; | ||
1427 | stats->tx_bytes += skb->len; | ||
1428 | dev->trans_start = jiffies; | ||
1429 | } else { | ||
1430 | /* Or do it through dma */ | ||
1431 | memcpy(card->tx_dma_handle_host, | ||
1432 | skb->data, skb->len); | ||
1433 | card->dma_port_tx = port; | ||
1434 | card->dma_len_tx = skb->len; | ||
1435 | card->dma_txpos = port->txpos; | ||
1436 | fst_tx_dma(card, | ||
1437 | (char *) card-> | ||
1438 | tx_dma_handle_card, | ||
1439 | (char *) | ||
1440 | BUF_OFFSET(txBuffer[pi] | ||
1441 | [port->txpos][0]), | ||
1442 | skb->len); | ||
1443 | } | ||
1444 | if (++port->txpos >= NUM_TX_BUFFER) | ||
1445 | port->txpos = 0; | ||
1446 | /* | ||
1447 | * If we have flow control on, can we now release it? | ||
1448 | */ | ||
1449 | if (port->start) { | ||
1450 | if (txq_length < fst_txq_low) { | ||
1451 | netif_wake_queue(port_to_dev | ||
1452 | (port)); | ||
1453 | port->start = 0; | ||
1454 | } | ||
1455 | } | ||
1456 | dev_kfree_skb(skb); | ||
1457 | } else { | ||
1458 | /* | ||
1459 | * Nothing to send so break out of the while loop | ||
1460 | */ | ||
1461 | break; | ||
1462 | } | ||
1463 | } | ||
1464 | } | ||
1465 | } | ||
1466 | |||
1467 | static void | ||
1468 | do_bottom_half_rx(struct fst_card_info *card) | ||
1469 | { | ||
1470 | struct fst_port_info *port; | ||
1471 | int pi; | ||
1472 | int rx_count = 0; | ||
1473 | |||
1474 | /* Check for rx completions on all ports on this card */ | ||
1475 | dbg(DBG_RX, "do_bottom_half_rx\n"); | ||
1476 | for (pi = 0, port = card->ports; pi < card->nports; pi++, port++) { | ||
1477 | if (!port->run) | ||
1478 | continue; | ||
1479 | |||
1480 | while (!(FST_RDB(card, rxDescrRing[pi][port->rxpos].bits) | ||
1481 | & DMA_OWN) && !(card->dmarx_in_progress)) { | ||
1482 | if (rx_count > fst_max_reads) { | ||
1483 | /* | ||
1484 | * Don't spend forever in receive processing | ||
1485 | * Schedule another event | ||
1486 | */ | ||
1487 | fst_q_work_item(&fst_work_intq, card->card_no); | ||
1488 | tasklet_schedule(&fst_int_task); | ||
1489 | break; /* Leave the loop */ | ||
1490 | } | ||
1491 | fst_intr_rx(card, port); | ||
1492 | rx_count++; | ||
1493 | } | ||
1494 | } | ||
1495 | } | ||
1496 | |||
1497 | /* | ||
1498 | * The interrupt service routine | ||
1499 | * Dev_id is our fst_card_info pointer | ||
1500 | */ | ||
1501 | irqreturn_t | ||
1502 | fst_intr(int irq, void *dev_id, struct pt_regs *regs) | ||
1503 | { | ||
1504 | struct fst_card_info *card; | ||
1505 | struct fst_port_info *port; | ||
1506 | int rdidx; /* Event buffer indices */ | ||
1507 | int wridx; | ||
1508 | int event; /* Actual event for processing */ | ||
1509 | unsigned int dma_intcsr = 0; | ||
1510 | unsigned int do_card_interrupt; | ||
1511 | unsigned int int_retry_count; | ||
1512 | |||
1513 | if ((card = dev_id) == NULL) { | ||
1514 | dbg(DBG_INTR, "intr: spurious %d\n", irq); | ||
1515 | return IRQ_NONE; | ||
1516 | } | ||
1517 | |||
1518 | /* | ||
1519 | * Check to see if the interrupt was for this card | ||
1520 | * return if not | ||
1521 | * Note that the call to clear the interrupt is important | ||
1522 | */ | ||
1523 | dbg(DBG_INTR, "intr: %d %p\n", irq, card); | ||
1524 | if (card->state != FST_RUNNING) { | ||
1525 | printk_err | ||
1526 | ("Interrupt received for card %d in a non running state (%d)\n", | ||
1527 | card->card_no, card->state); | ||
1528 | |||
1529 | /* | ||
1530 | * It is possible to really be running, i.e. we have re-loaded | ||
1531 | * a running card | ||
1532 | * Clear and reprime the interrupt source | ||
1533 | */ | ||
1534 | fst_clear_intr(card); | ||
1535 | return IRQ_HANDLED; | ||
1536 | } | ||
1537 | |||
1538 | /* Clear and reprime the interrupt source */ | ||
1539 | fst_clear_intr(card); | ||
1540 | |||
1541 | /* | ||
1542 | * Is the interrupt for this card (handshake == 1) | ||
1543 | */ | ||
1544 | do_card_interrupt = 0; | ||
1545 | if (FST_RDB(card, interruptHandshake) == 1) { | ||
1546 | do_card_interrupt += FST_CARD_INT; | ||
1547 | /* Set the software acknowledge */ | ||
1548 | FST_WRB(card, interruptHandshake, 0xEE); | ||
1549 | } | ||
1550 | if (card->family == FST_FAMILY_TXU) { | ||
1551 | /* | ||
1552 | * Is it a DMA Interrupt | ||
1553 | */ | ||
1554 | dma_intcsr = inl(card->pci_conf + INTCSR_9054); | ||
1555 | if (dma_intcsr & 0x00200000) { | ||
1556 | /* | ||
1557 | * DMA Channel 0 (Rx transfer complete) | ||
1558 | */ | ||
1559 | dbg(DBG_RX, "DMA Rx xfer complete\n"); | ||
1560 | outb(0x8, card->pci_conf + DMACSR0); | ||
1561 | fst_rx_dma_complete(card, card->dma_port_rx, | ||
1562 | card->dma_len_rx, card->dma_skb_rx, | ||
1563 | card->dma_rxpos); | ||
1564 | card->dmarx_in_progress = 0; | ||
1565 | do_card_interrupt += FST_RX_DMA_INT; | ||
1566 | } | ||
1567 | if (dma_intcsr & 0x00400000) { | ||
1568 | /* | ||
1569 | * DMA Channel 1 (Tx transfer complete) | ||
1570 | */ | ||
1571 | dbg(DBG_TX, "DMA Tx xfer complete\n"); | ||
1572 | outb(0x8, card->pci_conf + DMACSR1); | ||
1573 | fst_tx_dma_complete(card, card->dma_port_tx, | ||
1574 | card->dma_len_tx, card->dma_txpos); | ||
1575 | card->dmatx_in_progress = 0; | ||
1576 | do_card_interrupt += FST_TX_DMA_INT; | ||
1577 | } | ||
1578 | } | ||
1579 | |||
1580 | /* | ||
1581 | * Have we been missing Interrupts | ||
1582 | */ | ||
1583 | int_retry_count = FST_RDL(card, interruptRetryCount); | ||
1584 | if (int_retry_count) { | ||
1585 | dbg(DBG_ASS, "Card %d int_retry_count is %d\n", | ||
1586 | card->card_no, int_retry_count); | ||
1587 | FST_WRL(card, interruptRetryCount, 0); | ||
1588 | } | ||
1589 | |||
1590 | if (!do_card_interrupt) { | ||
1591 | return IRQ_HANDLED; | ||
1592 | } | ||
1593 | |||
1594 | /* Scehdule the bottom half of the ISR */ | ||
1595 | fst_q_work_item(&fst_work_intq, card->card_no); | ||
1596 | tasklet_schedule(&fst_int_task); | ||
1597 | |||
1598 | /* Drain the event queue */ | ||
1599 | rdidx = FST_RDB(card, interruptEvent.rdindex) & 0x1f; | ||
1600 | wridx = FST_RDB(card, interruptEvent.wrindex) & 0x1f; | ||
1601 | while (rdidx != wridx) { | ||
1602 | event = FST_RDB(card, interruptEvent.evntbuff[rdidx]); | ||
1603 | port = &card->ports[event & 0x03]; | ||
1604 | |||
1605 | dbg(DBG_INTR, "Processing Interrupt event: %x\n", event); | ||
1606 | |||
1607 | switch (event) { | ||
1608 | case TE1_ALMA: | ||
1609 | dbg(DBG_INTR, "TE1 Alarm intr\n"); | ||
1610 | if (port->run) | ||
1611 | fst_intr_te1_alarm(card, port); | ||
1612 | break; | ||
1613 | |||
1614 | case CTLA_CHG: | ||
1615 | case CTLB_CHG: | ||
1616 | case CTLC_CHG: | ||
1617 | case CTLD_CHG: | ||
1618 | if (port->run) | ||
1619 | fst_intr_ctlchg(card, port); | ||
1620 | break; | ||
1621 | |||
1622 | case ABTA_SENT: | ||
1623 | case ABTB_SENT: | ||
1624 | case ABTC_SENT: | ||
1625 | case ABTD_SENT: | ||
1626 | dbg(DBG_TX, "Abort complete port %d\n", port->index); | ||
1627 | break; | ||
1628 | |||
1629 | case TXA_UNDF: | ||
1630 | case TXB_UNDF: | ||
1631 | case TXC_UNDF: | ||
1632 | case TXD_UNDF: | ||
1633 | /* Difficult to see how we'd get this given that we | ||
1634 | * always load up the entire packet for DMA. | ||
1635 | */ | ||
1636 | dbg(DBG_TX, "Tx underflow port %d\n", port->index); | ||
1637 | hdlc_stats(port_to_dev(port))->tx_errors++; | ||
1638 | hdlc_stats(port_to_dev(port))->tx_fifo_errors++; | ||
1639 | dbg(DBG_ASS, "Tx underflow on card %d port %d\n", | ||
1640 | card->card_no, port->index); | ||
1641 | break; | ||
1642 | |||
1643 | case INIT_CPLT: | ||
1644 | dbg(DBG_INIT, "Card init OK intr\n"); | ||
1645 | break; | ||
1646 | |||
1647 | case INIT_FAIL: | ||
1648 | dbg(DBG_INIT, "Card init FAILED intr\n"); | ||
1649 | card->state = FST_IFAILED; | ||
1650 | break; | ||
1651 | |||
1652 | default: | ||
1653 | printk_err("intr: unknown card event %d. ignored\n", | ||
1654 | event); | ||
1655 | break; | ||
1656 | } | ||
1657 | |||
1658 | /* Bump and wrap the index */ | ||
1659 | if (++rdidx >= MAX_CIRBUFF) | ||
1660 | rdidx = 0; | ||
1661 | } | ||
1662 | FST_WRB(card, interruptEvent.rdindex, rdidx); | ||
1663 | return IRQ_HANDLED; | ||
1664 | } | ||
1665 | |||
1666 | /* Check that the shared memory configuration is one that we can handle | ||
1667 | * and that some basic parameters are correct | ||
1668 | */ | ||
1669 | static void | ||
1670 | check_started_ok(struct fst_card_info *card) | ||
1671 | { | ||
1672 | int i; | ||
1673 | |||
1674 | /* Check structure version and end marker */ | ||
1675 | if (FST_RDW(card, smcVersion) != SMC_VERSION) { | ||
1676 | printk_err("Bad shared memory version %d expected %d\n", | ||
1677 | FST_RDW(card, smcVersion), SMC_VERSION); | ||
1678 | card->state = FST_BADVERSION; | ||
1679 | return; | ||
1680 | } | ||
1681 | if (FST_RDL(card, endOfSmcSignature) != END_SIG) { | ||
1682 | printk_err("Missing shared memory signature\n"); | ||
1683 | card->state = FST_BADVERSION; | ||
1684 | return; | ||
1685 | } | ||
1686 | /* Firmware status flag, 0x00 = initialising, 0x01 = OK, 0xFF = fail */ | ||
1687 | if ((i = FST_RDB(card, taskStatus)) == 0x01) { | ||
1688 | card->state = FST_RUNNING; | ||
1689 | } else if (i == 0xFF) { | ||
1690 | printk_err("Firmware initialisation failed. Card halted\n"); | ||
1691 | card->state = FST_HALTED; | ||
1692 | return; | ||
1693 | } else if (i != 0x00) { | ||
1694 | printk_err("Unknown firmware status 0x%x\n", i); | ||
1695 | card->state = FST_HALTED; | ||
1696 | return; | ||
1697 | } | ||
1698 | |||
1699 | /* Finally check the number of ports reported by firmware against the | ||
1700 | * number we assumed at card detection. Should never happen with | ||
1701 | * existing firmware etc so we just report it for the moment. | ||
1702 | */ | ||
1703 | if (FST_RDL(card, numberOfPorts) != card->nports) { | ||
1704 | printk_warn("Port count mismatch on card %d." | ||
1705 | " Firmware thinks %d we say %d\n", card->card_no, | ||
1706 | FST_RDL(card, numberOfPorts), card->nports); | ||
1707 | } | ||
1708 | } | ||
1709 | |||
1710 | static int | ||
1711 | set_conf_from_info(struct fst_card_info *card, struct fst_port_info *port, | ||
1712 | struct fstioc_info *info) | ||
1713 | { | ||
1714 | int err; | ||
1715 | unsigned char my_framing; | ||
1716 | |||
1717 | /* Set things according to the user set valid flags | ||
1718 | * Several of the old options have been invalidated/replaced by the | ||
1719 | * generic hdlc package. | ||
1720 | */ | ||
1721 | err = 0; | ||
1722 | if (info->valid & FSTVAL_PROTO) { | ||
1723 | if (info->proto == FST_RAW) | ||
1724 | port->mode = FST_RAW; | ||
1725 | else | ||
1726 | port->mode = FST_GEN_HDLC; | ||
1727 | } | ||
1728 | |||
1729 | if (info->valid & FSTVAL_CABLE) | ||
1730 | err = -EINVAL; | ||
1731 | |||
1732 | if (info->valid & FSTVAL_SPEED) | ||
1733 | err = -EINVAL; | ||
1734 | |||
1735 | if (info->valid & FSTVAL_PHASE) | ||
1736 | FST_WRB(card, portConfig[port->index].invertClock, | ||
1737 | info->invertClock); | ||
1738 | if (info->valid & FSTVAL_MODE) | ||
1739 | FST_WRW(card, cardMode, info->cardMode); | ||
1740 | if (info->valid & FSTVAL_TE1) { | ||
1741 | FST_WRL(card, suConfig.dataRate, info->lineSpeed); | ||
1742 | FST_WRB(card, suConfig.clocking, info->clockSource); | ||
1743 | my_framing = FRAMING_E1; | ||
1744 | if (info->framing == E1) | ||
1745 | my_framing = FRAMING_E1; | ||
1746 | if (info->framing == T1) | ||
1747 | my_framing = FRAMING_T1; | ||
1748 | if (info->framing == J1) | ||
1749 | my_framing = FRAMING_J1; | ||
1750 | FST_WRB(card, suConfig.framing, my_framing); | ||
1751 | FST_WRB(card, suConfig.structure, info->structure); | ||
1752 | FST_WRB(card, suConfig.interface, info->interface); | ||
1753 | FST_WRB(card, suConfig.coding, info->coding); | ||
1754 | FST_WRB(card, suConfig.lineBuildOut, info->lineBuildOut); | ||
1755 | FST_WRB(card, suConfig.equalizer, info->equalizer); | ||
1756 | FST_WRB(card, suConfig.transparentMode, info->transparentMode); | ||
1757 | FST_WRB(card, suConfig.loopMode, info->loopMode); | ||
1758 | FST_WRB(card, suConfig.range, info->range); | ||
1759 | FST_WRB(card, suConfig.txBufferMode, info->txBufferMode); | ||
1760 | FST_WRB(card, suConfig.rxBufferMode, info->rxBufferMode); | ||
1761 | FST_WRB(card, suConfig.startingSlot, info->startingSlot); | ||
1762 | FST_WRB(card, suConfig.losThreshold, info->losThreshold); | ||
1763 | if (info->idleCode) | ||
1764 | FST_WRB(card, suConfig.enableIdleCode, 1); | ||
1765 | else | ||
1766 | FST_WRB(card, suConfig.enableIdleCode, 0); | ||
1767 | FST_WRB(card, suConfig.idleCode, info->idleCode); | ||
1768 | #if FST_DEBUG | ||
1769 | if (info->valid & FSTVAL_TE1) { | ||
1770 | printk("Setting TE1 data\n"); | ||
1771 | printk("Line Speed = %d\n", info->lineSpeed); | ||
1772 | printk("Start slot = %d\n", info->startingSlot); | ||
1773 | printk("Clock source = %d\n", info->clockSource); | ||
1774 | printk("Framing = %d\n", my_framing); | ||
1775 | printk("Structure = %d\n", info->structure); | ||
1776 | printk("interface = %d\n", info->interface); | ||
1777 | printk("Coding = %d\n", info->coding); | ||
1778 | printk("Line build out = %d\n", info->lineBuildOut); | ||
1779 | printk("Equaliser = %d\n", info->equalizer); | ||
1780 | printk("Transparent mode = %d\n", | ||
1781 | info->transparentMode); | ||
1782 | printk("Loop mode = %d\n", info->loopMode); | ||
1783 | printk("Range = %d\n", info->range); | ||
1784 | printk("Tx Buffer mode = %d\n", info->txBufferMode); | ||
1785 | printk("Rx Buffer mode = %d\n", info->rxBufferMode); | ||
1786 | printk("LOS Threshold = %d\n", info->losThreshold); | ||
1787 | printk("Idle Code = %d\n", info->idleCode); | ||
1788 | } | ||
1789 | #endif | ||
1790 | } | ||
1791 | #if FST_DEBUG | ||
1792 | if (info->valid & FSTVAL_DEBUG) { | ||
1793 | fst_debug_mask = info->debug; | ||
1794 | } | ||
1795 | #endif | ||
1796 | |||
1797 | return err; | ||
1798 | } | ||
1799 | |||
1800 | static void | ||
1801 | gather_conf_info(struct fst_card_info *card, struct fst_port_info *port, | ||
1802 | struct fstioc_info *info) | ||
1803 | { | ||
1804 | int i; | ||
1805 | |||
1806 | memset(info, 0, sizeof (struct fstioc_info)); | ||
1807 | |||
1808 | i = port->index; | ||
1809 | info->kernelVersion = LINUX_VERSION_CODE; | ||
1810 | info->nports = card->nports; | ||
1811 | info->type = card->type; | ||
1812 | info->state = card->state; | ||
1813 | info->proto = FST_GEN_HDLC; | ||
1814 | info->index = i; | ||
1815 | #if FST_DEBUG | ||
1816 | info->debug = fst_debug_mask; | ||
1817 | #endif | ||
1818 | |||
1819 | /* Only mark information as valid if card is running. | ||
1820 | * Copy the data anyway in case it is useful for diagnostics | ||
1821 | */ | ||
1822 | info->valid = ((card->state == FST_RUNNING) ? FSTVAL_ALL : FSTVAL_CARD) | ||
1823 | #if FST_DEBUG | ||
1824 | | FSTVAL_DEBUG | ||
1825 | #endif | ||
1826 | ; | ||
1827 | |||
1828 | info->lineInterface = FST_RDW(card, portConfig[i].lineInterface); | ||
1829 | info->internalClock = FST_RDB(card, portConfig[i].internalClock); | ||
1830 | info->lineSpeed = FST_RDL(card, portConfig[i].lineSpeed); | ||
1831 | info->invertClock = FST_RDB(card, portConfig[i].invertClock); | ||
1832 | info->v24IpSts = FST_RDL(card, v24IpSts[i]); | ||
1833 | info->v24OpSts = FST_RDL(card, v24OpSts[i]); | ||
1834 | info->clockStatus = FST_RDW(card, clockStatus[i]); | ||
1835 | info->cableStatus = FST_RDW(card, cableStatus); | ||
1836 | info->cardMode = FST_RDW(card, cardMode); | ||
1837 | info->smcFirmwareVersion = FST_RDL(card, smcFirmwareVersion); | ||
1838 | |||
1839 | /* | ||
1840 | * The T2U can report cable presence for both A or B | ||
1841 | * in bits 0 and 1 of cableStatus. See which port we are and | ||
1842 | * do the mapping. | ||
1843 | */ | ||
1844 | if (card->family == FST_FAMILY_TXU) { | ||
1845 | if (port->index == 0) { | ||
1846 | /* | ||
1847 | * Port A | ||
1848 | */ | ||
1849 | info->cableStatus = info->cableStatus & 1; | ||
1850 | } else { | ||
1851 | /* | ||
1852 | * Port B | ||
1853 | */ | ||
1854 | info->cableStatus = info->cableStatus >> 1; | ||
1855 | info->cableStatus = info->cableStatus & 1; | ||
1856 | } | ||
1857 | } | ||
1858 | /* | ||
1859 | * Some additional bits if we are TE1 | ||
1860 | */ | ||
1861 | if (card->type == FST_TYPE_TE1) { | ||
1862 | info->lineSpeed = FST_RDL(card, suConfig.dataRate); | ||
1863 | info->clockSource = FST_RDB(card, suConfig.clocking); | ||
1864 | info->framing = FST_RDB(card, suConfig.framing); | ||
1865 | info->structure = FST_RDB(card, suConfig.structure); | ||
1866 | info->interface = FST_RDB(card, suConfig.interface); | ||
1867 | info->coding = FST_RDB(card, suConfig.coding); | ||
1868 | info->lineBuildOut = FST_RDB(card, suConfig.lineBuildOut); | ||
1869 | info->equalizer = FST_RDB(card, suConfig.equalizer); | ||
1870 | info->loopMode = FST_RDB(card, suConfig.loopMode); | ||
1871 | info->range = FST_RDB(card, suConfig.range); | ||
1872 | info->txBufferMode = FST_RDB(card, suConfig.txBufferMode); | ||
1873 | info->rxBufferMode = FST_RDB(card, suConfig.rxBufferMode); | ||
1874 | info->startingSlot = FST_RDB(card, suConfig.startingSlot); | ||
1875 | info->losThreshold = FST_RDB(card, suConfig.losThreshold); | ||
1876 | if (FST_RDB(card, suConfig.enableIdleCode)) | ||
1877 | info->idleCode = FST_RDB(card, suConfig.idleCode); | ||
1878 | else | ||
1879 | info->idleCode = 0; | ||
1880 | info->receiveBufferDelay = | ||
1881 | FST_RDL(card, suStatus.receiveBufferDelay); | ||
1882 | info->framingErrorCount = | ||
1883 | FST_RDL(card, suStatus.framingErrorCount); | ||
1884 | info->codeViolationCount = | ||
1885 | FST_RDL(card, suStatus.codeViolationCount); | ||
1886 | info->crcErrorCount = FST_RDL(card, suStatus.crcErrorCount); | ||
1887 | info->lineAttenuation = FST_RDL(card, suStatus.lineAttenuation); | ||
1888 | info->lossOfSignal = FST_RDB(card, suStatus.lossOfSignal); | ||
1889 | info->receiveRemoteAlarm = | ||
1890 | FST_RDB(card, suStatus.receiveRemoteAlarm); | ||
1891 | info->alarmIndicationSignal = | ||
1892 | FST_RDB(card, suStatus.alarmIndicationSignal); | ||
1893 | } | ||
1894 | } | ||
1895 | |||
1896 | static int | ||
1897 | fst_set_iface(struct fst_card_info *card, struct fst_port_info *port, | ||
1898 | struct ifreq *ifr) | ||
1899 | { | ||
1900 | sync_serial_settings sync; | ||
1901 | int i; | ||
1902 | |||
1903 | if (ifr->ifr_settings.size != sizeof (sync)) { | ||
1904 | return -ENOMEM; | ||
1905 | } | ||
1906 | |||
1907 | if (copy_from_user | ||
1908 | (&sync, ifr->ifr_settings.ifs_ifsu.sync, sizeof (sync))) { | ||
1909 | return -EFAULT; | ||
1910 | } | ||
1911 | |||
1912 | if (sync.loopback) | ||
1913 | return -EINVAL; | ||
1914 | |||
1915 | i = port->index; | ||
1916 | |||
1917 | switch (ifr->ifr_settings.type) { | ||
1918 | case IF_IFACE_V35: | ||
1919 | FST_WRW(card, portConfig[i].lineInterface, V35); | ||
1920 | port->hwif = V35; | ||
1921 | break; | ||
1922 | |||
1923 | case IF_IFACE_V24: | ||
1924 | FST_WRW(card, portConfig[i].lineInterface, V24); | ||
1925 | port->hwif = V24; | ||
1926 | break; | ||
1927 | |||
1928 | case IF_IFACE_X21: | ||
1929 | FST_WRW(card, portConfig[i].lineInterface, X21); | ||
1930 | port->hwif = X21; | ||
1931 | break; | ||
1932 | |||
1933 | case IF_IFACE_X21D: | ||
1934 | FST_WRW(card, portConfig[i].lineInterface, X21D); | ||
1935 | port->hwif = X21D; | ||
1936 | break; | ||
1937 | |||
1938 | case IF_IFACE_T1: | ||
1939 | FST_WRW(card, portConfig[i].lineInterface, T1); | ||
1940 | port->hwif = T1; | ||
1941 | break; | ||
1942 | |||
1943 | case IF_IFACE_E1: | ||
1944 | FST_WRW(card, portConfig[i].lineInterface, E1); | ||
1945 | port->hwif = E1; | ||
1946 | break; | ||
1947 | |||
1948 | case IF_IFACE_SYNC_SERIAL: | ||
1949 | break; | ||
1950 | |||
1951 | default: | ||
1952 | return -EINVAL; | ||
1953 | } | ||
1954 | |||
1955 | switch (sync.clock_type) { | ||
1956 | case CLOCK_EXT: | ||
1957 | FST_WRB(card, portConfig[i].internalClock, EXTCLK); | ||
1958 | break; | ||
1959 | |||
1960 | case CLOCK_INT: | ||
1961 | FST_WRB(card, portConfig[i].internalClock, INTCLK); | ||
1962 | break; | ||
1963 | |||
1964 | default: | ||
1965 | return -EINVAL; | ||
1966 | } | ||
1967 | FST_WRL(card, portConfig[i].lineSpeed, sync.clock_rate); | ||
1968 | return 0; | ||
1969 | } | ||
1970 | |||
1971 | static int | ||
1972 | fst_get_iface(struct fst_card_info *card, struct fst_port_info *port, | ||
1973 | struct ifreq *ifr) | ||
1974 | { | ||
1975 | sync_serial_settings sync; | ||
1976 | int i; | ||
1977 | |||
1978 | /* First check what line type is set, we'll default to reporting X.21 | ||
1979 | * if nothing is set as IF_IFACE_SYNC_SERIAL implies it can't be | ||
1980 | * changed | ||
1981 | */ | ||
1982 | switch (port->hwif) { | ||
1983 | case E1: | ||
1984 | ifr->ifr_settings.type = IF_IFACE_E1; | ||
1985 | break; | ||
1986 | case T1: | ||
1987 | ifr->ifr_settings.type = IF_IFACE_T1; | ||
1988 | break; | ||
1989 | case V35: | ||
1990 | ifr->ifr_settings.type = IF_IFACE_V35; | ||
1991 | break; | ||
1992 | case V24: | ||
1993 | ifr->ifr_settings.type = IF_IFACE_V24; | ||
1994 | break; | ||
1995 | case X21D: | ||
1996 | ifr->ifr_settings.type = IF_IFACE_X21D; | ||
1997 | break; | ||
1998 | case X21: | ||
1999 | default: | ||
2000 | ifr->ifr_settings.type = IF_IFACE_X21; | ||
2001 | break; | ||
2002 | } | ||
2003 | if (ifr->ifr_settings.size == 0) { | ||
2004 | return 0; /* only type requested */ | ||
2005 | } | ||
2006 | if (ifr->ifr_settings.size < sizeof (sync)) { | ||
2007 | return -ENOMEM; | ||
2008 | } | ||
2009 | |||
2010 | i = port->index; | ||
2011 | sync.clock_rate = FST_RDL(card, portConfig[i].lineSpeed); | ||
2012 | /* Lucky card and linux use same encoding here */ | ||
2013 | sync.clock_type = FST_RDB(card, portConfig[i].internalClock) == | ||
2014 | INTCLK ? CLOCK_INT : CLOCK_EXT; | ||
2015 | sync.loopback = 0; | ||
2016 | |||
2017 | if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &sync, sizeof (sync))) { | ||
2018 | return -EFAULT; | ||
2019 | } | ||
2020 | |||
2021 | ifr->ifr_settings.size = sizeof (sync); | ||
2022 | return 0; | ||
2023 | } | ||
2024 | |||
2025 | static int | ||
2026 | fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
2027 | { | ||
2028 | struct fst_card_info *card; | ||
2029 | struct fst_port_info *port; | ||
2030 | struct fstioc_write wrthdr; | ||
2031 | struct fstioc_info info; | ||
2032 | unsigned long flags; | ||
2033 | |||
2034 | dbg(DBG_IOCTL, "ioctl: %x, %p\n", cmd, ifr->ifr_data); | ||
2035 | |||
2036 | port = dev_to_port(dev); | ||
2037 | card = port->card; | ||
2038 | |||
2039 | if (!capable(CAP_NET_ADMIN)) | ||
2040 | return -EPERM; | ||
2041 | |||
2042 | switch (cmd) { | ||
2043 | case FSTCPURESET: | ||
2044 | fst_cpureset(card); | ||
2045 | card->state = FST_RESET; | ||
2046 | return 0; | ||
2047 | |||
2048 | case FSTCPURELEASE: | ||
2049 | fst_cpurelease(card); | ||
2050 | card->state = FST_STARTING; | ||
2051 | return 0; | ||
2052 | |||
2053 | case FSTWRITE: /* Code write (download) */ | ||
2054 | |||
2055 | /* First copy in the header with the length and offset of data | ||
2056 | * to write | ||
2057 | */ | ||
2058 | if (ifr->ifr_data == NULL) { | ||
2059 | return -EINVAL; | ||
2060 | } | ||
2061 | if (copy_from_user(&wrthdr, ifr->ifr_data, | ||
2062 | sizeof (struct fstioc_write))) { | ||
2063 | return -EFAULT; | ||
2064 | } | ||
2065 | |||
2066 | /* Sanity check the parameters. We don't support partial writes | ||
2067 | * when going over the top | ||
2068 | */ | ||
2069 | if (wrthdr.size > FST_MEMSIZE || wrthdr.offset > FST_MEMSIZE | ||
2070 | || wrthdr.size + wrthdr.offset > FST_MEMSIZE) { | ||
2071 | return -ENXIO; | ||
2072 | } | ||
2073 | |||
2074 | /* Now copy the data to the card. | ||
2075 | * This will probably break on some architectures. | ||
2076 | * I'll fix it when I have something to test on. | ||
2077 | */ | ||
2078 | if (copy_from_user(card->mem + wrthdr.offset, | ||
2079 | ifr->ifr_data + sizeof (struct fstioc_write), | ||
2080 | wrthdr.size)) { | ||
2081 | return -EFAULT; | ||
2082 | } | ||
2083 | |||
2084 | /* Writes to the memory of a card in the reset state constitute | ||
2085 | * a download | ||
2086 | */ | ||
2087 | if (card->state == FST_RESET) { | ||
2088 | card->state = FST_DOWNLOAD; | ||
2089 | } | ||
2090 | return 0; | ||
2091 | |||
2092 | case FSTGETCONF: | ||
2093 | |||
2094 | /* If card has just been started check the shared memory config | ||
2095 | * version and marker | ||
2096 | */ | ||
2097 | if (card->state == FST_STARTING) { | ||
2098 | check_started_ok(card); | ||
2099 | |||
2100 | /* If everything checked out enable card interrupts */ | ||
2101 | if (card->state == FST_RUNNING) { | ||
2102 | spin_lock_irqsave(&card->card_lock, flags); | ||
2103 | fst_enable_intr(card); | ||
2104 | FST_WRB(card, interruptHandshake, 0xEE); | ||
2105 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
2106 | } | ||
2107 | } | ||
2108 | |||
2109 | if (ifr->ifr_data == NULL) { | ||
2110 | return -EINVAL; | ||
2111 | } | ||
2112 | |||
2113 | gather_conf_info(card, port, &info); | ||
2114 | |||
2115 | if (copy_to_user(ifr->ifr_data, &info, sizeof (info))) { | ||
2116 | return -EFAULT; | ||
2117 | } | ||
2118 | return 0; | ||
2119 | |||
2120 | case FSTSETCONF: | ||
2121 | |||
2122 | /* | ||
2123 | * Most of the settings have been moved to the generic ioctls | ||
2124 | * this just covers debug and board ident now | ||
2125 | */ | ||
2126 | |||
2127 | if (card->state != FST_RUNNING) { | ||
2128 | printk_err | ||
2129 | ("Attempt to configure card %d in non-running state (%d)\n", | ||
2130 | card->card_no, card->state); | ||
2131 | return -EIO; | ||
2132 | } | ||
2133 | if (copy_from_user(&info, ifr->ifr_data, sizeof (info))) { | ||
2134 | return -EFAULT; | ||
2135 | } | ||
2136 | |||
2137 | return set_conf_from_info(card, port, &info); | ||
2138 | |||
2139 | case SIOCWANDEV: | ||
2140 | switch (ifr->ifr_settings.type) { | ||
2141 | case IF_GET_IFACE: | ||
2142 | return fst_get_iface(card, port, ifr); | ||
2143 | |||
2144 | case IF_IFACE_SYNC_SERIAL: | ||
2145 | case IF_IFACE_V35: | ||
2146 | case IF_IFACE_V24: | ||
2147 | case IF_IFACE_X21: | ||
2148 | case IF_IFACE_X21D: | ||
2149 | case IF_IFACE_T1: | ||
2150 | case IF_IFACE_E1: | ||
2151 | return fst_set_iface(card, port, ifr); | ||
2152 | |||
2153 | case IF_PROTO_RAW: | ||
2154 | port->mode = FST_RAW; | ||
2155 | return 0; | ||
2156 | |||
2157 | case IF_GET_PROTO: | ||
2158 | if (port->mode == FST_RAW) { | ||
2159 | ifr->ifr_settings.type = IF_PROTO_RAW; | ||
2160 | return 0; | ||
2161 | } | ||
2162 | return hdlc_ioctl(dev, ifr, cmd); | ||
2163 | |||
2164 | default: | ||
2165 | port->mode = FST_GEN_HDLC; | ||
2166 | dbg(DBG_IOCTL, "Passing this type to hdlc %x\n", | ||
2167 | ifr->ifr_settings.type); | ||
2168 | return hdlc_ioctl(dev, ifr, cmd); | ||
2169 | } | ||
2170 | |||
2171 | default: | ||
2172 | /* Not one of ours. Pass through to HDLC package */ | ||
2173 | return hdlc_ioctl(dev, ifr, cmd); | ||
2174 | } | ||
2175 | } | ||
2176 | |||
2177 | static void | ||
2178 | fst_openport(struct fst_port_info *port) | ||
2179 | { | ||
2180 | int signals; | ||
2181 | int txq_length; | ||
2182 | |||
2183 | /* Only init things if card is actually running. This allows open to | ||
2184 | * succeed for downloads etc. | ||
2185 | */ | ||
2186 | if (port->card->state == FST_RUNNING) { | ||
2187 | if (port->run) { | ||
2188 | dbg(DBG_OPEN, "open: found port already running\n"); | ||
2189 | |||
2190 | fst_issue_cmd(port, STOPPORT); | ||
2191 | port->run = 0; | ||
2192 | } | ||
2193 | |||
2194 | fst_rx_config(port); | ||
2195 | fst_tx_config(port); | ||
2196 | fst_op_raise(port, OPSTS_RTS | OPSTS_DTR); | ||
2197 | |||
2198 | fst_issue_cmd(port, STARTPORT); | ||
2199 | port->run = 1; | ||
2200 | |||
2201 | signals = FST_RDL(port->card, v24DebouncedSts[port->index]); | ||
2202 | if (signals & (((port->hwif == X21) || (port->hwif == X21D)) | ||
2203 | ? IPSTS_INDICATE : IPSTS_DCD)) | ||
2204 | netif_carrier_on(port_to_dev(port)); | ||
2205 | else | ||
2206 | netif_carrier_off(port_to_dev(port)); | ||
2207 | |||
2208 | txq_length = port->txqe - port->txqs; | ||
2209 | port->txqe = 0; | ||
2210 | port->txqs = 0; | ||
2211 | } | ||
2212 | |||
2213 | } | ||
2214 | |||
2215 | static void | ||
2216 | fst_closeport(struct fst_port_info *port) | ||
2217 | { | ||
2218 | if (port->card->state == FST_RUNNING) { | ||
2219 | if (port->run) { | ||
2220 | port->run = 0; | ||
2221 | fst_op_lower(port, OPSTS_RTS | OPSTS_DTR); | ||
2222 | |||
2223 | fst_issue_cmd(port, STOPPORT); | ||
2224 | } else { | ||
2225 | dbg(DBG_OPEN, "close: port not running\n"); | ||
2226 | } | ||
2227 | } | ||
2228 | } | ||
2229 | |||
2230 | static int | ||
2231 | fst_open(struct net_device *dev) | ||
2232 | { | ||
2233 | int err; | ||
2234 | struct fst_port_info *port; | ||
2235 | |||
2236 | port = dev_to_port(dev); | ||
2237 | if (!try_module_get(THIS_MODULE)) | ||
2238 | return -EBUSY; | ||
2239 | |||
2240 | if (port->mode != FST_RAW) { | ||
2241 | err = hdlc_open(dev); | ||
2242 | if (err) | ||
2243 | return err; | ||
2244 | } | ||
2245 | |||
2246 | fst_openport(port); | ||
2247 | netif_wake_queue(dev); | ||
2248 | return 0; | ||
2249 | } | ||
2250 | |||
2251 | static int | ||
2252 | fst_close(struct net_device *dev) | ||
2253 | { | ||
2254 | struct fst_port_info *port; | ||
2255 | struct fst_card_info *card; | ||
2256 | unsigned char tx_dma_done; | ||
2257 | unsigned char rx_dma_done; | ||
2258 | |||
2259 | port = dev_to_port(dev); | ||
2260 | card = port->card; | ||
2261 | |||
2262 | tx_dma_done = inb(card->pci_conf + DMACSR1); | ||
2263 | rx_dma_done = inb(card->pci_conf + DMACSR0); | ||
2264 | dbg(DBG_OPEN, | ||
2265 | "Port Close: tx_dma_in_progress = %d (%x) rx_dma_in_progress = %d (%x)\n", | ||
2266 | card->dmatx_in_progress, tx_dma_done, card->dmarx_in_progress, | ||
2267 | rx_dma_done); | ||
2268 | |||
2269 | netif_stop_queue(dev); | ||
2270 | fst_closeport(dev_to_port(dev)); | ||
2271 | if (port->mode != FST_RAW) { | ||
2272 | hdlc_close(dev); | ||
2273 | } | ||
2274 | module_put(THIS_MODULE); | ||
2275 | return 0; | ||
2276 | } | ||
2277 | |||
2278 | static int | ||
2279 | fst_attach(struct net_device *dev, unsigned short encoding, unsigned short parity) | ||
2280 | { | ||
2281 | /* | ||
2282 | * Setting currently fixed in FarSync card so we check and forget | ||
2283 | */ | ||
2284 | if (encoding != ENCODING_NRZ || parity != PARITY_CRC16_PR1_CCITT) | ||
2285 | return -EINVAL; | ||
2286 | return 0; | ||
2287 | } | ||
2288 | |||
2289 | static void | ||
2290 | fst_tx_timeout(struct net_device *dev) | ||
2291 | { | ||
2292 | struct fst_port_info *port; | ||
2293 | struct fst_card_info *card; | ||
2294 | struct net_device_stats *stats = hdlc_stats(dev); | ||
2295 | |||
2296 | port = dev_to_port(dev); | ||
2297 | card = port->card; | ||
2298 | stats->tx_errors++; | ||
2299 | stats->tx_aborted_errors++; | ||
2300 | dbg(DBG_ASS, "Tx timeout card %d port %d\n", | ||
2301 | card->card_no, port->index); | ||
2302 | fst_issue_cmd(port, ABORTTX); | ||
2303 | |||
2304 | dev->trans_start = jiffies; | ||
2305 | netif_wake_queue(dev); | ||
2306 | port->start = 0; | ||
2307 | } | ||
2308 | |||
2309 | static int | ||
2310 | fst_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
2311 | { | ||
2312 | struct fst_card_info *card; | ||
2313 | struct fst_port_info *port; | ||
2314 | struct net_device_stats *stats = hdlc_stats(dev); | ||
2315 | unsigned long flags; | ||
2316 | int txq_length; | ||
2317 | |||
2318 | port = dev_to_port(dev); | ||
2319 | card = port->card; | ||
2320 | dbg(DBG_TX, "fst_start_xmit: length = %d\n", skb->len); | ||
2321 | |||
2322 | /* Drop packet with error if we don't have carrier */ | ||
2323 | if (!netif_carrier_ok(dev)) { | ||
2324 | dev_kfree_skb(skb); | ||
2325 | stats->tx_errors++; | ||
2326 | stats->tx_carrier_errors++; | ||
2327 | dbg(DBG_ASS, | ||
2328 | "Tried to transmit but no carrier on card %d port %d\n", | ||
2329 | card->card_no, port->index); | ||
2330 | return 0; | ||
2331 | } | ||
2332 | |||
2333 | /* Drop it if it's too big! MTU failure ? */ | ||
2334 | if (skb->len > LEN_TX_BUFFER) { | ||
2335 | dbg(DBG_ASS, "Packet too large %d vs %d\n", skb->len, | ||
2336 | LEN_TX_BUFFER); | ||
2337 | dev_kfree_skb(skb); | ||
2338 | stats->tx_errors++; | ||
2339 | return 0; | ||
2340 | } | ||
2341 | |||
2342 | /* | ||
2343 | * We are always going to queue the packet | ||
2344 | * so that the bottom half is the only place we tx from | ||
2345 | * Check there is room in the port txq | ||
2346 | */ | ||
2347 | spin_lock_irqsave(&card->card_lock, flags); | ||
2348 | if ((txq_length = port->txqe - port->txqs) < 0) { | ||
2349 | /* | ||
2350 | * This is the case where the next free has wrapped but the | ||
2351 | * last used hasn't | ||
2352 | */ | ||
2353 | txq_length = txq_length + FST_TXQ_DEPTH; | ||
2354 | } | ||
2355 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
2356 | if (txq_length > fst_txq_high) { | ||
2357 | /* | ||
2358 | * We have got enough buffers in the pipeline. Ask the network | ||
2359 | * layer to stop sending frames down | ||
2360 | */ | ||
2361 | netif_stop_queue(dev); | ||
2362 | port->start = 1; /* I'm using this to signal stop sent up */ | ||
2363 | } | ||
2364 | |||
2365 | if (txq_length == FST_TXQ_DEPTH - 1) { | ||
2366 | /* | ||
2367 | * This shouldn't have happened but such is life | ||
2368 | */ | ||
2369 | dev_kfree_skb(skb); | ||
2370 | stats->tx_errors++; | ||
2371 | dbg(DBG_ASS, "Tx queue overflow card %d port %d\n", | ||
2372 | card->card_no, port->index); | ||
2373 | return 0; | ||
2374 | } | ||
2375 | |||
2376 | /* | ||
2377 | * queue the buffer | ||
2378 | */ | ||
2379 | spin_lock_irqsave(&card->card_lock, flags); | ||
2380 | port->txq[port->txqe] = skb; | ||
2381 | port->txqe++; | ||
2382 | if (port->txqe == FST_TXQ_DEPTH) | ||
2383 | port->txqe = 0; | ||
2384 | spin_unlock_irqrestore(&card->card_lock, flags); | ||
2385 | |||
2386 | /* Scehdule the bottom half which now does transmit processing */ | ||
2387 | fst_q_work_item(&fst_work_txq, card->card_no); | ||
2388 | tasklet_schedule(&fst_tx_task); | ||
2389 | |||
2390 | return 0; | ||
2391 | } | ||
2392 | |||
2393 | /* | ||
2394 | * Card setup having checked hardware resources. | ||
2395 | * Should be pretty bizarre if we get an error here (kernel memory | ||
2396 | * exhaustion is one possibility). If we do see a problem we report it | ||
2397 | * via a printk and leave the corresponding interface and all that follow | ||
2398 | * disabled. | ||
2399 | */ | ||
2400 | static char *type_strings[] __devinitdata = { | ||
2401 | "no hardware", /* Should never be seen */ | ||
2402 | "FarSync T2P", | ||
2403 | "FarSync T4P", | ||
2404 | "FarSync T1U", | ||
2405 | "FarSync T2U", | ||
2406 | "FarSync T4U", | ||
2407 | "FarSync TE1" | ||
2408 | }; | ||
2409 | |||
2410 | static void __devinit | ||
2411 | fst_init_card(struct fst_card_info *card) | ||
2412 | { | ||
2413 | int i; | ||
2414 | int err; | ||
2415 | |||
2416 | /* We're working on a number of ports based on the card ID. If the | ||
2417 | * firmware detects something different later (should never happen) | ||
2418 | * we'll have to revise it in some way then. | ||
2419 | */ | ||
2420 | for (i = 0; i < card->nports; i++) { | ||
2421 | err = register_hdlc_device(card->ports[i].dev); | ||
2422 | if (err < 0) { | ||
2423 | int j; | ||
2424 | printk_err ("Cannot register HDLC device for port %d" | ||
2425 | " (errno %d)\n", i, -err ); | ||
2426 | for (j = i; j < card->nports; j++) { | ||
2427 | free_netdev(card->ports[j].dev); | ||
2428 | card->ports[j].dev = NULL; | ||
2429 | } | ||
2430 | card->nports = i; | ||
2431 | break; | ||
2432 | } | ||
2433 | } | ||
2434 | |||
2435 | printk_info("%s-%s: %s IRQ%d, %d ports\n", | ||
2436 | port_to_dev(&card->ports[0])->name, | ||
2437 | port_to_dev(&card->ports[card->nports - 1])->name, | ||
2438 | type_strings[card->type], card->irq, card->nports); | ||
2439 | } | ||
2440 | |||
2441 | /* | ||
2442 | * Initialise card when detected. | ||
2443 | * Returns 0 to indicate success, or errno otherwise. | ||
2444 | */ | ||
2445 | static int __devinit | ||
2446 | fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
2447 | { | ||
2448 | static int firsttime_done = 0; | ||
2449 | static int no_of_cards_added = 0; | ||
2450 | struct fst_card_info *card; | ||
2451 | int err = 0; | ||
2452 | int i; | ||
2453 | |||
2454 | if (!firsttime_done) { | ||
2455 | printk_info("FarSync WAN driver " FST_USER_VERSION | ||
2456 | " (c) 2001-2004 FarSite Communications Ltd.\n"); | ||
2457 | firsttime_done = 1; | ||
2458 | dbg(DBG_ASS, "The value of debug mask is %x\n", fst_debug_mask); | ||
2459 | } | ||
2460 | |||
2461 | /* | ||
2462 | * We are going to be clever and allow certain cards not to be | ||
2463 | * configured. An exclude list can be provided in /etc/modules.conf | ||
2464 | */ | ||
2465 | if (fst_excluded_cards != 0) { | ||
2466 | /* | ||
2467 | * There are cards to exclude | ||
2468 | * | ||
2469 | */ | ||
2470 | for (i = 0; i < fst_excluded_cards; i++) { | ||
2471 | if ((pdev->devfn) >> 3 == fst_excluded_list[i]) { | ||
2472 | printk_info("FarSync PCI device %d not assigned\n", | ||
2473 | (pdev->devfn) >> 3); | ||
2474 | return -EBUSY; | ||
2475 | } | ||
2476 | } | ||
2477 | } | ||
2478 | |||
2479 | /* Allocate driver private data */ | ||
2480 | card = kmalloc(sizeof (struct fst_card_info), GFP_KERNEL); | ||
2481 | if (card == NULL) { | ||
2482 | printk_err("FarSync card found but insufficient memory for" | ||
2483 | " driver storage\n"); | ||
2484 | return -ENOMEM; | ||
2485 | } | ||
2486 | memset(card, 0, sizeof (struct fst_card_info)); | ||
2487 | |||
2488 | /* Try to enable the device */ | ||
2489 | if ((err = pci_enable_device(pdev)) != 0) { | ||
2490 | printk_err("Failed to enable card. Err %d\n", -err); | ||
2491 | kfree(card); | ||
2492 | return err; | ||
2493 | } | ||
2494 | |||
2495 | if ((err = pci_request_regions(pdev, "FarSync")) !=0) { | ||
2496 | printk_err("Failed to allocate regions. Err %d\n", -err); | ||
2497 | pci_disable_device(pdev); | ||
2498 | kfree(card); | ||
2499 | return err; | ||
2500 | } | ||
2501 | |||
2502 | /* Get virtual addresses of memory regions */ | ||
2503 | card->pci_conf = pci_resource_start(pdev, 1); | ||
2504 | card->phys_mem = pci_resource_start(pdev, 2); | ||
2505 | card->phys_ctlmem = pci_resource_start(pdev, 3); | ||
2506 | if ((card->mem = ioremap(card->phys_mem, FST_MEMSIZE)) == NULL) { | ||
2507 | printk_err("Physical memory remap failed\n"); | ||
2508 | pci_release_regions(pdev); | ||
2509 | pci_disable_device(pdev); | ||
2510 | kfree(card); | ||
2511 | return -ENODEV; | ||
2512 | } | ||
2513 | if ((card->ctlmem = ioremap(card->phys_ctlmem, 0x10)) == NULL) { | ||
2514 | printk_err("Control memory remap failed\n"); | ||
2515 | pci_release_regions(pdev); | ||
2516 | pci_disable_device(pdev); | ||
2517 | kfree(card); | ||
2518 | return -ENODEV; | ||
2519 | } | ||
2520 | dbg(DBG_PCI, "kernel mem %p, ctlmem %p\n", card->mem, card->ctlmem); | ||
2521 | |||
2522 | /* Register the interrupt handler */ | ||
2523 | if (request_irq(pdev->irq, fst_intr, SA_SHIRQ, FST_DEV_NAME, card)) { | ||
2524 | printk_err("Unable to register interrupt %d\n", card->irq); | ||
2525 | pci_release_regions(pdev); | ||
2526 | pci_disable_device(pdev); | ||
2527 | iounmap(card->ctlmem); | ||
2528 | iounmap(card->mem); | ||
2529 | kfree(card); | ||
2530 | return -ENODEV; | ||
2531 | } | ||
2532 | |||
2533 | /* Record info we need */ | ||
2534 | card->irq = pdev->irq; | ||
2535 | card->type = ent->driver_data; | ||
2536 | card->family = ((ent->driver_data == FST_TYPE_T2P) || | ||
2537 | (ent->driver_data == FST_TYPE_T4P)) | ||
2538 | ? FST_FAMILY_TXP : FST_FAMILY_TXU; | ||
2539 | if ((ent->driver_data == FST_TYPE_T1U) || | ||
2540 | (ent->driver_data == FST_TYPE_TE1)) | ||
2541 | card->nports = 1; | ||
2542 | else | ||
2543 | card->nports = ((ent->driver_data == FST_TYPE_T2P) || | ||
2544 | (ent->driver_data == FST_TYPE_T2U)) ? 2 : 4; | ||
2545 | |||
2546 | card->state = FST_UNINIT; | ||
2547 | spin_lock_init ( &card->card_lock ); | ||
2548 | |||
2549 | for ( i = 0 ; i < card->nports ; i++ ) { | ||
2550 | struct net_device *dev = alloc_hdlcdev(&card->ports[i]); | ||
2551 | hdlc_device *hdlc; | ||
2552 | if (!dev) { | ||
2553 | while (i--) | ||
2554 | free_netdev(card->ports[i].dev); | ||
2555 | printk_err ("FarSync: out of memory\n"); | ||
2556 | free_irq(card->irq, card); | ||
2557 | pci_release_regions(pdev); | ||
2558 | pci_disable_device(pdev); | ||
2559 | iounmap(card->ctlmem); | ||
2560 | iounmap(card->mem); | ||
2561 | kfree(card); | ||
2562 | return -ENODEV; | ||
2563 | } | ||
2564 | card->ports[i].dev = dev; | ||
2565 | card->ports[i].card = card; | ||
2566 | card->ports[i].index = i; | ||
2567 | card->ports[i].run = 0; | ||
2568 | |||
2569 | hdlc = dev_to_hdlc(dev); | ||
2570 | |||
2571 | /* Fill in the net device info */ | ||
2572 | /* Since this is a PCI setup this is purely | ||
2573 | * informational. Give them the buffer addresses | ||
2574 | * and basic card I/O. | ||
2575 | */ | ||
2576 | dev->mem_start = card->phys_mem | ||
2577 | + BUF_OFFSET ( txBuffer[i][0][0]); | ||
2578 | dev->mem_end = card->phys_mem | ||
2579 | + BUF_OFFSET ( txBuffer[i][NUM_TX_BUFFER][0]); | ||
2580 | dev->base_addr = card->pci_conf; | ||
2581 | dev->irq = card->irq; | ||
2582 | |||
2583 | dev->tx_queue_len = FST_TX_QUEUE_LEN; | ||
2584 | dev->open = fst_open; | ||
2585 | dev->stop = fst_close; | ||
2586 | dev->do_ioctl = fst_ioctl; | ||
2587 | dev->watchdog_timeo = FST_TX_TIMEOUT; | ||
2588 | dev->tx_timeout = fst_tx_timeout; | ||
2589 | hdlc->attach = fst_attach; | ||
2590 | hdlc->xmit = fst_start_xmit; | ||
2591 | } | ||
2592 | |||
2593 | card->device = pdev; | ||
2594 | |||
2595 | dbg(DBG_PCI, "type %d nports %d irq %d\n", card->type, | ||
2596 | card->nports, card->irq); | ||
2597 | dbg(DBG_PCI, "conf %04x mem %08x ctlmem %08x\n", | ||
2598 | card->pci_conf, card->phys_mem, card->phys_ctlmem); | ||
2599 | |||
2600 | /* Reset the card's processor */ | ||
2601 | fst_cpureset(card); | ||
2602 | card->state = FST_RESET; | ||
2603 | |||
2604 | /* Initialise DMA (if required) */ | ||
2605 | fst_init_dma(card); | ||
2606 | |||
2607 | /* Record driver data for later use */ | ||
2608 | pci_set_drvdata(pdev, card); | ||
2609 | |||
2610 | /* Remainder of card setup */ | ||
2611 | fst_card_array[no_of_cards_added] = card; | ||
2612 | card->card_no = no_of_cards_added++; /* Record instance and bump it */ | ||
2613 | fst_init_card(card); | ||
2614 | if (card->family == FST_FAMILY_TXU) { | ||
2615 | /* | ||
2616 | * Allocate a dma buffer for transmit and receives | ||
2617 | */ | ||
2618 | card->rx_dma_handle_host = | ||
2619 | pci_alloc_consistent(card->device, FST_MAX_MTU, | ||
2620 | &card->rx_dma_handle_card); | ||
2621 | if (card->rx_dma_handle_host == NULL) { | ||
2622 | printk_err("Could not allocate rx dma buffer\n"); | ||
2623 | fst_disable_intr(card); | ||
2624 | pci_release_regions(pdev); | ||
2625 | pci_disable_device(pdev); | ||
2626 | iounmap(card->ctlmem); | ||
2627 | iounmap(card->mem); | ||
2628 | kfree(card); | ||
2629 | return -ENOMEM; | ||
2630 | } | ||
2631 | card->tx_dma_handle_host = | ||
2632 | pci_alloc_consistent(card->device, FST_MAX_MTU, | ||
2633 | &card->tx_dma_handle_card); | ||
2634 | if (card->tx_dma_handle_host == NULL) { | ||
2635 | printk_err("Could not allocate tx dma buffer\n"); | ||
2636 | fst_disable_intr(card); | ||
2637 | pci_release_regions(pdev); | ||
2638 | pci_disable_device(pdev); | ||
2639 | iounmap(card->ctlmem); | ||
2640 | iounmap(card->mem); | ||
2641 | kfree(card); | ||
2642 | return -ENOMEM; | ||
2643 | } | ||
2644 | } | ||
2645 | return 0; /* Success */ | ||
2646 | } | ||
2647 | |||
2648 | /* | ||
2649 | * Cleanup and close down a card | ||
2650 | */ | ||
2651 | static void __devexit | ||
2652 | fst_remove_one(struct pci_dev *pdev) | ||
2653 | { | ||
2654 | struct fst_card_info *card; | ||
2655 | int i; | ||
2656 | |||
2657 | card = pci_get_drvdata(pdev); | ||
2658 | |||
2659 | for (i = 0; i < card->nports; i++) { | ||
2660 | struct net_device *dev = port_to_dev(&card->ports[i]); | ||
2661 | unregister_hdlc_device(dev); | ||
2662 | } | ||
2663 | |||
2664 | fst_disable_intr(card); | ||
2665 | free_irq(card->irq, card); | ||
2666 | |||
2667 | iounmap(card->ctlmem); | ||
2668 | iounmap(card->mem); | ||
2669 | pci_release_regions(pdev); | ||
2670 | if (card->family == FST_FAMILY_TXU) { | ||
2671 | /* | ||
2672 | * Free dma buffers | ||
2673 | */ | ||
2674 | pci_free_consistent(card->device, FST_MAX_MTU, | ||
2675 | card->rx_dma_handle_host, | ||
2676 | card->rx_dma_handle_card); | ||
2677 | pci_free_consistent(card->device, FST_MAX_MTU, | ||
2678 | card->tx_dma_handle_host, | ||
2679 | card->tx_dma_handle_card); | ||
2680 | } | ||
2681 | fst_card_array[card->card_no] = NULL; | ||
2682 | } | ||
2683 | |||
2684 | static struct pci_driver fst_driver = { | ||
2685 | .name = FST_NAME, | ||
2686 | .id_table = fst_pci_dev_id, | ||
2687 | .probe = fst_add_one, | ||
2688 | .remove = __devexit_p(fst_remove_one), | ||
2689 | .suspend = NULL, | ||
2690 | .resume = NULL, | ||
2691 | }; | ||
2692 | |||
2693 | static int __init | ||
2694 | fst_init(void) | ||
2695 | { | ||
2696 | int i; | ||
2697 | |||
2698 | for (i = 0; i < FST_MAX_CARDS; i++) | ||
2699 | fst_card_array[i] = NULL; | ||
2700 | spin_lock_init(&fst_work_q_lock); | ||
2701 | return pci_module_init(&fst_driver); | ||
2702 | } | ||
2703 | |||
2704 | static void __exit | ||
2705 | fst_cleanup_module(void) | ||
2706 | { | ||
2707 | printk_info("FarSync WAN driver unloading\n"); | ||
2708 | pci_unregister_driver(&fst_driver); | ||
2709 | } | ||
2710 | |||
2711 | module_init(fst_init); | ||
2712 | module_exit(fst_cleanup_module); | ||