#include <linux/module.h>
#include <linux/pci.h>
#include <linux/poison.h>
#include <linux/skbuff.h>
#include <linux/kernel.h>
#include <linux/vmalloc.h>
#include <linux/netdevice.h>
#include <linux/atmdev.h>
#include <linux/atm.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <linux/atomic.h>
#include <asm/byteorder.h>
#ifdef CONFIG_ATM_IDT77252_USE_SUNI
#include "suni.h"
#endif
#include "idt77252.h"
#include "idt77252_tables.h"
static unsigned int vpibits = …;
#define ATM_IDT77252_SEND_IDLE …
#define DEBUG_MODULE …
#undef HAVE_EEPROM
#ifdef CONFIG_ATM_IDT77252_DEBUG
static unsigned long debug = …;
#endif
#define SAR_RX_DELAY …
static struct scq_info *alloc_scq(struct idt77252_dev *, int);
static void free_scq(struct idt77252_dev *, struct scq_info *);
static int queue_skb(struct idt77252_dev *, struct vc_map *,
struct sk_buff *, int oam);
static void drain_scq(struct idt77252_dev *, struct vc_map *);
static unsigned long get_free_scd(struct idt77252_dev *, struct vc_map *);
static void fill_scd(struct idt77252_dev *, struct scq_info *, int);
static int push_rx_skb(struct idt77252_dev *,
struct sk_buff *, int queue);
static void recycle_rx_skb(struct idt77252_dev *, struct sk_buff *);
static void flush_rx_pool(struct idt77252_dev *, struct rx_pool *);
static void recycle_rx_pool_skb(struct idt77252_dev *,
struct rx_pool *);
static void add_rx_skb(struct idt77252_dev *, int queue,
unsigned int size, unsigned int count);
static int init_rsq(struct idt77252_dev *);
static void deinit_rsq(struct idt77252_dev *);
static void idt77252_rx(struct idt77252_dev *);
static int init_tsq(struct idt77252_dev *);
static void deinit_tsq(struct idt77252_dev *);
static void idt77252_tx(struct idt77252_dev *);
static void idt77252_dev_close(struct atm_dev *dev);
static int idt77252_open(struct atm_vcc *vcc);
static void idt77252_close(struct atm_vcc *vcc);
static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb);
static int idt77252_send_oam(struct atm_vcc *vcc, void *cell,
int flags);
static void idt77252_phy_put(struct atm_dev *dev, unsigned char value,
unsigned long addr);
static unsigned char idt77252_phy_get(struct atm_dev *dev, unsigned long addr);
static int idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos,
int flags);
static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos,
char *page);
static void idt77252_softint(struct work_struct *work);
static const struct atmdev_ops idt77252_ops = …;
static struct idt77252_dev *idt77252_chain = …;
static unsigned int idt77252_sram_write_errors = …;
static void
waitfor_idle(struct idt77252_dev *card)
{ … }
static u32
read_sram(struct idt77252_dev *card, unsigned long addr)
{ … }
static void
write_sram(struct idt77252_dev *card, unsigned long addr, u32 value)
{ … }
static u8
read_utility(void *dev, unsigned long ubus_addr)
{ … }
static void
write_utility(void *dev, unsigned long ubus_addr, u8 value)
{ … }
#ifdef HAVE_EEPROM
static u32 rdsrtab[] =
{
SAR_GP_EECS | SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
SAR_GP_EEDO,
SAR_GP_EESCLK | SAR_GP_EEDO,
0,
SAR_GP_EESCLK,
SAR_GP_EEDO,
SAR_GP_EESCLK | SAR_GP_EEDO
};
static u32 wrentab[] =
{
SAR_GP_EECS | SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
SAR_GP_EEDO,
SAR_GP_EESCLK | SAR_GP_EEDO,
SAR_GP_EEDO,
SAR_GP_EESCLK | SAR_GP_EEDO,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK
};
static u32 rdtab[] =
{
SAR_GP_EECS | SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
SAR_GP_EEDO,
SAR_GP_EESCLK | SAR_GP_EEDO,
SAR_GP_EEDO,
SAR_GP_EESCLK | SAR_GP_EEDO
};
static u32 wrtab[] =
{
SAR_GP_EECS | SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
SAR_GP_EEDO,
SAR_GP_EESCLK | SAR_GP_EEDO,
0,
SAR_GP_EESCLK
};
static u32 clktab[] =
{
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0,
SAR_GP_EESCLK,
0
};
static u32
idt77252_read_gp(struct idt77252_dev *card)
{
u32 gp;
gp = readl(SAR_REG_GP);
#if 0
printk("RD: %s\n", gp & SAR_GP_EEDI ? "1" : "0");
#endif
return gp;
}
static void
idt77252_write_gp(struct idt77252_dev *card, u32 value)
{
unsigned long flags;
#if 0
printk("WR: %s %s %s\n", value & SAR_GP_EECS ? " " : "/CS",
value & SAR_GP_EESCLK ? "HIGH" : "LOW ",
value & SAR_GP_EEDO ? "1" : "0");
#endif
spin_lock_irqsave(&card->cmd_lock, flags);
waitfor_idle(card);
writel(value, SAR_REG_GP);
spin_unlock_irqrestore(&card->cmd_lock, flags);
}
static u8
idt77252_eeprom_read_status(struct idt77252_dev *card)
{
u8 byte;
u32 gp;
int i, j;
gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
idt77252_write_gp(card, gp | rdsrtab[i]);
udelay(5);
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
byte = 0;
for (i = 0, j = 0; i < 8; i++) {
byte <<= 1;
idt77252_write_gp(card, gp | clktab[j++]);
udelay(5);
byte |= idt77252_read_gp(card) & SAR_GP_EEDI ? 1 : 0;
idt77252_write_gp(card, gp | clktab[j++]);
udelay(5);
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
return byte;
}
static u8
idt77252_eeprom_read_byte(struct idt77252_dev *card, u8 offset)
{
u8 byte;
u32 gp;
int i, j;
gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
for (i = 0; i < ARRAY_SIZE(rdtab); i++) {
idt77252_write_gp(card, gp | rdtab[i]);
udelay(5);
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
for (i = 0, j = 0; i < 8; i++) {
idt77252_write_gp(card, gp | clktab[j++] |
(offset & 1 ? SAR_GP_EEDO : 0));
udelay(5);
idt77252_write_gp(card, gp | clktab[j++] |
(offset & 1 ? SAR_GP_EEDO : 0));
udelay(5);
offset >>= 1;
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
byte = 0;
for (i = 0, j = 0; i < 8; i++) {
byte <<= 1;
idt77252_write_gp(card, gp | clktab[j++]);
udelay(5);
byte |= idt77252_read_gp(card) & SAR_GP_EEDI ? 1 : 0;
idt77252_write_gp(card, gp | clktab[j++]);
udelay(5);
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
return byte;
}
static void
idt77252_eeprom_write_byte(struct idt77252_dev *card, u8 offset, u8 data)
{
u32 gp;
int i, j;
gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
for (i = 0; i < ARRAY_SIZE(wrentab); i++) {
idt77252_write_gp(card, gp | wrentab[i]);
udelay(5);
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
for (i = 0; i < ARRAY_SIZE(wrtab); i++) {
idt77252_write_gp(card, gp | wrtab[i]);
udelay(5);
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
for (i = 0, j = 0; i < 8; i++) {
idt77252_write_gp(card, gp | clktab[j++] |
(offset & 1 ? SAR_GP_EEDO : 0));
udelay(5);
idt77252_write_gp(card, gp | clktab[j++] |
(offset & 1 ? SAR_GP_EEDO : 0));
udelay(5);
offset >>= 1;
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
for (i = 0, j = 0; i < 8; i++) {
idt77252_write_gp(card, gp | clktab[j++] |
(data & 1 ? SAR_GP_EEDO : 0));
udelay(5);
idt77252_write_gp(card, gp | clktab[j++] |
(data & 1 ? SAR_GP_EEDO : 0));
udelay(5);
data >>= 1;
}
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
}
static void
idt77252_eeprom_init(struct idt77252_dev *card)
{
u32 gp;
gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
idt77252_write_gp(card, gp | SAR_GP_EECS | SAR_GP_EESCLK);
udelay(5);
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
idt77252_write_gp(card, gp | SAR_GP_EECS | SAR_GP_EESCLK);
udelay(5);
idt77252_write_gp(card, gp | SAR_GP_EECS);
udelay(5);
}
#endif
#ifdef CONFIG_ATM_IDT77252_DEBUG
static void
dump_tct(struct idt77252_dev *card, int index)
{ … }
static void
idt77252_tx_dump(struct idt77252_dev *card)
{ … }
#endif
static int
sb_pool_add(struct idt77252_dev *card, struct sk_buff *skb, int queue)
{ … }
static void
sb_pool_remove(struct idt77252_dev *card, struct sk_buff *skb)
{ … }
static struct sk_buff *
sb_pool_skb(struct idt77252_dev *card, u32 handle)
{ … }
static struct scq_info *
alloc_scq(struct idt77252_dev *card, int class)
{ … }
static void
free_scq(struct idt77252_dev *card, struct scq_info *scq)
{ … }
static int
push_on_scq(struct idt77252_dev *card, struct vc_map *vc, struct sk_buff *skb)
{ … }
static void
drain_scq(struct idt77252_dev *card, struct vc_map *vc)
{ … }
static int
queue_skb(struct idt77252_dev *card, struct vc_map *vc,
struct sk_buff *skb, int oam)
{ … }
static unsigned long
get_free_scd(struct idt77252_dev *card, struct vc_map *vc)
{ … }
static void
fill_scd(struct idt77252_dev *card, struct scq_info *scq, int class)
{ … }
static void
clear_scd(struct idt77252_dev *card, struct scq_info *scq, int class)
{ … }
static int
init_rsq(struct idt77252_dev *card)
{ … }
static void
deinit_rsq(struct idt77252_dev *card)
{ … }
static void
dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
{ … }
static void
idt77252_rx(struct idt77252_dev *card)
{ … }
static void
idt77252_rx_raw(struct idt77252_dev *card)
{ … }
static int
init_tsq(struct idt77252_dev *card)
{ … }
static void
deinit_tsq(struct idt77252_dev *card)
{ … }
static void
idt77252_tx(struct idt77252_dev *card)
{ … }
static void
tst_timer(struct timer_list *t)
{ … }
static int
__fill_tst(struct idt77252_dev *card, struct vc_map *vc,
int n, unsigned int opc)
{ … }
static int
fill_tst(struct idt77252_dev *card, struct vc_map *vc, int n, unsigned int opc)
{ … }
static int
__clear_tst(struct idt77252_dev *card, struct vc_map *vc)
{ … }
static int
clear_tst(struct idt77252_dev *card, struct vc_map *vc)
{ … }
static int
change_tst(struct idt77252_dev *card, struct vc_map *vc,
int n, unsigned int opc)
{ … }
static int
set_tct(struct idt77252_dev *card, struct vc_map *vc)
{ … }
static __inline__ int
idt77252_fbq_full(struct idt77252_dev *card, int queue)
{ … }
static int
push_rx_skb(struct idt77252_dev *card, struct sk_buff *skb, int queue)
{ … }
static void
add_rx_skb(struct idt77252_dev *card, int queue,
unsigned int size, unsigned int count)
{ … }
static void
recycle_rx_skb(struct idt77252_dev *card, struct sk_buff *skb)
{ … }
static void
flush_rx_pool(struct idt77252_dev *card, struct rx_pool *rpp)
{ … }
static void
recycle_rx_pool_skb(struct idt77252_dev *card, struct rx_pool *rpp)
{ … }
static void
idt77252_phy_put(struct atm_dev *dev, unsigned char value, unsigned long addr)
{ … }
static unsigned char
idt77252_phy_get(struct atm_dev *dev, unsigned long addr)
{ … }
static inline int
idt77252_send_skb(struct atm_vcc *vcc, struct sk_buff *skb, int oam)
{ … }
static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb)
{ … }
static int
idt77252_send_oam(struct atm_vcc *vcc, void *cell, int flags)
{ … }
static __inline__ unsigned int
idt77252_fls(unsigned int x)
{ … }
static u16
idt77252_int_to_atmfp(unsigned int rate)
{ … }
static u8
idt77252_rate_logindex(struct idt77252_dev *card, int pcr)
{ … }
static void
idt77252_est_timer(struct timer_list *t)
{ … }
static struct rate_estimator *
idt77252_init_est(struct vc_map *vc, int pcr)
{ … }
static int
idt77252_init_cbr(struct idt77252_dev *card, struct vc_map *vc,
struct atm_vcc *vcc, struct atm_qos *qos)
{ … }
static int
idt77252_init_ubr(struct idt77252_dev *card, struct vc_map *vc,
struct atm_vcc *vcc, struct atm_qos *qos)
{ … }
static int
idt77252_init_tx(struct idt77252_dev *card, struct vc_map *vc,
struct atm_vcc *vcc, struct atm_qos *qos)
{ … }
static int
idt77252_init_rx(struct idt77252_dev *card, struct vc_map *vc,
struct atm_vcc *vcc, struct atm_qos *qos)
{ … }
static int
idt77252_open(struct atm_vcc *vcc)
{ … }
static void
idt77252_close(struct atm_vcc *vcc)
{ … }
static int
idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
{ … }
static int
idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
{ … }
static void
idt77252_collect_stat(struct idt77252_dev *card)
{ … }
static irqreturn_t
idt77252_interrupt(int irq, void *dev_id)
{ … }
static void
idt77252_softint(struct work_struct *work)
{ … }
static int
open_card_oam(struct idt77252_dev *card)
{ … }
static void
close_card_oam(struct idt77252_dev *card)
{ … }
static int
open_card_ubr0(struct idt77252_dev *card)
{ … }
static void
close_card_ubr0(struct idt77252_dev *card)
{ … }
static int
idt77252_dev_open(struct idt77252_dev *card)
{ … }
static void idt77252_dev_close(struct atm_dev *dev)
{ … }
static void
deinit_card(struct idt77252_dev *card)
{ … }
static void init_sram(struct idt77252_dev *card)
{ … }
static int init_card(struct atm_dev *dev)
{ … }
static int idt77252_preset(struct idt77252_dev *card)
{ … }
static unsigned long probe_sram(struct idt77252_dev *card)
{ … }
static int idt77252_init_one(struct pci_dev *pcidev,
const struct pci_device_id *id)
{ … }
static const struct pci_device_id idt77252_pci_tbl[] = …;
MODULE_DEVICE_TABLE(pci, idt77252_pci_tbl);
static struct pci_driver idt77252_driver = …;
static int __init idt77252_init(void)
{ … }
static void __exit idt77252_exit(void)
{ … }
module_init(…) …;
module_exit(idt77252_exit);
MODULE_LICENSE(…) …;
module_param(vpibits, uint, 0);
MODULE_PARM_DESC(…) …;
#ifdef CONFIG_ATM_IDT77252_DEBUG
module_param(debug, ulong, 0644);
MODULE_PARM_DESC(…) …;
#endif
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;