2604 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* lanai.c -- Copyright 1999-2003 by Mitchell Blank Jr <mitch@sfgoth.com>3 *4 * This driver supports ATM cards based on the Efficient "Lanai"5 * chipset such as the Speedstream 3010 and the ENI-25p. The6 * Speedstream 3060 is currently not supported since we don't7 * have the code to drive the on-board Alcatel DSL chipset (yet).8 *9 * Thanks to Efficient for supporting this project with hardware,10 * documentation, and by answering my questions.11 *12 * Things not working yet:13 *14 * o We don't support the Speedstream 3060 yet - this card has15 * an on-board DSL modem chip by Alcatel and the driver will16 * need some extra code added to handle it17 *18 * o Note that due to limitations of the Lanai only one VCC can be19 * in CBR at once20 *21 * o We don't currently parse the EEPROM at all. The code is all22 * there as per the spec, but it doesn't actually work. I think23 * there may be some issues with the docs. Anyway, do NOT24 * enable it yet - bugs in that code may actually damage your25 * hardware! Because of this you should hardware an ESI before26 * trying to use this in a LANE or MPOA environment.27 *28 * o AAL0 is stubbed in but the actual rx/tx path isn't written yet:29 * vcc_tx_aal0() needs to send or queue a SKB30 * vcc_tx_unqueue_aal0() needs to attempt to send queued SKBs31 * vcc_rx_aal0() needs to handle AAL0 interrupts32 * This isn't too much work - I just wanted to get other things33 * done first.34 *35 * o lanai_change_qos() isn't written yet36 *37 * o There aren't any ioctl's yet -- I'd like to eventually support38 * setting loopback and LED modes that way.39 *40 * o If the segmentation engine or DMA gets shut down we should restart41 * card as per section 17.0i. (see lanai_reset)42 *43 * o setsockopt(SO_CIRANGE) isn't done (although despite what the44 * API says it isn't exactly commonly implemented)45 */46 47/* Version history:48 * v.1.00 -- 26-JUL-2003 -- PCI/DMA updates49 * v.0.02 -- 11-JAN-2000 -- Endian fixes50 * v.0.01 -- 30-NOV-1999 -- Initial release51 */52 53#include <linux/module.h>54#include <linux/slab.h>55#include <linux/mm.h>56#include <linux/atmdev.h>57#include <asm/io.h>58#include <asm/byteorder.h>59#include <linux/spinlock.h>60#include <linux/pci.h>61#include <linux/dma-mapping.h>62#include <linux/init.h>63#include <linux/delay.h>64#include <linux/interrupt.h>65 66/* -------------------- TUNABLE PARAMATERS: */67 68/*69 * Maximum number of VCIs per card. Setting it lower could theoretically70 * save some memory, but since we allocate our vcc list with get_free_pages,71 * it's not really likely for most architectures72 */73#define NUM_VCI (1024)74 75/*76 * Enable extra debugging77 */78#define DEBUG79/*80 * Debug _all_ register operations with card, except the memory test.81 * Also disables the timed poll to prevent extra chattiness. This82 * isn't for normal use83 */84#undef DEBUG_RW85 86/*87 * The programming guide specifies a full test of the on-board SRAM88 * at initialization time. Undefine to remove this89 */90#define FULL_MEMORY_TEST91 92/*93 * This is the number of (4 byte) service entries that we will94 * try to allocate at startup. Note that we will end up with95 * one PAGE_SIZE's worth regardless of what this is set to96 */97#define SERVICE_ENTRIES (1024)98/* TODO: make above a module load-time option */99 100/*101 * We normally read the onboard EEPROM in order to discover our MAC102 * address. Undefine to _not_ do this103 */104/* #define READ_EEPROM */ /* ***DONT ENABLE YET*** */105/* TODO: make above a module load-time option (also) */106 107/*108 * Depth of TX fifo (in 128 byte units; range 2-31)109 * Smaller numbers are better for network latency110 * Larger numbers are better for PCI latency111 * I'm really sure where the best tradeoff is, but the BSD driver uses112 * 7 and it seems to work ok.113 */114#define TX_FIFO_DEPTH (7)115/* TODO: make above a module load-time option */116 117/*118 * How often (in jiffies) we will try to unstick stuck connections -119 * shouldn't need to happen much120 */121#define LANAI_POLL_PERIOD (10*HZ)122/* TODO: make above a module load-time option */123 124/*125 * When allocating an AAL5 receiving buffer, try to make it at least126 * large enough to hold this many max_sdu sized PDUs127 */128#define AAL5_RX_MULTIPLIER (3)129/* TODO: make above a module load-time option */130 131/*132 * Same for transmitting buffer133 */134#define AAL5_TX_MULTIPLIER (3)135/* TODO: make above a module load-time option */136 137/*138 * When allocating an AAL0 transmiting buffer, how many cells should fit.139 * Remember we'll end up with a PAGE_SIZE of them anyway, so this isn't140 * really critical141 */142#define AAL0_TX_MULTIPLIER (40)143/* TODO: make above a module load-time option */144 145/*146 * How large should we make the AAL0 receiving buffer. Remember that this147 * is shared between all AAL0 VC's148 */149#define AAL0_RX_BUFFER_SIZE (PAGE_SIZE)150/* TODO: make above a module load-time option */151 152/*153 * Should we use Lanai's "powerdown" feature when no vcc's are bound?154 */155/* #define USE_POWERDOWN */156/* TODO: make above a module load-time option (also) */157 158/* -------------------- DEBUGGING AIDS: */159 160#define DEV_LABEL "lanai"161 162#ifdef DEBUG163 164#define DPRINTK(format, args...) \165 printk(KERN_DEBUG DEV_LABEL ": " format, ##args)166#define APRINTK(truth, format, args...) \167 do { \168 if (unlikely(!(truth))) \169 printk(KERN_ERR DEV_LABEL ": " format, ##args); \170 } while (0)171 172#else /* !DEBUG */173 174#define DPRINTK(format, args...)175#define APRINTK(truth, format, args...)176 177#endif /* DEBUG */178 179#ifdef DEBUG_RW180#define RWDEBUG(format, args...) \181 printk(KERN_DEBUG DEV_LABEL ": " format, ##args)182#else /* !DEBUG_RW */183#define RWDEBUG(format, args...)184#endif185 186/* -------------------- DATA DEFINITIONS: */187 188#define LANAI_MAPPING_SIZE (0x40000)189#define LANAI_EEPROM_SIZE (128)190 191typedef int vci_t;192typedef void __iomem *bus_addr_t;193 194/* DMA buffer in host memory for TX, RX, or service list. */195struct lanai_buffer {196 u32 *start; /* From get_free_pages */197 u32 *end; /* One past last byte */198 u32 *ptr; /* Pointer to current host location */199 dma_addr_t dmaaddr;200};201 202struct lanai_vcc_stats {203 unsigned rx_nomem;204 union {205 struct {206 unsigned rx_badlen;207 unsigned service_trash;208 unsigned service_stream;209 unsigned service_rxcrc;210 } aal5;211 struct {212 } aal0;213 } x;214};215 216struct lanai_dev; /* Forward declaration */217 218/*219 * This is the card-specific per-vcc data. Note that unlike some other220 * drivers there is NOT a 1-to-1 correspondance between these and221 * atm_vcc's - each one of these represents an actual 2-way vcc, but222 * an atm_vcc can be 1-way and share with a 1-way vcc in the other223 * direction. To make it weirder, there can even be 0-way vccs224 * bound to us, waiting to do a change_qos225 */226struct lanai_vcc {227 bus_addr_t vbase; /* Base of VCC's registers */228 struct lanai_vcc_stats stats;229 int nref; /* # of atm_vcc's who reference us */230 vci_t vci;231 struct {232 struct lanai_buffer buf;233 struct atm_vcc *atmvcc; /* atm_vcc who is receiver */234 } rx;235 struct {236 struct lanai_buffer buf;237 struct atm_vcc *atmvcc; /* atm_vcc who is transmitter */238 int endptr; /* last endptr from service entry */239 struct sk_buff_head backlog;240 void (*unqueue)(struct lanai_dev *, struct lanai_vcc *, int);241 } tx;242};243 244enum lanai_type {245 lanai2 = PCI_DEVICE_ID_EF_ATM_LANAI2,246 lanaihb = PCI_DEVICE_ID_EF_ATM_LANAIHB247};248 249struct lanai_dev_stats {250 unsigned ovfl_trash; /* # of cells dropped - buffer overflow */251 unsigned vci_trash; /* # of cells dropped - closed vci */252 unsigned hec_err; /* # of cells dropped - bad HEC */253 unsigned atm_ovfl; /* # of cells dropped - rx fifo overflow */254 unsigned pcierr_parity_detect;255 unsigned pcierr_serr_set;256 unsigned pcierr_master_abort;257 unsigned pcierr_m_target_abort;258 unsigned pcierr_s_target_abort;259 unsigned pcierr_master_parity;260 unsigned service_notx;261 unsigned service_norx;262 unsigned service_rxnotaal5;263 unsigned dma_reenable;264 unsigned card_reset;265};266 267struct lanai_dev {268 bus_addr_t base;269 struct lanai_dev_stats stats;270 struct lanai_buffer service;271 struct lanai_vcc **vccs;272#ifdef USE_POWERDOWN273 int nbound; /* number of bound vccs */274#endif275 enum lanai_type type;276 vci_t num_vci; /* Currently just NUM_VCI */277 u8 eeprom[LANAI_EEPROM_SIZE];278 u32 serialno, magicno;279 struct pci_dev *pci;280 DECLARE_BITMAP(backlog_vccs, NUM_VCI); /* VCCs with tx backlog */281 DECLARE_BITMAP(transmit_ready, NUM_VCI); /* VCCs with transmit space */282 struct timer_list timer;283 int naal0;284 struct lanai_buffer aal0buf; /* AAL0 RX buffers */285 u32 conf1, conf2; /* CONFIG[12] registers */286 u32 status; /* STATUS register */287 spinlock_t endtxlock;288 spinlock_t servicelock;289 struct atm_vcc *cbrvcc;290 int number;291 int board_rev;292/* TODO - look at race conditions with maintence of conf1/conf2 */293/* TODO - transmit locking: should we use _irq not _irqsave? */294/* TODO - organize above in some rational fashion (see <asm/cache.h>) */295};296 297/*298 * Each device has two bitmaps for each VCC (baclog_vccs and transmit_ready)299 * This function iterates one of these, calling a given function for each300 * vci with their bit set301 */302static void vci_bitfield_iterate(struct lanai_dev *lanai,303 const unsigned long *lp,304 void (*func)(struct lanai_dev *,vci_t vci))305{306 vci_t vci;307 308 for_each_set_bit(vci, lp, NUM_VCI)309 func(lanai, vci);310}311 312/* -------------------- BUFFER UTILITIES: */313 314/*315 * Lanai needs DMA buffers aligned to 256 bytes of at least 1024 bytes -316 * usually any page allocation will do. Just to be safe in case317 * PAGE_SIZE is insanely tiny, though...318 */319#define LANAI_PAGE_SIZE ((PAGE_SIZE >= 1024) ? PAGE_SIZE : 1024)320 321/*322 * Allocate a buffer in host RAM for service list, RX, or TX323 * Returns buf->start==NULL if no memory324 * Note that the size will be rounded up 2^n bytes, and325 * if we can't allocate that we'll settle for something smaller326 * until minbytes327 */328static void lanai_buf_allocate(struct lanai_buffer *buf,329 size_t bytes, size_t minbytes, struct pci_dev *pci)330{331 int size;332 333 if (bytes > (128 * 1024)) /* max lanai buffer size */334 bytes = 128 * 1024;335 for (size = LANAI_PAGE_SIZE; size < bytes; size *= 2)336 ;337 if (minbytes < LANAI_PAGE_SIZE)338 minbytes = LANAI_PAGE_SIZE;339 do {340 /*341 * Technically we could use non-consistent mappings for342 * everything, but the way the lanai uses DMA memory would343 * make that a terrific pain. This is much simpler.344 */345 buf->start = dma_alloc_coherent(&pci->dev,346 size, &buf->dmaaddr, GFP_KERNEL);347 if (buf->start != NULL) { /* Success */348 /* Lanai requires 256-byte alignment of DMA bufs */349 APRINTK((buf->dmaaddr & ~0xFFFFFF00) == 0,350 "bad dmaaddr: 0x%lx\n",351 (unsigned long) buf->dmaaddr);352 buf->ptr = buf->start;353 buf->end = (u32 *)354 (&((unsigned char *) buf->start)[size]);355 memset(buf->start, 0, size);356 break;357 }358 size /= 2;359 } while (size >= minbytes);360}361 362/* size of buffer in bytes */363static inline size_t lanai_buf_size(const struct lanai_buffer *buf)364{365 return ((unsigned long) buf->end) - ((unsigned long) buf->start);366}367 368static void lanai_buf_deallocate(struct lanai_buffer *buf,369 struct pci_dev *pci)370{371 if (buf->start != NULL) {372 dma_free_coherent(&pci->dev, lanai_buf_size(buf),373 buf->start, buf->dmaaddr);374 buf->start = buf->end = buf->ptr = NULL;375 }376}377 378/* size of buffer as "card order" (0=1k .. 7=128k) */379static int lanai_buf_size_cardorder(const struct lanai_buffer *buf)380{381 int order = get_order(lanai_buf_size(buf)) + (PAGE_SHIFT - 10);382 383 /* This can only happen if PAGE_SIZE is gigantic, but just in case */384 if (order > 7)385 order = 7;386 return order;387}388 389/* -------------------- PORT I/O UTILITIES: */390 391/* Registers (and their bit-fields) */392enum lanai_register {393 Reset_Reg = 0x00, /* Reset; read for chip type; bits: */394#define RESET_GET_BOARD_REV(x) (((x)>> 0)&0x03) /* Board revision */395#define RESET_GET_BOARD_ID(x) (((x)>> 2)&0x03) /* Board ID */396#define BOARD_ID_LANAI256 (0) /* 25.6M adapter card */397 Endian_Reg = 0x04, /* Endian setting */398 IntStatus_Reg = 0x08, /* Interrupt status */399 IntStatusMasked_Reg = 0x0C, /* Interrupt status (masked) */400 IntAck_Reg = 0x10, /* Interrupt acknowledge */401 IntAckMasked_Reg = 0x14, /* Interrupt acknowledge (masked) */402 IntStatusSet_Reg = 0x18, /* Get status + enable/disable */403 IntStatusSetMasked_Reg = 0x1C, /* Get status + en/di (masked) */404 IntControlEna_Reg = 0x20, /* Interrupt control enable */405 IntControlDis_Reg = 0x24, /* Interrupt control disable */406 Status_Reg = 0x28, /* Status */407#define STATUS_PROMDATA (0x00000001) /* PROM_DATA pin */408#define STATUS_WAITING (0x00000002) /* Interrupt being delayed */409#define STATUS_SOOL (0x00000004) /* SOOL alarm */410#define STATUS_LOCD (0x00000008) /* LOCD alarm */411#define STATUS_LED (0x00000010) /* LED (HAPPI) output */412#define STATUS_GPIN (0x00000020) /* GPIN pin */413#define STATUS_BUTTBUSY (0x00000040) /* Butt register is pending */414 Config1_Reg = 0x2C, /* Config word 1; bits: */415#define CONFIG1_PROMDATA (0x00000001) /* PROM_DATA pin */416#define CONFIG1_PROMCLK (0x00000002) /* PROM_CLK pin */417#define CONFIG1_SET_READMODE(x) ((x)*0x004) /* PCI BM reads; values: */418#define READMODE_PLAIN (0) /* Plain memory read */419#define READMODE_LINE (2) /* Memory read line */420#define READMODE_MULTIPLE (3) /* Memory read multiple */421#define CONFIG1_DMA_ENABLE (0x00000010) /* Turn on DMA */422#define CONFIG1_POWERDOWN (0x00000020) /* Turn off clocks */423#define CONFIG1_SET_LOOPMODE(x) ((x)*0x080) /* Clock&loop mode; values: */424#define LOOPMODE_NORMAL (0) /* Normal - no loop */425#define LOOPMODE_TIME (1)426#define LOOPMODE_DIAG (2)427#define LOOPMODE_LINE (3)428#define CONFIG1_MASK_LOOPMODE (0x00000180)429#define CONFIG1_SET_LEDMODE(x) ((x)*0x0200) /* Mode of LED; values: */430#define LEDMODE_NOT_SOOL (0) /* !SOOL */431#define LEDMODE_OFF (1) /* 0 */432#define LEDMODE_ON (2) /* 1 */433#define LEDMODE_NOT_LOCD (3) /* !LOCD */434#define LEDMORE_GPIN (4) /* GPIN */435#define LEDMODE_NOT_GPIN (7) /* !GPIN */436#define CONFIG1_MASK_LEDMODE (0x00000E00)437#define CONFIG1_GPOUT1 (0x00001000) /* Toggle for reset */438#define CONFIG1_GPOUT2 (0x00002000) /* Loopback PHY */439#define CONFIG1_GPOUT3 (0x00004000) /* Loopback lanai */440 Config2_Reg = 0x30, /* Config word 2; bits: */441#define CONFIG2_HOWMANY (0x00000001) /* >512 VCIs? */442#define CONFIG2_PTI7_MODE (0x00000002) /* Make PTI=7 RM, not OAM */443#define CONFIG2_VPI_CHK_DIS (0x00000004) /* Ignore RX VPI value */444#define CONFIG2_HEC_DROP (0x00000008) /* Drop cells w/ HEC errors */445#define CONFIG2_VCI0_NORMAL (0x00000010) /* Treat VCI=0 normally */446#define CONFIG2_CBR_ENABLE (0x00000020) /* Deal with CBR traffic */447#define CONFIG2_TRASH_ALL (0x00000040) /* Trashing incoming cells */448#define CONFIG2_TX_DISABLE (0x00000080) /* Trashing outgoing cells */449#define CONFIG2_SET_TRASH (0x00000100) /* Turn trashing on */450 Statistics_Reg = 0x34, /* Statistics; bits: */451#define STATS_GET_FIFO_OVFL(x) (((x)>> 0)&0xFF) /* FIFO overflowed */452#define STATS_GET_HEC_ERR(x) (((x)>> 8)&0xFF) /* HEC was bad */453#define STATS_GET_BAD_VCI(x) (((x)>>16)&0xFF) /* VCI not open */454#define STATS_GET_BUF_OVFL(x) (((x)>>24)&0xFF) /* VCC buffer full */455 ServiceStuff_Reg = 0x38, /* Service stuff; bits: */456#define SSTUFF_SET_SIZE(x) ((x)*0x20000000) /* size of service buffer */457#define SSTUFF_SET_ADDR(x) ((x)>>8) /* set address of buffer */458 ServWrite_Reg = 0x3C, /* ServWrite Pointer */459 ServRead_Reg = 0x40, /* ServRead Pointer */460 TxDepth_Reg = 0x44, /* FIFO Transmit Depth */461 Butt_Reg = 0x48, /* Butt register */462 CBR_ICG_Reg = 0x50,463 CBR_PTR_Reg = 0x54,464 PingCount_Reg = 0x58, /* Ping count */465 DMA_Addr_Reg = 0x5C /* DMA address */466};467 468static inline bus_addr_t reg_addr(const struct lanai_dev *lanai,469 enum lanai_register reg)470{471 return lanai->base + reg;472}473 474static inline u32 reg_read(const struct lanai_dev *lanai,475 enum lanai_register reg)476{477 u32 t;478 t = readl(reg_addr(lanai, reg));479 RWDEBUG("R [0x%08X] 0x%02X = 0x%08X\n", (unsigned int) lanai->base,480 (int) reg, t);481 return t;482}483 484static inline void reg_write(const struct lanai_dev *lanai, u32 val,485 enum lanai_register reg)486{487 RWDEBUG("W [0x%08X] 0x%02X < 0x%08X\n", (unsigned int) lanai->base,488 (int) reg, val);489 writel(val, reg_addr(lanai, reg));490}491 492static inline void conf1_write(const struct lanai_dev *lanai)493{494 reg_write(lanai, lanai->conf1, Config1_Reg);495}496 497static inline void conf2_write(const struct lanai_dev *lanai)498{499 reg_write(lanai, lanai->conf2, Config2_Reg);500}501 502/* Same as conf2_write(), but defers I/O if we're powered down */503static inline void conf2_write_if_powerup(const struct lanai_dev *lanai)504{505#ifdef USE_POWERDOWN506 if (unlikely((lanai->conf1 & CONFIG1_POWERDOWN) != 0))507 return;508#endif /* USE_POWERDOWN */509 conf2_write(lanai);510}511 512static inline void reset_board(const struct lanai_dev *lanai)513{514 DPRINTK("about to reset board\n");515 reg_write(lanai, 0, Reset_Reg);516 /*517 * If we don't delay a little while here then we can end up518 * leaving the card in a VERY weird state and lock up the519 * PCI bus. This isn't documented anywhere but I've convinced520 * myself after a lot of painful experimentation521 */522 udelay(5);523}524 525/* -------------------- CARD SRAM UTILITIES: */526 527/* The SRAM is mapped into normal PCI memory space - the only catch is528 * that it is only 16-bits wide but must be accessed as 32-bit. The529 * 16 high bits will be zero. We don't hide this, since they get530 * programmed mostly like discrete registers anyway531 */532#define SRAM_START (0x20000)533#define SRAM_BYTES (0x20000) /* Again, half don't really exist */534 535static inline bus_addr_t sram_addr(const struct lanai_dev *lanai, int offset)536{537 return lanai->base + SRAM_START + offset;538}539 540static inline u32 sram_read(const struct lanai_dev *lanai, int offset)541{542 return readl(sram_addr(lanai, offset));543}544 545static inline void sram_write(const struct lanai_dev *lanai,546 u32 val, int offset)547{548 writel(val, sram_addr(lanai, offset));549}550 551static int sram_test_word(const struct lanai_dev *lanai, int offset,552 u32 pattern)553{554 u32 readback;555 sram_write(lanai, pattern, offset);556 readback = sram_read(lanai, offset);557 if (likely(readback == pattern))558 return 0;559 printk(KERN_ERR DEV_LABEL560 "(itf %d): SRAM word at %d bad: wrote 0x%X, read 0x%X\n",561 lanai->number, offset,562 (unsigned int) pattern, (unsigned int) readback);563 return -EIO;564}565 566static int sram_test_pass(const struct lanai_dev *lanai, u32 pattern)567{568 int offset, result = 0;569 for (offset = 0; offset < SRAM_BYTES && result == 0; offset += 4)570 result = sram_test_word(lanai, offset, pattern);571 return result;572}573 574static int sram_test_and_clear(const struct lanai_dev *lanai)575{576#ifdef FULL_MEMORY_TEST577 int result;578 DPRINTK("testing SRAM\n");579 if ((result = sram_test_pass(lanai, 0x5555)) != 0)580 return result;581 if ((result = sram_test_pass(lanai, 0xAAAA)) != 0)582 return result;583#endif584 DPRINTK("clearing SRAM\n");585 return sram_test_pass(lanai, 0x0000);586}587 588/* -------------------- CARD-BASED VCC TABLE UTILITIES: */589 590/* vcc table */591enum lanai_vcc_offset {592 vcc_rxaddr1 = 0x00, /* Location1, plus bits: */593#define RXADDR1_SET_SIZE(x) ((x)*0x0000100) /* size of RX buffer */594#define RXADDR1_SET_RMMODE(x) ((x)*0x00800) /* RM cell action; values: */595#define RMMODE_TRASH (0) /* discard */596#define RMMODE_PRESERVE (1) /* input as AAL0 */597#define RMMODE_PIPE (2) /* pipe to coscheduler */598#define RMMODE_PIPEALL (3) /* pipe non-RM too */599#define RXADDR1_OAM_PRESERVE (0x00002000) /* Input OAM cells as AAL0 */600#define RXADDR1_SET_MODE(x) ((x)*0x0004000) /* Reassembly mode */601#define RXMODE_TRASH (0) /* discard */602#define RXMODE_AAL0 (1) /* non-AAL5 mode */603#define RXMODE_AAL5 (2) /* AAL5, intr. each PDU */604#define RXMODE_AAL5_STREAM (3) /* AAL5 w/o per-PDU intr */605 vcc_rxaddr2 = 0x04, /* Location2 */606 vcc_rxcrc1 = 0x08, /* RX CRC claculation space */607 vcc_rxcrc2 = 0x0C,608 vcc_rxwriteptr = 0x10, /* RX writeptr, plus bits: */609#define RXWRITEPTR_LASTEFCI (0x00002000) /* Last PDU had EFCI bit */610#define RXWRITEPTR_DROPPING (0x00004000) /* Had error, dropping */611#define RXWRITEPTR_TRASHING (0x00008000) /* Trashing */612 vcc_rxbufstart = 0x14, /* RX bufstart, plus bits: */613#define RXBUFSTART_CLP (0x00004000)614#define RXBUFSTART_CI (0x00008000)615 vcc_rxreadptr = 0x18, /* RX readptr */616 vcc_txicg = 0x1C, /* TX ICG */617 vcc_txaddr1 = 0x20, /* Location1, plus bits: */618#define TXADDR1_SET_SIZE(x) ((x)*0x0000100) /* size of TX buffer */619#define TXADDR1_ABR (0x00008000) /* use ABR (doesn't work) */620 vcc_txaddr2 = 0x24, /* Location2 */621 vcc_txcrc1 = 0x28, /* TX CRC claculation space */622 vcc_txcrc2 = 0x2C,623 vcc_txreadptr = 0x30, /* TX Readptr, plus bits: */624#define TXREADPTR_GET_PTR(x) ((x)&0x01FFF)625#define TXREADPTR_MASK_DELTA (0x0000E000) /* ? */626 vcc_txendptr = 0x34, /* TX Endptr, plus bits: */627#define TXENDPTR_CLP (0x00002000)628#define TXENDPTR_MASK_PDUMODE (0x0000C000) /* PDU mode; values: */629#define PDUMODE_AAL0 (0*0x04000)630#define PDUMODE_AAL5 (2*0x04000)631#define PDUMODE_AAL5STREAM (3*0x04000)632 vcc_txwriteptr = 0x38, /* TX Writeptr */633#define TXWRITEPTR_GET_PTR(x) ((x)&0x1FFF)634 vcc_txcbr_next = 0x3C /* # of next CBR VCI in ring */635#define TXCBR_NEXT_BOZO (0x00008000) /* "bozo bit" */636};637 638#define CARDVCC_SIZE (0x40)639 640static inline bus_addr_t cardvcc_addr(const struct lanai_dev *lanai,641 vci_t vci)642{643 return sram_addr(lanai, vci * CARDVCC_SIZE);644}645 646static inline u32 cardvcc_read(const struct lanai_vcc *lvcc,647 enum lanai_vcc_offset offset)648{649 u32 val;650 APRINTK(lvcc->vbase != NULL, "cardvcc_read: unbound vcc!\n");651 val= readl(lvcc->vbase + offset);652 RWDEBUG("VR vci=%04d 0x%02X = 0x%08X\n",653 lvcc->vci, (int) offset, val);654 return val;655}656 657static inline void cardvcc_write(const struct lanai_vcc *lvcc,658 u32 val, enum lanai_vcc_offset offset)659{660 APRINTK(lvcc->vbase != NULL, "cardvcc_write: unbound vcc!\n");661 APRINTK((val & ~0xFFFF) == 0,662 "cardvcc_write: bad val 0x%X (vci=%d, addr=0x%02X)\n",663 (unsigned int) val, lvcc->vci, (unsigned int) offset);664 RWDEBUG("VW vci=%04d 0x%02X > 0x%08X\n",665 lvcc->vci, (unsigned int) offset, (unsigned int) val);666 writel(val, lvcc->vbase + offset);667}668 669/* -------------------- COMPUTE SIZE OF AN AAL5 PDU: */670 671/* How many bytes will an AAL5 PDU take to transmit - remember that:672 * o we need to add 8 bytes for length, CPI, UU, and CRC673 * o we need to round up to 48 bytes for cells674 */675static inline int aal5_size(int size)676{677 int cells = (size + 8 + 47) / 48;678 return cells * 48;679}680 681/* -------------------- FREE AN ATM SKB: */682 683static inline void lanai_free_skb(struct atm_vcc *atmvcc, struct sk_buff *skb)684{685 if (atmvcc->pop != NULL)686 atmvcc->pop(atmvcc, skb);687 else688 dev_kfree_skb_any(skb);689}690 691/* -------------------- TURN VCCS ON AND OFF: */692 693static void host_vcc_start_rx(const struct lanai_vcc *lvcc)694{695 u32 addr1;696 if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5) {697 dma_addr_t dmaaddr = lvcc->rx.buf.dmaaddr;698 cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc1);699 cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc2);700 cardvcc_write(lvcc, 0, vcc_rxwriteptr);701 cardvcc_write(lvcc, 0, vcc_rxbufstart);702 cardvcc_write(lvcc, 0, vcc_rxreadptr);703 cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_rxaddr2);704 addr1 = ((dmaaddr >> 8) & 0xFF) |705 RXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->rx.buf))|706 RXADDR1_SET_RMMODE(RMMODE_TRASH) | /* ??? */707 /* RXADDR1_OAM_PRESERVE | --- no OAM support yet */708 RXADDR1_SET_MODE(RXMODE_AAL5);709 } else710 addr1 = RXADDR1_SET_RMMODE(RMMODE_PRESERVE) | /* ??? */711 RXADDR1_OAM_PRESERVE | /* ??? */712 RXADDR1_SET_MODE(RXMODE_AAL0);713 /* This one must be last! */714 cardvcc_write(lvcc, addr1, vcc_rxaddr1);715}716 717static void host_vcc_start_tx(const struct lanai_vcc *lvcc)718{719 dma_addr_t dmaaddr = lvcc->tx.buf.dmaaddr;720 cardvcc_write(lvcc, 0, vcc_txicg);721 cardvcc_write(lvcc, 0xFFFF, vcc_txcrc1);722 cardvcc_write(lvcc, 0xFFFF, vcc_txcrc2);723 cardvcc_write(lvcc, 0, vcc_txreadptr);724 cardvcc_write(lvcc, 0, vcc_txendptr);725 cardvcc_write(lvcc, 0, vcc_txwriteptr);726 cardvcc_write(lvcc,727 (lvcc->tx.atmvcc->qos.txtp.traffic_class == ATM_CBR) ?728 TXCBR_NEXT_BOZO | lvcc->vci : 0, vcc_txcbr_next);729 cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_txaddr2);730 cardvcc_write(lvcc,731 ((dmaaddr >> 8) & 0xFF) |732 TXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->tx.buf)),733 vcc_txaddr1);734}735 736/* Shutdown receiving on card */737static void lanai_shutdown_rx_vci(const struct lanai_vcc *lvcc)738{739 if (lvcc->vbase == NULL) /* We were never bound to a VCI */740 return;741 /* 15.1.1 - set to trashing, wait one cell time (15us) */742 cardvcc_write(lvcc,743 RXADDR1_SET_RMMODE(RMMODE_TRASH) |744 RXADDR1_SET_MODE(RXMODE_TRASH), vcc_rxaddr1);745 udelay(15);746 /* 15.1.2 - clear rest of entries */747 cardvcc_write(lvcc, 0, vcc_rxaddr2);748 cardvcc_write(lvcc, 0, vcc_rxcrc1);749 cardvcc_write(lvcc, 0, vcc_rxcrc2);750 cardvcc_write(lvcc, 0, vcc_rxwriteptr);751 cardvcc_write(lvcc, 0, vcc_rxbufstart);752 cardvcc_write(lvcc, 0, vcc_rxreadptr);753}754 755/* Shutdown transmitting on card.756 * Unfortunately the lanai needs us to wait until all the data757 * drains out of the buffer before we can dealloc it, so this758 * can take awhile -- up to 370ms for a full 128KB buffer759 * assuming everone else is quiet. In theory the time is760 * boundless if there's a CBR VCC holding things up.761 */762static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,763 struct lanai_vcc *lvcc)764{765 struct sk_buff *skb;766 unsigned long flags, timeout;767 int read, write, lastread = -1;768 769 if (lvcc->vbase == NULL) /* We were never bound to a VCI */770 return;771 /* 15.2.1 - wait for queue to drain */772 while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)773 lanai_free_skb(lvcc->tx.atmvcc, skb);774 read_lock_irqsave(&vcc_sklist_lock, flags);775 __clear_bit(lvcc->vci, lanai->backlog_vccs);776 read_unlock_irqrestore(&vcc_sklist_lock, flags);777 /*778 * We need to wait for the VCC to drain but don't wait forever. We779 * give each 1K of buffer size 1/128th of a second to clear out.780 * TODO: maybe disable CBR if we're about to timeout?781 */782 timeout = jiffies +783 (((lanai_buf_size(&lvcc->tx.buf) / 1024) * HZ) >> 7);784 write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));785 for (;;) {786 read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));787 if (read == write && /* Is TX buffer empty? */788 (lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR ||789 (cardvcc_read(lvcc, vcc_txcbr_next) &790 TXCBR_NEXT_BOZO) == 0))791 break;792 if (read != lastread) { /* Has there been any progress? */793 lastread = read;794 timeout += HZ / 10;795 }796 if (unlikely(time_after(jiffies, timeout))) {797 printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on "798 "backlog closing vci %d\n",799 lvcc->tx.atmvcc->dev->number, lvcc->vci);800 DPRINTK("read, write = %d, %d\n", read, write);801 break;802 }803 msleep(40);804 }805 /* 15.2.2 - clear out all tx registers */806 cardvcc_write(lvcc, 0, vcc_txreadptr);807 cardvcc_write(lvcc, 0, vcc_txwriteptr);808 cardvcc_write(lvcc, 0, vcc_txendptr);809 cardvcc_write(lvcc, 0, vcc_txcrc1);810 cardvcc_write(lvcc, 0, vcc_txcrc2);811 cardvcc_write(lvcc, 0, vcc_txaddr2);812 cardvcc_write(lvcc, 0, vcc_txaddr1);813}814 815/* -------------------- MANAGING AAL0 RX BUFFER: */816 817static inline int aal0_buffer_allocate(struct lanai_dev *lanai)818{819 DPRINTK("aal0_buffer_allocate: allocating AAL0 RX buffer\n");820 lanai_buf_allocate(&lanai->aal0buf, AAL0_RX_BUFFER_SIZE, 80,821 lanai->pci);822 return (lanai->aal0buf.start == NULL) ? -ENOMEM : 0;823}824 825static inline void aal0_buffer_free(struct lanai_dev *lanai)826{827 DPRINTK("aal0_buffer_allocate: freeing AAL0 RX buffer\n");828 lanai_buf_deallocate(&lanai->aal0buf, lanai->pci);829}830 831/* -------------------- EEPROM UTILITIES: */832 833/* Offsets of data in the EEPROM */834#define EEPROM_COPYRIGHT (0)835#define EEPROM_COPYRIGHT_LEN (44)836#define EEPROM_CHECKSUM (62)837#define EEPROM_CHECKSUM_REV (63)838#define EEPROM_MAC (64)839#define EEPROM_MAC_REV (70)840#define EEPROM_SERIAL (112)841#define EEPROM_SERIAL_REV (116)842#define EEPROM_MAGIC (120)843#define EEPROM_MAGIC_REV (124)844 845#define EEPROM_MAGIC_VALUE (0x5AB478D2)846 847#ifndef READ_EEPROM848 849/* Stub functions to use if EEPROM reading is disabled */850static int eeprom_read(struct lanai_dev *lanai)851{852 printk(KERN_INFO DEV_LABEL "(itf %d): *NOT* reading EEPROM\n",853 lanai->number);854 memset(&lanai->eeprom[EEPROM_MAC], 0, 6);855 return 0;856}857 858static int eeprom_validate(struct lanai_dev *lanai)859{860 lanai->serialno = 0;861 lanai->magicno = EEPROM_MAGIC_VALUE;862 return 0;863}864 865#else /* READ_EEPROM */866 867static int eeprom_read(struct lanai_dev *lanai)868{869 int i, address;870 u8 data;871 u32 tmp;872#define set_config1(x) do { lanai->conf1 = x; conf1_write(lanai); \873 } while (0)874#define clock_h() set_config1(lanai->conf1 | CONFIG1_PROMCLK)875#define clock_l() set_config1(lanai->conf1 &~ CONFIG1_PROMCLK)876#define data_h() set_config1(lanai->conf1 | CONFIG1_PROMDATA)877#define data_l() set_config1(lanai->conf1 &~ CONFIG1_PROMDATA)878#define pre_read() do { data_h(); clock_h(); udelay(5); } while (0)879#define read_pin() (reg_read(lanai, Status_Reg) & STATUS_PROMDATA)880#define send_stop() do { data_l(); udelay(5); clock_h(); udelay(5); \881 data_h(); udelay(5); } while (0)882 /* start with both clock and data high */883 data_h(); clock_h(); udelay(5);884 for (address = 0; address < LANAI_EEPROM_SIZE; address++) {885 data = (address << 1) | 1; /* Command=read + address */886 /* send start bit */887 data_l(); udelay(5);888 clock_l(); udelay(5);889 for (i = 128; i != 0; i >>= 1) { /* write command out */890 tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |891 ((data & i) ? CONFIG1_PROMDATA : 0);892 if (lanai->conf1 != tmp) {893 set_config1(tmp);894 udelay(5); /* Let new data settle */895 }896 clock_h(); udelay(5); clock_l(); udelay(5);897 }898 /* look for ack */899 data_h(); clock_h(); udelay(5);900 if (read_pin() != 0)901 goto error; /* No ack seen */902 clock_l(); udelay(5);903 /* read back result */904 for (data = 0, i = 7; i >= 0; i--) {905 data_h(); clock_h(); udelay(5);906 data = (data << 1) | !!read_pin();907 clock_l(); udelay(5);908 }909 /* look again for ack */910 data_h(); clock_h(); udelay(5);911 if (read_pin() == 0)912 goto error; /* Spurious ack */913 clock_l(); udelay(5);914 send_stop();915 lanai->eeprom[address] = data;916 DPRINTK("EEPROM 0x%04X %02X\n",917 (unsigned int) address, (unsigned int) data);918 }919 return 0;920 error:921 clock_l(); udelay(5); /* finish read */922 send_stop();923 printk(KERN_ERR DEV_LABEL "(itf %d): error reading EEPROM byte %d\n",924 lanai->number, address);925 return -EIO;926#undef set_config1927#undef clock_h928#undef clock_l929#undef data_h930#undef data_l931#undef pre_read932#undef read_pin933#undef send_stop934}935 936/* read a big-endian 4-byte value out of eeprom */937static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address)938{939 return be32_to_cpup((const u32 *) &lanai->eeprom[address]);940}941 942/* Checksum/validate EEPROM contents */943static int eeprom_validate(struct lanai_dev *lanai)944{945 int i, s;946 u32 v;947 const u8 *e = lanai->eeprom;948#ifdef DEBUG949 /* First, see if we can get an ASCIIZ string out of the copyright */950 for (i = EEPROM_COPYRIGHT;951 i < (EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN); i++)952 if (e[i] < 0x20 || e[i] > 0x7E)953 break;954 if ( i != EEPROM_COPYRIGHT &&955 i != EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN && e[i] == '\0')956 DPRINTK("eeprom: copyright = \"%s\"\n",957 (char *) &e[EEPROM_COPYRIGHT]);958 else959 DPRINTK("eeprom: copyright not found\n");960#endif961 /* Validate checksum */962 for (i = s = 0; i < EEPROM_CHECKSUM; i++)963 s += e[i];964 s &= 0xFF;965 if (s != e[EEPROM_CHECKSUM]) {966 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM checksum bad "967 "(wanted 0x%02X, got 0x%02X)\n", lanai->number,968 (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM]);969 return -EIO;970 }971 s ^= 0xFF;972 if (s != e[EEPROM_CHECKSUM_REV]) {973 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM inverse checksum "974 "bad (wanted 0x%02X, got 0x%02X)\n", lanai->number,975 (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM_REV]);976 return -EIO;977 }978 /* Verify MAC address */979 for (i = 0; i < 6; i++)980 if ((e[EEPROM_MAC + i] ^ e[EEPROM_MAC_REV + i]) != 0xFF) {981 printk(KERN_ERR DEV_LABEL982 "(itf %d) : EEPROM MAC addresses don't match "983 "(0x%02X, inverse 0x%02X)\n", lanai->number,984 (unsigned int) e[EEPROM_MAC + i],985 (unsigned int) e[EEPROM_MAC_REV + i]);986 return -EIO;987 }988 DPRINTK("eeprom: MAC address = %pM\n", &e[EEPROM_MAC]);989 /* Verify serial number */990 lanai->serialno = eeprom_be4(lanai, EEPROM_SERIAL);991 v = eeprom_be4(lanai, EEPROM_SERIAL_REV);992 if ((lanai->serialno ^ v) != 0xFFFFFFFF) {993 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM serial numbers "994 "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,995 (unsigned int) lanai->serialno, (unsigned int) v);996 return -EIO;997 }998 DPRINTK("eeprom: Serial number = %d\n", (unsigned int) lanai->serialno);999 /* Verify magic number */1000 lanai->magicno = eeprom_be4(lanai, EEPROM_MAGIC);1001 v = eeprom_be4(lanai, EEPROM_MAGIC_REV);1002 if ((lanai->magicno ^ v) != 0xFFFFFFFF) {1003 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM magic numbers "1004 "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,1005 lanai->magicno, v);1006 return -EIO;1007 }1008 DPRINTK("eeprom: Magic number = 0x%08X\n", lanai->magicno);1009 if (lanai->magicno != EEPROM_MAGIC_VALUE)1010 printk(KERN_WARNING DEV_LABEL "(itf %d): warning - EEPROM "1011 "magic not what expected (got 0x%08X, not 0x%08X)\n",1012 lanai->number, (unsigned int) lanai->magicno,1013 (unsigned int) EEPROM_MAGIC_VALUE);1014 return 0;1015}1016 1017#endif /* READ_EEPROM */1018 1019static inline const u8 *eeprom_mac(const struct lanai_dev *lanai)1020{1021 return &lanai->eeprom[EEPROM_MAC];1022}1023 1024/* -------------------- INTERRUPT HANDLING UTILITIES: */1025 1026/* Interrupt types */1027#define INT_STATS (0x00000002) /* Statistics counter overflow */1028#define INT_SOOL (0x00000004) /* SOOL changed state */1029#define INT_LOCD (0x00000008) /* LOCD changed state */1030#define INT_LED (0x00000010) /* LED (HAPPI) changed state */1031#define INT_GPIN (0x00000020) /* GPIN changed state */1032#define INT_PING (0x00000040) /* PING_COUNT fulfilled */1033#define INT_WAKE (0x00000080) /* Lanai wants bus */1034#define INT_CBR0 (0x00000100) /* CBR sched hit VCI 0 */1035#define INT_LOCK (0x00000200) /* Service list overflow */1036#define INT_MISMATCH (0x00000400) /* TX magic list mismatch */1037#define INT_AAL0_STR (0x00000800) /* Non-AAL5 buffer half filled */1038#define INT_AAL0 (0x00001000) /* Non-AAL5 data available */1039#define INT_SERVICE (0x00002000) /* Service list entries available */1040#define INT_TABORTSENT (0x00004000) /* Target abort sent by lanai */1041#define INT_TABORTBM (0x00008000) /* Abort rcv'd as bus master */1042#define INT_TIMEOUTBM (0x00010000) /* No response to bus master */1043#define INT_PCIPARITY (0x00020000) /* Parity error on PCI */1044 1045/* Sets of the above */1046#define INT_ALL (0x0003FFFE) /* All interrupts */1047#define INT_STATUS (0x0000003C) /* Some status pin changed */1048#define INT_DMASHUT (0x00038000) /* DMA engine got shut down */1049#define INT_SEGSHUT (0x00000700) /* Segmentation got shut down */1050 1051static inline u32 intr_pending(const struct lanai_dev *lanai)1052{1053 return reg_read(lanai, IntStatusMasked_Reg);1054}1055 1056static inline void intr_enable(const struct lanai_dev *lanai, u32 i)1057{1058 reg_write(lanai, i, IntControlEna_Reg);1059}1060 1061static inline void intr_disable(const struct lanai_dev *lanai, u32 i)1062{1063 reg_write(lanai, i, IntControlDis_Reg);1064}1065 1066/* -------------------- CARD/PCI STATUS: */1067 1068static void status_message(int itf, const char *name, int status)1069{1070 static const char *onoff[2] = { "off to on", "on to off" };1071 printk(KERN_INFO DEV_LABEL "(itf %d): %s changed from %s\n",1072 itf, name, onoff[!status]);1073}1074 1075static void lanai_check_status(struct lanai_dev *lanai)1076{1077 u32 new = reg_read(lanai, Status_Reg);1078 u32 changes = new ^ lanai->status;1079 lanai->status = new;1080#define e(flag, name) \1081 if (changes & flag) \1082 status_message(lanai->number, name, new & flag)1083 e(STATUS_SOOL, "SOOL");1084 e(STATUS_LOCD, "LOCD");1085 e(STATUS_LED, "LED");1086 e(STATUS_GPIN, "GPIN");1087#undef e1088}1089 1090static void pcistatus_got(int itf, const char *name)1091{1092 printk(KERN_INFO DEV_LABEL "(itf %d): PCI got %s error\n", itf, name);1093}1094 1095static void pcistatus_check(struct lanai_dev *lanai, int clearonly)1096{1097 u16 s;1098 int result;1099 result = pci_read_config_word(lanai->pci, PCI_STATUS, &s);1100 if (result != PCIBIOS_SUCCESSFUL) {1101 printk(KERN_ERR DEV_LABEL "(itf %d): can't read PCI_STATUS: "1102 "%d\n", lanai->number, result);1103 return;1104 }1105 s &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |1106 PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT |1107 PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_PARITY;1108 if (s == 0)1109 return;1110 result = pci_write_config_word(lanai->pci, PCI_STATUS, s);1111 if (result != PCIBIOS_SUCCESSFUL)1112 printk(KERN_ERR DEV_LABEL "(itf %d): can't write PCI_STATUS: "1113 "%d\n", lanai->number, result);1114 if (clearonly)1115 return;1116#define e(flag, name, stat) \1117 if (s & flag) { \1118 pcistatus_got(lanai->number, name); \1119 ++lanai->stats.pcierr_##stat; \1120 }1121 e(PCI_STATUS_DETECTED_PARITY, "parity", parity_detect);1122 e(PCI_STATUS_SIG_SYSTEM_ERROR, "signalled system", serr_set);1123 e(PCI_STATUS_REC_MASTER_ABORT, "master", master_abort);1124 e(PCI_STATUS_REC_TARGET_ABORT, "master target", m_target_abort);1125 e(PCI_STATUS_SIG_TARGET_ABORT, "slave", s_target_abort);1126 e(PCI_STATUS_PARITY, "master parity", master_parity);1127#undef e1128}1129 1130/* -------------------- VCC TX BUFFER UTILITIES: */1131 1132/* space left in tx buffer in bytes */1133static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)1134{1135 int r;1136 r = endptr * 16;1137 r -= ((unsigned long) lvcc->tx.buf.ptr) -1138 ((unsigned long) lvcc->tx.buf.start);1139 r -= 16; /* Leave "bubble" - if start==end it looks empty */1140 if (r < 0)1141 r += lanai_buf_size(&lvcc->tx.buf);1142 return r;1143}1144 1145/* test if VCC is currently backlogged */1146static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)1147{1148 return !skb_queue_empty(&lvcc->tx.backlog);1149}1150 1151/* Bit fields in the segmentation buffer descriptor */1152#define DESCRIPTOR_MAGIC (0xD0000000)1153#define DESCRIPTOR_AAL5 (0x00008000)1154#define DESCRIPTOR_AAL5_STREAM (0x00004000)1155#define DESCRIPTOR_CLP (0x00002000)1156 1157/* Add 32-bit descriptor with its padding */1158static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,1159 u32 flags, int len)1160{1161 int pos;1162 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 0,1163 "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);1164 lvcc->tx.buf.ptr += 4; /* Hope the values REALLY don't matter */1165 pos = ((unsigned char *) lvcc->tx.buf.ptr) -1166 (unsigned char *) lvcc->tx.buf.start;1167 APRINTK((pos & ~0x0001FFF0) == 0,1168 "vcc_tx_add_aal5_descriptor: bad pos (%d) before, vci=%d, "1169 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,1170 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);1171 pos = (pos + len) & (lanai_buf_size(&lvcc->tx.buf) - 1);1172 APRINTK((pos & ~0x0001FFF0) == 0,1173 "vcc_tx_add_aal5_descriptor: bad pos (%d) after, vci=%d, "1174 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,1175 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);1176 lvcc->tx.buf.ptr[-1] =1177 cpu_to_le32(DESCRIPTOR_MAGIC | DESCRIPTOR_AAL5 |1178 ((lvcc->tx.atmvcc->atm_options & ATM_ATMOPT_CLP) ?1179 DESCRIPTOR_CLP : 0) | flags | pos >> 4);1180 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)1181 lvcc->tx.buf.ptr = lvcc->tx.buf.start;1182}1183 1184/* Add 32-bit AAL5 trailer and leave room for its CRC */1185static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc,1186 int len, int cpi, int uu)1187{1188 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8,1189 "vcc_tx_add_aal5_trailer: bad ptr=%p\n", lvcc->tx.buf.ptr);1190 lvcc->tx.buf.ptr += 2;1191 lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len);1192 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)1193 lvcc->tx.buf.ptr = lvcc->tx.buf.start;1194}1195 1196static inline void vcc_tx_memcpy(struct lanai_vcc *lvcc,1197 const unsigned char *src, int n)1198{1199 unsigned char *e;1200 int m;1201 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;1202 m = e - (unsigned char *) lvcc->tx.buf.end;1203 if (m < 0)1204 m = 0;1205 memcpy(lvcc->tx.buf.ptr, src, n - m);1206 if (m != 0) {1207 memcpy(lvcc->tx.buf.start, src + n - m, m);1208 e = ((unsigned char *) lvcc->tx.buf.start) + m;1209 }1210 lvcc->tx.buf.ptr = (u32 *) e;1211}1212 1213static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)1214{1215 unsigned char *e;1216 int m;1217 if (n == 0)1218 return;1219 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;1220 m = e - (unsigned char *) lvcc->tx.buf.end;1221 if (m < 0)1222 m = 0;1223 memset(lvcc->tx.buf.ptr, 0, n - m);1224 if (m != 0) {1225 memset(lvcc->tx.buf.start, 0, m);1226 e = ((unsigned char *) lvcc->tx.buf.start) + m;1227 }1228 lvcc->tx.buf.ptr = (u32 *) e;1229}1230 1231/* Update "butt" register to specify new WritePtr */1232static inline void lanai_endtx(struct lanai_dev *lanai,1233 const struct lanai_vcc *lvcc)1234{1235 int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) -1236 (unsigned char *) lvcc->tx.buf.start;1237 APRINTK((ptr & ~0x0001FFF0) == 0,1238 "lanai_endtx: bad ptr (%d), vci=%d, start,ptr,end=%p,%p,%p\n",1239 ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr,1240 lvcc->tx.buf.end);1241 1242 /*1243 * Since the "butt register" is a shared resounce on the card we1244 * serialize all accesses to it through this spinlock. This is1245 * mostly just paranoia since the register is rarely "busy" anyway1246 * but is needed for correctness.1247 */1248 spin_lock(&lanai->endtxlock);1249 /*1250 * We need to check if the "butt busy" bit is set before1251 * updating the butt register. In theory this should1252 * never happen because the ATM card is plenty fast at1253 * updating the register. Still, we should make sure1254 */1255 for (i = 0; reg_read(lanai, Status_Reg) & STATUS_BUTTBUSY; i++) {1256 if (unlikely(i > 50)) {1257 printk(KERN_ERR DEV_LABEL "(itf %d): butt register "1258 "always busy!\n", lanai->number);1259 break;1260 }1261 udelay(5);1262 }1263 /*1264 * Before we tall the card to start work we need to be sure 100% of1265 * the info in the service buffer has been written before we tell1266 * the card about it1267 */1268 wmb();1269 reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg);1270 spin_unlock(&lanai->endtxlock);1271}1272 1273/*1274 * Add one AAL5 PDU to lvcc's transmit buffer. Caller garauntees there's1275 * space available. "pdusize" is the number of bytes the PDU will take1276 */1277static void lanai_send_one_aal5(struct lanai_dev *lanai,1278 struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize)1279{1280 int pad;1281 APRINTK(pdusize == aal5_size(skb->len),1282 "lanai_send_one_aal5: wrong size packet (%d != %d)\n",1283 pdusize, aal5_size(skb->len));1284 vcc_tx_add_aal5_descriptor(lvcc, 0, pdusize);1285 pad = pdusize - skb->len - 8;1286 APRINTK(pad >= 0, "pad is negative (%d)\n", pad);1287 APRINTK(pad < 48, "pad is too big (%d)\n", pad);1288 vcc_tx_memcpy(lvcc, skb->data, skb->len);1289 vcc_tx_memzero(lvcc, pad);1290 vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);1291 lanai_endtx(lanai, lvcc);1292 lanai_free_skb(lvcc->tx.atmvcc, skb);1293 atomic_inc(&lvcc->tx.atmvcc->stats->tx);1294}1295 1296/* Try to fill the buffer - don't call unless there is backlog */1297static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai,1298 struct lanai_vcc *lvcc, int endptr)1299{1300 int n;1301 struct sk_buff *skb;1302 int space = vcc_tx_space(lvcc, endptr);1303 APRINTK(vcc_is_backlogged(lvcc),1304 "vcc_tx_unqueue() called with empty backlog (vci=%d)\n",1305 lvcc->vci);1306 while (space >= 64) {1307 skb = skb_dequeue(&lvcc->tx.backlog);1308 if (skb == NULL)1309 goto no_backlog;1310 n = aal5_size(skb->len);1311 if (n + 16 > space) {1312 /* No room for this packet - put it back on queue */1313 skb_queue_head(&lvcc->tx.backlog, skb);1314 return;1315 }1316 lanai_send_one_aal5(lanai, lvcc, skb, n);1317 space -= n + 16;1318 }1319 if (!vcc_is_backlogged(lvcc)) {1320 no_backlog:1321 __clear_bit(lvcc->vci, lanai->backlog_vccs);1322 }1323}1324 1325/* Given an skb that we want to transmit either send it now or queue */1326static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,1327 struct sk_buff *skb)1328{1329 int space, n;1330 if (vcc_is_backlogged(lvcc)) /* Already backlogged */1331 goto queue_it;1332 space = vcc_tx_space(lvcc,1333 TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)));1334 n = aal5_size(skb->len);1335 APRINTK(n + 16 >= 64, "vcc_tx_aal5: n too small (%d)\n", n);1336 if (space < n + 16) { /* No space for this PDU */1337 __set_bit(lvcc->vci, lanai->backlog_vccs);1338 queue_it:1339 skb_queue_tail(&lvcc->tx.backlog, skb);1340 return;1341 }1342 lanai_send_one_aal5(lanai, lvcc, skb, n);1343}1344 1345static void vcc_tx_unqueue_aal0(struct lanai_dev *lanai,1346 struct lanai_vcc *lvcc, int endptr)1347{1348 printk(KERN_INFO DEV_LABEL1349 ": vcc_tx_unqueue_aal0: not implemented\n");1350}1351 1352static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,1353 struct sk_buff *skb)1354{1355 printk(KERN_INFO DEV_LABEL ": vcc_tx_aal0: not implemented\n");1356 /* Remember to increment lvcc->tx.atmvcc->stats->tx */1357 lanai_free_skb(lvcc->tx.atmvcc, skb);1358}1359 1360/* -------------------- VCC RX BUFFER UTILITIES: */1361 1362/* unlike the _tx_ cousins, this doesn't update ptr */1363static inline void vcc_rx_memcpy(unsigned char *dest,1364 const struct lanai_vcc *lvcc, int n)1365{1366 int m = ((const unsigned char *) lvcc->rx.buf.ptr) + n -1367 ((const unsigned char *) (lvcc->rx.buf.end));1368 if (m < 0)1369 m = 0;1370 memcpy(dest, lvcc->rx.buf.ptr, n - m);1371 memcpy(dest + n - m, lvcc->rx.buf.start, m);1372 /* Make sure that these copies don't get reordered */1373 barrier();1374}1375 1376/* Receive AAL5 data on a VCC with a particular endptr */1377static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)1378{1379 int size;1380 struct sk_buff *skb;1381 const u32 *x;1382 u32 *end = &lvcc->rx.buf.start[endptr * 4];1383 int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);1384 if (n < 0)1385 n += lanai_buf_size(&lvcc->rx.buf);1386 APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15),1387 "vcc_rx_aal5: n out of range (%d/%zu)\n",1388 n, lanai_buf_size(&lvcc->rx.buf));1389 /* Recover the second-to-last word to get true pdu length */1390 if ((x = &end[-2]) < lvcc->rx.buf.start)1391 x = &lvcc->rx.buf.end[-2];1392 /*1393 * Before we actually read from the buffer, make sure the memory1394 * changes have arrived1395 */1396 rmb();1397 size = be32_to_cpup(x) & 0xffff;1398 if (unlikely(n != aal5_size(size))) {1399 /* Make sure size matches padding */1400 printk(KERN_INFO DEV_LABEL "(itf %d): Got bad AAL5 length "1401 "on vci=%d - size=%d n=%d\n",1402 lvcc->rx.atmvcc->dev->number, lvcc->vci, size, n);1403 lvcc->stats.x.aal5.rx_badlen++;1404 goto out;1405 }1406 skb = atm_alloc_charge(lvcc->rx.atmvcc, size, GFP_ATOMIC);1407 if (unlikely(skb == NULL)) {1408 lvcc->stats.rx_nomem++;1409 goto out;1410 }1411 skb_put(skb, size);1412 vcc_rx_memcpy(skb->data, lvcc, size);1413 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;1414 __net_timestamp(skb);1415 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);1416 atomic_inc(&lvcc->rx.atmvcc->stats->rx);1417 out:1418 lvcc->rx.buf.ptr = end;1419 cardvcc_write(lvcc, endptr, vcc_rxreadptr);1420}1421 1422static void vcc_rx_aal0(struct lanai_dev *lanai)1423{1424 printk(KERN_INFO DEV_LABEL ": vcc_rx_aal0: not implemented\n");1425 /* Remember to get read_lock(&vcc_sklist_lock) while looking up VC */1426 /* Remember to increment lvcc->rx.atmvcc->stats->rx */1427}1428 1429/* -------------------- MANAGING HOST-BASED VCC TABLE: */1430 1431/* Decide whether to use vmalloc or get_zeroed_page for VCC table */1432#if (NUM_VCI * BITS_PER_LONG) <= PAGE_SIZE1433#define VCCTABLE_GETFREEPAGE1434#else1435#include <linux/vmalloc.h>1436#endif1437 1438static int vcc_table_allocate(struct lanai_dev *lanai)1439{1440#ifdef VCCTABLE_GETFREEPAGE1441 APRINTK((lanai->num_vci) * sizeof(struct lanai_vcc *) <= PAGE_SIZE,1442 "vcc table > PAGE_SIZE!");1443 lanai->vccs = (struct lanai_vcc **) get_zeroed_page(GFP_KERNEL);1444 return (lanai->vccs == NULL) ? -ENOMEM : 0;1445#else1446 int bytes = (lanai->num_vci) * sizeof(struct lanai_vcc *);1447 lanai->vccs = vzalloc(bytes);1448 if (unlikely(lanai->vccs == NULL))1449 return -ENOMEM;1450 return 0;1451#endif1452}1453 1454static inline void vcc_table_deallocate(const struct lanai_dev *lanai)1455{1456#ifdef VCCTABLE_GETFREEPAGE1457 free_page((unsigned long) lanai->vccs);1458#else1459 vfree(lanai->vccs);1460#endif1461}1462 1463/* Allocate a fresh lanai_vcc, with the appropriate things cleared */1464static inline struct lanai_vcc *new_lanai_vcc(void)1465{1466 struct lanai_vcc *lvcc;1467 lvcc = kzalloc(sizeof(*lvcc), GFP_KERNEL);1468 if (likely(lvcc != NULL)) {1469 skb_queue_head_init(&lvcc->tx.backlog);1470#ifdef DEBUG1471 lvcc->vci = -1;1472#endif1473 }1474 return lvcc;1475}1476 1477static int lanai_get_sized_buffer(struct lanai_dev *lanai,1478 struct lanai_buffer *buf, int max_sdu, int multiplier,1479 const char *name)1480{1481 int size;1482 if (unlikely(max_sdu < 1))1483 max_sdu = 1;1484 max_sdu = aal5_size(max_sdu);1485 size = (max_sdu + 16) * multiplier + 16;1486 lanai_buf_allocate(buf, size, max_sdu + 32, lanai->pci);1487 if (unlikely(buf->start == NULL))1488 return -ENOMEM;1489 if (unlikely(lanai_buf_size(buf) < size))1490 printk(KERN_WARNING DEV_LABEL "(itf %d): wanted %d bytes "1491 "for %s buffer, got only %zu\n", lanai->number, size,1492 name, lanai_buf_size(buf));1493 DPRINTK("Allocated %zu byte %s buffer\n", lanai_buf_size(buf), name);1494 return 0;1495}1496 1497/* Setup a RX buffer for a currently unbound AAL5 vci */1498static inline int lanai_setup_rx_vci_aal5(struct lanai_dev *lanai,1499 struct lanai_vcc *lvcc, const struct atm_qos *qos)1500{1501 return lanai_get_sized_buffer(lanai, &lvcc->rx.buf,1502 qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, "RX");1503}1504 1505/* Setup a TX buffer for a currently unbound AAL5 vci */1506static int lanai_setup_tx_vci(struct lanai_dev *lanai, struct lanai_vcc *lvcc,1507 const struct atm_qos *qos)1508{1509 int max_sdu, multiplier;1510 if (qos->aal == ATM_AAL0) {1511 lvcc->tx.unqueue = vcc_tx_unqueue_aal0;1512 max_sdu = ATM_CELL_SIZE - 1;1513 multiplier = AAL0_TX_MULTIPLIER;1514 } else {1515 lvcc->tx.unqueue = vcc_tx_unqueue_aal5;1516 max_sdu = qos->txtp.max_sdu;1517 multiplier = AAL5_TX_MULTIPLIER;1518 }1519 return lanai_get_sized_buffer(lanai, &lvcc->tx.buf, max_sdu,1520 multiplier, "TX");1521}1522 1523static inline void host_vcc_bind(struct lanai_dev *lanai,1524 struct lanai_vcc *lvcc, vci_t vci)1525{1526 if (lvcc->vbase != NULL)1527 return; /* We already were bound in the other direction */1528 DPRINTK("Binding vci %d\n", vci);1529#ifdef USE_POWERDOWN1530 if (lanai->nbound++ == 0) {1531 DPRINTK("Coming out of powerdown\n");1532 lanai->conf1 &= ~CONFIG1_POWERDOWN;1533 conf1_write(lanai);1534 conf2_write(lanai);1535 }1536#endif1537 lvcc->vbase = cardvcc_addr(lanai, vci);1538 lanai->vccs[lvcc->vci = vci] = lvcc;1539}1540 1541static inline void host_vcc_unbind(struct lanai_dev *lanai,1542 struct lanai_vcc *lvcc)1543{1544 if (lvcc->vbase == NULL)1545 return; /* This vcc was never bound */1546 DPRINTK("Unbinding vci %d\n", lvcc->vci);1547 lvcc->vbase = NULL;1548 lanai->vccs[lvcc->vci] = NULL;1549#ifdef USE_POWERDOWN1550 if (--lanai->nbound == 0) {1551 DPRINTK("Going into powerdown\n");1552 lanai->conf1 |= CONFIG1_POWERDOWN;1553 conf1_write(lanai);1554 }1555#endif1556}1557 1558/* -------------------- RESET CARD: */1559 1560static void lanai_reset(struct lanai_dev *lanai)1561{1562 printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* resetting - not "1563 "implemented\n", lanai->number);1564 /* TODO */1565 /* The following is just a hack until we write the real1566 * resetter - at least ack whatever interrupt sent us1567 * here1568 */1569 reg_write(lanai, INT_ALL, IntAck_Reg);1570 lanai->stats.card_reset++;1571}1572 1573/* -------------------- SERVICE LIST UTILITIES: */1574 1575/*1576 * Allocate service buffer and tell card about it1577 */1578static int service_buffer_allocate(struct lanai_dev *lanai)1579{1580 lanai_buf_allocate(&lanai->service, SERVICE_ENTRIES * 4, 8,1581 lanai->pci);1582 if (unlikely(lanai->service.start == NULL))1583 return -ENOMEM;1584 DPRINTK("allocated service buffer at %p, size %zu(%d)\n",1585 lanai->service.start,1586 lanai_buf_size(&lanai->service),1587 lanai_buf_size_cardorder(&lanai->service));1588 /* Clear ServWrite register to be safe */1589 reg_write(lanai, 0, ServWrite_Reg);1590 /* ServiceStuff register contains size and address of buffer */1591 reg_write(lanai,1592 SSTUFF_SET_SIZE(lanai_buf_size_cardorder(&lanai->service)) |1593 SSTUFF_SET_ADDR(lanai->service.dmaaddr),1594 ServiceStuff_Reg);1595 return 0;1596}1597 1598static inline void service_buffer_deallocate(struct lanai_dev *lanai)1599{1600 lanai_buf_deallocate(&lanai->service, lanai->pci);1601}1602 1603/* Bitfields in service list */1604#define SERVICE_TX (0x80000000) /* Was from transmission */1605#define SERVICE_TRASH (0x40000000) /* RXed PDU was trashed */1606#define SERVICE_CRCERR (0x20000000) /* RXed PDU had CRC error */1607#define SERVICE_CI (0x10000000) /* RXed PDU had CI set */1608#define SERVICE_CLP (0x08000000) /* RXed PDU had CLP set */1609#define SERVICE_STREAM (0x04000000) /* RX Stream mode */1610#define SERVICE_GET_VCI(x) (((x)>>16)&0x3FF)1611#define SERVICE_GET_END(x) ((x)&0x1FFF)1612 1613/* Handle one thing from the service list - returns true if it marked a1614 * VCC ready for xmit1615 */1616static int handle_service(struct lanai_dev *lanai, u32 s)1617{1618 vci_t vci = SERVICE_GET_VCI(s);1619 struct lanai_vcc *lvcc;1620 read_lock(&vcc_sklist_lock);1621 lvcc = lanai->vccs[vci];1622 if (unlikely(lvcc == NULL)) {1623 read_unlock(&vcc_sklist_lock);1624 DPRINTK("(itf %d) got service entry 0x%X for nonexistent "1625 "vcc %d\n", lanai->number, (unsigned int) s, vci);1626 if (s & SERVICE_TX)1627 lanai->stats.service_notx++;1628 else1629 lanai->stats.service_norx++;1630 return 0;1631 }1632 if (s & SERVICE_TX) { /* segmentation interrupt */1633 if (unlikely(lvcc->tx.atmvcc == NULL)) {1634 read_unlock(&vcc_sklist_lock);1635 DPRINTK("(itf %d) got service entry 0x%X for non-TX "1636 "vcc %d\n", lanai->number, (unsigned int) s, vci);1637 lanai->stats.service_notx++;1638 return 0;1639 }1640 __set_bit(vci, lanai->transmit_ready);1641 lvcc->tx.endptr = SERVICE_GET_END(s);1642 read_unlock(&vcc_sklist_lock);1643 return 1;1644 }1645 if (unlikely(lvcc->rx.atmvcc == NULL)) {1646 read_unlock(&vcc_sklist_lock);1647 DPRINTK("(itf %d) got service entry 0x%X for non-RX "1648 "vcc %d\n", lanai->number, (unsigned int) s, vci);1649 lanai->stats.service_norx++;1650 return 0;1651 }1652 if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) {1653 read_unlock(&vcc_sklist_lock);1654 DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "1655 "vcc %d\n", lanai->number, (unsigned int) s, vci);1656 lanai->stats.service_rxnotaal5++;1657 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);1658 return 0;1659 }1660 if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {1661 vcc_rx_aal5(lvcc, SERVICE_GET_END(s));1662 read_unlock(&vcc_sklist_lock);1663 return 0;1664 }1665 if (s & SERVICE_TRASH) {1666 int bytes;1667 read_unlock(&vcc_sklist_lock);1668 DPRINTK("got trashed rx pdu on vci %d\n", vci);1669 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);1670 lvcc->stats.x.aal5.service_trash++;1671 bytes = (SERVICE_GET_END(s) * 16) -1672 (((unsigned long) lvcc->rx.buf.ptr) -1673 ((unsigned long) lvcc->rx.buf.start)) + 47;1674 if (bytes < 0)1675 bytes += lanai_buf_size(&lvcc->rx.buf);1676 lanai->stats.ovfl_trash += (bytes / 48);1677 return 0;1678 }1679 if (s & SERVICE_STREAM) {1680 read_unlock(&vcc_sklist_lock);1681 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);1682 lvcc->stats.x.aal5.service_stream++;1683 printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "1684 "PDU on VCI %d!\n", lanai->number, vci);1685 lanai_reset(lanai);1686 return 0;1687 }1688 DPRINTK("got rx crc error on vci %d\n", vci);1689 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);1690 lvcc->stats.x.aal5.service_rxcrc++;1691 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];1692 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);1693 read_unlock(&vcc_sklist_lock);1694 return 0;1695}1696 1697/* Try transmitting on all VCIs that we marked ready to serve */1698static void iter_transmit(struct lanai_dev *lanai, vci_t vci)1699{1700 struct lanai_vcc *lvcc = lanai->vccs[vci];1701 if (vcc_is_backlogged(lvcc))1702 lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);1703}1704 1705/* Run service queue -- called from interrupt context or with1706 * interrupts otherwise disabled and with the lanai->servicelock1707 * lock held1708 */1709static void run_service(struct lanai_dev *lanai)1710{1711 int ntx = 0;1712 u32 wreg = reg_read(lanai, ServWrite_Reg);1713 const u32 *end = lanai->service.start + wreg;1714 while (lanai->service.ptr != end) {1715 ntx += handle_service(lanai,1716 le32_to_cpup(lanai->service.ptr++));1717 if (lanai->service.ptr >= lanai->service.end)1718 lanai->service.ptr = lanai->service.start;1719 }1720 reg_write(lanai, wreg, ServRead_Reg);1721 if (ntx != 0) {1722 read_lock(&vcc_sklist_lock);1723 vci_bitfield_iterate(lanai, lanai->transmit_ready,1724 iter_transmit);1725 bitmap_zero(lanai->transmit_ready, NUM_VCI);1726 read_unlock(&vcc_sklist_lock);1727 }1728}1729 1730/* -------------------- GATHER STATISTICS: */1731 1732static void get_statistics(struct lanai_dev *lanai)1733{1734 u32 statreg = reg_read(lanai, Statistics_Reg);1735 lanai->stats.atm_ovfl += STATS_GET_FIFO_OVFL(statreg);1736 lanai->stats.hec_err += STATS_GET_HEC_ERR(statreg);1737 lanai->stats.vci_trash += STATS_GET_BAD_VCI(statreg);1738 lanai->stats.ovfl_trash += STATS_GET_BUF_OVFL(statreg);1739}1740 1741/* -------------------- POLLING TIMER: */1742 1743#ifndef DEBUG_RW1744/* Try to undequeue 1 backlogged vcc */1745static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)1746{1747 struct lanai_vcc *lvcc = lanai->vccs[vci];1748 int endptr;1749 if (lvcc == NULL || lvcc->tx.atmvcc == NULL ||1750 !vcc_is_backlogged(lvcc)) {1751 __clear_bit(vci, lanai->backlog_vccs);1752 return;1753 }1754 endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));1755 lvcc->tx.unqueue(lanai, lvcc, endptr);1756}1757#endif /* !DEBUG_RW */1758 1759static void lanai_timed_poll(struct timer_list *t)1760{1761 struct lanai_dev *lanai = from_timer(lanai, t, timer);1762#ifndef DEBUG_RW1763 unsigned long flags;1764#ifdef USE_POWERDOWN1765 if (lanai->conf1 & CONFIG1_POWERDOWN)1766 return;1767#endif /* USE_POWERDOWN */1768 local_irq_save(flags);1769 /* If we can grab the spinlock, check if any services need to be run */1770 if (spin_trylock(&lanai->servicelock)) {1771 run_service(lanai);1772 spin_unlock(&lanai->servicelock);1773 }1774 /* ...and see if any backlogged VCs can make progress */1775 /* unfortunately linux has no read_trylock() currently */1776 read_lock(&vcc_sklist_lock);1777 vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue);1778 read_unlock(&vcc_sklist_lock);1779 local_irq_restore(flags);1780 1781 get_statistics(lanai);1782#endif /* !DEBUG_RW */1783 mod_timer(&lanai->timer, jiffies + LANAI_POLL_PERIOD);1784}1785 1786static inline void lanai_timed_poll_start(struct lanai_dev *lanai)1787{1788 timer_setup(&lanai->timer, lanai_timed_poll, 0);1789 lanai->timer.expires = jiffies + LANAI_POLL_PERIOD;1790 add_timer(&lanai->timer);1791}1792 1793static inline void lanai_timed_poll_stop(struct lanai_dev *lanai)1794{1795 del_timer_sync(&lanai->timer);1796}1797 1798/* -------------------- INTERRUPT SERVICE: */1799 1800static inline void lanai_int_1(struct lanai_dev *lanai, u32 reason)1801{1802 u32 ack = 0;1803 if (reason & INT_SERVICE) {1804 ack = INT_SERVICE;1805 spin_lock(&lanai->servicelock);1806 run_service(lanai);1807 spin_unlock(&lanai->servicelock);1808 }1809 if (reason & (INT_AAL0_STR | INT_AAL0)) {1810 ack |= reason & (INT_AAL0_STR | INT_AAL0);1811 vcc_rx_aal0(lanai);1812 }1813 /* The rest of the interrupts are pretty rare */1814 if (ack == reason)1815 goto done;1816 if (reason & INT_STATS) {1817 reason &= ~INT_STATS; /* No need to ack */1818 get_statistics(lanai);1819 }1820 if (reason & INT_STATUS) {1821 ack |= reason & INT_STATUS;1822 lanai_check_status(lanai);1823 }1824 if (unlikely(reason & INT_DMASHUT)) {1825 printk(KERN_ERR DEV_LABEL "(itf %d): driver error - DMA "1826 "shutdown, reason=0x%08X, address=0x%08X\n",1827 lanai->number, (unsigned int) (reason & INT_DMASHUT),1828 (unsigned int) reg_read(lanai, DMA_Addr_Reg));1829 if (reason & INT_TABORTBM) {1830 lanai_reset(lanai);1831 return;1832 }1833 ack |= (reason & INT_DMASHUT);1834 printk(KERN_ERR DEV_LABEL "(itf %d): re-enabling DMA\n",1835 lanai->number);1836 conf1_write(lanai);1837 lanai->stats.dma_reenable++;1838 pcistatus_check(lanai, 0);1839 }1840 if (unlikely(reason & INT_TABORTSENT)) {1841 ack |= (reason & INT_TABORTSENT);1842 printk(KERN_ERR DEV_LABEL "(itf %d): sent PCI target abort\n",1843 lanai->number);1844 pcistatus_check(lanai, 0);1845 }1846 if (unlikely(reason & INT_SEGSHUT)) {1847 printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "1848 "segmentation shutdown, reason=0x%08X\n", lanai->number,1849 (unsigned int) (reason & INT_SEGSHUT));1850 lanai_reset(lanai);1851 return;1852 }1853 if (unlikely(reason & (INT_PING | INT_WAKE))) {1854 printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "1855 "unexpected interrupt 0x%08X, resetting\n",1856 lanai->number,1857 (unsigned int) (reason & (INT_PING | INT_WAKE)));1858 lanai_reset(lanai);1859 return;1860 }1861#ifdef DEBUG1862 if (unlikely(ack != reason)) {1863 DPRINTK("unacked ints: 0x%08X\n",1864 (unsigned int) (reason & ~ack));1865 ack = reason;1866 }1867#endif1868 done:1869 if (ack != 0)1870 reg_write(lanai, ack, IntAck_Reg);1871}1872 1873static irqreturn_t lanai_int(int irq, void *devid)1874{1875 struct lanai_dev *lanai = devid;1876 u32 reason;1877 1878#ifdef USE_POWERDOWN1879 /*1880 * If we're powered down we shouldn't be generating any interrupts -1881 * so assume that this is a shared interrupt line and it's for someone1882 * else1883 */1884 if (unlikely(lanai->conf1 & CONFIG1_POWERDOWN))1885 return IRQ_NONE;1886#endif1887 1888 reason = intr_pending(lanai);1889 if (reason == 0)1890 return IRQ_NONE; /* Must be for someone else */1891 1892 do {1893 if (unlikely(reason == 0xFFFFFFFF))1894 break; /* Maybe we've been unplugged? */1895 lanai_int_1(lanai, reason);1896 reason = intr_pending(lanai);1897 } while (reason != 0);1898 1899 return IRQ_HANDLED;1900}1901 1902/* TODO - it would be nice if we could use the "delayed interrupt" system1903 * to some advantage1904 */1905 1906/* -------------------- CHECK BOARD ID/REV: */1907 1908/*1909 * The board id and revision are stored both in the reset register and1910 * in the PCI configuration space - the documentation says to check1911 * each of them. If revp!=NULL we store the revision there1912 */1913static int check_board_id_and_rev(const char *name, u32 val, int *revp)1914{1915 DPRINTK("%s says board_id=%d, board_rev=%d\n", name,1916 (int) RESET_GET_BOARD_ID(val),1917 (int) RESET_GET_BOARD_REV(val));1918 if (RESET_GET_BOARD_ID(val) != BOARD_ID_LANAI256) {1919 printk(KERN_ERR DEV_LABEL ": Found %s board-id %d -- not a "1920 "Lanai 25.6\n", name, (int) RESET_GET_BOARD_ID(val));1921 return -ENODEV;1922 }1923 if (revp != NULL)1924 *revp = RESET_GET_BOARD_REV(val);1925 return 0;1926}1927 1928/* -------------------- PCI INITIALIZATION/SHUTDOWN: */1929 1930static int lanai_pci_start(struct lanai_dev *lanai)1931{1932 struct pci_dev *pci = lanai->pci;1933 int result;1934 1935 if (pci_enable_device(pci) != 0) {1936 printk(KERN_ERR DEV_LABEL "(itf %d): can't enable "1937 "PCI device", lanai->number);1938 return -ENXIO;1939 }1940 pci_set_master(pci);1941 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)) != 0) {1942 printk(KERN_WARNING DEV_LABEL1943 "(itf %d): No suitable DMA available.\n", lanai->number);1944 return -EBUSY;1945 }1946 result = check_board_id_and_rev("PCI", pci->subsystem_device, NULL);1947 if (result != 0)1948 return result;1949 /* Set latency timer to zero as per lanai docs */1950 result = pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0);1951 if (result != PCIBIOS_SUCCESSFUL) {1952 printk(KERN_ERR DEV_LABEL "(itf %d): can't write "1953 "PCI_LATENCY_TIMER: %d\n", lanai->number, result);1954 return -EINVAL;1955 }1956 pcistatus_check(lanai, 1);1957 pcistatus_check(lanai, 0);1958 return 0;1959}1960 1961/* -------------------- VPI/VCI ALLOCATION: */1962 1963/*1964 * We _can_ use VCI==0 for normal traffic, but only for UBR (or we'll1965 * get a CBRZERO interrupt), and we can use it only if no one is receiving1966 * AAL0 traffic (since they will use the same queue) - according to the1967 * docs we shouldn't even use it for AAL0 traffic1968 */1969static inline int vci0_is_ok(struct lanai_dev *lanai,1970 const struct atm_qos *qos)1971{1972 if (qos->txtp.traffic_class == ATM_CBR || qos->aal == ATM_AAL0)1973 return 0;1974 if (qos->rxtp.traffic_class != ATM_NONE) {1975 if (lanai->naal0 != 0)1976 return 0;1977 lanai->conf2 |= CONFIG2_VCI0_NORMAL;1978 conf2_write_if_powerup(lanai);1979 }1980 return 1;1981}1982 1983/* return true if vci is currently unused, or if requested qos is1984 * compatible1985 */1986static int vci_is_ok(struct lanai_dev *lanai, vci_t vci,1987 const struct atm_vcc *atmvcc)1988{1989 const struct atm_qos *qos = &atmvcc->qos;1990 const struct lanai_vcc *lvcc = lanai->vccs[vci];1991 if (vci == 0 && !vci0_is_ok(lanai, qos))1992 return 0;1993 if (unlikely(lvcc != NULL)) {1994 if (qos->rxtp.traffic_class != ATM_NONE &&1995 lvcc->rx.atmvcc != NULL && lvcc->rx.atmvcc != atmvcc)1996 return 0;1997 if (qos->txtp.traffic_class != ATM_NONE &&1998 lvcc->tx.atmvcc != NULL && lvcc->tx.atmvcc != atmvcc)1999 return 0;2000 if (qos->txtp.traffic_class == ATM_CBR &&2001 lanai->cbrvcc != NULL && lanai->cbrvcc != atmvcc)2002 return 0;2003 }2004 if (qos->aal == ATM_AAL0 && lanai->naal0 == 0 &&2005 qos->rxtp.traffic_class != ATM_NONE) {2006 const struct lanai_vcc *vci0 = lanai->vccs[0];2007 if (vci0 != NULL && vci0->rx.atmvcc != NULL)2008 return 0;2009 lanai->conf2 &= ~CONFIG2_VCI0_NORMAL;2010 conf2_write_if_powerup(lanai);2011 }2012 return 1;2013}2014 2015static int lanai_normalize_ci(struct lanai_dev *lanai,2016 const struct atm_vcc *atmvcc, short *vpip, vci_t *vcip)2017{2018 switch (*vpip) {2019 case ATM_VPI_ANY:2020 *vpip = 0;2021 fallthrough;2022 case 0:2023 break;2024 default:2025 return -EADDRINUSE;2026 }2027 switch (*vcip) {2028 case ATM_VCI_ANY:2029 for (*vcip = ATM_NOT_RSV_VCI; *vcip < lanai->num_vci;2030 (*vcip)++)2031 if (vci_is_ok(lanai, *vcip, atmvcc))2032 return 0;2033 return -EADDRINUSE;2034 default:2035 if (*vcip >= lanai->num_vci || *vcip < 0 ||2036 !vci_is_ok(lanai, *vcip, atmvcc))2037 return -EADDRINUSE;2038 }2039 return 0;2040}2041 2042/* -------------------- MANAGE CBR: */2043 2044/*2045 * CBR ICG is stored as a fixed-point number with 4 fractional bits.2046 * Note that storing a number greater than 2046.0 will result in2047 * incorrect shaping2048 */2049#define CBRICG_FRAC_BITS (4)2050#define CBRICG_MAX (2046 << CBRICG_FRAC_BITS)2051 2052/*2053 * ICG is related to PCR with the formula PCR = MAXPCR / (ICG + 1)2054 * where MAXPCR is (according to the docs) 25600000/(54*8),2055 * which is equal to (3125<<9)/27.2056 *2057 * Solving for ICG, we get:2058 * ICG = MAXPCR/PCR - 12059 * ICG = (3125<<9)/(27*PCR) - 12060 * ICG = ((3125<<9) - (27*PCR)) / (27*PCR)2061 *2062 * The end result is supposed to be a fixed-point number with FRAC_BITS2063 * bits of a fractional part, so we keep everything in the numerator2064 * shifted by that much as we compute2065 *2066 */2067static int pcr_to_cbricg(const struct atm_qos *qos)2068{2069 int rounddown = 0; /* 1 = Round PCR down, i.e. round ICG _up_ */2070 int x, icg, pcr = atm_pcr_goal(&qos->txtp);2071 if (pcr == 0) /* Use maximum bandwidth */2072 return 0;2073 if (pcr < 0) {2074 rounddown = 1;2075 pcr = -pcr;2076 }2077 x = pcr * 27;2078 icg = (3125 << (9 + CBRICG_FRAC_BITS)) - (x << CBRICG_FRAC_BITS);2079 if (rounddown)2080 icg += x - 1;2081 icg /= x;2082 if (icg > CBRICG_MAX)2083 icg = CBRICG_MAX;2084 DPRINTK("pcr_to_cbricg: pcr=%d rounddown=%c icg=%d\n",2085 pcr, rounddown ? 'Y' : 'N', icg);2086 return icg;2087}2088 2089static inline void lanai_cbr_setup(struct lanai_dev *lanai)2090{2091 reg_write(lanai, pcr_to_cbricg(&lanai->cbrvcc->qos), CBR_ICG_Reg);2092 reg_write(lanai, lanai->cbrvcc->vci, CBR_PTR_Reg);2093 lanai->conf2 |= CONFIG2_CBR_ENABLE;2094 conf2_write(lanai);2095}2096 2097static inline void lanai_cbr_shutdown(struct lanai_dev *lanai)2098{2099 lanai->conf2 &= ~CONFIG2_CBR_ENABLE;2100 conf2_write(lanai);2101}2102 2103/* -------------------- OPERATIONS: */2104 2105/* setup a newly detected device */2106static int lanai_dev_open(struct atm_dev *atmdev)2107{2108 struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;2109 unsigned long raw_base;2110 int result;2111 2112 DPRINTK("In lanai_dev_open()\n");2113 /* Basic device fields */2114 lanai->number = atmdev->number;2115 lanai->num_vci = NUM_VCI;2116 bitmap_zero(lanai->backlog_vccs, NUM_VCI);2117 bitmap_zero(lanai->transmit_ready, NUM_VCI);2118 lanai->naal0 = 0;2119#ifdef USE_POWERDOWN2120 lanai->nbound = 0;2121#endif2122 lanai->cbrvcc = NULL;2123 memset(&lanai->stats, 0, sizeof lanai->stats);2124 spin_lock_init(&lanai->endtxlock);2125 spin_lock_init(&lanai->servicelock);2126 atmdev->ci_range.vpi_bits = 0;2127 atmdev->ci_range.vci_bits = 0;2128 while (1 << atmdev->ci_range.vci_bits < lanai->num_vci)2129 atmdev->ci_range.vci_bits++;2130 atmdev->link_rate = ATM_25_PCR;2131 2132 /* 3.2: PCI initialization */2133 if ((result = lanai_pci_start(lanai)) != 0)2134 goto error;2135 raw_base = lanai->pci->resource[0].start;2136 lanai->base = (bus_addr_t) ioremap(raw_base, LANAI_MAPPING_SIZE);2137 if (lanai->base == NULL) {2138 printk(KERN_ERR DEV_LABEL ": couldn't remap I/O space\n");2139 result = -ENOMEM;2140 goto error_pci;2141 }2142 /* 3.3: Reset lanai and PHY */2143 reset_board(lanai);2144 lanai->conf1 = reg_read(lanai, Config1_Reg);2145 lanai->conf1 &= ~(CONFIG1_GPOUT1 | CONFIG1_POWERDOWN |2146 CONFIG1_MASK_LEDMODE);2147 lanai->conf1 |= CONFIG1_SET_LEDMODE(LEDMODE_NOT_SOOL);2148 reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);2149 udelay(1000);2150 conf1_write(lanai);2151 2152 /*2153 * 3.4: Turn on endian mode for big-endian hardware2154 * We don't actually want to do this - the actual bit fields2155 * in the endian register are not documented anywhere.2156 * Instead we do the bit-flipping ourselves on big-endian2157 * hardware.2158 *2159 * 3.5: get the board ID/rev by reading the reset register2160 */2161 result = check_board_id_and_rev("register",2162 reg_read(lanai, Reset_Reg), &lanai->board_rev);2163 if (result != 0)2164 goto error_unmap;2165 2166 /* 3.6: read EEPROM */2167 if ((result = eeprom_read(lanai)) != 0)2168 goto error_unmap;2169 if ((result = eeprom_validate(lanai)) != 0)2170 goto error_unmap;2171 2172 /* 3.7: re-reset PHY, do loopback tests, setup PHY */2173 reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);2174 udelay(1000);2175 conf1_write(lanai);2176 /* TODO - loopback tests */2177 lanai->conf1 |= (CONFIG1_GPOUT2 | CONFIG1_GPOUT3 | CONFIG1_DMA_ENABLE);2178 conf1_write(lanai);2179 2180 /* 3.8/3.9: test and initialize card SRAM */2181 if ((result = sram_test_and_clear(lanai)) != 0)2182 goto error_unmap;2183 2184 /* 3.10: initialize lanai registers */2185 lanai->conf1 |= CONFIG1_DMA_ENABLE;2186 conf1_write(lanai);2187 if ((result = service_buffer_allocate(lanai)) != 0)2188 goto error_unmap;2189 if ((result = vcc_table_allocate(lanai)) != 0)2190 goto error_service;2191 lanai->conf2 = (lanai->num_vci >= 512 ? CONFIG2_HOWMANY : 0) |2192 CONFIG2_HEC_DROP | /* ??? */ CONFIG2_PTI7_MODE;2193 conf2_write(lanai);2194 reg_write(lanai, TX_FIFO_DEPTH, TxDepth_Reg);2195 reg_write(lanai, 0, CBR_ICG_Reg); /* CBR defaults to no limit */2196 if ((result = request_irq(lanai->pci->irq, lanai_int, IRQF_SHARED,2197 DEV_LABEL, lanai)) != 0) {2198 printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");2199 goto error_vcctable;2200 }2201 mb(); /* Make sure that all that made it */2202 intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));2203 /* 3.11: initialize loop mode (i.e. turn looping off) */2204 lanai->conf1 = (lanai->conf1 & ~CONFIG1_MASK_LOOPMODE) |2205 CONFIG1_SET_LOOPMODE(LOOPMODE_NORMAL) |2206 CONFIG1_GPOUT2 | CONFIG1_GPOUT3;2207 conf1_write(lanai);2208 lanai->status = reg_read(lanai, Status_Reg);2209 /* We're now done initializing this card */2210#ifdef USE_POWERDOWN2211 lanai->conf1 |= CONFIG1_POWERDOWN;2212 conf1_write(lanai);2213#endif2214 memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN);2215 lanai_timed_poll_start(lanai);2216 printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=%p, irq=%u "2217 "(%pMF)\n", lanai->number, (int) lanai->pci->revision,2218 lanai->base, lanai->pci->irq, atmdev->esi);2219 printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%u(0x%X), "2220 "board_rev=%d\n", lanai->number,2221 lanai->type==lanai2 ? "2" : "HB", (unsigned int) lanai->serialno,2222 (unsigned int) lanai->serialno, lanai->board_rev);2223 return 0;2224 2225 error_vcctable:2226 vcc_table_deallocate(lanai);2227 error_service:2228 service_buffer_deallocate(lanai);2229 error_unmap:2230 reset_board(lanai);2231#ifdef USE_POWERDOWN2232 lanai->conf1 = reg_read(lanai, Config1_Reg) | CONFIG1_POWERDOWN;2233 conf1_write(lanai);2234#endif2235 iounmap(lanai->base);2236 lanai->base = NULL;2237 error_pci:2238 pci_disable_device(lanai->pci);2239 error:2240 return result;2241}2242 2243/* called when device is being shutdown, and all vcc's are gone - higher2244 * levels will deallocate the atm device for us2245 */2246static void lanai_dev_close(struct atm_dev *atmdev)2247{2248 struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;2249 if (lanai->base==NULL)2250 return;2251 printk(KERN_INFO DEV_LABEL "(itf %d): shutting down interface\n",2252 lanai->number);2253 lanai_timed_poll_stop(lanai);2254#ifdef USE_POWERDOWN2255 lanai->conf1 = reg_read(lanai, Config1_Reg) & ~CONFIG1_POWERDOWN;2256 conf1_write(lanai);2257#endif2258 intr_disable(lanai, INT_ALL);2259 free_irq(lanai->pci->irq, lanai);2260 reset_board(lanai);2261#ifdef USE_POWERDOWN2262 lanai->conf1 |= CONFIG1_POWERDOWN;2263 conf1_write(lanai);2264#endif2265 pci_disable_device(lanai->pci);2266 vcc_table_deallocate(lanai);2267 service_buffer_deallocate(lanai);2268 iounmap(lanai->base);2269 kfree(lanai);2270}2271 2272/* close a vcc */2273static void lanai_close(struct atm_vcc *atmvcc)2274{2275 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;2276 struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;2277 if (lvcc == NULL)2278 return;2279 clear_bit(ATM_VF_READY, &atmvcc->flags);2280 clear_bit(ATM_VF_PARTIAL, &atmvcc->flags);2281 if (lvcc->rx.atmvcc == atmvcc) {2282 lanai_shutdown_rx_vci(lvcc);2283 if (atmvcc->qos.aal == ATM_AAL0) {2284 if (--lanai->naal0 <= 0)2285 aal0_buffer_free(lanai);2286 } else2287 lanai_buf_deallocate(&lvcc->rx.buf, lanai->pci);2288 lvcc->rx.atmvcc = NULL;2289 }2290 if (lvcc->tx.atmvcc == atmvcc) {2291 if (atmvcc == lanai->cbrvcc) {2292 if (lvcc->vbase != NULL)2293 lanai_cbr_shutdown(lanai);2294 lanai->cbrvcc = NULL;2295 }2296 lanai_shutdown_tx_vci(lanai, lvcc);2297 lanai_buf_deallocate(&lvcc->tx.buf, lanai->pci);2298 lvcc->tx.atmvcc = NULL;2299 }2300 if (--lvcc->nref == 0) {2301 host_vcc_unbind(lanai, lvcc);2302 kfree(lvcc);2303 }2304 atmvcc->dev_data = NULL;2305 clear_bit(ATM_VF_ADDR, &atmvcc->flags);2306}2307 2308/* open a vcc on the card to vpi/vci */2309static int lanai_open(struct atm_vcc *atmvcc)2310{2311 struct lanai_dev *lanai;2312 struct lanai_vcc *lvcc;2313 int result = 0;2314 int vci = atmvcc->vci;2315 short vpi = atmvcc->vpi;2316 /* we don't support partial open - it's not really useful anyway */2317 if ((test_bit(ATM_VF_PARTIAL, &atmvcc->flags)) ||2318 (vpi == ATM_VPI_UNSPEC) || (vci == ATM_VCI_UNSPEC))2319 return -EINVAL;2320 lanai = (struct lanai_dev *) atmvcc->dev->dev_data;2321 result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci);2322 if (unlikely(result != 0))2323 goto out;2324 set_bit(ATM_VF_ADDR, &atmvcc->flags);2325 if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5)2326 return -EINVAL;2327 DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number,2328 (int) vpi, vci);2329 lvcc = lanai->vccs[vci];2330 if (lvcc == NULL) {2331 lvcc = new_lanai_vcc();2332 if (unlikely(lvcc == NULL))2333 return -ENOMEM;2334 atmvcc->dev_data = lvcc;2335 }2336 lvcc->nref++;2337 if (atmvcc->qos.rxtp.traffic_class != ATM_NONE) {2338 APRINTK(lvcc->rx.atmvcc == NULL, "rx.atmvcc!=NULL, vci=%d\n",2339 vci);2340 if (atmvcc->qos.aal == ATM_AAL0) {2341 if (lanai->naal0 == 0)2342 result = aal0_buffer_allocate(lanai);2343 } else2344 result = lanai_setup_rx_vci_aal5(2345 lanai, lvcc, &atmvcc->qos);2346 if (unlikely(result != 0))2347 goto out_free;2348 lvcc->rx.atmvcc = atmvcc;2349 lvcc->stats.rx_nomem = 0;2350 lvcc->stats.x.aal5.rx_badlen = 0;2351 lvcc->stats.x.aal5.service_trash = 0;2352 lvcc->stats.x.aal5.service_stream = 0;2353 lvcc->stats.x.aal5.service_rxcrc = 0;2354 if (atmvcc->qos.aal == ATM_AAL0)2355 lanai->naal0++;2356 }2357 if (atmvcc->qos.txtp.traffic_class != ATM_NONE) {2358 APRINTK(lvcc->tx.atmvcc == NULL, "tx.atmvcc!=NULL, vci=%d\n",2359 vci);2360 result = lanai_setup_tx_vci(lanai, lvcc, &atmvcc->qos);2361 if (unlikely(result != 0))2362 goto out_free;2363 lvcc->tx.atmvcc = atmvcc;2364 if (atmvcc->qos.txtp.traffic_class == ATM_CBR) {2365 APRINTK(lanai->cbrvcc == NULL,2366 "cbrvcc!=NULL, vci=%d\n", vci);2367 lanai->cbrvcc = atmvcc;2368 }2369 }2370 host_vcc_bind(lanai, lvcc, vci);2371 /*2372 * Make sure everything made it to RAM before we tell the card about2373 * the VCC2374 */2375 wmb();2376 if (atmvcc == lvcc->rx.atmvcc)2377 host_vcc_start_rx(lvcc);2378 if (atmvcc == lvcc->tx.atmvcc) {2379 host_vcc_start_tx(lvcc);2380 if (lanai->cbrvcc == atmvcc)2381 lanai_cbr_setup(lanai);2382 }2383 set_bit(ATM_VF_READY, &atmvcc->flags);2384 return 0;2385 out_free:2386 lanai_close(atmvcc);2387 out:2388 return result;2389}2390 2391static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)2392{2393 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;2394 struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;2395 unsigned long flags;2396 if (unlikely(lvcc == NULL || lvcc->vbase == NULL ||2397 lvcc->tx.atmvcc != atmvcc))2398 goto einval;2399#ifdef DEBUG2400 if (unlikely(skb == NULL)) {2401 DPRINTK("lanai_send: skb==NULL for vci=%d\n", atmvcc->vci);2402 goto einval;2403 }2404 if (unlikely(lanai == NULL)) {2405 DPRINTK("lanai_send: lanai==NULL for vci=%d\n", atmvcc->vci);2406 goto einval;2407 }2408#endif2409 ATM_SKB(skb)->vcc = atmvcc;2410 switch (atmvcc->qos.aal) {2411 case ATM_AAL5:2412 read_lock_irqsave(&vcc_sklist_lock, flags);2413 vcc_tx_aal5(lanai, lvcc, skb);2414 read_unlock_irqrestore(&vcc_sklist_lock, flags);2415 return 0;2416 case ATM_AAL0:2417 if (unlikely(skb->len != ATM_CELL_SIZE-1))2418 goto einval;2419 /* NOTE - this next line is technically invalid - we haven't unshared skb */2420 cpu_to_be32s((u32 *) skb->data);2421 read_lock_irqsave(&vcc_sklist_lock, flags);2422 vcc_tx_aal0(lanai, lvcc, skb);2423 read_unlock_irqrestore(&vcc_sklist_lock, flags);2424 return 0;2425 }2426 DPRINTK("lanai_send: bad aal=%d on vci=%d\n", (int) atmvcc->qos.aal,2427 atmvcc->vci);2428 einval:2429 lanai_free_skb(atmvcc, skb);2430 return -EINVAL;2431}2432 2433static int lanai_change_qos(struct atm_vcc *atmvcc,2434 /*const*/ struct atm_qos *qos, int flags)2435{2436 return -EBUSY; /* TODO: need to write this */2437}2438 2439#ifndef CONFIG_PROC_FS2440#define lanai_proc_read NULL2441#else2442static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)2443{2444 struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;2445 loff_t left = *pos;2446 struct lanai_vcc *lvcc;2447 if (left-- == 0)2448 return sprintf(page, DEV_LABEL "(itf %d): chip=LANAI%s, "2449 "serial=%u, magic=0x%08X, num_vci=%d\n",2450 atmdev->number, lanai->type==lanai2 ? "2" : "HB",2451 (unsigned int) lanai->serialno,2452 (unsigned int) lanai->magicno, lanai->num_vci);2453 if (left-- == 0)2454 return sprintf(page, "revision: board=%d, pci_if=%d\n",2455 lanai->board_rev, (int) lanai->pci->revision);2456 if (left-- == 0)2457 return sprintf(page, "EEPROM ESI: %pM\n",2458 &lanai->eeprom[EEPROM_MAC]);2459 if (left-- == 0)2460 return sprintf(page, "status: SOOL=%d, LOCD=%d, LED=%d, "2461 "GPIN=%d\n", (lanai->status & STATUS_SOOL) ? 1 : 0,2462 (lanai->status & STATUS_LOCD) ? 1 : 0,2463 (lanai->status & STATUS_LED) ? 1 : 0,2464 (lanai->status & STATUS_GPIN) ? 1 : 0);2465 if (left-- == 0)2466 return sprintf(page, "global buffer sizes: service=%zu, "2467 "aal0_rx=%zu\n", lanai_buf_size(&lanai->service),2468 lanai->naal0 ? lanai_buf_size(&lanai->aal0buf) : 0);2469 if (left-- == 0) {2470 get_statistics(lanai);2471 return sprintf(page, "cells in error: overflow=%u, "2472 "closed_vci=%u, bad_HEC=%u, rx_fifo=%u\n",2473 lanai->stats.ovfl_trash, lanai->stats.vci_trash,2474 lanai->stats.hec_err, lanai->stats.atm_ovfl);2475 }2476 if (left-- == 0)2477 return sprintf(page, "PCI errors: parity_detect=%u, "2478 "master_abort=%u, master_target_abort=%u,\n",2479 lanai->stats.pcierr_parity_detect,2480 lanai->stats.pcierr_serr_set,2481 lanai->stats.pcierr_m_target_abort);2482 if (left-- == 0)2483 return sprintf(page, " slave_target_abort=%u, "2484 "master_parity=%u\n", lanai->stats.pcierr_s_target_abort,2485 lanai->stats.pcierr_master_parity);2486 if (left-- == 0)2487 return sprintf(page, " no_tx=%u, "2488 "no_rx=%u, bad_rx_aal=%u\n", lanai->stats.service_norx,2489 lanai->stats.service_notx,2490 lanai->stats.service_rxnotaal5);2491 if (left-- == 0)2492 return sprintf(page, "resets: dma=%u, card=%u\n",2493 lanai->stats.dma_reenable, lanai->stats.card_reset);2494 /* At this point, "left" should be the VCI we're looking for */2495 read_lock(&vcc_sklist_lock);2496 for (; ; left++) {2497 if (left >= NUM_VCI) {2498 left = 0;2499 goto out;2500 }2501 if ((lvcc = lanai->vccs[left]) != NULL)2502 break;2503 (*pos)++;2504 }2505 /* Note that we re-use "left" here since we're done with it */2506 left = sprintf(page, "VCI %4d: nref=%d, rx_nomem=%u", (vci_t) left,2507 lvcc->nref, lvcc->stats.rx_nomem);2508 if (lvcc->rx.atmvcc != NULL) {2509 left += sprintf(&page[left], ",\n rx_AAL=%d",2510 lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0);2511 if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5)2512 left += sprintf(&page[left], ", rx_buf_size=%zu, "2513 "rx_bad_len=%u,\n rx_service_trash=%u, "2514 "rx_service_stream=%u, rx_bad_crc=%u",2515 lanai_buf_size(&lvcc->rx.buf),2516 lvcc->stats.x.aal5.rx_badlen,2517 lvcc->stats.x.aal5.service_trash,2518 lvcc->stats.x.aal5.service_stream,2519 lvcc->stats.x.aal5.service_rxcrc);2520 }2521 if (lvcc->tx.atmvcc != NULL)2522 left += sprintf(&page[left], ",\n tx_AAL=%d, "2523 "tx_buf_size=%zu, tx_qos=%cBR, tx_backlogged=%c",2524 lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0,2525 lanai_buf_size(&lvcc->tx.buf),2526 lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U',2527 vcc_is_backlogged(lvcc) ? 'Y' : 'N');2528 page[left++] = '\n';2529 page[left] = '\0';2530 out:2531 read_unlock(&vcc_sklist_lock);2532 return left;2533}2534#endif /* CONFIG_PROC_FS */2535 2536/* -------------------- HOOKS: */2537 2538static const struct atmdev_ops ops = {2539 .dev_close = lanai_dev_close,2540 .open = lanai_open,2541 .close = lanai_close,2542 .send = lanai_send,2543 .phy_put = NULL,2544 .phy_get = NULL,2545 .change_qos = lanai_change_qos,2546 .proc_read = lanai_proc_read,2547 .owner = THIS_MODULE2548};2549 2550/* initialize one probed card */2551static int lanai_init_one(struct pci_dev *pci,2552 const struct pci_device_id *ident)2553{2554 struct lanai_dev *lanai;2555 struct atm_dev *atmdev;2556 int result;2557 2558 lanai = kzalloc(sizeof(*lanai), GFP_KERNEL);2559 if (lanai == NULL) {2560 printk(KERN_ERR DEV_LABEL2561 ": couldn't allocate dev_data structure!\n");2562 return -ENOMEM;2563 }2564 2565 atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);2566 if (atmdev == NULL) {2567 printk(KERN_ERR DEV_LABEL2568 ": couldn't register atm device!\n");2569 kfree(lanai);2570 return -EBUSY;2571 }2572 2573 atmdev->dev_data = lanai;2574 lanai->pci = pci;2575 lanai->type = (enum lanai_type) ident->device;2576 2577 result = lanai_dev_open(atmdev);2578 if (result != 0) {2579 DPRINTK("lanai_start() failed, err=%d\n", -result);2580 atm_dev_deregister(atmdev);2581 kfree(lanai);2582 }2583 return result;2584}2585 2586static const struct pci_device_id lanai_pci_tbl[] = {2587 { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAI2) },2588 { PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAIHB) },2589 { 0, } /* terminal entry */2590};2591MODULE_DEVICE_TABLE(pci, lanai_pci_tbl);2592 2593static struct pci_driver lanai_driver = {2594 .name = DEV_LABEL,2595 .id_table = lanai_pci_tbl,2596 .probe = lanai_init_one,2597};2598 2599module_pci_driver(lanai_driver);2600 2601MODULE_AUTHOR("Mitchell Blank Jr <mitch@sfgoth.com>");2602MODULE_DESCRIPTION("Efficient Networks Speedstream 3010 driver");2603MODULE_LICENSE("GPL");2604