#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/atmdev.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#define NUM_VCI …
#define DEBUG
#undef DEBUG_RW
#define FULL_MEMORY_TEST
#define SERVICE_ENTRIES …
#define TX_FIFO_DEPTH …
#define LANAI_POLL_PERIOD …
#define AAL5_RX_MULTIPLIER …
#define AAL5_TX_MULTIPLIER …
#define AAL0_TX_MULTIPLIER …
#define AAL0_RX_BUFFER_SIZE …
#define DEV_LABEL …
#ifdef DEBUG
#define DPRINTK(format, args...) …
#define APRINTK(truth, format, args...) …
#else
#define DPRINTK …
#define APRINTK …
#endif
#ifdef DEBUG_RW
#define RWDEBUG …
#else
#define RWDEBUG(format, args...) …
#endif
#define LANAI_MAPPING_SIZE …
#define LANAI_EEPROM_SIZE …
vci_t;
bus_addr_t;
struct lanai_buffer { … };
struct lanai_vcc_stats { … };
struct lanai_dev;
struct lanai_vcc { … };
enum lanai_type { … };
struct lanai_dev_stats { … };
struct lanai_dev { … };
static void vci_bitfield_iterate(struct lanai_dev *lanai,
const unsigned long *lp,
void (*func)(struct lanai_dev *,vci_t vci))
{ … }
#define LANAI_PAGE_SIZE …
static void lanai_buf_allocate(struct lanai_buffer *buf,
size_t bytes, size_t minbytes, struct pci_dev *pci)
{ … }
static inline size_t lanai_buf_size(const struct lanai_buffer *buf)
{ … }
static void lanai_buf_deallocate(struct lanai_buffer *buf,
struct pci_dev *pci)
{ … }
static int lanai_buf_size_cardorder(const struct lanai_buffer *buf)
{ … }
enum lanai_register { … };
static inline bus_addr_t reg_addr(const struct lanai_dev *lanai,
enum lanai_register reg)
{ … }
static inline u32 reg_read(const struct lanai_dev *lanai,
enum lanai_register reg)
{ … }
static inline void reg_write(const struct lanai_dev *lanai, u32 val,
enum lanai_register reg)
{ … }
static inline void conf1_write(const struct lanai_dev *lanai)
{ … }
static inline void conf2_write(const struct lanai_dev *lanai)
{ … }
static inline void conf2_write_if_powerup(const struct lanai_dev *lanai)
{ … }
static inline void reset_board(const struct lanai_dev *lanai)
{ … }
#define SRAM_START …
#define SRAM_BYTES …
static inline bus_addr_t sram_addr(const struct lanai_dev *lanai, int offset)
{ … }
static inline u32 sram_read(const struct lanai_dev *lanai, int offset)
{ … }
static inline void sram_write(const struct lanai_dev *lanai,
u32 val, int offset)
{ … }
static int sram_test_word(const struct lanai_dev *lanai, int offset,
u32 pattern)
{ … }
static int sram_test_pass(const struct lanai_dev *lanai, u32 pattern)
{ … }
static int sram_test_and_clear(const struct lanai_dev *lanai)
{ … }
enum lanai_vcc_offset { … };
#define CARDVCC_SIZE …
static inline bus_addr_t cardvcc_addr(const struct lanai_dev *lanai,
vci_t vci)
{ … }
static inline u32 cardvcc_read(const struct lanai_vcc *lvcc,
enum lanai_vcc_offset offset)
{ … }
static inline void cardvcc_write(const struct lanai_vcc *lvcc,
u32 val, enum lanai_vcc_offset offset)
{ … }
static inline int aal5_size(int size)
{ … }
static inline void lanai_free_skb(struct atm_vcc *atmvcc, struct sk_buff *skb)
{ … }
static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
{ … }
static void host_vcc_start_tx(const struct lanai_vcc *lvcc)
{ … }
static void lanai_shutdown_rx_vci(const struct lanai_vcc *lvcc)
{ … }
static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
struct lanai_vcc *lvcc)
{ … }
static inline int aal0_buffer_allocate(struct lanai_dev *lanai)
{ … }
static inline void aal0_buffer_free(struct lanai_dev *lanai)
{ … }
#define EEPROM_COPYRIGHT …
#define EEPROM_COPYRIGHT_LEN …
#define EEPROM_CHECKSUM …
#define EEPROM_CHECKSUM_REV …
#define EEPROM_MAC …
#define EEPROM_MAC_REV …
#define EEPROM_SERIAL …
#define EEPROM_SERIAL_REV …
#define EEPROM_MAGIC …
#define EEPROM_MAGIC_REV …
#define EEPROM_MAGIC_VALUE …
#ifndef READ_EEPROM
static int eeprom_read(struct lanai_dev *lanai)
{ … }
static int eeprom_validate(struct lanai_dev *lanai)
{ … }
#else
static int eeprom_read(struct lanai_dev *lanai)
{
int i, address;
u8 data;
u32 tmp;
#define set_config1 …
#define clock_h …
#define clock_l …
#define data_h …
#define data_l …
#define pre_read …
#define read_pin …
#define send_stop …
data_h(); clock_h(); udelay(5);
for (address = 0; address < LANAI_EEPROM_SIZE; address++) {
data = (address << 1) | 1;
data_l(); udelay(5);
clock_l(); udelay(5);
for (i = 128; i != 0; i >>= 1) {
tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |
((data & i) ? CONFIG1_PROMDATA : 0);
if (lanai->conf1 != tmp) {
set_config1(tmp);
udelay(5);
}
clock_h(); udelay(5); clock_l(); udelay(5);
}
data_h(); clock_h(); udelay(5);
if (read_pin() != 0)
goto error;
clock_l(); udelay(5);
for (data = 0, i = 7; i >= 0; i--) {
data_h(); clock_h(); udelay(5);
data = (data << 1) | !!read_pin();
clock_l(); udelay(5);
}
data_h(); clock_h(); udelay(5);
if (read_pin() == 0)
goto error;
clock_l(); udelay(5);
send_stop();
lanai->eeprom[address] = data;
DPRINTK("EEPROM 0x%04X %02X\n",
(unsigned int) address, (unsigned int) data);
}
return 0;
error:
clock_l(); udelay(5);
send_stop();
printk(KERN_ERR DEV_LABEL "(itf %d): error reading EEPROM byte %d\n",
lanai->number, address);
return -EIO;
#undef set_config1
#undef clock_h
#undef clock_l
#undef data_h
#undef data_l
#undef pre_read
#undef read_pin
#undef send_stop
}
static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address)
{
return be32_to_cpup((const u32 *) &lanai->eeprom[address]);
}
static int eeprom_validate(struct lanai_dev *lanai)
{
int i, s;
u32 v;
const u8 *e = lanai->eeprom;
#ifdef DEBUG
for (i = EEPROM_COPYRIGHT;
i < (EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN); i++)
if (e[i] < 0x20 || e[i] > 0x7E)
break;
if ( i != EEPROM_COPYRIGHT &&
i != EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN && e[i] == '\0')
DPRINTK("eeprom: copyright = \"%s\"\n",
(char *) &e[EEPROM_COPYRIGHT]);
else
DPRINTK("eeprom: copyright not found\n");
#endif
for (i = s = 0; i < EEPROM_CHECKSUM; i++)
s += e[i];
s &= 0xFF;
if (s != e[EEPROM_CHECKSUM]) {
printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM checksum bad "
"(wanted 0x%02X, got 0x%02X)\n", lanai->number,
(unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM]);
return -EIO;
}
s ^= 0xFF;
if (s != e[EEPROM_CHECKSUM_REV]) {
printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM inverse checksum "
"bad (wanted 0x%02X, got 0x%02X)\n", lanai->number,
(unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM_REV]);
return -EIO;
}
for (i = 0; i < 6; i++)
if ((e[EEPROM_MAC + i] ^ e[EEPROM_MAC_REV + i]) != 0xFF) {
printk(KERN_ERR DEV_LABEL
"(itf %d) : EEPROM MAC addresses don't match "
"(0x%02X, inverse 0x%02X)\n", lanai->number,
(unsigned int) e[EEPROM_MAC + i],
(unsigned int) e[EEPROM_MAC_REV + i]);
return -EIO;
}
DPRINTK("eeprom: MAC address = %pM\n", &e[EEPROM_MAC]);
lanai->serialno = eeprom_be4(lanai, EEPROM_SERIAL);
v = eeprom_be4(lanai, EEPROM_SERIAL_REV);
if ((lanai->serialno ^ v) != 0xFFFFFFFF) {
printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM serial numbers "
"don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
(unsigned int) lanai->serialno, (unsigned int) v);
return -EIO;
}
DPRINTK("eeprom: Serial number = %d\n", (unsigned int) lanai->serialno);
lanai->magicno = eeprom_be4(lanai, EEPROM_MAGIC);
v = eeprom_be4(lanai, EEPROM_MAGIC_REV);
if ((lanai->magicno ^ v) != 0xFFFFFFFF) {
printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM magic numbers "
"don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
lanai->magicno, v);
return -EIO;
}
DPRINTK("eeprom: Magic number = 0x%08X\n", lanai->magicno);
if (lanai->magicno != EEPROM_MAGIC_VALUE)
printk(KERN_WARNING DEV_LABEL "(itf %d): warning - EEPROM "
"magic not what expected (got 0x%08X, not 0x%08X)\n",
lanai->number, (unsigned int) lanai->magicno,
(unsigned int) EEPROM_MAGIC_VALUE);
return 0;
}
#endif
static inline const u8 *eeprom_mac(const struct lanai_dev *lanai)
{ … }
#define INT_STATS …
#define INT_SOOL …
#define INT_LOCD …
#define INT_LED …
#define INT_GPIN …
#define INT_PING …
#define INT_WAKE …
#define INT_CBR0 …
#define INT_LOCK …
#define INT_MISMATCH …
#define INT_AAL0_STR …
#define INT_AAL0 …
#define INT_SERVICE …
#define INT_TABORTSENT …
#define INT_TABORTBM …
#define INT_TIMEOUTBM …
#define INT_PCIPARITY …
#define INT_ALL …
#define INT_STATUS …
#define INT_DMASHUT …
#define INT_SEGSHUT …
static inline u32 intr_pending(const struct lanai_dev *lanai)
{ … }
static inline void intr_enable(const struct lanai_dev *lanai, u32 i)
{ … }
static inline void intr_disable(const struct lanai_dev *lanai, u32 i)
{ … }
static void status_message(int itf, const char *name, int status)
{ … }
static void lanai_check_status(struct lanai_dev *lanai)
{ … }
static void pcistatus_got(int itf, const char *name)
{ … }
static void pcistatus_check(struct lanai_dev *lanai, int clearonly)
{ … }
static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
{ … }
static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)
{ … }
#define DESCRIPTOR_MAGIC …
#define DESCRIPTOR_AAL5 …
#define DESCRIPTOR_AAL5_STREAM …
#define DESCRIPTOR_CLP …
static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
u32 flags, int len)
{ … }
static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc,
int len, int cpi, int uu)
{ … }
static inline void vcc_tx_memcpy(struct lanai_vcc *lvcc,
const unsigned char *src, int n)
{ … }
static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)
{ … }
static inline void lanai_endtx(struct lanai_dev *lanai,
const struct lanai_vcc *lvcc)
{ … }
static void lanai_send_one_aal5(struct lanai_dev *lanai,
struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize)
{ … }
static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai,
struct lanai_vcc *lvcc, int endptr)
{ … }
static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
struct sk_buff *skb)
{ … }
static void vcc_tx_unqueue_aal0(struct lanai_dev *lanai,
struct lanai_vcc *lvcc, int endptr)
{ … }
static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
struct sk_buff *skb)
{ … }
static inline void vcc_rx_memcpy(unsigned char *dest,
const struct lanai_vcc *lvcc, int n)
{ … }
static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
{ … }
static void vcc_rx_aal0(struct lanai_dev *lanai)
{ … }
#if (NUM_VCI * BITS_PER_LONG) <= PAGE_SIZE
#define VCCTABLE_GETFREEPAGE
#else
#include <linux/vmalloc.h>
#endif
static int vcc_table_allocate(struct lanai_dev *lanai)
{ … }
static inline void vcc_table_deallocate(const struct lanai_dev *lanai)
{ … }
static inline struct lanai_vcc *new_lanai_vcc(void)
{ … }
static int lanai_get_sized_buffer(struct lanai_dev *lanai,
struct lanai_buffer *buf, int max_sdu, int multiplier,
const char *name)
{ … }
static inline int lanai_setup_rx_vci_aal5(struct lanai_dev *lanai,
struct lanai_vcc *lvcc, const struct atm_qos *qos)
{ … }
static int lanai_setup_tx_vci(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
const struct atm_qos *qos)
{ … }
static inline void host_vcc_bind(struct lanai_dev *lanai,
struct lanai_vcc *lvcc, vci_t vci)
{ … }
static inline void host_vcc_unbind(struct lanai_dev *lanai,
struct lanai_vcc *lvcc)
{ … }
static void lanai_reset(struct lanai_dev *lanai)
{ … }
static int service_buffer_allocate(struct lanai_dev *lanai)
{ … }
static inline void service_buffer_deallocate(struct lanai_dev *lanai)
{ … }
#define SERVICE_TX …
#define SERVICE_TRASH …
#define SERVICE_CRCERR …
#define SERVICE_CI …
#define SERVICE_CLP …
#define SERVICE_STREAM …
#define SERVICE_GET_VCI(x) …
#define SERVICE_GET_END(x) …
static int handle_service(struct lanai_dev *lanai, u32 s)
{ … }
static void iter_transmit(struct lanai_dev *lanai, vci_t vci)
{ … }
static void run_service(struct lanai_dev *lanai)
{ … }
static void get_statistics(struct lanai_dev *lanai)
{ … }
#ifndef DEBUG_RW
static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)
{ … }
#endif
static void lanai_timed_poll(struct timer_list *t)
{ … }
static inline void lanai_timed_poll_start(struct lanai_dev *lanai)
{ … }
static inline void lanai_timed_poll_stop(struct lanai_dev *lanai)
{ … }
static inline void lanai_int_1(struct lanai_dev *lanai, u32 reason)
{ … }
static irqreturn_t lanai_int(int irq, void *devid)
{ … }
static int check_board_id_and_rev(const char *name, u32 val, int *revp)
{ … }
static int lanai_pci_start(struct lanai_dev *lanai)
{ … }
static inline int vci0_is_ok(struct lanai_dev *lanai,
const struct atm_qos *qos)
{ … }
static int vci_is_ok(struct lanai_dev *lanai, vci_t vci,
const struct atm_vcc *atmvcc)
{ … }
static int lanai_normalize_ci(struct lanai_dev *lanai,
const struct atm_vcc *atmvcc, short *vpip, vci_t *vcip)
{ … }
#define CBRICG_FRAC_BITS …
#define CBRICG_MAX …
static int pcr_to_cbricg(const struct atm_qos *qos)
{ … }
static inline void lanai_cbr_setup(struct lanai_dev *lanai)
{ … }
static inline void lanai_cbr_shutdown(struct lanai_dev *lanai)
{ … }
static int lanai_dev_open(struct atm_dev *atmdev)
{ … }
static void lanai_dev_close(struct atm_dev *atmdev)
{ … }
static void lanai_close(struct atm_vcc *atmvcc)
{ … }
static int lanai_open(struct atm_vcc *atmvcc)
{ … }
static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
{ … }
static int lanai_change_qos(struct atm_vcc *atmvcc,
struct atm_qos *qos, int flags)
{ … }
#ifndef CONFIG_PROC_FS
#define lanai_proc_read …
#else
static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
{ … }
#endif
static const struct atmdev_ops ops = …;
static int lanai_init_one(struct pci_dev *pci,
const struct pci_device_id *ident)
{ … }
static const struct pci_device_id lanai_pci_tbl[] = …;
MODULE_DEVICE_TABLE(pci, lanai_pci_tbl);
static struct pci_driver lanai_driver = …;
module_pci_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;