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