^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /* drivers/atm/firestream.c - FireStream 155 (MB86697) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * FireStream 50 (MB86695) device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /* Written & (C) 2000 by R.E.Wolff@BitWizard.nl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copied snippets from zatm.c by Werner Almesberger, EPFL LRC/ICA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * and ambassador.c Copyright (C) 1995-1999 Madge Networks Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/poison.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/atm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/atmdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/sonet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/ioport.h> /* for request_region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/uio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "firestream.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int loopback = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int num=0x5a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* According to measurements (but they look suspicious to me!) done in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * '97, 37% of the packets are one cell in size. So it pays to have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * buffers allocated at that size. A large jump in percentage of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * packets occurs at packets around 536 bytes in length. So it also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * pays to have those pre-allocated. Unfortunately, we can't fully
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * take advantage of this as the majority of the packets is likely to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * be TCP/IP (As where obviously the measurement comes from) There the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * link would be opened with say a 1500 byte MTU, and we can't handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * smaller buffers more efficiently than the larger ones. -- REW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Due to the way Linux memory management works, specifying "576" as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * an allocation size here isn't going to help. They are allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * from 1024-byte regions anyway. With the size of the sk_buffs (quite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * large), it doesn't pay to allocate the smallest size (64) -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* This is all guesswork. Hard numbers to back this up or disprove this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * are appreciated. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* The last entry should be about 64k. However, the "buffer size" is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * passed to the chip in a 16 bit field. I don't know how "65536"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * would be interpreted. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define NP FS_NR_FREE_POOLS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int rx_buf_sizes[NP] = {128, 256, 512, 1024, 2048, 4096, 16384, 65520};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* log2: 7 8 9 10 11 12 14 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int rx_pool_sizes[NP] = {1024, 1024, 512, 256, 128, 64, 32, 32};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int rx_pool_sizes[NP] = {128, 128, 128, 64, 64, 64, 32, 32};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* log2: 10 10 9 8 7 6 5 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* sumlog2: 17 18 18 18 18 18 19 21 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* mem allocated: 128k 256k 256k 256k 256k 256k 512k 2M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* tot mem: almost 4M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* NP is shorter, so that it fits on a single line. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #undef NP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Small hardware gotcha:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) The FS50 CAM (VP/VC match registers) always take the lowest channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) number that matches. This is not a problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) However, they also ignore whether the channel is enabled or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) not. This means that if you allocate channel 0 to 1.2 and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) channel 1 to 0.0, then disabeling channel 0 and writing 0 to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) match channel for channel 0 will "steal" the traffic from channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 1, even if you correctly disable channel 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) Workaround:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) - When disabling channels, write an invalid VP/VC value to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) match register. (We use 0xffffffff, which in the worst case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) matches VP/VC = <maxVP>/<maxVC>, but I expect it not to match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) anything as some "when not in use, program to 0" bits are now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) programmed to 1...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) - Don't initialize the match registers to 0, as 0.0 is a valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Optimization hints and tips.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) The FireStream chips are very capable of reducing the amount of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) "interrupt-traffic" for the CPU. This driver requests an interrupt on EVERY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) action. You could try to minimize this a bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) Besides that, the userspace->kernel copy and the PCI bus are the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) performance limiting issues for this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) You could queue up a bunch of outgoing packets without telling the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) FireStream. I'm not sure that's going to win you much though. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) Linux layer won't tell us in advance when it's not going to give us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) any more packets in a while. So this is tricky to implement right without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) introducing extra delays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) -- REW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* The strings that define what the RX queue entry is all about. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Fujitsu: Please tell me which ones can have a pointer to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) freepool descriptor! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static char *res_strings[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) "RX OK: streaming not EOP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "RX OK: streaming EOP",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) "RX OK: Single buffer packet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) "RX OK: packet mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) "RX OK: F4 OAM (end to end)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) "RX OK: F4 OAM (Segment)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) "RX OK: F5 OAM (end to end)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) "RX OK: F5 OAM (Segment)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) "RX OK: RM cell",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) "RX OK: TRANSP cell",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) "RX OK: TRANSPC cell",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) "Unmatched cell",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) "reserved 12",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) "reserved 13",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) "reserved 14",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) "Unrecognized cell",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) "reserved 16",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) "reassembly abort: AAL5 abort",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) "packet purged",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) "packet ageing timeout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) "channel ageing timeout",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) "calculated length error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) "programmed length limit error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) "aal5 crc32 error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) "oam transp or transpc crc10 error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) "reserved 25",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) "reserved 26",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) "reserved 27",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) "reserved 28",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) "reserved 29",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) "reserved 30", /* FIXME: The strings between 30-40 might be wrong. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) "reassembly abort: no buffers",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "receive buffer overflow",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) "change in GFC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) "receive buffer full",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "low priority discard - no receive descriptor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) "low priority discard - missing end of packet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) "reserved 37",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) "reserved 38",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) "reserved 39",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) "reserved 40",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) "reserved 41",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) "reserved 42",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) "reserved 43",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) "reserved 44",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) "reserved 45",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) "reserved 46",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) "reserved 47",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) "reserved 48",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) "reserved 49",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) "reserved 50",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) "reserved 51",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "reserved 52",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) "reserved 53",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) "reserved 54",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) "reserved 55",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) "reserved 56",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) "reserved 57",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) "reserved 58",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) "reserved 59",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) "reserved 60",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) "reserved 61",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) "reserved 62",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) "reserved 63",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static char *irq_bitname[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) "LPCO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) "DPCO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) "RBRQ0_W",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) "RBRQ1_W",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) "RBRQ2_W",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) "RBRQ3_W",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) "RBRQ0_NF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) "RBRQ1_NF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) "RBRQ2_NF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) "RBRQ3_NF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "BFP_SC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) "INIT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) "INIT_ERR",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) "USCEO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) "UPEC0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) "VPFCO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) "CRCCO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) "HECO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) "TBRQ_W",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) "TBRQ_NF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) "CTPQ_E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) "GFC_C0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) "PCI_FTL",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) "CSQ_W",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) "CSQ_NF",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) "EXT_INT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) "RXDMA_S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define PHY_EOF -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define PHY_CLEARALL -2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct reginit_item {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int reg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static struct reginit_item PHY_NTC_INIT[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) { PHY_CLEARALL, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) { 0x12, 0x0001 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) { 0x13, 0x7605 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) { 0x1A, 0x0001 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { 0x1B, 0x0005 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { 0x38, 0x0003 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { 0x39, 0x0006 }, /* changed here to make loopback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { 0x01, 0x5262 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { 0x15, 0x0213 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { 0x00, 0x0003 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { PHY_EOF, 0}, /* -1 signals end of list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* Safetyfeature: If the card interrupts more than this number of times
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) in a jiffy (1/100th of a second) then we just disable the interrupt and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) print a message. This prevents the system from hanging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 150000 packets per second is close to the limit a PC is going to have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) anyway. We therefore have to disable this for production. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #undef IRQ_RATE_LIMIT // 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Interrupts work now. Unlike serial cards, ATM cards don't work all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) that great without interrupts. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #undef FS_POLL_FREQ // 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) This driver can spew a whole lot of debugging output at you. If you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) need maximum performance, you should disable the DEBUG define. To
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) aid in debugging in the field, I'm leaving the compile-time debug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) features enabled, and disable them "runtime". That allows me to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) instruct people with problems to enable debugging without requiring
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) them to recompile... -- REW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define fs_dprintk(f, str...) if (fs_debug & f) printk (str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define fs_dprintk(f, str...) /* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int fs_keystream = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* I didn't forget to set this to zero before shipping. Hit me with a stick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if you get this with the debug default not set to zero again. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int fs_debug = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #define fs_debug 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) module_param(fs_debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) module_param(loopback, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) module_param(num, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) module_param(fs_keystream, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* XXX Add rx_buf_sizes, and rx_pool_sizes As per request Amar. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #define FS_DEBUG_FLOW 0x00000001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) #define FS_DEBUG_OPEN 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #define FS_DEBUG_QUEUE 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #define FS_DEBUG_IRQ 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #define FS_DEBUG_INIT 0x00000010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) #define FS_DEBUG_SEND 0x00000020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) #define FS_DEBUG_PHY 0x00000040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #define FS_DEBUG_CLEANUP 0x00000080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #define FS_DEBUG_QOS 0x00000100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) #define FS_DEBUG_TXQ 0x00000200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) #define FS_DEBUG_ALLOC 0x00000400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #define FS_DEBUG_TXMEM 0x00000800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #define FS_DEBUG_QSIZE 0x00001000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #define func_enter() fs_dprintk(FS_DEBUG_FLOW, "fs: enter %s\n", __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #define func_exit() fs_dprintk(FS_DEBUG_FLOW, "fs: exit %s\n", __func__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static struct fs_dev *fs_boards = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static void my_hd (void *addr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int j, ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) unsigned char *ptr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) printk ("%p ", ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) for (j=0;j < ((len < 16)?len:16);j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) printk ("%02x %s", ptr[j], (j==7)?" ":"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) for ( ;j < 16;j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) printk (" %s", (j==7)?" ":"");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) for (j=0;j < ((len < 16)?len:16);j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ch = ptr[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) printk ("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ptr += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) len -= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #else /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static void my_hd (void *addr, int len){}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #endif /* DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /********** free an skb (as per ATM device driver documentation) **********/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Hmm. If this is ATM specific, why isn't there an ATM routine for this?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * I copied it over from the ambassador driver. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static inline void fs_kfree_skb (struct sk_buff * skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (ATM_SKB(skb)->vcc->pop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ATM_SKB(skb)->vcc->pop (ATM_SKB(skb)->vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) dev_kfree_skb_any (skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* It seems the ATM forum recommends this horribly complicated 16bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * floating point format. Turns out the Ambassador uses the exact same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * encoding. I just copied it over. If Mitch agrees, I'll move it over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * to the atm_misc file or something like that. (and remove it from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * here and the ambassador driver) -- REW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* The good thing about this format is that it is monotonic. So,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) a conversion routine need not be very complicated. To be able to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) round "nearest" we need to take along a few extra bits. Lets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) put these after 16 bits, so that we can just return the top 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) bits of the 32bit number as the result:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int mr (unsigned int rate, int r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) int e = 16+9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static int round[4]={0, 0, 0xffff, 0x8000};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (!rate) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) while (rate & 0xfc000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) rate >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) e++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) while (! (rate & 0xfe000000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) rate <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) e--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) // Now the mantissa is in positions bit 16-25. Excepf for the "hidden 1" that's in bit 26.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) rate &= ~0x02000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) // Next add in the exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) rate |= e << (16+9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) // And perform the rounding:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return (rate + round[r]) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 14 lines-of-code. Compare that with the 120 that the Ambassador
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) guys needed. (would be 8 lines shorter if I'd try to really reduce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) the number of lines:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) int mr (unsigned int rate, int r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) int e = 16+9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static int round[4]={0, 0, 0xffff, 0x8000};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (!rate) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) for (; rate & 0xfc000000 ;rate >>= 1, e++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) for (;!(rate & 0xfe000000);rate <<= 1, e--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return ((rate & ~0x02000000) | (e << (16+9)) + round[r]) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) Exercise for the reader: Remove one more line-of-code, without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) cheating. (Just joining two lines is cheating). (I know it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) possible, don't think you've beat me if you found it... If you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) manage to lose two lines or more, keep me updated! ;-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #define ROUND_UP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) #define ROUND_DOWN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) #define ROUND_NEAREST 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /********** make rate (not quite as much fun as Horizon) **********/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int make_rate(unsigned int rate, int r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) u16 *bits, unsigned int *actual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) unsigned char exp = -1; /* hush gcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned int man = -1; /* hush gcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) fs_dprintk (FS_DEBUG_QOS, "make_rate %u", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* rates in cells per second, ITU format (nasty 16-bit floating-point)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) given 5-bit e and 9-bit m:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) rate = EITHER (1+m/2^9)*2^e OR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) bits = EITHER 1<<14 | e<<9 | m OR 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) (bit 15 is "reserved", bit 14 "non-zero")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) smallest rate is 0 (special representation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) largest rate is (1+511/512)*2^31 = 4290772992 (< 2^32-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) smallest non-zero rate is (1+0/512)*2^0 = 1 (> 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) simple algorithm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) find position of top bit, this gives e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) remove top bit and shift (rounding if feeling clever) by 9-e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* Ambassador ucode bug: please don't set bit 14! so 0 rate not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) representable. // This should move into the ambassador driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) when properly merged. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (rate > 0xffc00000U) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /* larger than largest representable rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (r == ROUND_UP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) exp = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) man = 511;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) } else if (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* representable rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) exp = 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) man = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /* invariant: rate = man*2^(exp-31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) while (!(man & (1<<31))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) exp = exp - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) man = man<<1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* man has top bit set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) rate = (2^31+(man-2^31))*2^(exp-31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) rate = (1+(man-2^31)/2^31)*2^exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) man = man<<1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) man &= 0xffffffffU; /* a nop on 32-bit systems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* rate = (1+man/2^32)*2^exp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) exp is in the range 0 to 31, man is in the range 0 to 2^32-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) time to lose significance... we want m in the range 0 to 2^9-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) rounding presents a minor problem... we first decide which way
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) we are rounding (based on given rounding direction and possibly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) the bits of the mantissa that are to be discarded).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) switch (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) case ROUND_DOWN: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* just truncate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) man = man>>(32-9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) case ROUND_UP: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* check all bits that we are discarding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (man & (~0U>>9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) man = (man>>(32-9)) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (man == (1<<9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* no need to check for round up outside of range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) man = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) exp += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) man = (man>>(32-9));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) case ROUND_NEAREST: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* check msb that we are discarding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (man & (1<<(32-9-1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) man = (man>>(32-9)) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (man == (1<<9)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* no need to check for round up outside of range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) man = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) exp += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) man = (man>>(32-9));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* zero rate - not representable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (r == ROUND_DOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) exp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) man = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) fs_dprintk (FS_DEBUG_QOS, "rate: man=%u, exp=%hu", man, exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) *bits = /* (1<<14) | */ (exp<<9) | man;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (actual)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) *actual = (exp >= 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ? (1 << exp) + (man << (exp-9))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) : (1 << exp) + ((man + (1<<(9-exp-1))) >> (9-exp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* FireStream access routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* For DEEP-DOWN debugging these can be rigged to intercept accesses to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) certain registers or to just log all accesses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static inline void write_fs (struct fs_dev *dev, int offset, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) writel (val, dev->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static inline u32 read_fs (struct fs_dev *dev, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return readl (dev->base + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static inline struct FS_QENTRY *get_qentry (struct fs_dev *dev, struct queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return bus_to_virt (read_fs (dev, Q_WP(q->offset)) & Q_ADDR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static void submit_qentry (struct fs_dev *dev, struct queue *q, struct FS_QENTRY *qe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) u32 wp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct FS_QENTRY *cqe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* XXX Sanity check: the write pointer can be checked to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) still the same as the value passed as qe... -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /* udelay (5); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) while ((wp = read_fs (dev, Q_WP (q->offset))) & Q_FULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) fs_dprintk (FS_DEBUG_TXQ, "Found queue at %x full. Waiting.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) q->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) schedule ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) wp &= ~0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) cqe = bus_to_virt (wp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (qe != cqe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) fs_dprintk (FS_DEBUG_TXQ, "q mismatch! %p %p\n", qe, cqe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) write_fs (dev, Q_WP(q->offset), Q_INCWRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (!(c++ % 100))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) int rp, wp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) rp = read_fs (dev, Q_RP(q->offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) wp = read_fs (dev, Q_WP(q->offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) fs_dprintk (FS_DEBUG_TXQ, "q at %d: %x-%x: %x entries.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) q->offset, rp, wp, wp-rp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) #ifdef DEBUG_EXTRA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static struct FS_QENTRY pq[60];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static int qp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static struct FS_BPENTRY dq[60];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static int qd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static void *da[60];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static void submit_queue (struct fs_dev *dev, struct queue *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) u32 cmd, u32 p1, u32 p2, u32 p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct FS_QENTRY *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) qe = get_qentry (dev, q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) qe->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) qe->p0 = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) qe->p1 = p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) qe->p2 = p3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) submit_qentry (dev, q, qe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #ifdef DEBUG_EXTRA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) pq[qp].cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) pq[qp].p0 = p1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) pq[qp].p1 = p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pq[qp].p2 = p3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) qp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (qp >= 60) qp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Test the "other" way one day... -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) #define submit_command submit_queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static void submit_command (struct fs_dev *dev, struct queue *q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) u32 cmd, u32 p1, u32 p2, u32 p3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) write_fs (dev, CMDR0, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) write_fs (dev, CMDR1, p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) write_fs (dev, CMDR2, p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) write_fs (dev, CMDR3, p3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static void process_return_queue (struct fs_dev *dev, struct queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) long rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct FS_QENTRY *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) void *tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) while (!((rq = read_fs (dev, Q_RP(q->offset))) & Q_EMPTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) fs_dprintk (FS_DEBUG_QUEUE, "reaping return queue entry at %lx\n", rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) qe = bus_to_virt (rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) fs_dprintk (FS_DEBUG_QUEUE, "queue entry: %08x %08x %08x %08x. (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) qe->cmd, qe->p0, qe->p1, qe->p2, STATUS_CODE (qe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) switch (STATUS_CODE (qe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) tc = bus_to_virt (qe->p0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) fs_dprintk (FS_DEBUG_ALLOC, "Free tc: %p\n", tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) kfree (tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) write_fs (dev, Q_RP(q->offset), Q_INCWRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static void process_txdone_queue (struct fs_dev *dev, struct queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) long rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct FS_QENTRY *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) struct FS_BPENTRY *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) while (!((rq = read_fs (dev, Q_RP(q->offset))) & Q_EMPTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) fs_dprintk (FS_DEBUG_QUEUE, "reaping txdone entry at %lx\n", rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) qe = bus_to_virt (rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) fs_dprintk (FS_DEBUG_QUEUE, "queue entry: %08x %08x %08x %08x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) qe->cmd, qe->p0, qe->p1, qe->p2, STATUS_CODE (qe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (STATUS_CODE (qe) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) fs_dprintk (FS_DEBUG_TXMEM, "queue entry: %08x %08x %08x %08x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) qe->cmd, qe->p0, qe->p1, qe->p2, STATUS_CODE (qe));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) switch (STATUS_CODE (qe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) case 0x01: /* This is for AAL0 where we put the chip in streaming mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case 0x02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* Process a real txdone entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) tmp = qe->p0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (tmp & 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) printk (KERN_WARNING "td not aligned: %ld\n", tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) tmp &= ~0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) td = bus_to_virt (tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) fs_dprintk (FS_DEBUG_QUEUE, "Pool entry: %08x %08x %08x %08x %p.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) td->flags, td->next, td->bsa, td->aal_bufsize, td->skb );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) skb = td->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (skb == FS_VCC (ATM_SKB(skb)->vcc)->last_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) FS_VCC (ATM_SKB(skb)->vcc)->last_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) wake_up_interruptible (& FS_VCC (ATM_SKB(skb)->vcc)->close_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) td->dev->ntxpckts--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static int c=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (!(c++ % 100)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) fs_dprintk (FS_DEBUG_QSIZE, "[%d]", td->dev->ntxpckts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) atomic_inc(&ATM_SKB(skb)->vcc->stats->tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) fs_dprintk (FS_DEBUG_TXMEM, "i");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) fs_dprintk (FS_DEBUG_ALLOC, "Free t-skb: %p\n", skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) fs_kfree_skb (skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) fs_dprintk (FS_DEBUG_ALLOC, "Free trans-d: %p\n", td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) memset (td, ATM_POISON_FREE, sizeof(struct FS_BPENTRY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) kfree (td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) /* Here we get the tx purge inhibit command ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /* Action, I believe, is "don't do anything". -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) write_fs (dev, Q_RP(q->offset), Q_INCWRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static void process_incoming (struct fs_dev *dev, struct queue *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) long rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct FS_QENTRY *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct FS_BPENTRY *pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) unsigned int channo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct atm_vcc *atm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) while (!((rq = read_fs (dev, Q_RP(q->offset))) & Q_EMPTY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) fs_dprintk (FS_DEBUG_QUEUE, "reaping incoming queue entry at %lx\n", rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) qe = bus_to_virt (rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) fs_dprintk (FS_DEBUG_QUEUE, "queue entry: %08x %08x %08x %08x. ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) qe->cmd, qe->p0, qe->p1, qe->p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) fs_dprintk (FS_DEBUG_QUEUE, "-> %x: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) STATUS_CODE (qe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) res_strings[STATUS_CODE(qe)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) pe = bus_to_virt (qe->p0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) fs_dprintk (FS_DEBUG_QUEUE, "Pool entry: %08x %08x %08x %08x %p %p.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) pe->flags, pe->next, pe->bsa, pe->aal_bufsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) pe->skb, pe->fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) channo = qe->cmd & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (channo < dev->nchannels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) atm_vcc = dev->atm_vccs[channo];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) atm_vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /* Single buffer packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) switch (STATUS_CODE (qe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) case 0x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /* Fall through for streaming mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case 0x2:/* Packet received OK.... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (atm_vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) skb = pe->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) pe->fp->n--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) fs_dprintk (FS_DEBUG_QUEUE, "Got skb: %p\n", skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (FS_DEBUG_QUEUE & fs_debug) my_hd (bus_to_virt (pe->bsa), 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) skb_put (skb, qe->p1 & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) ATM_SKB(skb)->vcc = atm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) atomic_inc(&atm_vcc->stats->rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) __net_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) atm_vcc->push (atm_vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) kfree (pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) printk (KERN_ERR "Got a receive on a non-open channel %d.\n", channo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case 0x17:/* AAL 5 CRC32 error. IFF the length field is nonzero, a buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) has been consumed and needs to be processed. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (qe->p1 & 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) pe = bus_to_virt (qe->p0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) pe->fp->n--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", pe->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) dev_kfree_skb_any (pe->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) kfree (pe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (atm_vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) atomic_inc(&atm_vcc->stats->rx_drop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) case 0x1f: /* Reassembly abort: no buffers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /* Silently increment error counter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (atm_vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) atomic_inc(&atm_vcc->stats->rx_drop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) default: /* Hmm. Haven't written the code to handle the others yet... -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) printk (KERN_WARNING "Don't know what to do with RX status %x: %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) STATUS_CODE(qe), res_strings[STATUS_CODE (qe)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) write_fs (dev, Q_RP(q->offset), Q_INCWRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) #define DO_DIRECTION(tp) ((tp)->traffic_class != ATM_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int fs_open(struct atm_vcc *atm_vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct fs_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct fs_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct fs_transmit_config *tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct atm_trafprm * txtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct atm_trafprm * rxtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* struct fs_receive_config *rc;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* struct FS_QENTRY *qe; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) int bfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) unsigned short tmc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) short vpi = atm_vcc->vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) int vci = atm_vcc->vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) dev = FS_DEV(atm_vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) fs_dprintk (FS_DEBUG_OPEN, "fs: open on dev: %p, vcc at %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) dev, atm_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) set_bit(ATM_VF_ADDR, &atm_vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if ((atm_vcc->qos.aal != ATM_AAL5) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) (atm_vcc->qos.aal != ATM_AAL2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return -EINVAL; /* XXX AAL0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) fs_dprintk (FS_DEBUG_OPEN, "fs: (itf %d): open %d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) atm_vcc->dev->number, atm_vcc->vpi, atm_vcc->vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* XXX handle qos parameters (rate limiting) ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) vcc = kmalloc(sizeof(struct fs_vcc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) fs_dprintk (FS_DEBUG_ALLOC, "Alloc VCC: %p(%zd)\n", vcc, sizeof(struct fs_vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) clear_bit(ATM_VF_ADDR, &atm_vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) atm_vcc->dev_data = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) vcc->last_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) init_waitqueue_head (&vcc->close_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) txtp = &atm_vcc->qos.txtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) rxtp = &atm_vcc->qos.rxtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (!test_bit(ATM_VF_PARTIAL, &atm_vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (IS_FS50(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* Increment the channel numer: take a free one next time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) for (to=33;to;to--, dev->channo++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /* We only have 32 channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (dev->channo >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) dev->channo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* If we need to do RX, AND the RX is inuse, try the next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (DO_DIRECTION(rxtp) && dev->atm_vccs[dev->channo])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* If we need to do TX, AND the TX is inuse, try the next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (DO_DIRECTION(txtp) && test_bit (dev->channo, dev->tx_inuse))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* Ok, both are free! (or not needed) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (!to) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) printk ("No more free channels for FS50..\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) kfree(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) vcc->channo = dev->channo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dev->channo &= dev->channel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) vcc->channo = (vpi << FS155_VCI_BITS) | (vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (((DO_DIRECTION(rxtp) && dev->atm_vccs[vcc->channo])) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) ( DO_DIRECTION(txtp) && test_bit (vcc->channo, dev->tx_inuse))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) printk ("Channel is in use for FS155.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) kfree(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) fs_dprintk (FS_DEBUG_OPEN, "OK. Allocated channel %x(%d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) vcc->channo, vcc->channo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (DO_DIRECTION (txtp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) tc = kmalloc (sizeof (struct fs_transmit_config), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) fs_dprintk (FS_DEBUG_ALLOC, "Alloc tc: %p(%zd)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) tc, sizeof (struct fs_transmit_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (!tc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) fs_dprintk (FS_DEBUG_OPEN, "fs: can't alloc transmit_config.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) kfree(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /* Allocate the "open" entry from the high priority txq. This makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) it most likely that the chip will notice it. It also prevents us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) from having to wait for completion. On the other hand, we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) need to wait for completion anyway, to see if it completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) successfully. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) switch (atm_vcc->qos.aal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) case ATM_AAL2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) case ATM_AAL0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) tc->flags = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) | TC_FLAGS_TRANSPARENT_PAYLOAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) | TC_FLAGS_PACKET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) | (1 << 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) | TC_FLAGS_TYPE_UBR /* XXX Change to VBR -- PVDL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) | TC_FLAGS_CAL0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) case ATM_AAL5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) tc->flags = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) | TC_FLAGS_AAL5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) | TC_FLAGS_PACKET /* ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) | TC_FLAGS_TYPE_CBR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) | TC_FLAGS_CAL0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) printk ("Unknown aal: %d\n", atm_vcc->qos.aal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) tc->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* Docs are vague about this atm_hdr field. By the way, the FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * chip makes odd errors if lower bits are set.... -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) tc->atm_hdr = (vpi << 20) | (vci << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) tmc0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) int pcr = atm_pcr_goal (txtp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /* XXX Hmm. officially we're only allowed to do this if rounding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) is round_down -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (IS_FS50(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (pcr > 51840000/53/8) pcr = 51840000/53/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (pcr > 155520000/53/8) pcr = 155520000/53/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (!pcr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /* no rate cap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) tmc0 = IS_FS50(dev)?0x61BE:0x64c9; /* Just copied over the bits from Fujitsu -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (pcr < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) r = ROUND_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) pcr = -pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) r = ROUND_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) error = make_rate (pcr, r, &tmc0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) kfree(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) kfree(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) fs_dprintk (FS_DEBUG_OPEN, "pcr = %d.\n", pcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) tc->TMC[0] = tmc0 | 0x4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) tc->TMC[1] = 0; /* Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) tc->TMC[2] = 0; /* Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) tc->TMC[3] = 0; /* Unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) tc->spec = 0; /* UTOPIA address, UDF, HEC: Unused -> 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) tc->rtag[0] = 0; /* What should I do with routing tags???
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) -- Not used -- AS -- Thanks -- REW*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) tc->rtag[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) tc->rtag[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (fs_debug & FS_DEBUG_OPEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) fs_dprintk (FS_DEBUG_OPEN, "TX config record:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) my_hd (tc, sizeof (*tc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) /* We now use the "submit_command" function to submit commands to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) the firestream. There is a define up near the definition of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) that routine that switches this routine between immediate write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) to the immediate command registers and queuing the commands in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) the HPTXQ for execution. This last technique might be more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) efficient if we know we're going to submit a whole lot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) commands in one go, but this driver is not setup to be able to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) use such a construct. So it probably doen't matter much right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) now. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* The command is IMMediate and INQueue. The parameters are out-of-line.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) QE_CMD_CONFIG_TX | QE_CMD_IMM_INQ | vcc->channo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) virt_to_bus (tc), 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) QE_CMD_TX_EN | QE_CMD_IMM_INQ | vcc->channo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) set_bit (vcc->channo, dev->tx_inuse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (DO_DIRECTION (rxtp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) dev->atm_vccs[vcc->channo] = atm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) for (bfp = 0;bfp < FS_NR_FREE_POOLS; bfp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (atm_vcc->qos.rxtp.max_sdu <= dev->rx_fp[bfp].bufsize) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (bfp >= FS_NR_FREE_POOLS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) fs_dprintk (FS_DEBUG_OPEN, "No free pool fits sdu: %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) atm_vcc->qos.rxtp.max_sdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* XXX Cleanup? -- Would just calling fs_close work??? -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* XXX clear tx inuse. Close TX part? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) dev->atm_vccs[vcc->channo] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) kfree (vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) switch (atm_vcc->qos.aal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) case ATM_AAL0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) case ATM_AAL2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) QE_CMD_CONFIG_RX | QE_CMD_IMM_INQ | vcc->channo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) RC_FLAGS_TRANSP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) RC_FLAGS_BFPS_BFP * bfp |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) RC_FLAGS_RXBM_PSB, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) case ATM_AAL5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) QE_CMD_CONFIG_RX | QE_CMD_IMM_INQ | vcc->channo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) RC_FLAGS_AAL5 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) RC_FLAGS_BFPS_BFP * bfp |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) RC_FLAGS_RXBM_PSB, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (IS_FS50 (dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) QE_CMD_REG_WR | QE_CMD_IMM_INQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 0x80 + vcc->channo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) (vpi << 16) | vci, 0 ); /* XXX -- Use defines. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) QE_CMD_RX_EN | QE_CMD_IMM_INQ | vcc->channo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* Indicate we're done! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) set_bit(ATM_VF_READY, &atm_vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) static void fs_close(struct atm_vcc *atm_vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct fs_dev *dev = FS_DEV (atm_vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct fs_vcc *vcc = FS_VCC (atm_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct atm_trafprm * txtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct atm_trafprm * rxtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) clear_bit(ATM_VF_READY, &atm_vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) fs_dprintk (FS_DEBUG_QSIZE, "--==**[%d]**==--", dev->ntxpckts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (vcc->last_skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) fs_dprintk (FS_DEBUG_QUEUE, "Waiting for skb %p to be sent.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) vcc->last_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* We're going to wait for the last packet to get sent on this VC. It would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) be impolite not to send them don't you think?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) XXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) We don't know which packets didn't get sent. So if we get interrupted in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) this sleep_on, we'll lose any reference to these packets. Memory leak!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) On the other hand, it's awfully convenient that we can abort a "close" that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) is taking too long. Maybe just use non-interruptible sleep on? -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) wait_event_interruptible(vcc->close_wait, !vcc->last_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) txtp = &atm_vcc->qos.txtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) rxtp = &atm_vcc->qos.rxtp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) /* See App note XXX (Unpublished as of now) for the reason for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) removal of the "CMD_IMM_INQ" part of the TX_PURGE_INH... -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (DO_DIRECTION (txtp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) QE_CMD_TX_PURGE_INH | /*QE_CMD_IMM_INQ|*/ vcc->channo, 0,0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) clear_bit (vcc->channo, dev->tx_inuse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (DO_DIRECTION (rxtp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) QE_CMD_RX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) dev->atm_vccs [vcc->channo] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /* This means that this is configured as a receive channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (IS_FS50 (dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /* Disable the receive filter. Is 0/0 indeed an invalid receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) channel? -- REW. Yes it is. -- Hang. Ok. I'll use -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) (0xfff...) -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) QE_CMD_REG_WR | QE_CMD_IMM_INQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 0x80 + vcc->channo, -1, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) fs_dprintk (FS_DEBUG_ALLOC, "Free vcc: %p\n", vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) kfree (vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static int fs_send (struct atm_vcc *atm_vcc, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct fs_dev *dev = FS_DEV (atm_vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct fs_vcc *vcc = FS_VCC (atm_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct FS_BPENTRY *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) fs_dprintk (FS_DEBUG_TXMEM, "I");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) fs_dprintk (FS_DEBUG_SEND, "Send: atm_vcc %p skb %p vcc %p dev %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) atm_vcc, skb, vcc, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) fs_dprintk (FS_DEBUG_ALLOC, "Alloc t-skb: %p (atm_send)\n", skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) ATM_SKB(skb)->vcc = atm_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) vcc->last_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) td = kmalloc (sizeof (struct FS_BPENTRY), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) fs_dprintk (FS_DEBUG_ALLOC, "Alloc transd: %p(%zd)\n", td, sizeof (struct FS_BPENTRY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (!td) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) /* Oops out of mem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) fs_dprintk (FS_DEBUG_SEND, "first word in buffer: %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) *(int *) skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) td->flags = TD_EPI | TD_DATA | skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) td->next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) td->bsa = virt_to_bus (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) td->skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) td->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) dev->ntxpckts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) #ifdef DEBUG_EXTRA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) da[qd] = td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) dq[qd].flags = td->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) dq[qd].next = td->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) dq[qd].bsa = td->bsa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) dq[qd].skb = td->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) dq[qd].dev = td->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) qd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (qd >= 60) qd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) submit_queue (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) QE_TRANSMIT_DE | vcc->channo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) virt_to_bus (td), 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) virt_to_bus (td));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) fs_dprintk (FS_DEBUG_QUEUE, "in send: txq %d txrq %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) read_fs (dev, Q_EA (dev->hp_txq.offset)) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) read_fs (dev, Q_SA (dev->hp_txq.offset)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) read_fs (dev, Q_EA (dev->tx_relq.offset)) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) read_fs (dev, Q_SA (dev->tx_relq.offset)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* Some function placeholders for functions we don't yet support. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static int fs_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) void __user *optval,int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) void __user *optval,unsigned int optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static void fs_phy_put(struct atm_dev *dev,unsigned char value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static unsigned char fs_phy_get(struct atm_dev *dev,unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static int fs_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) static const struct atmdev_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .open = fs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .close = fs_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .send = fs_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* ioctl: fs_ioctl, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) /* change_qos: fs_change_qos, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) /* For now implement these internally here... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) /* phy_put: fs_phy_put, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) /* phy_get: fs_phy_get, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) static void undocumented_pci_fix(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) u32 tint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /* The Windows driver says: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) /* Switch off FireStream Retry Limit Threshold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /* The register at 0x28 is documented as "reserved", no further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) comments. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) pci_read_config_dword (pdev, 0x28, &tint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (tint != 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) tint = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) pci_write_config_dword (pdev, 0x28, tint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * PHY routines *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) static void write_phy(struct fs_dev *dev, int regnum, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) submit_command (dev, &dev->hp_txq, QE_CMD_PRP_WR | QE_CMD_IMM_INQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) regnum, val, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) static int init_phy(struct fs_dev *dev, struct reginit_item *reginit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) while (reginit->reg != PHY_EOF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (reginit->reg == PHY_CLEARALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /* "PHY_CLEARALL means clear all registers. Numregisters is in "val". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) for (i=0;i<reginit->val;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) write_phy (dev, i, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) write_phy (dev, reginit->reg, reginit->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) reginit++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static void reset_chip (struct fs_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) write_fs (dev, SARMODE0, SARMODE0_SRTS0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) /* Undocumented delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) udelay (128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) /* The "internal registers are documented to all reset to zero, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) comments & code in the Windows driver indicates that the pools are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) NOT reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) for (i=0;i < FS_NR_FREE_POOLS;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) write_fs (dev, FP_CNF (RXB_FP(i)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) write_fs (dev, FP_SA (RXB_FP(i)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) write_fs (dev, FP_EA (RXB_FP(i)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) write_fs (dev, FP_CNT (RXB_FP(i)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) write_fs (dev, FP_CTU (RXB_FP(i)), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) /* The same goes for the match channel registers, although those are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) NOT documented that way in the Windows driver. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) /* The Windows driver DOES write 0 to these registers somewhere in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) the init sequence. However, a small hardware-feature, will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) prevent reception of data on VPI/VCI = 0/0 (Unless the channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) allocated happens to have no disabled channels that have a lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) number. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) /* Clear the match channel registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (IS_FS50 (dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) for (i=0;i<FS50_NR_CHANNELS;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) write_fs (dev, 0x200 + i * 4, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static void *aligned_kmalloc(int size, gfp_t flags, int alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) void *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (alignment <= 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) t = kmalloc (size, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if ((unsigned long)t & (alignment-1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) printk ("Kmalloc doesn't align things correctly! %p\n", t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) kfree (t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return aligned_kmalloc (size, flags, alignment * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) printk (KERN_ERR "Request for > 0x10 alignment not yet implemented (hard!)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) static int init_q(struct fs_dev *dev, struct queue *txq, int queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) int nentries, int is_rq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) int sz = nentries * sizeof (struct FS_QENTRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) struct FS_QENTRY *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) fs_dprintk (FS_DEBUG_INIT, "Initializing queue at %x: %d entries:\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) queue, nentries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) p = aligned_kmalloc (sz, GFP_KERNEL, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) fs_dprintk (FS_DEBUG_ALLOC, "Alloc queue: %p(%d)\n", p, sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (!p) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) write_fs (dev, Q_SA(queue), virt_to_bus(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) write_fs (dev, Q_EA(queue), virt_to_bus(p+nentries-1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) write_fs (dev, Q_WP(queue), virt_to_bus(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) write_fs (dev, Q_RP(queue), virt_to_bus(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (is_rq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /* Configuration for the receive queue: 0: interrupt immediately,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) no pre-warning to empty queues: We do our best to keep the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) queue filled anyway. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) write_fs (dev, Q_CNF(queue), 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) txq->sa = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) txq->ea = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) txq->offset = queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) static int init_fp(struct fs_dev *dev, struct freepool *fp, int queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) int bufsize, int nr_buffers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) fs_dprintk (FS_DEBUG_INIT, "Initializing free pool at %x:\n", queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) write_fs (dev, FP_CNF(queue), (bufsize * RBFP_RBS) | RBFP_RBSVAL | RBFP_CME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) write_fs (dev, FP_SA(queue), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) write_fs (dev, FP_EA(queue), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) write_fs (dev, FP_CTU(queue), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) write_fs (dev, FP_CNT(queue), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) fp->offset = queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) fp->bufsize = bufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) fp->nr_buffers = nr_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) static inline int nr_buffers_in_freepool (struct fs_dev *dev, struct freepool *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) /* This seems to be unreliable.... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) return read_fs (dev, FP_CNT (fp->offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return fp->n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) /* Check if this gets going again if a pool ever runs out. -- Yes, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) does. I've seen "receive abort: no buffers" and things started
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) working again after that... -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static void top_off_fp (struct fs_dev *dev, struct freepool *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) gfp_t gfp_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) struct FS_BPENTRY *qe, *ne;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) u32 qe_tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) fs_dprintk (FS_DEBUG_QUEUE, "Topping off queue at %x (%d-%d/%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) fp->offset, read_fs (dev, FP_CNT (fp->offset)), fp->n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) fp->nr_buffers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) while (nr_buffers_in_freepool(dev, fp) < fp->nr_buffers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) skb = alloc_skb (fp->bufsize, gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-skb: %p(%d)\n", skb, fp->bufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (!skb) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) ne = kmalloc (sizeof (struct FS_BPENTRY), gfp_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-d: %p(%zd)\n", ne, sizeof (struct FS_BPENTRY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (!ne) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) dev_kfree_skb_any (skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) fs_dprintk (FS_DEBUG_QUEUE, "Adding skb %p desc %p -> %p(%p) ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) skb, ne, skb->data, skb->head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) ne->flags = FP_FLAGS_EPI | fp->bufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) ne->next = virt_to_bus (NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) ne->bsa = virt_to_bus (skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) ne->aal_bufsize = fp->bufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) ne->skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) ne->fp = fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) * FIXME: following code encodes and decodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * machine pointers (could be 64-bit) into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * 32-bit register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) qe_tmp = read_fs (dev, FP_EA(fp->offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) fs_dprintk (FS_DEBUG_QUEUE, "link at %x\n", qe_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (qe_tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) qe = bus_to_virt ((long) qe_tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) qe->next = virt_to_bus(ne);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) qe->flags &= ~FP_FLAGS_EPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) write_fs (dev, FP_SA(fp->offset), virt_to_bus(ne));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) write_fs (dev, FP_EA(fp->offset), virt_to_bus (ne));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) fp->n++; /* XXX Atomic_inc? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) write_fs (dev, FP_CTU(fp->offset), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) fs_dprintk (FS_DEBUG_QUEUE, "Added %d entries. \n", n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) static void free_queue(struct fs_dev *dev, struct queue *txq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) write_fs (dev, Q_SA(txq->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) write_fs (dev, Q_EA(txq->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) write_fs (dev, Q_RP(txq->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) write_fs (dev, Q_WP(txq->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /* Configuration ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) fs_dprintk (FS_DEBUG_ALLOC, "Free queue: %p\n", txq->sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) kfree (txq->sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) static void free_freepool(struct fs_dev *dev, struct freepool *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) write_fs (dev, FP_CNF(fp->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) write_fs (dev, FP_SA (fp->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) write_fs (dev, FP_EA (fp->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) write_fs (dev, FP_CNT(fp->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) write_fs (dev, FP_CTU(fp->offset), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) static irqreturn_t fs_irq (int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) struct fs_dev *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) status = read_fs (dev, ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (!status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) #ifdef IRQ_RATE_LIMIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) /* Aaargh! I'm ashamed. This costs more lines-of-code than the actual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) interrupt routine!. (Well, used to when I wrote that comment) -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) static int lastjif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) static int nintr=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (lastjif == jiffies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (++nintr > IRQ_RATE_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) free_irq (dev->irq, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) printk (KERN_ERR "fs: Too many interrupts. Turning off interrupt %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) lastjif = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) nintr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) fs_dprintk (FS_DEBUG_QUEUE, "in intr: txq %d txrq %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) read_fs (dev, Q_EA (dev->hp_txq.offset)) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) read_fs (dev, Q_SA (dev->hp_txq.offset)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) read_fs (dev, Q_EA (dev->tx_relq.offset)) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) read_fs (dev, Q_SA (dev->tx_relq.offset)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) /* print the bits in the ISR register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (fs_debug & FS_DEBUG_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* The FS_DEBUG things are unnecessary here. But this way it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) clear for grep that these are debug prints. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) fs_dprintk (FS_DEBUG_IRQ, "IRQ status:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) for (i=0;i<27;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) if (status & (1 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) fs_dprintk (FS_DEBUG_IRQ, " %s", irq_bitname[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) fs_dprintk (FS_DEBUG_IRQ, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (status & ISR_RBRQ0_W) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (0)!!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) process_incoming (dev, &dev->rx_rq[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) /* items mentioned on RBRQ0 are from FP 0 or 1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) top_off_fp (dev, &dev->rx_fp[0], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) top_off_fp (dev, &dev->rx_fp[1], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) if (status & ISR_RBRQ1_W) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (1)!!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) process_incoming (dev, &dev->rx_rq[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) top_off_fp (dev, &dev->rx_fp[2], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) top_off_fp (dev, &dev->rx_fp[3], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (status & ISR_RBRQ2_W) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (2)!!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) process_incoming (dev, &dev->rx_rq[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) top_off_fp (dev, &dev->rx_fp[4], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) top_off_fp (dev, &dev->rx_fp[5], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (status & ISR_RBRQ3_W) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (3)!!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) process_incoming (dev, &dev->rx_rq[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) top_off_fp (dev, &dev->rx_fp[6], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) top_off_fp (dev, &dev->rx_fp[7], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (status & ISR_CSQ_W) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) fs_dprintk (FS_DEBUG_IRQ, "Command executed ok!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) process_return_queue (dev, &dev->st_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (status & ISR_TBRQ_W) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) fs_dprintk (FS_DEBUG_IRQ, "Data transmitted!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) process_txdone_queue (dev, &dev->tx_relq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) #ifdef FS_POLL_FREQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static void fs_poll (struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) struct fs_dev *dev = from_timer(dev, t, timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) fs_irq (0, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) dev->timer.expires = jiffies + FS_POLL_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) add_timer (&dev->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static int fs_init(struct fs_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) struct pci_dev *pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) int isr, to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) pci_dev = dev->pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) printk (KERN_INFO "found a FireStream %d card, base %16llx, irq%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) IS_FS50(dev)?50:155,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) (unsigned long long)pci_resource_start(pci_dev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) dev->pci_dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) if (fs_debug & FS_DEBUG_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) my_hd ((unsigned char *) dev, sizeof (*dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) undocumented_pci_fix (pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) dev->hw_base = pci_resource_start(pci_dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) dev->base = ioremap(dev->hw_base, 0x1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (!dev->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) reset_chip (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) write_fs (dev, SARMODE0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) | (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) | (1 * SARMODE0_INTMODE_READCLEAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) | (1 * SARMODE0_CWRE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) | (IS_FS50(dev) ? SARMODE0_PRPWT_FS50_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) SARMODE0_PRPWT_FS155_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) | (1 * SARMODE0_CALSUP_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) | (IS_FS50(dev) ? (0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) | SARMODE0_RXVCS_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) | SARMODE0_ABRVCS_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) | SARMODE0_TXVCS_32):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) (0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) | SARMODE0_RXVCS_1k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) | SARMODE0_ABRVCS_1k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) | SARMODE0_TXVCS_1k)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) /* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 1ms. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) to = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) while (--to) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) isr = read_fs (dev, ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) /* This bit is documented as "RESERVED" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (isr & ISR_INIT_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) printk (KERN_ERR "Error initializing the FS... \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) goto unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) if (isr & ISR_INIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) fs_dprintk (FS_DEBUG_INIT, "Ha! Initialized OK!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) /* Try again after 10ms. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (!to) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) printk (KERN_ERR "timeout initializing the FS... \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) goto unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) /* XXX fix for fs155 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) dev->channel_mask = 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) dev->channo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) /* AN3: 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) write_fs (dev, SARMODE1, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) | (fs_keystream * SARMODE1_DEFHEC) /* XXX PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) | ((loopback == 1) * SARMODE1_TSTLP) /* XXX Loopback mode enable... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) | (1 * SARMODE1_DCRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) | (1 * SARMODE1_DCOAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) | (0 * SARMODE1_OAMCRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) | (0 * SARMODE1_DUMPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) | (0 * SARMODE1_GPLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) | (0 * SARMODE1_GNAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) | (0 * SARMODE1_GVAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) | (0 * SARMODE1_GPAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) | (1 * SARMODE1_GPRI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) | (0 * SARMODE1_PMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) | (0 * SARMODE1_GFCR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) | (1 * SARMODE1_HECM2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) | (1 * SARMODE1_HECM1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) | (1 * SARMODE1_HECM0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) | (1 << 12) /* That's what hang's driver does. Program to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) | (0 * 0xff) /* XXX FS155 */);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) /* Cal prescale etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) /* AN3: 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) write_fs (dev, TMCONF, 0x0000000f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) write_fs (dev, CALPRESCALE, 0x01010101 * num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) write_fs (dev, 0x80, 0x000F00E4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) /* AN3: 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) write_fs (dev, CELLOSCONF, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) | ( 0 * CELLOSCONF_CEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) | ( CELLOSCONF_SC1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) | (0x80 * CELLOSCONF_COBS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) | (num * CELLOSCONF_COPK) /* Changed from 0xff to 0x5a */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) | (num * CELLOSCONF_COST));/* after a hint from Hang.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) * performance jumped 50->70... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) /* Magic value by Hang */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) write_fs (dev, CELLOSCONF_COST, 0x0B809191);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) if (IS_FS50 (dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) write_fs (dev, RAS0, RAS0_DCD_XHLT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) dev->atm_dev->ci_range.vpi_bits = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) dev->atm_dev->ci_range.vci_bits = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) dev->nchannels = FS50_NR_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) write_fs (dev, RAS0, RAS0_DCD_XHLT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) | (((1 << FS155_VPI_BITS) - 1) * RAS0_VPSEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) | (((1 << FS155_VCI_BITS) - 1) * RAS0_VCSEL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /* We can chose the split arbitrarily. We might be able to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) support more. Whatever. This should do for now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) dev->atm_dev->ci_range.vpi_bits = FS155_VPI_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) dev->atm_dev->ci_range.vci_bits = FS155_VCI_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) /* Address bits we can't use should be compared to 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) write_fs (dev, RAC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) /* Manual (AN9, page 6) says ASF1=0 means compare Utopia address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) * too. I can't find ASF1 anywhere. Anyway, we AND with just the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) * other bits, then compare with 0, which is exactly what we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) * want. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) write_fs (dev, RAM, (1 << (28 - FS155_VPI_BITS - FS155_VCI_BITS)) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) dev->nchannels = FS155_NR_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) dev->atm_vccs = kcalloc (dev->nchannels, sizeof (struct atm_vcc *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%zd)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (!dev->atm_vccs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) printk (KERN_WARNING "Couldn't allocate memory for VCC buffers. Woops!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) /* XXX Clean up..... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) goto unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) dev->tx_inuse = kzalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) fs_dprintk (FS_DEBUG_ALLOC, "Alloc tx_inuse: %p(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) dev->atm_vccs, dev->nchannels / 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) if (!dev->tx_inuse) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) printk (KERN_WARNING "Couldn't allocate memory for tx_inuse bits!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /* XXX Clean up..... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) goto unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) /* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /* -- RAS2 : FS50 only: Default is OK. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) /* DMAMODE, default should be OK. -- REW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) write_fs (dev, DMAMR, DMAMR_TX_MODE_FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) init_q (dev, &dev->hp_txq, TX_PQ(TXQ_HP), TXQ_NENTRIES, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) init_q (dev, &dev->lp_txq, TX_PQ(TXQ_LP), TXQ_NENTRIES, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) init_q (dev, &dev->tx_relq, TXB_RQ, TXQ_NENTRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) init_q (dev, &dev->st_q, ST_Q, TXQ_NENTRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) for (i=0;i < FS_NR_FREE_POOLS;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) init_fp (dev, &dev->rx_fp[i], RXB_FP(i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) rx_buf_sizes[i], rx_pool_sizes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) top_off_fp (dev, &dev->rx_fp[i], GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) for (i=0;i < FS_NR_RX_QUEUES;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) init_q (dev, &dev->rx_rq[i], RXB_RQ(i), RXRQ_NENTRIES, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) dev->irq = pci_dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (request_irq (dev->irq, fs_irq, IRQF_SHARED, "firestream", dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) printk (KERN_WARNING "couldn't get irq %d for firestream.\n", pci_dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /* XXX undo all previous stuff... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) goto unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) fs_dprintk (FS_DEBUG_INIT, "Grabbed irq %d for dev at %p.\n", dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) /* We want to be notified of most things. Just the statistics count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) overflows are not interesting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) write_fs (dev, IMR, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) | ISR_RBRQ0_W
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) | ISR_RBRQ1_W
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) | ISR_RBRQ2_W
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) | ISR_RBRQ3_W
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) | ISR_TBRQ_W
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) | ISR_CSQ_W);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) write_fs (dev, SARMODE0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) | (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) | (1 * SARMODE0_GINT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) | (1 * SARMODE0_INTMODE_READCLEAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) | (0 * SARMODE0_CWRE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) | (IS_FS50(dev)?SARMODE0_PRPWT_FS50_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) SARMODE0_PRPWT_FS155_3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) | (1 * SARMODE0_CALSUP_1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) | (IS_FS50 (dev)?(0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) | SARMODE0_RXVCS_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) | SARMODE0_ABRVCS_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) | SARMODE0_TXVCS_32):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) (0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) | SARMODE0_RXVCS_1k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) | SARMODE0_ABRVCS_1k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) | SARMODE0_TXVCS_1k))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) | (1 * SARMODE0_RUN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) init_phy (dev, PHY_NTC_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (loopback == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) write_phy (dev, 0x39, 0x000e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) #ifdef FS_POLL_FREQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) timer_setup(&dev->timer, fs_poll, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) dev->timer.expires = jiffies + FS_POLL_FREQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) add_timer (&dev->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) dev->atm_dev->dev_data = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) iounmap(dev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) static int firestream_init_one(struct pci_dev *pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) struct atm_dev *atm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) struct fs_dev *fs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) if (pci_enable_device(pci_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) fs_dev = kzalloc (sizeof (struct fs_dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%zd)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) fs_dev, sizeof (struct fs_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (!fs_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (!atm_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) goto err_out_free_fs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) fs_dev->pci_dev = pci_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) fs_dev->atm_dev = atm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) fs_dev->flags = ent->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (fs_init(fs_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) goto err_out_free_atm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) fs_dev->next = fs_boards;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) fs_boards = fs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) err_out_free_atm_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) atm_dev_deregister(atm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) err_out_free_fs_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) kfree(fs_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) static void firestream_remove_one(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) struct fs_dev *dev, *nxtdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) struct fs_vcc *vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) struct FS_BPENTRY *fp, *nxt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) printk ("hptxq:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) for (i=0;i<60;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) printk ("%d: %08x %08x %08x %08x \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) i, pq[qp].cmd, pq[qp].p0, pq[qp].p1, pq[qp].p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) qp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (qp >= 60) qp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) printk ("descriptors:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) for (i=0;i<60;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) printk ("%d: %p: %08x %08x %p %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) i, da[qd], dq[qd].flags, dq[qd].bsa, dq[qd].skb, dq[qd].dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) qd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) if (qd >= 60) qd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) for (dev = fs_boards;dev != NULL;dev=nxtdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) fs_dprintk (FS_DEBUG_CLEANUP, "Releasing resources for dev at %p.\n", dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) /* XXX Hit all the tx channels too! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) for (i=0;i < dev->nchannels;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) if (dev->atm_vccs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) vcc = FS_VCC (dev->atm_vccs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) QE_CMD_TX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) submit_command (dev, &dev->hp_txq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) QE_CMD_RX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) /* XXX Wait a while for the chip to release all buffers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) for (i=0;i < FS_NR_FREE_POOLS;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) for (fp=bus_to_virt (read_fs (dev, FP_SA(dev->rx_fp[i].offset)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) !(fp->flags & FP_FLAGS_EPI);fp = nxt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", fp->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) dev_kfree_skb_any (fp->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) nxt = bus_to_virt (fp->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) kfree (fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", fp->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) dev_kfree_skb_any (fp->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) kfree (fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) /* Hang the chip in "reset", prevent it clobbering memory that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) no longer ours. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) reset_chip (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) fs_dprintk (FS_DEBUG_CLEANUP, "Freeing irq%d.\n", dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) free_irq (dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) del_timer_sync (&dev->timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) atm_dev_deregister(dev->atm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) free_queue (dev, &dev->hp_txq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) free_queue (dev, &dev->lp_txq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) free_queue (dev, &dev->tx_relq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) free_queue (dev, &dev->st_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) fs_dprintk (FS_DEBUG_ALLOC, "Free atmvccs: %p\n", dev->atm_vccs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) kfree (dev->atm_vccs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) for (i=0;i< FS_NR_FREE_POOLS;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) free_freepool (dev, &dev->rx_fp[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) for (i=0;i < FS_NR_RX_QUEUES;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) free_queue (dev, &dev->rx_rq[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) iounmap(dev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) fs_dprintk (FS_DEBUG_ALLOC, "Free fs-dev: %p\n", dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) nxtdev = dev->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) kfree (dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) static const struct pci_device_id firestream_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) { PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50), FS_IS50},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) { PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155), FS_IS155},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) MODULE_DEVICE_TABLE(pci, firestream_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) static struct pci_driver firestream_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) .name = "firestream",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) .id_table = firestream_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) .probe = firestream_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) .remove = firestream_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) static int __init firestream_init_module (void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) func_enter ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) error = pci_register_driver(&firestream_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) func_exit ();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) static void __exit firestream_cleanup_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) pci_unregister_driver(&firestream_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) module_init(firestream_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) module_exit(firestream_cleanup_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)