2760 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * nicstar.c4 *5 * Device driver supporting CBR for IDT 77201/77211 "NICStAR" based cards.6 *7 * IMPORTANT: The included file nicstarmac.c was NOT WRITTEN BY ME.8 * It was taken from the frle-0.22 device driver.9 * As the file doesn't have a copyright notice, in the file10 * nicstarmac.copyright I put the copyright notice from the11 * frle-0.22 device driver.12 * Some code is based on the nicstar driver by M. Welsh.13 *14 * Author: Rui Prior (rprior@inescn.pt)15 * PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 199916 *17 *18 * (C) INESC 199919 */20 21/*22 * IMPORTANT INFORMATION23 *24 * There are currently three types of spinlocks:25 *26 * 1 - Per card interrupt spinlock (to protect structures and such)27 * 2 - Per SCQ scq spinlock28 * 3 - Per card resource spinlock (to access registers, etc.)29 *30 * These must NEVER be grabbed in reverse order.31 *32 */33 34/* Header files */35 36#include <linux/module.h>37#include <linux/kernel.h>38#include <linux/skbuff.h>39#include <linux/atmdev.h>40#include <linux/atm.h>41#include <linux/pci.h>42#include <linux/dma-mapping.h>43#include <linux/types.h>44#include <linux/string.h>45#include <linux/delay.h>46#include <linux/init.h>47#include <linux/sched.h>48#include <linux/timer.h>49#include <linux/interrupt.h>50#include <linux/bitops.h>51#include <linux/slab.h>52#include <linux/idr.h>53#include <asm/io.h>54#include <linux/uaccess.h>55#include <linux/atomic.h>56#include <linux/etherdevice.h>57#include "nicstar.h"58#ifdef CONFIG_ATM_NICSTAR_USE_SUNI59#include "suni.h"60#endif /* CONFIG_ATM_NICSTAR_USE_SUNI */61#ifdef CONFIG_ATM_NICSTAR_USE_IDT7710562#include "idt77105.h"63#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */64 65/* Additional code */66 67#include "nicstarmac.c"68 69/* Configurable parameters */70 71#undef PHY_LOOPBACK72#undef TX_DEBUG73#undef RX_DEBUG74#undef GENERAL_DEBUG75#undef EXTRA_DEBUG76 77/* Do not touch these */78 79#ifdef TX_DEBUG80#define TXPRINTK(args...) printk(args)81#else82#define TXPRINTK(args...)83#endif /* TX_DEBUG */84 85#ifdef RX_DEBUG86#define RXPRINTK(args...) printk(args)87#else88#define RXPRINTK(args...)89#endif /* RX_DEBUG */90 91#ifdef GENERAL_DEBUG92#define PRINTK(args...) printk(args)93#else94#define PRINTK(args...) do {} while (0)95#endif /* GENERAL_DEBUG */96 97#ifdef EXTRA_DEBUG98#define XPRINTK(args...) printk(args)99#else100#define XPRINTK(args...)101#endif /* EXTRA_DEBUG */102 103/* Macros */104 105#define CMD_BUSY(card) (readl((card)->membase + STAT) & NS_STAT_CMDBZ)106 107#define NS_DELAY mdelay(1)108 109#define PTR_DIFF(a, b) ((u32)((unsigned long)(a) - (unsigned long)(b)))110 111#ifndef ATM_SKB112#define ATM_SKB(s) (&(s)->atm)113#endif114 115#define scq_virt_to_bus(scq, p) \116 (scq->dma + ((unsigned long)(p) - (unsigned long)(scq)->org))117 118/* Function declarations */119 120static u32 ns_read_sram(ns_dev * card, u32 sram_address);121static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value,122 int count);123static int ns_init_card(int i, struct pci_dev *pcidev);124static void ns_init_card_error(ns_dev * card, int error);125static scq_info *get_scq(ns_dev *card, int size, u32 scd);126static void free_scq(ns_dev *card, scq_info * scq, struct atm_vcc *vcc);127static void push_rxbufs(ns_dev *, struct sk_buff *);128static irqreturn_t ns_irq_handler(int irq, void *dev_id);129static int ns_open(struct atm_vcc *vcc);130static void ns_close(struct atm_vcc *vcc);131static void fill_tst(ns_dev * card, int n, vc_map * vc);132static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb);133static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb);134static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,135 struct sk_buff *skb, bool may_sleep);136static void process_tsq(ns_dev * card);137static void drain_scq(ns_dev * card, scq_info * scq, int pos);138static void process_rsq(ns_dev * card);139static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe);140static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb);141static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count);142static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb);143static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb);144static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb);145static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page);146static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);147#ifdef EXTRA_DEBUG148static void which_list(ns_dev * card, struct sk_buff *skb);149#endif150static void ns_poll(struct timer_list *unused);151static void ns_phy_put(struct atm_dev *dev, unsigned char value,152 unsigned long addr);153static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr);154 155/* Global variables */156 157static struct ns_dev *cards[NS_MAX_CARDS];158static unsigned num_cards;159static const struct atmdev_ops atm_ops = {160 .open = ns_open,161 .close = ns_close,162 .ioctl = ns_ioctl,163 .send = ns_send,164 .send_bh = ns_send_bh,165 .phy_put = ns_phy_put,166 .phy_get = ns_phy_get,167 .proc_read = ns_proc_read,168 .owner = THIS_MODULE,169};170 171static struct timer_list ns_timer;172static char *mac[NS_MAX_CARDS];173module_param_array(mac, charp, NULL, 0);174MODULE_DESCRIPTION("ATM NIC driver for IDT 77201/77211 \"NICStAR\" and Fore ForeRunnerLE.");175MODULE_LICENSE("GPL");176 177/* Functions */178 179static int nicstar_init_one(struct pci_dev *pcidev,180 const struct pci_device_id *ent)181{182 static int index = -1;183 unsigned int error;184 185 index++;186 cards[index] = NULL;187 188 error = ns_init_card(index, pcidev);189 if (error) {190 cards[index--] = NULL; /* don't increment index */191 goto err_out;192 }193 194 return 0;195err_out:196 return -ENODEV;197}198 199static void nicstar_remove_one(struct pci_dev *pcidev)200{201 int i, j;202 ns_dev *card = pci_get_drvdata(pcidev);203 struct sk_buff *hb;204 struct sk_buff *iovb;205 struct sk_buff *lb;206 struct sk_buff *sb;207 208 i = card->index;209 210 if (cards[i] == NULL)211 return;212 213 if (card->atmdev->phy && card->atmdev->phy->stop)214 card->atmdev->phy->stop(card->atmdev);215 216 /* Stop everything */217 writel(0x00000000, card->membase + CFG);218 219 /* De-register device */220 atm_dev_deregister(card->atmdev);221 222 /* Disable PCI device */223 pci_disable_device(pcidev);224 225 /* Free up resources */226 j = 0;227 PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count);228 while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) {229 dev_kfree_skb_any(hb);230 j++;231 }232 PRINTK("nicstar%d: %d huge buffers freed.\n", i, j);233 j = 0;234 PRINTK("nicstar%d: freeing %d iovec buffers.\n", i,235 card->iovpool.count);236 while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) {237 dev_kfree_skb_any(iovb);238 j++;239 }240 PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j);241 while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL)242 dev_kfree_skb_any(lb);243 while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)244 dev_kfree_skb_any(sb);245 free_scq(card, card->scq0, NULL);246 for (j = 0; j < NS_FRSCD_NUM; j++) {247 if (card->scd2vc[j] != NULL)248 free_scq(card, card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc);249 }250 idr_destroy(&card->idr);251 dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,252 card->rsq.org, card->rsq.dma);253 dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,254 card->tsq.org, card->tsq.dma);255 free_irq(card->pcidev->irq, card);256 iounmap(card->membase);257 kfree(card);258}259 260static const struct pci_device_id nicstar_pci_tbl[] = {261 { PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77201), 0 },262 {0,} /* terminate list */263};264 265MODULE_DEVICE_TABLE(pci, nicstar_pci_tbl);266 267static struct pci_driver nicstar_driver = {268 .name = "nicstar",269 .id_table = nicstar_pci_tbl,270 .probe = nicstar_init_one,271 .remove = nicstar_remove_one,272};273 274static int __init nicstar_init(void)275{276 unsigned error = 0; /* Initialized to remove compile warning */277 278 XPRINTK("nicstar: nicstar_init() called.\n");279 280 error = pci_register_driver(&nicstar_driver);281 282 TXPRINTK("nicstar: TX debug enabled.\n");283 RXPRINTK("nicstar: RX debug enabled.\n");284 PRINTK("nicstar: General debug enabled.\n");285#ifdef PHY_LOOPBACK286 printk("nicstar: using PHY loopback.\n");287#endif /* PHY_LOOPBACK */288 XPRINTK("nicstar: nicstar_init() returned.\n");289 290 if (!error) {291 timer_setup(&ns_timer, ns_poll, 0);292 ns_timer.expires = jiffies + NS_POLL_PERIOD;293 add_timer(&ns_timer);294 }295 296 return error;297}298 299static void __exit nicstar_cleanup(void)300{301 XPRINTK("nicstar: nicstar_cleanup() called.\n");302 303 del_timer_sync(&ns_timer);304 305 pci_unregister_driver(&nicstar_driver);306 307 XPRINTK("nicstar: nicstar_cleanup() returned.\n");308}309 310static u32 ns_read_sram(ns_dev * card, u32 sram_address)311{312 unsigned long flags;313 u32 data;314 sram_address <<= 2;315 sram_address &= 0x0007FFFC; /* address must be dword aligned */316 sram_address |= 0x50000000; /* SRAM read command */317 spin_lock_irqsave(&card->res_lock, flags);318 while (CMD_BUSY(card)) ;319 writel(sram_address, card->membase + CMD);320 while (CMD_BUSY(card)) ;321 data = readl(card->membase + DR0);322 spin_unlock_irqrestore(&card->res_lock, flags);323 return data;324}325 326static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value,327 int count)328{329 unsigned long flags;330 int i, c;331 count--; /* count range now is 0..3 instead of 1..4 */332 c = count;333 c <<= 2; /* to use increments of 4 */334 spin_lock_irqsave(&card->res_lock, flags);335 while (CMD_BUSY(card)) ;336 for (i = 0; i <= c; i += 4)337 writel(*(value++), card->membase + i);338 /* Note: DR# registers are the first 4 dwords in nicstar's memspace,339 so card->membase + DR0 == card->membase */340 sram_address <<= 2;341 sram_address &= 0x0007FFFC;342 sram_address |= (0x40000000 | count);343 writel(sram_address, card->membase + CMD);344 spin_unlock_irqrestore(&card->res_lock, flags);345}346 347static int ns_init_card(int i, struct pci_dev *pcidev)348{349 int j;350 struct ns_dev *card = NULL;351 unsigned char pci_latency;352 unsigned error;353 u32 data;354 u32 u32d[4];355 u32 ns_cfg_rctsize;356 int bcount;357 unsigned long membase;358 359 error = 0;360 361 if (pci_enable_device(pcidev)) {362 printk("nicstar%d: can't enable PCI device\n", i);363 error = 2;364 ns_init_card_error(card, error);365 return error;366 }367 if (dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)) != 0) {368 printk(KERN_WARNING369 "nicstar%d: No suitable DMA available.\n", i);370 error = 2;371 ns_init_card_error(card, error);372 return error;373 }374 375 card = kmalloc(sizeof(*card), GFP_KERNEL);376 if (!card) {377 printk378 ("nicstar%d: can't allocate memory for device structure.\n",379 i);380 error = 2;381 ns_init_card_error(card, error);382 return error;383 }384 cards[i] = card;385 spin_lock_init(&card->int_lock);386 spin_lock_init(&card->res_lock);387 388 pci_set_drvdata(pcidev, card);389 390 card->index = i;391 card->atmdev = NULL;392 card->pcidev = pcidev;393 membase = pci_resource_start(pcidev, 1);394 card->membase = ioremap(membase, NS_IOREMAP_SIZE);395 if (!card->membase) {396 printk("nicstar%d: can't ioremap() membase.\n", i);397 error = 3;398 ns_init_card_error(card, error);399 return error;400 }401 PRINTK("nicstar%d: membase at 0x%p.\n", i, card->membase);402 403 pci_set_master(pcidev);404 405 if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0) {406 printk("nicstar%d: can't read PCI latency timer.\n", i);407 error = 6;408 ns_init_card_error(card, error);409 return error;410 }411#ifdef NS_PCI_LATENCY412 if (pci_latency < NS_PCI_LATENCY) {413 PRINTK("nicstar%d: setting PCI latency timer to %d.\n", i,414 NS_PCI_LATENCY);415 for (j = 1; j < 4; j++) {416 if (pci_write_config_byte417 (pcidev, PCI_LATENCY_TIMER, NS_PCI_LATENCY) != 0)418 break;419 }420 if (j == 4) {421 printk422 ("nicstar%d: can't set PCI latency timer to %d.\n",423 i, NS_PCI_LATENCY);424 error = 7;425 ns_init_card_error(card, error);426 return error;427 }428 }429#endif /* NS_PCI_LATENCY */430 431 /* Clear timer overflow */432 data = readl(card->membase + STAT);433 if (data & NS_STAT_TMROF)434 writel(NS_STAT_TMROF, card->membase + STAT);435 436 /* Software reset */437 writel(NS_CFG_SWRST, card->membase + CFG);438 NS_DELAY;439 writel(0x00000000, card->membase + CFG);440 441 /* PHY reset */442 writel(0x00000008, card->membase + GP);443 NS_DELAY;444 writel(0x00000001, card->membase + GP);445 NS_DELAY;446 while (CMD_BUSY(card)) ;447 writel(NS_CMD_WRITE_UTILITY | 0x00000100, card->membase + CMD); /* Sync UTOPIA with SAR clock */448 NS_DELAY;449 450 /* Detect PHY type */451 while (CMD_BUSY(card)) ;452 writel(NS_CMD_READ_UTILITY | 0x00000200, card->membase + CMD);453 while (CMD_BUSY(card)) ;454 data = readl(card->membase + DR0);455 switch (data) {456 case 0x00000009:457 printk("nicstar%d: PHY seems to be 25 Mbps.\n", i);458 card->max_pcr = ATM_25_PCR;459 while (CMD_BUSY(card)) ;460 writel(0x00000008, card->membase + DR0);461 writel(NS_CMD_WRITE_UTILITY | 0x00000200, card->membase + CMD);462 /* Clear an eventual pending interrupt */463 writel(NS_STAT_SFBQF, card->membase + STAT);464#ifdef PHY_LOOPBACK465 while (CMD_BUSY(card)) ;466 writel(0x00000022, card->membase + DR0);467 writel(NS_CMD_WRITE_UTILITY | 0x00000202, card->membase + CMD);468#endif /* PHY_LOOPBACK */469 break;470 case 0x00000030:471 case 0x00000031:472 printk("nicstar%d: PHY seems to be 155 Mbps.\n", i);473 card->max_pcr = ATM_OC3_PCR;474#ifdef PHY_LOOPBACK475 while (CMD_BUSY(card)) ;476 writel(0x00000002, card->membase + DR0);477 writel(NS_CMD_WRITE_UTILITY | 0x00000205, card->membase + CMD);478#endif /* PHY_LOOPBACK */479 break;480 default:481 printk("nicstar%d: unknown PHY type (0x%08X).\n", i, data);482 error = 8;483 ns_init_card_error(card, error);484 return error;485 }486 writel(0x00000000, card->membase + GP);487 488 /* Determine SRAM size */489 data = 0x76543210;490 ns_write_sram(card, 0x1C003, &data, 1);491 data = 0x89ABCDEF;492 ns_write_sram(card, 0x14003, &data, 1);493 if (ns_read_sram(card, 0x14003) == 0x89ABCDEF &&494 ns_read_sram(card, 0x1C003) == 0x76543210)495 card->sram_size = 128;496 else497 card->sram_size = 32;498 PRINTK("nicstar%d: %dK x 32bit SRAM size.\n", i, card->sram_size);499 500 card->rct_size = NS_MAX_RCTSIZE;501 502#if (NS_MAX_RCTSIZE == 4096)503 if (card->sram_size == 128)504 printk505 ("nicstar%d: limiting maximum VCI. See NS_MAX_RCTSIZE in nicstar.h\n",506 i);507#elif (NS_MAX_RCTSIZE == 16384)508 if (card->sram_size == 32) {509 printk510 ("nicstar%d: wasting memory. See NS_MAX_RCTSIZE in nicstar.h\n",511 i);512 card->rct_size = 4096;513 }514#else515#error NS_MAX_RCTSIZE must be either 4096 or 16384 in nicstar.c516#endif517 518 card->vpibits = NS_VPIBITS;519 if (card->rct_size == 4096)520 card->vcibits = 12 - NS_VPIBITS;521 else /* card->rct_size == 16384 */522 card->vcibits = 14 - NS_VPIBITS;523 524 /* Initialize the nicstar eeprom/eprom stuff, for the MAC addr */525 if (mac[i] == NULL)526 nicstar_init_eprom(card->membase);527 528 /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */529 writel(0x00000000, card->membase + VPM);530 531 card->intcnt = 0;532 if (request_irq533 (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) {534 pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);535 error = 9;536 ns_init_card_error(card, error);537 return error;538 }539 540 /* Initialize TSQ */541 card->tsq.org = dma_alloc_coherent(&card->pcidev->dev,542 NS_TSQSIZE + NS_TSQ_ALIGNMENT,543 &card->tsq.dma, GFP_KERNEL);544 if (card->tsq.org == NULL) {545 printk("nicstar%d: can't allocate TSQ.\n", i);546 error = 10;547 ns_init_card_error(card, error);548 return error;549 }550 card->tsq.base = PTR_ALIGN(card->tsq.org, NS_TSQ_ALIGNMENT);551 card->tsq.next = card->tsq.base;552 card->tsq.last = card->tsq.base + (NS_TSQ_NUM_ENTRIES - 1);553 for (j = 0; j < NS_TSQ_NUM_ENTRIES; j++)554 ns_tsi_init(card->tsq.base + j);555 writel(0x00000000, card->membase + TSQH);556 writel(ALIGN(card->tsq.dma, NS_TSQ_ALIGNMENT), card->membase + TSQB);557 PRINTK("nicstar%d: TSQ base at 0x%p.\n", i, card->tsq.base);558 559 /* Initialize RSQ */560 card->rsq.org = dma_alloc_coherent(&card->pcidev->dev,561 NS_RSQSIZE + NS_RSQ_ALIGNMENT,562 &card->rsq.dma, GFP_KERNEL);563 if (card->rsq.org == NULL) {564 printk("nicstar%d: can't allocate RSQ.\n", i);565 error = 11;566 ns_init_card_error(card, error);567 return error;568 }569 card->rsq.base = PTR_ALIGN(card->rsq.org, NS_RSQ_ALIGNMENT);570 card->rsq.next = card->rsq.base;571 card->rsq.last = card->rsq.base + (NS_RSQ_NUM_ENTRIES - 1);572 for (j = 0; j < NS_RSQ_NUM_ENTRIES; j++)573 ns_rsqe_init(card->rsq.base + j);574 writel(0x00000000, card->membase + RSQH);575 writel(ALIGN(card->rsq.dma, NS_RSQ_ALIGNMENT), card->membase + RSQB);576 PRINTK("nicstar%d: RSQ base at 0x%p.\n", i, card->rsq.base);577 578 /* Initialize SCQ0, the only VBR SCQ used */579 card->scq1 = NULL;580 card->scq2 = NULL;581 card->scq0 = get_scq(card, VBR_SCQSIZE, NS_VRSCD0);582 if (card->scq0 == NULL) {583 printk("nicstar%d: can't get SCQ0.\n", i);584 error = 12;585 ns_init_card_error(card, error);586 return error;587 }588 u32d[0] = scq_virt_to_bus(card->scq0, card->scq0->base);589 u32d[1] = (u32) 0x00000000;590 u32d[2] = (u32) 0xffffffff;591 u32d[3] = (u32) 0x00000000;592 ns_write_sram(card, NS_VRSCD0, u32d, 4);593 ns_write_sram(card, NS_VRSCD1, u32d, 4); /* These last two won't be used */594 ns_write_sram(card, NS_VRSCD2, u32d, 4); /* but are initialized, just in case... */595 card->scq0->scd = NS_VRSCD0;596 PRINTK("nicstar%d: VBR-SCQ0 base at 0x%p.\n", i, card->scq0->base);597 598 /* Initialize TSTs */599 card->tst_addr = NS_TST0;600 card->tst_free_entries = NS_TST_NUM_ENTRIES;601 data = NS_TST_OPCODE_VARIABLE;602 for (j = 0; j < NS_TST_NUM_ENTRIES; j++)603 ns_write_sram(card, NS_TST0 + j, &data, 1);604 data = ns_tste_make(NS_TST_OPCODE_END, NS_TST0);605 ns_write_sram(card, NS_TST0 + NS_TST_NUM_ENTRIES, &data, 1);606 for (j = 0; j < NS_TST_NUM_ENTRIES; j++)607 ns_write_sram(card, NS_TST1 + j, &data, 1);608 data = ns_tste_make(NS_TST_OPCODE_END, NS_TST1);609 ns_write_sram(card, NS_TST1 + NS_TST_NUM_ENTRIES, &data, 1);610 for (j = 0; j < NS_TST_NUM_ENTRIES; j++)611 card->tste2vc[j] = NULL;612 writel(NS_TST0 << 2, card->membase + TSTB);613 614 /* Initialize RCT. AAL type is set on opening the VC. */615#ifdef RCQ_SUPPORT616 u32d[0] = NS_RCTE_RAWCELLINTEN;617#else618 u32d[0] = 0x00000000;619#endif /* RCQ_SUPPORT */620 u32d[1] = 0x00000000;621 u32d[2] = 0x00000000;622 u32d[3] = 0xFFFFFFFF;623 for (j = 0; j < card->rct_size; j++)624 ns_write_sram(card, j * 4, u32d, 4);625 626 memset(card->vcmap, 0, sizeof(card->vcmap));627 628 for (j = 0; j < NS_FRSCD_NUM; j++)629 card->scd2vc[j] = NULL;630 631 /* Initialize buffer levels */632 card->sbnr.min = MIN_SB;633 card->sbnr.init = NUM_SB;634 card->sbnr.max = MAX_SB;635 card->lbnr.min = MIN_LB;636 card->lbnr.init = NUM_LB;637 card->lbnr.max = MAX_LB;638 card->iovnr.min = MIN_IOVB;639 card->iovnr.init = NUM_IOVB;640 card->iovnr.max = MAX_IOVB;641 card->hbnr.min = MIN_HB;642 card->hbnr.init = NUM_HB;643 card->hbnr.max = MAX_HB;644 645 card->sm_handle = NULL;646 card->sm_addr = 0x00000000;647 card->lg_handle = NULL;648 card->lg_addr = 0x00000000;649 650 card->efbie = 1; /* To prevent push_rxbufs from enabling the interrupt */651 652 idr_init(&card->idr);653 654 /* Pre-allocate some huge buffers */655 skb_queue_head_init(&card->hbpool.queue);656 card->hbpool.count = 0;657 for (j = 0; j < NUM_HB; j++) {658 struct sk_buff *hb;659 hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);660 if (hb == NULL) {661 printk662 ("nicstar%d: can't allocate %dth of %d huge buffers.\n",663 i, j, NUM_HB);664 error = 13;665 ns_init_card_error(card, error);666 return error;667 }668 NS_PRV_BUFTYPE(hb) = BUF_NONE;669 skb_queue_tail(&card->hbpool.queue, hb);670 card->hbpool.count++;671 }672 673 /* Allocate large buffers */674 skb_queue_head_init(&card->lbpool.queue);675 card->lbpool.count = 0; /* Not used */676 for (j = 0; j < NUM_LB; j++) {677 struct sk_buff *lb;678 lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);679 if (lb == NULL) {680 printk681 ("nicstar%d: can't allocate %dth of %d large buffers.\n",682 i, j, NUM_LB);683 error = 14;684 ns_init_card_error(card, error);685 return error;686 }687 NS_PRV_BUFTYPE(lb) = BUF_LG;688 skb_queue_tail(&card->lbpool.queue, lb);689 skb_reserve(lb, NS_SMBUFSIZE);690 push_rxbufs(card, lb);691 /* Due to the implementation of push_rxbufs() this is 1, not 0 */692 if (j == 1) {693 card->rcbuf = lb;694 card->rawcell = (struct ns_rcqe *) lb->data;695 card->rawch = NS_PRV_DMA(lb);696 }697 }698 /* Test for strange behaviour which leads to crashes */699 if ((bcount =700 ns_stat_lfbqc_get(readl(card->membase + STAT))) < card->lbnr.min) {701 printk702 ("nicstar%d: Strange... Just allocated %d large buffers and lfbqc = %d.\n",703 i, j, bcount);704 error = 14;705 ns_init_card_error(card, error);706 return error;707 }708 709 /* Allocate small buffers */710 skb_queue_head_init(&card->sbpool.queue);711 card->sbpool.count = 0; /* Not used */712 for (j = 0; j < NUM_SB; j++) {713 struct sk_buff *sb;714 sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);715 if (sb == NULL) {716 printk717 ("nicstar%d: can't allocate %dth of %d small buffers.\n",718 i, j, NUM_SB);719 error = 15;720 ns_init_card_error(card, error);721 return error;722 }723 NS_PRV_BUFTYPE(sb) = BUF_SM;724 skb_queue_tail(&card->sbpool.queue, sb);725 skb_reserve(sb, NS_AAL0_HEADER);726 push_rxbufs(card, sb);727 }728 /* Test for strange behaviour which leads to crashes */729 if ((bcount =730 ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min) {731 printk732 ("nicstar%d: Strange... Just allocated %d small buffers and sfbqc = %d.\n",733 i, j, bcount);734 error = 15;735 ns_init_card_error(card, error);736 return error;737 }738 739 /* Allocate iovec buffers */740 skb_queue_head_init(&card->iovpool.queue);741 card->iovpool.count = 0;742 for (j = 0; j < NUM_IOVB; j++) {743 struct sk_buff *iovb;744 iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);745 if (iovb == NULL) {746 printk747 ("nicstar%d: can't allocate %dth of %d iovec buffers.\n",748 i, j, NUM_IOVB);749 error = 16;750 ns_init_card_error(card, error);751 return error;752 }753 NS_PRV_BUFTYPE(iovb) = BUF_NONE;754 skb_queue_tail(&card->iovpool.queue, iovb);755 card->iovpool.count++;756 }757 758 /* Configure NICStAR */759 if (card->rct_size == 4096)760 ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES;761 else /* (card->rct_size == 16384) */762 ns_cfg_rctsize = NS_CFG_RCTSIZE_16384_ENTRIES;763 764 card->efbie = 1;765 766 /* Register device */767 card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,768 -1, NULL);769 if (card->atmdev == NULL) {770 printk("nicstar%d: can't register device.\n", i);771 error = 17;772 ns_init_card_error(card, error);773 return error;774 }775 776 if (mac[i] == NULL || !mac_pton(mac[i], card->atmdev->esi)) {777 nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET,778 card->atmdev->esi, 6);779 if (ether_addr_equal(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00")) {780 nicstar_read_eprom(card->membase,781 NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT,782 card->atmdev->esi, 6);783 }784 }785 786 printk("nicstar%d: MAC address %pM\n", i, card->atmdev->esi);787 788 card->atmdev->dev_data = card;789 card->atmdev->ci_range.vpi_bits = card->vpibits;790 card->atmdev->ci_range.vci_bits = card->vcibits;791 card->atmdev->link_rate = card->max_pcr;792 card->atmdev->phy = NULL;793 794#ifdef CONFIG_ATM_NICSTAR_USE_SUNI795 if (card->max_pcr == ATM_OC3_PCR)796 suni_init(card->atmdev);797#endif /* CONFIG_ATM_NICSTAR_USE_SUNI */798 799#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105800 if (card->max_pcr == ATM_25_PCR)801 idt77105_init(card->atmdev);802#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */803 804 if (card->atmdev->phy && card->atmdev->phy->start)805 card->atmdev->phy->start(card->atmdev);806 807 writel(NS_CFG_RXPATH | NS_CFG_SMBUFSIZE | NS_CFG_LGBUFSIZE | NS_CFG_EFBIE | NS_CFG_RSQSIZE | NS_CFG_VPIBITS | ns_cfg_rctsize | NS_CFG_RXINT_NODELAY | NS_CFG_RAWIE | /* Only enabled if RCQ_SUPPORT */808 NS_CFG_RSQAFIE | NS_CFG_TXEN | NS_CFG_TXIE | NS_CFG_TSQFIE_OPT | /* Only enabled if ENABLE_TSQFIE */809 NS_CFG_PHYIE, card->membase + CFG);810 811 num_cards++;812 813 return error;814}815 816static void ns_init_card_error(ns_dev *card, int error)817{818 if (error >= 17) {819 writel(0x00000000, card->membase + CFG);820 }821 if (error >= 16) {822 struct sk_buff *iovb;823 while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL)824 dev_kfree_skb_any(iovb);825 }826 if (error >= 15) {827 struct sk_buff *sb;828 while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)829 dev_kfree_skb_any(sb);830 free_scq(card, card->scq0, NULL);831 }832 if (error >= 14) {833 struct sk_buff *lb;834 while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL)835 dev_kfree_skb_any(lb);836 }837 if (error >= 13) {838 struct sk_buff *hb;839 while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL)840 dev_kfree_skb_any(hb);841 }842 if (error >= 12) {843 dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,844 card->rsq.org, card->rsq.dma);845 }846 if (error >= 11) {847 dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,848 card->tsq.org, card->tsq.dma);849 }850 if (error >= 10) {851 free_irq(card->pcidev->irq, card);852 }853 if (error >= 4) {854 iounmap(card->membase);855 }856 if (error >= 3) {857 pci_disable_device(card->pcidev);858 kfree(card);859 }860}861 862static scq_info *get_scq(ns_dev *card, int size, u32 scd)863{864 scq_info *scq;865 866 if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)867 return NULL;868 869 scq = kmalloc(sizeof(*scq), GFP_KERNEL);870 if (!scq)871 return NULL;872 scq->org = dma_alloc_coherent(&card->pcidev->dev,873 2 * size, &scq->dma, GFP_KERNEL);874 if (!scq->org) {875 kfree(scq);876 return NULL;877 }878 scq->skb = kcalloc(size / NS_SCQE_SIZE, sizeof(*scq->skb),879 GFP_KERNEL);880 if (!scq->skb) {881 dma_free_coherent(&card->pcidev->dev,882 2 * size, scq->org, scq->dma);883 kfree(scq);884 return NULL;885 }886 scq->num_entries = size / NS_SCQE_SIZE;887 scq->base = PTR_ALIGN(scq->org, size);888 scq->next = scq->base;889 scq->last = scq->base + (scq->num_entries - 1);890 scq->tail = scq->last;891 scq->scd = scd;892 scq->tbd_count = 0;893 init_waitqueue_head(&scq->scqfull_waitq);894 scq->full = 0;895 spin_lock_init(&scq->lock);896 897 return scq;898}899 900/* For variable rate SCQ vcc must be NULL */901static void free_scq(ns_dev *card, scq_info *scq, struct atm_vcc *vcc)902{903 int i;904 905 if (scq->num_entries == VBR_SCQ_NUM_ENTRIES)906 for (i = 0; i < scq->num_entries; i++) {907 if (scq->skb[i] != NULL) {908 vcc = ATM_SKB(scq->skb[i])->vcc;909 if (vcc->pop != NULL)910 vcc->pop(vcc, scq->skb[i]);911 else912 dev_kfree_skb_any(scq->skb[i]);913 }914 } else { /* vcc must be != NULL */915 916 if (vcc == NULL) {917 printk918 ("nicstar: free_scq() called with vcc == NULL for fixed rate scq.");919 for (i = 0; i < scq->num_entries; i++)920 dev_kfree_skb_any(scq->skb[i]);921 } else922 for (i = 0; i < scq->num_entries; i++) {923 if (scq->skb[i] != NULL) {924 if (vcc->pop != NULL)925 vcc->pop(vcc, scq->skb[i]);926 else927 dev_kfree_skb_any(scq->skb[i]);928 }929 }930 }931 kfree(scq->skb);932 dma_free_coherent(&card->pcidev->dev,933 2 * (scq->num_entries == VBR_SCQ_NUM_ENTRIES ?934 VBR_SCQSIZE : CBR_SCQSIZE),935 scq->org, scq->dma);936 kfree(scq);937}938 939/* The handles passed must be pointers to the sk_buff containing the small940 or large buffer(s) cast to u32. */941static void push_rxbufs(ns_dev * card, struct sk_buff *skb)942{943 struct sk_buff *handle1, *handle2;944 int id1, id2;945 u32 addr1, addr2;946 u32 stat;947 unsigned long flags;948 949 /* *BARF* */950 handle2 = NULL;951 addr2 = 0;952 handle1 = skb;953 addr1 = dma_map_single(&card->pcidev->dev,954 skb->data,955 (NS_PRV_BUFTYPE(skb) == BUF_SM956 ? NS_SMSKBSIZE : NS_LGSKBSIZE),957 DMA_TO_DEVICE);958 NS_PRV_DMA(skb) = addr1; /* save so we can unmap later */959 960#ifdef GENERAL_DEBUG961 if (!addr1)962 printk("nicstar%d: push_rxbufs called with addr1 = 0.\n",963 card->index);964#endif /* GENERAL_DEBUG */965 966 stat = readl(card->membase + STAT);967 card->sbfqc = ns_stat_sfbqc_get(stat);968 card->lbfqc = ns_stat_lfbqc_get(stat);969 if (NS_PRV_BUFTYPE(skb) == BUF_SM) {970 if (!addr2) {971 if (card->sm_addr) {972 addr2 = card->sm_addr;973 handle2 = card->sm_handle;974 card->sm_addr = 0x00000000;975 card->sm_handle = NULL;976 } else { /* (!sm_addr) */977 978 card->sm_addr = addr1;979 card->sm_handle = handle1;980 }981 }982 } else { /* buf_type == BUF_LG */983 984 if (!addr2) {985 if (card->lg_addr) {986 addr2 = card->lg_addr;987 handle2 = card->lg_handle;988 card->lg_addr = 0x00000000;989 card->lg_handle = NULL;990 } else { /* (!lg_addr) */991 992 card->lg_addr = addr1;993 card->lg_handle = handle1;994 }995 }996 }997 998 if (addr2) {999 if (NS_PRV_BUFTYPE(skb) == BUF_SM) {1000 if (card->sbfqc >= card->sbnr.max) {1001 skb_unlink(handle1, &card->sbpool.queue);1002 dev_kfree_skb_any(handle1);1003 skb_unlink(handle2, &card->sbpool.queue);1004 dev_kfree_skb_any(handle2);1005 return;1006 } else1007 card->sbfqc += 2;1008 } else { /* (buf_type == BUF_LG) */1009 1010 if (card->lbfqc >= card->lbnr.max) {1011 skb_unlink(handle1, &card->lbpool.queue);1012 dev_kfree_skb_any(handle1);1013 skb_unlink(handle2, &card->lbpool.queue);1014 dev_kfree_skb_any(handle2);1015 return;1016 } else1017 card->lbfqc += 2;1018 }1019 1020 id1 = idr_alloc(&card->idr, handle1, 0, 0, GFP_ATOMIC);1021 if (id1 < 0)1022 goto out;1023 1024 id2 = idr_alloc(&card->idr, handle2, 0, 0, GFP_ATOMIC);1025 if (id2 < 0)1026 goto out;1027 1028 spin_lock_irqsave(&card->res_lock, flags);1029 while (CMD_BUSY(card)) ;1030 writel(addr2, card->membase + DR3);1031 writel(id2, card->membase + DR2);1032 writel(addr1, card->membase + DR1);1033 writel(id1, card->membase + DR0);1034 writel(NS_CMD_WRITE_FREEBUFQ | NS_PRV_BUFTYPE(skb),1035 card->membase + CMD);1036 spin_unlock_irqrestore(&card->res_lock, flags);1037 1038 XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n",1039 card->index,1040 (NS_PRV_BUFTYPE(skb) == BUF_SM ? "small" : "large"),1041 addr1, addr2);1042 }1043 1044 if (!card->efbie && card->sbfqc >= card->sbnr.min &&1045 card->lbfqc >= card->lbnr.min) {1046 card->efbie = 1;1047 writel((readl(card->membase + CFG) | NS_CFG_EFBIE),1048 card->membase + CFG);1049 }1050 1051out:1052 return;1053}1054 1055static irqreturn_t ns_irq_handler(int irq, void *dev_id)1056{1057 u32 stat_r;1058 ns_dev *card;1059 struct atm_dev *dev;1060 unsigned long flags;1061 1062 card = (ns_dev *) dev_id;1063 dev = card->atmdev;1064 card->intcnt++;1065 1066 PRINTK("nicstar%d: NICStAR generated an interrupt\n", card->index);1067 1068 spin_lock_irqsave(&card->int_lock, flags);1069 1070 stat_r = readl(card->membase + STAT);1071 1072 /* Transmit Status Indicator has been written to T. S. Queue */1073 if (stat_r & NS_STAT_TSIF) {1074 TXPRINTK("nicstar%d: TSI interrupt\n", card->index);1075 process_tsq(card);1076 writel(NS_STAT_TSIF, card->membase + STAT);1077 }1078 1079 /* Incomplete CS-PDU has been transmitted */1080 if (stat_r & NS_STAT_TXICP) {1081 writel(NS_STAT_TXICP, card->membase + STAT);1082 TXPRINTK("nicstar%d: Incomplete CS-PDU transmitted.\n",1083 card->index);1084 }1085 1086 /* Transmit Status Queue 7/8 full */1087 if (stat_r & NS_STAT_TSQF) {1088 writel(NS_STAT_TSQF, card->membase + STAT);1089 PRINTK("nicstar%d: TSQ full.\n", card->index);1090 process_tsq(card);1091 }1092 1093 /* Timer overflow */1094 if (stat_r & NS_STAT_TMROF) {1095 writel(NS_STAT_TMROF, card->membase + STAT);1096 PRINTK("nicstar%d: Timer overflow.\n", card->index);1097 }1098 1099 /* PHY device interrupt signal active */1100 if (stat_r & NS_STAT_PHYI) {1101 writel(NS_STAT_PHYI, card->membase + STAT);1102 PRINTK("nicstar%d: PHY interrupt.\n", card->index);1103 if (dev->phy && dev->phy->interrupt) {1104 dev->phy->interrupt(dev);1105 }1106 }1107 1108 /* Small Buffer Queue is full */1109 if (stat_r & NS_STAT_SFBQF) {1110 writel(NS_STAT_SFBQF, card->membase + STAT);1111 printk("nicstar%d: Small free buffer queue is full.\n",1112 card->index);1113 }1114 1115 /* Large Buffer Queue is full */1116 if (stat_r & NS_STAT_LFBQF) {1117 writel(NS_STAT_LFBQF, card->membase + STAT);1118 printk("nicstar%d: Large free buffer queue is full.\n",1119 card->index);1120 }1121 1122 /* Receive Status Queue is full */1123 if (stat_r & NS_STAT_RSQF) {1124 writel(NS_STAT_RSQF, card->membase + STAT);1125 printk("nicstar%d: RSQ full.\n", card->index);1126 process_rsq(card);1127 }1128 1129 /* Complete CS-PDU received */1130 if (stat_r & NS_STAT_EOPDU) {1131 RXPRINTK("nicstar%d: End of CS-PDU received.\n", card->index);1132 process_rsq(card);1133 writel(NS_STAT_EOPDU, card->membase + STAT);1134 }1135 1136 /* Raw cell received */1137 if (stat_r & NS_STAT_RAWCF) {1138 writel(NS_STAT_RAWCF, card->membase + STAT);1139#ifndef RCQ_SUPPORT1140 printk("nicstar%d: Raw cell received and no support yet...\n",1141 card->index);1142#endif /* RCQ_SUPPORT */1143 /* NOTE: the following procedure may keep a raw cell pending until the1144 next interrupt. As this preliminary support is only meant to1145 avoid buffer leakage, this is not an issue. */1146 while (readl(card->membase + RAWCT) != card->rawch) {1147 1148 if (ns_rcqe_islast(card->rawcell)) {1149 struct sk_buff *oldbuf;1150 1151 oldbuf = card->rcbuf;1152 card->rcbuf = idr_find(&card->idr,1153 ns_rcqe_nextbufhandle(card->rawcell));1154 card->rawch = NS_PRV_DMA(card->rcbuf);1155 card->rawcell = (struct ns_rcqe *)1156 card->rcbuf->data;1157 recycle_rx_buf(card, oldbuf);1158 } else {1159 card->rawch += NS_RCQE_SIZE;1160 card->rawcell++;1161 }1162 }1163 }1164 1165 /* Small buffer queue is empty */1166 if (stat_r & NS_STAT_SFBQE) {1167 int i;1168 struct sk_buff *sb;1169 1170 writel(NS_STAT_SFBQE, card->membase + STAT);1171 printk("nicstar%d: Small free buffer queue empty.\n",1172 card->index);1173 for (i = 0; i < card->sbnr.min; i++) {1174 sb = dev_alloc_skb(NS_SMSKBSIZE);1175 if (sb == NULL) {1176 writel(readl(card->membase + CFG) &1177 ~NS_CFG_EFBIE, card->membase + CFG);1178 card->efbie = 0;1179 break;1180 }1181 NS_PRV_BUFTYPE(sb) = BUF_SM;1182 skb_queue_tail(&card->sbpool.queue, sb);1183 skb_reserve(sb, NS_AAL0_HEADER);1184 push_rxbufs(card, sb);1185 }1186 card->sbfqc = i;1187 process_rsq(card);1188 }1189 1190 /* Large buffer queue empty */1191 if (stat_r & NS_STAT_LFBQE) {1192 int i;1193 struct sk_buff *lb;1194 1195 writel(NS_STAT_LFBQE, card->membase + STAT);1196 printk("nicstar%d: Large free buffer queue empty.\n",1197 card->index);1198 for (i = 0; i < card->lbnr.min; i++) {1199 lb = dev_alloc_skb(NS_LGSKBSIZE);1200 if (lb == NULL) {1201 writel(readl(card->membase + CFG) &1202 ~NS_CFG_EFBIE, card->membase + CFG);1203 card->efbie = 0;1204 break;1205 }1206 NS_PRV_BUFTYPE(lb) = BUF_LG;1207 skb_queue_tail(&card->lbpool.queue, lb);1208 skb_reserve(lb, NS_SMBUFSIZE);1209 push_rxbufs(card, lb);1210 }1211 card->lbfqc = i;1212 process_rsq(card);1213 }1214 1215 /* Receive Status Queue is 7/8 full */1216 if (stat_r & NS_STAT_RSQAF) {1217 writel(NS_STAT_RSQAF, card->membase + STAT);1218 RXPRINTK("nicstar%d: RSQ almost full.\n", card->index);1219 process_rsq(card);1220 }1221 1222 spin_unlock_irqrestore(&card->int_lock, flags);1223 PRINTK("nicstar%d: end of interrupt service\n", card->index);1224 return IRQ_HANDLED;1225}1226 1227static int ns_open(struct atm_vcc *vcc)1228{1229 ns_dev *card;1230 vc_map *vc;1231 unsigned long tmpl, modl;1232 int tcr, tcra; /* target cell rate, and absolute value */1233 int n = 0; /* Number of entries in the TST. Initialized to remove1234 the compiler warning. */1235 u32 u32d[4];1236 int frscdi = 0; /* Index of the SCD. Initialized to remove the compiler1237 warning. How I wish compilers were clever enough to1238 tell which variables can truly be used1239 uninitialized... */1240 int inuse; /* tx or rx vc already in use by another vcc */1241 short vpi = vcc->vpi;1242 int vci = vcc->vci;1243 1244 card = (ns_dev *) vcc->dev->dev_data;1245 PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int)vpi,1246 vci);1247 if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {1248 PRINTK("nicstar%d: unsupported AAL.\n", card->index);1249 return -EINVAL;1250 }1251 1252 vc = &(card->vcmap[vpi << card->vcibits | vci]);1253 vcc->dev_data = vc;1254 1255 inuse = 0;1256 if (vcc->qos.txtp.traffic_class != ATM_NONE && vc->tx)1257 inuse = 1;1258 if (vcc->qos.rxtp.traffic_class != ATM_NONE && vc->rx)1259 inuse += 2;1260 if (inuse) {1261 printk("nicstar%d: %s vci already in use.\n", card->index,1262 inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");1263 return -EINVAL;1264 }1265 1266 set_bit(ATM_VF_ADDR, &vcc->flags);1267 1268 /* NOTE: You are not allowed to modify an open connection's QOS. To change1269 that, remove the ATM_VF_PARTIAL flag checking. There may be other changes1270 needed to do that. */1271 if (!test_bit(ATM_VF_PARTIAL, &vcc->flags)) {1272 scq_info *scq;1273 1274 set_bit(ATM_VF_PARTIAL, &vcc->flags);1275 if (vcc->qos.txtp.traffic_class == ATM_CBR) {1276 /* Check requested cell rate and availability of SCD */1277 if (vcc->qos.txtp.max_pcr == 0 && vcc->qos.txtp.pcr == 01278 && vcc->qos.txtp.min_pcr == 0) {1279 PRINTK1280 ("nicstar%d: trying to open a CBR vc with cell rate = 0 \n",1281 card->index);1282 clear_bit(ATM_VF_PARTIAL, &vcc->flags);1283 clear_bit(ATM_VF_ADDR, &vcc->flags);1284 return -EINVAL;1285 }1286 1287 tcr = atm_pcr_goal(&(vcc->qos.txtp));1288 tcra = tcr >= 0 ? tcr : -tcr;1289 1290 PRINTK("nicstar%d: target cell rate = %d.\n",1291 card->index, vcc->qos.txtp.max_pcr);1292 1293 tmpl =1294 (unsigned long)tcra *(unsigned long)1295 NS_TST_NUM_ENTRIES;1296 modl = tmpl % card->max_pcr;1297 1298 n = (int)(tmpl / card->max_pcr);1299 if (tcr > 0) {1300 if (modl > 0)1301 n++;1302 } else if (tcr == 0) {1303 if ((n =1304 (card->tst_free_entries -1305 NS_TST_RESERVED)) <= 0) {1306 PRINTK1307 ("nicstar%d: no CBR bandwidth free.\n",1308 card->index);1309 clear_bit(ATM_VF_PARTIAL, &vcc->flags);1310 clear_bit(ATM_VF_ADDR, &vcc->flags);1311 return -EINVAL;1312 }1313 }1314 1315 if (n == 0) {1316 printk1317 ("nicstar%d: selected bandwidth < granularity.\n",1318 card->index);1319 clear_bit(ATM_VF_PARTIAL, &vcc->flags);1320 clear_bit(ATM_VF_ADDR, &vcc->flags);1321 return -EINVAL;1322 }1323 1324 if (n > (card->tst_free_entries - NS_TST_RESERVED)) {1325 PRINTK1326 ("nicstar%d: not enough free CBR bandwidth.\n",1327 card->index);1328 clear_bit(ATM_VF_PARTIAL, &vcc->flags);1329 clear_bit(ATM_VF_ADDR, &vcc->flags);1330 return -EINVAL;1331 } else1332 card->tst_free_entries -= n;1333 1334 XPRINTK("nicstar%d: writing %d tst entries.\n",1335 card->index, n);1336 for (frscdi = 0; frscdi < NS_FRSCD_NUM; frscdi++) {1337 if (card->scd2vc[frscdi] == NULL) {1338 card->scd2vc[frscdi] = vc;1339 break;1340 }1341 }1342 if (frscdi == NS_FRSCD_NUM) {1343 PRINTK1344 ("nicstar%d: no SCD available for CBR channel.\n",1345 card->index);1346 card->tst_free_entries += n;1347 clear_bit(ATM_VF_PARTIAL, &vcc->flags);1348 clear_bit(ATM_VF_ADDR, &vcc->flags);1349 return -EBUSY;1350 }1351 1352 vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE;1353 1354 scq = get_scq(card, CBR_SCQSIZE, vc->cbr_scd);1355 if (scq == NULL) {1356 PRINTK("nicstar%d: can't get fixed rate SCQ.\n",1357 card->index);1358 card->scd2vc[frscdi] = NULL;1359 card->tst_free_entries += n;1360 clear_bit(ATM_VF_PARTIAL, &vcc->flags);1361 clear_bit(ATM_VF_ADDR, &vcc->flags);1362 return -ENOMEM;1363 }1364 vc->scq = scq;1365 u32d[0] = scq_virt_to_bus(scq, scq->base);1366 u32d[1] = (u32) 0x00000000;1367 u32d[2] = (u32) 0xffffffff;1368 u32d[3] = (u32) 0x00000000;1369 ns_write_sram(card, vc->cbr_scd, u32d, 4);1370 1371 fill_tst(card, n, vc);1372 } else if (vcc->qos.txtp.traffic_class == ATM_UBR) {1373 vc->cbr_scd = 0x00000000;1374 vc->scq = card->scq0;1375 }1376 1377 if (vcc->qos.txtp.traffic_class != ATM_NONE) {1378 vc->tx = 1;1379 vc->tx_vcc = vcc;1380 vc->tbd_count = 0;1381 }1382 if (vcc->qos.rxtp.traffic_class != ATM_NONE) {1383 u32 status;1384 1385 vc->rx = 1;1386 vc->rx_vcc = vcc;1387 vc->rx_iov = NULL;1388 1389 /* Open the connection in hardware */1390 if (vcc->qos.aal == ATM_AAL5)1391 status = NS_RCTE_AAL5 | NS_RCTE_CONNECTOPEN;1392 else /* vcc->qos.aal == ATM_AAL0 */1393 status = NS_RCTE_AAL0 | NS_RCTE_CONNECTOPEN;1394#ifdef RCQ_SUPPORT1395 status |= NS_RCTE_RAWCELLINTEN;1396#endif /* RCQ_SUPPORT */1397 ns_write_sram(card,1398 NS_RCT +1399 (vpi << card->vcibits | vci) *1400 NS_RCT_ENTRY_SIZE, &status, 1);1401 }1402 1403 }1404 1405 set_bit(ATM_VF_READY, &vcc->flags);1406 return 0;1407}1408 1409static void ns_close(struct atm_vcc *vcc)1410{1411 vc_map *vc;1412 ns_dev *card;1413 u32 data;1414 int i;1415 1416 vc = vcc->dev_data;1417 card = vcc->dev->dev_data;1418 PRINTK("nicstar%d: closing vpi.vci %d.%d \n", card->index,1419 (int)vcc->vpi, vcc->vci);1420 1421 clear_bit(ATM_VF_READY, &vcc->flags);1422 1423 if (vcc->qos.rxtp.traffic_class != ATM_NONE) {1424 u32 addr;1425 unsigned long flags;1426 1427 addr =1428 NS_RCT +1429 (vcc->vpi << card->vcibits | vcc->vci) * NS_RCT_ENTRY_SIZE;1430 spin_lock_irqsave(&card->res_lock, flags);1431 while (CMD_BUSY(card)) ;1432 writel(NS_CMD_CLOSE_CONNECTION | addr << 2,1433 card->membase + CMD);1434 spin_unlock_irqrestore(&card->res_lock, flags);1435 1436 vc->rx = 0;1437 if (vc->rx_iov != NULL) {1438 struct sk_buff *iovb;1439 u32 stat;1440 1441 stat = readl(card->membase + STAT);1442 card->sbfqc = ns_stat_sfbqc_get(stat);1443 card->lbfqc = ns_stat_lfbqc_get(stat);1444 1445 PRINTK1446 ("nicstar%d: closing a VC with pending rx buffers.\n",1447 card->index);1448 iovb = vc->rx_iov;1449 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,1450 NS_PRV_IOVCNT(iovb));1451 NS_PRV_IOVCNT(iovb) = 0;1452 spin_lock_irqsave(&card->int_lock, flags);1453 recycle_iov_buf(card, iovb);1454 spin_unlock_irqrestore(&card->int_lock, flags);1455 vc->rx_iov = NULL;1456 }1457 }1458 1459 if (vcc->qos.txtp.traffic_class != ATM_NONE) {1460 vc->tx = 0;1461 }1462 1463 if (vcc->qos.txtp.traffic_class == ATM_CBR) {1464 unsigned long flags;1465 ns_scqe *scqep;1466 scq_info *scq;1467 1468 scq = vc->scq;1469 1470 for (;;) {1471 spin_lock_irqsave(&scq->lock, flags);1472 scqep = scq->next;1473 if (scqep == scq->base)1474 scqep = scq->last;1475 else1476 scqep--;1477 if (scqep == scq->tail) {1478 spin_unlock_irqrestore(&scq->lock, flags);1479 break;1480 }1481 /* If the last entry is not a TSR, place one in the SCQ in order to1482 be able to completely drain it and then close. */1483 if (!ns_scqe_is_tsr(scqep) && scq->tail != scq->next) {1484 ns_scqe tsr;1485 u32 scdi, scqi;1486 u32 data;1487 int index;1488 1489 tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE);1490 scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE;1491 scqi = scq->next - scq->base;1492 tsr.word_2 = ns_tsr_mkword_2(scdi, scqi);1493 tsr.word_3 = 0x00000000;1494 tsr.word_4 = 0x00000000;1495 *scq->next = tsr;1496 index = (int)scqi;1497 scq->skb[index] = NULL;1498 if (scq->next == scq->last)1499 scq->next = scq->base;1500 else1501 scq->next++;1502 data = scq_virt_to_bus(scq, scq->next);1503 ns_write_sram(card, scq->scd, &data, 1);1504 }1505 spin_unlock_irqrestore(&scq->lock, flags);1506 schedule();1507 }1508 1509 /* Free all TST entries */1510 data = NS_TST_OPCODE_VARIABLE;1511 for (i = 0; i < NS_TST_NUM_ENTRIES; i++) {1512 if (card->tste2vc[i] == vc) {1513 ns_write_sram(card, card->tst_addr + i, &data,1514 1);1515 card->tste2vc[i] = NULL;1516 card->tst_free_entries++;1517 }1518 }1519 1520 card->scd2vc[(vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE] = NULL;1521 free_scq(card, vc->scq, vcc);1522 }1523 1524 /* remove all references to vcc before deleting it */1525 if (vcc->qos.txtp.traffic_class != ATM_NONE) {1526 unsigned long flags;1527 scq_info *scq = card->scq0;1528 1529 spin_lock_irqsave(&scq->lock, flags);1530 1531 for (i = 0; i < scq->num_entries; i++) {1532 if (scq->skb[i] && ATM_SKB(scq->skb[i])->vcc == vcc) {1533 ATM_SKB(scq->skb[i])->vcc = NULL;1534 atm_return(vcc, scq->skb[i]->truesize);1535 PRINTK1536 ("nicstar: deleted pending vcc mapping\n");1537 }1538 }1539 1540 spin_unlock_irqrestore(&scq->lock, flags);1541 }1542 1543 vcc->dev_data = NULL;1544 clear_bit(ATM_VF_PARTIAL, &vcc->flags);1545 clear_bit(ATM_VF_ADDR, &vcc->flags);1546 1547#ifdef RX_DEBUG1548 {1549 u32 stat, cfg;1550 stat = readl(card->membase + STAT);1551 cfg = readl(card->membase + CFG);1552 printk("STAT = 0x%08X CFG = 0x%08X \n", stat, cfg);1553 printk1554 ("TSQ: base = 0x%p next = 0x%p last = 0x%p TSQT = 0x%08X \n",1555 card->tsq.base, card->tsq.next,1556 card->tsq.last, readl(card->membase + TSQT));1557 printk1558 ("RSQ: base = 0x%p next = 0x%p last = 0x%p RSQT = 0x%08X \n",1559 card->rsq.base, card->rsq.next,1560 card->rsq.last, readl(card->membase + RSQT));1561 printk("Empty free buffer queue interrupt %s \n",1562 card->efbie ? "enabled" : "disabled");1563 printk("SBCNT = %d count = %d LBCNT = %d count = %d \n",1564 ns_stat_sfbqc_get(stat), card->sbpool.count,1565 ns_stat_lfbqc_get(stat), card->lbpool.count);1566 printk("hbpool.count = %d iovpool.count = %d \n",1567 card->hbpool.count, card->iovpool.count);1568 }1569#endif /* RX_DEBUG */1570}1571 1572static void fill_tst(ns_dev * card, int n, vc_map * vc)1573{1574 u32 new_tst;1575 unsigned long cl;1576 int e, r;1577 u32 data;1578 1579 /* It would be very complicated to keep the two TSTs synchronized while1580 assuring that writes are only made to the inactive TST. So, for now I1581 will use only one TST. If problems occur, I will change this again */1582 1583 new_tst = card->tst_addr;1584 1585 /* Fill procedure */1586 1587 for (e = 0; e < NS_TST_NUM_ENTRIES; e++) {1588 if (card->tste2vc[e] == NULL)1589 break;1590 }1591 if (e == NS_TST_NUM_ENTRIES) {1592 printk("nicstar%d: No free TST entries found. \n", card->index);1593 return;1594 }1595 1596 r = n;1597 cl = NS_TST_NUM_ENTRIES;1598 data = ns_tste_make(NS_TST_OPCODE_FIXED, vc->cbr_scd);1599 1600 while (r > 0) {1601 if (cl >= NS_TST_NUM_ENTRIES && card->tste2vc[e] == NULL) {1602 card->tste2vc[e] = vc;1603 ns_write_sram(card, new_tst + e, &data, 1);1604 cl -= NS_TST_NUM_ENTRIES;1605 r--;1606 }1607 1608 if (++e == NS_TST_NUM_ENTRIES) {1609 e = 0;1610 }1611 cl += n;1612 }1613 1614 /* End of fill procedure */1615 1616 data = ns_tste_make(NS_TST_OPCODE_END, new_tst);1617 ns_write_sram(card, new_tst + NS_TST_NUM_ENTRIES, &data, 1);1618 ns_write_sram(card, card->tst_addr + NS_TST_NUM_ENTRIES, &data, 1);1619 card->tst_addr = new_tst;1620}1621 1622static int _ns_send(struct atm_vcc *vcc, struct sk_buff *skb, bool may_sleep)1623{1624 ns_dev *card;1625 vc_map *vc;1626 scq_info *scq;1627 unsigned long buflen;1628 ns_scqe scqe;1629 u32 flags; /* TBD flags, not CPU flags */1630 1631 card = vcc->dev->dev_data;1632 TXPRINTK("nicstar%d: ns_send() called.\n", card->index);1633 if ((vc = (vc_map *) vcc->dev_data) == NULL) {1634 printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n",1635 card->index);1636 atomic_inc(&vcc->stats->tx_err);1637 dev_kfree_skb_any(skb);1638 return -EINVAL;1639 }1640 1641 if (!vc->tx) {1642 printk("nicstar%d: Trying to transmit on a non-tx VC.\n",1643 card->index);1644 atomic_inc(&vcc->stats->tx_err);1645 dev_kfree_skb_any(skb);1646 return -EINVAL;1647 }1648 1649 if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {1650 printk("nicstar%d: Only AAL0 and AAL5 are supported.\n",1651 card->index);1652 atomic_inc(&vcc->stats->tx_err);1653 dev_kfree_skb_any(skb);1654 return -EINVAL;1655 }1656 1657 if (skb_shinfo(skb)->nr_frags != 0) {1658 printk("nicstar%d: No scatter-gather yet.\n", card->index);1659 atomic_inc(&vcc->stats->tx_err);1660 dev_kfree_skb_any(skb);1661 return -EINVAL;1662 }1663 1664 ATM_SKB(skb)->vcc = vcc;1665 1666 NS_PRV_DMA(skb) = dma_map_single(&card->pcidev->dev, skb->data,1667 skb->len, DMA_TO_DEVICE);1668 1669 if (vcc->qos.aal == ATM_AAL5) {1670 buflen = (skb->len + 47 + 8) / 48 * 48; /* Multiple of 48 */1671 flags = NS_TBD_AAL5;1672 scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb));1673 scqe.word_3 = cpu_to_le32(skb->len);1674 scqe.word_4 =1675 ns_tbd_mkword_4(0, (u32) vcc->vpi, (u32) vcc->vci, 0,1676 ATM_SKB(skb)->1677 atm_options & ATM_ATMOPT_CLP ? 1 : 0);1678 flags |= NS_TBD_EOPDU;1679 } else { /* (vcc->qos.aal == ATM_AAL0) */1680 1681 buflen = ATM_CELL_PAYLOAD; /* i.e., 48 bytes */1682 flags = NS_TBD_AAL0;1683 scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb) + NS_AAL0_HEADER);1684 scqe.word_3 = cpu_to_le32(0x00000000);1685 if (*skb->data & 0x02) /* Payload type 1 - end of pdu */1686 flags |= NS_TBD_EOPDU;1687 scqe.word_4 =1688 cpu_to_le32(*((u32 *) skb->data) & ~NS_TBD_VC_MASK);1689 /* Force the VPI/VCI to be the same as in VCC struct */1690 scqe.word_4 |=1691 cpu_to_le32((((u32) vcc->1692 vpi) << NS_TBD_VPI_SHIFT | ((u32) vcc->1693 vci) <<1694 NS_TBD_VCI_SHIFT) & NS_TBD_VC_MASK);1695 }1696 1697 if (vcc->qos.txtp.traffic_class == ATM_CBR) {1698 scqe.word_1 = ns_tbd_mkword_1_novbr(flags, (u32) buflen);1699 scq = ((vc_map *) vcc->dev_data)->scq;1700 } else {1701 scqe.word_1 =1702 ns_tbd_mkword_1(flags, (u32) 1, (u32) 1, (u32) buflen);1703 scq = card->scq0;1704 }1705 1706 if (push_scqe(card, vc, scq, &scqe, skb, may_sleep) != 0) {1707 atomic_inc(&vcc->stats->tx_err);1708 dma_unmap_single(&card->pcidev->dev, NS_PRV_DMA(skb), skb->len,1709 DMA_TO_DEVICE);1710 dev_kfree_skb_any(skb);1711 return -EIO;1712 }1713 atomic_inc(&vcc->stats->tx);1714 1715 return 0;1716}1717 1718static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)1719{1720 return _ns_send(vcc, skb, true);1721}1722 1723static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb)1724{1725 return _ns_send(vcc, skb, false);1726}1727 1728static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,1729 struct sk_buff *skb, bool may_sleep)1730{1731 unsigned long flags;1732 ns_scqe tsr;1733 u32 scdi, scqi;1734 int scq_is_vbr;1735 u32 data;1736 int index;1737 1738 spin_lock_irqsave(&scq->lock, flags);1739 while (scq->tail == scq->next) {1740 if (!may_sleep) {1741 spin_unlock_irqrestore(&scq->lock, flags);1742 printk("nicstar%d: Error pushing TBD.\n", card->index);1743 return 1;1744 }1745 1746 scq->full = 1;1747 wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq,1748 scq->tail != scq->next,1749 scq->lock,1750 SCQFULL_TIMEOUT);1751 1752 if (scq->full) {1753 spin_unlock_irqrestore(&scq->lock, flags);1754 printk("nicstar%d: Timeout pushing TBD.\n",1755 card->index);1756 return 1;1757 }1758 }1759 *scq->next = *tbd;1760 index = (int)(scq->next - scq->base);1761 scq->skb[index] = skb;1762 XPRINTK("nicstar%d: sending skb at 0x%p (pos %d).\n",1763 card->index, skb, index);1764 XPRINTK("nicstar%d: TBD written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",1765 card->index, le32_to_cpu(tbd->word_1), le32_to_cpu(tbd->word_2),1766 le32_to_cpu(tbd->word_3), le32_to_cpu(tbd->word_4),1767 scq->next);1768 if (scq->next == scq->last)1769 scq->next = scq->base;1770 else1771 scq->next++;1772 1773 vc->tbd_count++;1774 if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) {1775 scq->tbd_count++;1776 scq_is_vbr = 1;1777 } else1778 scq_is_vbr = 0;1779 1780 if (vc->tbd_count >= MAX_TBD_PER_VC1781 || scq->tbd_count >= MAX_TBD_PER_SCQ) {1782 int has_run = 0;1783 1784 while (scq->tail == scq->next) {1785 if (!may_sleep) {1786 data = scq_virt_to_bus(scq, scq->next);1787 ns_write_sram(card, scq->scd, &data, 1);1788 spin_unlock_irqrestore(&scq->lock, flags);1789 printk("nicstar%d: Error pushing TSR.\n",1790 card->index);1791 return 0;1792 }1793 1794 scq->full = 1;1795 if (has_run++)1796 break;1797 wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq,1798 scq->tail != scq->next,1799 scq->lock,1800 SCQFULL_TIMEOUT);1801 }1802 1803 if (!scq->full) {1804 tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE);1805 if (scq_is_vbr)1806 scdi = NS_TSR_SCDISVBR;1807 else1808 scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE;1809 scqi = scq->next - scq->base;1810 tsr.word_2 = ns_tsr_mkword_2(scdi, scqi);1811 tsr.word_3 = 0x00000000;1812 tsr.word_4 = 0x00000000;1813 1814 *scq->next = tsr;1815 index = (int)scqi;1816 scq->skb[index] = NULL;1817 XPRINTK1818 ("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",1819 card->index, le32_to_cpu(tsr.word_1),1820 le32_to_cpu(tsr.word_2), le32_to_cpu(tsr.word_3),1821 le32_to_cpu(tsr.word_4), scq->next);1822 if (scq->next == scq->last)1823 scq->next = scq->base;1824 else1825 scq->next++;1826 vc->tbd_count = 0;1827 scq->tbd_count = 0;1828 } else1829 PRINTK("nicstar%d: Timeout pushing TSR.\n",1830 card->index);1831 }1832 data = scq_virt_to_bus(scq, scq->next);1833 ns_write_sram(card, scq->scd, &data, 1);1834 1835 spin_unlock_irqrestore(&scq->lock, flags);1836 1837 return 0;1838}1839 1840static void process_tsq(ns_dev * card)1841{1842 u32 scdi;1843 scq_info *scq;1844 ns_tsi *previous = NULL, *one_ahead, *two_ahead;1845 int serviced_entries; /* flag indicating at least on entry was serviced */1846 1847 serviced_entries = 0;1848 1849 if (card->tsq.next == card->tsq.last)1850 one_ahead = card->tsq.base;1851 else1852 one_ahead = card->tsq.next + 1;1853 1854 if (one_ahead == card->tsq.last)1855 two_ahead = card->tsq.base;1856 else1857 two_ahead = one_ahead + 1;1858 1859 while (!ns_tsi_isempty(card->tsq.next) || !ns_tsi_isempty(one_ahead) ||1860 !ns_tsi_isempty(two_ahead))1861 /* At most two empty, as stated in the 77201 errata */1862 {1863 serviced_entries = 1;1864 1865 /* Skip the one or two possible empty entries */1866 while (ns_tsi_isempty(card->tsq.next)) {1867 if (card->tsq.next == card->tsq.last)1868 card->tsq.next = card->tsq.base;1869 else1870 card->tsq.next++;1871 }1872 1873 if (!ns_tsi_tmrof(card->tsq.next)) {1874 scdi = ns_tsi_getscdindex(card->tsq.next);1875 if (scdi == NS_TSI_SCDISVBR)1876 scq = card->scq0;1877 else {1878 if (card->scd2vc[scdi] == NULL) {1879 printk1880 ("nicstar%d: could not find VC from SCD index.\n",1881 card->index);1882 ns_tsi_init(card->tsq.next);1883 return;1884 }1885 scq = card->scd2vc[scdi]->scq;1886 }1887 drain_scq(card, scq, ns_tsi_getscqpos(card->tsq.next));1888 scq->full = 0;1889 wake_up_interruptible(&(scq->scqfull_waitq));1890 }1891 1892 ns_tsi_init(card->tsq.next);1893 previous = card->tsq.next;1894 if (card->tsq.next == card->tsq.last)1895 card->tsq.next = card->tsq.base;1896 else1897 card->tsq.next++;1898 1899 if (card->tsq.next == card->tsq.last)1900 one_ahead = card->tsq.base;1901 else1902 one_ahead = card->tsq.next + 1;1903 1904 if (one_ahead == card->tsq.last)1905 two_ahead = card->tsq.base;1906 else1907 two_ahead = one_ahead + 1;1908 }1909 1910 if (serviced_entries)1911 writel(PTR_DIFF(previous, card->tsq.base),1912 card->membase + TSQH);1913}1914 1915static void drain_scq(ns_dev * card, scq_info * scq, int pos)1916{1917 struct atm_vcc *vcc;1918 struct sk_buff *skb;1919 int i;1920 unsigned long flags;1921 1922 XPRINTK("nicstar%d: drain_scq() called, scq at 0x%p, pos %d.\n",1923 card->index, scq, pos);1924 if (pos >= scq->num_entries) {1925 printk("nicstar%d: Bad index on drain_scq().\n", card->index);1926 return;1927 }1928 1929 spin_lock_irqsave(&scq->lock, flags);1930 i = (int)(scq->tail - scq->base);1931 if (++i == scq->num_entries)1932 i = 0;1933 while (i != pos) {1934 skb = scq->skb[i];1935 XPRINTK("nicstar%d: freeing skb at 0x%p (index %d).\n",1936 card->index, skb, i);1937 if (skb != NULL) {1938 dma_unmap_single(&card->pcidev->dev,1939 NS_PRV_DMA(skb),1940 skb->len,1941 DMA_TO_DEVICE);1942 vcc = ATM_SKB(skb)->vcc;1943 if (vcc && vcc->pop != NULL) {1944 vcc->pop(vcc, skb);1945 } else {1946 dev_kfree_skb_irq(skb);1947 }1948 scq->skb[i] = NULL;1949 }1950 if (++i == scq->num_entries)1951 i = 0;1952 }1953 scq->tail = scq->base + pos;1954 spin_unlock_irqrestore(&scq->lock, flags);1955}1956 1957static void process_rsq(ns_dev * card)1958{1959 ns_rsqe *previous;1960 1961 if (!ns_rsqe_valid(card->rsq.next))1962 return;1963 do {1964 dequeue_rx(card, card->rsq.next);1965 ns_rsqe_init(card->rsq.next);1966 previous = card->rsq.next;1967 if (card->rsq.next == card->rsq.last)1968 card->rsq.next = card->rsq.base;1969 else1970 card->rsq.next++;1971 } while (ns_rsqe_valid(card->rsq.next));1972 writel(PTR_DIFF(previous, card->rsq.base), card->membase + RSQH);1973}1974 1975static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe)1976{1977 u32 vpi, vci;1978 vc_map *vc;1979 struct sk_buff *iovb;1980 struct iovec *iov;1981 struct atm_vcc *vcc;1982 struct sk_buff *skb;1983 unsigned short aal5_len;1984 int len;1985 u32 stat;1986 u32 id;1987 1988 stat = readl(card->membase + STAT);1989 card->sbfqc = ns_stat_sfbqc_get(stat);1990 card->lbfqc = ns_stat_lfbqc_get(stat);1991 1992 id = le32_to_cpu(rsqe->buffer_handle);1993 skb = idr_remove(&card->idr, id);1994 if (!skb) {1995 RXPRINTK(KERN_ERR1996 "nicstar%d: skb not found!\n", card->index);1997 return;1998 }1999 dma_sync_single_for_cpu(&card->pcidev->dev,2000 NS_PRV_DMA(skb),2001 (NS_PRV_BUFTYPE(skb) == BUF_SM2002 ? NS_SMSKBSIZE : NS_LGSKBSIZE),2003 DMA_FROM_DEVICE);2004 dma_unmap_single(&card->pcidev->dev,2005 NS_PRV_DMA(skb),2006 (NS_PRV_BUFTYPE(skb) == BUF_SM2007 ? NS_SMSKBSIZE : NS_LGSKBSIZE),2008 DMA_FROM_DEVICE);2009 vpi = ns_rsqe_vpi(rsqe);2010 vci = ns_rsqe_vci(rsqe);2011 if (vpi >= 1UL << card->vpibits || vci >= 1UL << card->vcibits) {2012 printk("nicstar%d: SDU received for out-of-range vc %d.%d.\n",2013 card->index, vpi, vci);2014 recycle_rx_buf(card, skb);2015 return;2016 }2017 2018 vc = &(card->vcmap[vpi << card->vcibits | vci]);2019 if (!vc->rx) {2020 RXPRINTK("nicstar%d: SDU received on non-rx vc %d.%d.\n",2021 card->index, vpi, vci);2022 recycle_rx_buf(card, skb);2023 return;2024 }2025 2026 vcc = vc->rx_vcc;2027 2028 if (vcc->qos.aal == ATM_AAL0) {2029 struct sk_buff *sb;2030 unsigned char *cell;2031 int i;2032 2033 cell = skb->data;2034 for (i = ns_rsqe_cellcount(rsqe); i; i--) {2035 sb = dev_alloc_skb(NS_SMSKBSIZE);2036 if (!sb) {2037 printk2038 ("nicstar%d: Can't allocate buffers for aal0.\n",2039 card->index);2040 atomic_add(i, &vcc->stats->rx_drop);2041 break;2042 }2043 if (!atm_charge(vcc, sb->truesize)) {2044 RXPRINTK2045 ("nicstar%d: atm_charge() dropped aal0 packets.\n",2046 card->index);2047 atomic_add(i - 1, &vcc->stats->rx_drop); /* already increased by 1 */2048 dev_kfree_skb_any(sb);2049 break;2050 }2051 /* Rebuild the header */2052 *((u32 *) sb->data) = le32_to_cpu(rsqe->word_1) << 4 |2053 (ns_rsqe_clp(rsqe) ? 0x00000001 : 0x00000000);2054 if (i == 1 && ns_rsqe_eopdu(rsqe))2055 *((u32 *) sb->data) |= 0x00000002;2056 skb_put(sb, NS_AAL0_HEADER);2057 memcpy(skb_tail_pointer(sb), cell, ATM_CELL_PAYLOAD);2058 skb_put(sb, ATM_CELL_PAYLOAD);2059 ATM_SKB(sb)->vcc = vcc;2060 __net_timestamp(sb);2061 vcc->push(vcc, sb);2062 atomic_inc(&vcc->stats->rx);2063 cell += ATM_CELL_PAYLOAD;2064 }2065 2066 recycle_rx_buf(card, skb);2067 return;2068 }2069 2070 /* To reach this point, the AAL layer can only be AAL5 */2071 2072 if ((iovb = vc->rx_iov) == NULL) {2073 iovb = skb_dequeue(&(card->iovpool.queue));2074 if (iovb == NULL) { /* No buffers in the queue */2075 iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC);2076 if (iovb == NULL) {2077 printk("nicstar%d: Out of iovec buffers.\n",2078 card->index);2079 atomic_inc(&vcc->stats->rx_drop);2080 recycle_rx_buf(card, skb);2081 return;2082 }2083 NS_PRV_BUFTYPE(iovb) = BUF_NONE;2084 } else if (--card->iovpool.count < card->iovnr.min) {2085 struct sk_buff *new_iovb;2086 if ((new_iovb =2087 alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL) {2088 NS_PRV_BUFTYPE(iovb) = BUF_NONE;2089 skb_queue_tail(&card->iovpool.queue, new_iovb);2090 card->iovpool.count++;2091 }2092 }2093 vc->rx_iov = iovb;2094 NS_PRV_IOVCNT(iovb) = 0;2095 iovb->len = 0;2096 iovb->data = iovb->head;2097 skb_reset_tail_pointer(iovb);2098 /* IMPORTANT: a pointer to the sk_buff containing the small or large2099 buffer is stored as iovec base, NOT a pointer to the2100 small or large buffer itself. */2101 } else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) {2102 printk("nicstar%d: received too big AAL5 SDU.\n", card->index);2103 atomic_inc(&vcc->stats->rx_err);2104 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,2105 NS_MAX_IOVECS);2106 NS_PRV_IOVCNT(iovb) = 0;2107 iovb->len = 0;2108 iovb->data = iovb->head;2109 skb_reset_tail_pointer(iovb);2110 }2111 iov = &((struct iovec *)iovb->data)[NS_PRV_IOVCNT(iovb)++];2112 iov->iov_base = (void *)skb;2113 iov->iov_len = ns_rsqe_cellcount(rsqe) * 48;2114 iovb->len += iov->iov_len;2115 2116#ifdef EXTRA_DEBUG2117 if (NS_PRV_IOVCNT(iovb) == 1) {2118 if (NS_PRV_BUFTYPE(skb) != BUF_SM) {2119 printk2120 ("nicstar%d: Expected a small buffer, and this is not one.\n",2121 card->index);2122 which_list(card, skb);2123 atomic_inc(&vcc->stats->rx_err);2124 recycle_rx_buf(card, skb);2125 vc->rx_iov = NULL;2126 recycle_iov_buf(card, iovb);2127 return;2128 }2129 } else { /* NS_PRV_IOVCNT(iovb) >= 2 */2130 2131 if (NS_PRV_BUFTYPE(skb) != BUF_LG) {2132 printk2133 ("nicstar%d: Expected a large buffer, and this is not one.\n",2134 card->index);2135 which_list(card, skb);2136 atomic_inc(&vcc->stats->rx_err);2137 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,2138 NS_PRV_IOVCNT(iovb));2139 vc->rx_iov = NULL;2140 recycle_iov_buf(card, iovb);2141 return;2142 }2143 }2144#endif /* EXTRA_DEBUG */2145 2146 if (ns_rsqe_eopdu(rsqe)) {2147 /* This works correctly regardless of the endianness of the host */2148 unsigned char *L1L2 = (unsigned char *)2149 (skb->data + iov->iov_len - 6);2150 aal5_len = L1L2[0] << 8 | L1L2[1];2151 len = (aal5_len == 0x0000) ? 0x10000 : aal5_len;2152 if (ns_rsqe_crcerr(rsqe) ||2153 len + 8 > iovb->len || len + (47 + 8) < iovb->len) {2154 printk("nicstar%d: AAL5 CRC error", card->index);2155 if (len + 8 > iovb->len || len + (47 + 8) < iovb->len)2156 printk(" - PDU size mismatch.\n");2157 else2158 printk(".\n");2159 atomic_inc(&vcc->stats->rx_err);2160 recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,2161 NS_PRV_IOVCNT(iovb));2162 vc->rx_iov = NULL;2163 recycle_iov_buf(card, iovb);2164 return;2165 }2166 2167 /* By this point we (hopefully) have a complete SDU without errors. */2168 2169 if (NS_PRV_IOVCNT(iovb) == 1) { /* Just a small buffer */2170 /* skb points to a small buffer */2171 if (!atm_charge(vcc, skb->truesize)) {2172 push_rxbufs(card, skb);2173 atomic_inc(&vcc->stats->rx_drop);2174 } else {2175 skb_put(skb, len);2176 dequeue_sm_buf(card, skb);2177 ATM_SKB(skb)->vcc = vcc;2178 __net_timestamp(skb);2179 vcc->push(vcc, skb);2180 atomic_inc(&vcc->stats->rx);2181 }2182 } else if (NS_PRV_IOVCNT(iovb) == 2) { /* One small plus one large buffer */2183 struct sk_buff *sb;2184 2185 sb = (struct sk_buff *)(iov - 1)->iov_base;2186 /* skb points to a large buffer */2187 2188 if (len <= NS_SMBUFSIZE) {2189 if (!atm_charge(vcc, sb->truesize)) {2190 push_rxbufs(card, sb);2191 atomic_inc(&vcc->stats->rx_drop);2192 } else {2193 skb_put(sb, len);2194 dequeue_sm_buf(card, sb);2195 ATM_SKB(sb)->vcc = vcc;2196 __net_timestamp(sb);2197 vcc->push(vcc, sb);2198 atomic_inc(&vcc->stats->rx);2199 }2200 2201 push_rxbufs(card, skb);2202 2203 } else { /* len > NS_SMBUFSIZE, the usual case */2204 2205 if (!atm_charge(vcc, skb->truesize)) {2206 push_rxbufs(card, skb);2207 atomic_inc(&vcc->stats->rx_drop);2208 } else {2209 dequeue_lg_buf(card, skb);2210 skb_push(skb, NS_SMBUFSIZE);2211 skb_copy_from_linear_data(sb, skb->data,2212 NS_SMBUFSIZE);2213 skb_put(skb, len - NS_SMBUFSIZE);2214 ATM_SKB(skb)->vcc = vcc;2215 __net_timestamp(skb);2216 vcc->push(vcc, skb);2217 atomic_inc(&vcc->stats->rx);2218 }2219 2220 push_rxbufs(card, sb);2221 2222 }2223 2224 } else { /* Must push a huge buffer */2225 2226 struct sk_buff *hb, *sb, *lb;2227 int remaining, tocopy;2228 int j;2229 2230 hb = skb_dequeue(&(card->hbpool.queue));2231 if (hb == NULL) { /* No buffers in the queue */2232 2233 hb = dev_alloc_skb(NS_HBUFSIZE);2234 if (hb == NULL) {2235 printk2236 ("nicstar%d: Out of huge buffers.\n",2237 card->index);2238 atomic_inc(&vcc->stats->rx_drop);2239 recycle_iovec_rx_bufs(card,2240 (struct iovec *)2241 iovb->data,2242 NS_PRV_IOVCNT(iovb));2243 vc->rx_iov = NULL;2244 recycle_iov_buf(card, iovb);2245 return;2246 } else if (card->hbpool.count < card->hbnr.min) {2247 struct sk_buff *new_hb;2248 if ((new_hb =2249 dev_alloc_skb(NS_HBUFSIZE)) !=2250 NULL) {2251 skb_queue_tail(&card->hbpool.2252 queue, new_hb);2253 card->hbpool.count++;2254 }2255 }2256 NS_PRV_BUFTYPE(hb) = BUF_NONE;2257 } else if (--card->hbpool.count < card->hbnr.min) {2258 struct sk_buff *new_hb;2259 if ((new_hb =2260 dev_alloc_skb(NS_HBUFSIZE)) != NULL) {2261 NS_PRV_BUFTYPE(new_hb) = BUF_NONE;2262 skb_queue_tail(&card->hbpool.queue,2263 new_hb);2264 card->hbpool.count++;2265 }2266 if (card->hbpool.count < card->hbnr.min) {2267 if ((new_hb =2268 dev_alloc_skb(NS_HBUFSIZE)) !=2269 NULL) {2270 NS_PRV_BUFTYPE(new_hb) =2271 BUF_NONE;2272 skb_queue_tail(&card->hbpool.2273 queue, new_hb);2274 card->hbpool.count++;2275 }2276 }2277 }2278 2279 iov = (struct iovec *)iovb->data;2280 2281 if (!atm_charge(vcc, hb->truesize)) {2282 recycle_iovec_rx_bufs(card, iov,2283 NS_PRV_IOVCNT(iovb));2284 if (card->hbpool.count < card->hbnr.max) {2285 skb_queue_tail(&card->hbpool.queue, hb);2286 card->hbpool.count++;2287 } else2288 dev_kfree_skb_any(hb);2289 atomic_inc(&vcc->stats->rx_drop);2290 } else {2291 /* Copy the small buffer to the huge buffer */2292 sb = (struct sk_buff *)iov->iov_base;2293 skb_copy_from_linear_data(sb, hb->data,2294 iov->iov_len);2295 skb_put(hb, iov->iov_len);2296 remaining = len - iov->iov_len;2297 iov++;2298 /* Free the small buffer */2299 push_rxbufs(card, sb);2300 2301 /* Copy all large buffers to the huge buffer and free them */2302 for (j = 1; j < NS_PRV_IOVCNT(iovb); j++) {2303 lb = (struct sk_buff *)iov->iov_base;2304 tocopy =2305 min_t(int, remaining, iov->iov_len);2306 skb_copy_from_linear_data(lb,2307 skb_tail_pointer2308 (hb), tocopy);2309 skb_put(hb, tocopy);2310 iov++;2311 remaining -= tocopy;2312 push_rxbufs(card, lb);2313 }2314#ifdef EXTRA_DEBUG2315 if (remaining != 0 || hb->len != len)2316 printk2317 ("nicstar%d: Huge buffer len mismatch.\n",2318 card->index);2319#endif /* EXTRA_DEBUG */2320 ATM_SKB(hb)->vcc = vcc;2321 __net_timestamp(hb);2322 vcc->push(vcc, hb);2323 atomic_inc(&vcc->stats->rx);2324 }2325 }2326 2327 vc->rx_iov = NULL;2328 recycle_iov_buf(card, iovb);2329 }2330 2331}2332 2333static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb)2334{2335 if (unlikely(NS_PRV_BUFTYPE(skb) == BUF_NONE)) {2336 printk("nicstar%d: What kind of rx buffer is this?\n",2337 card->index);2338 dev_kfree_skb_any(skb);2339 } else2340 push_rxbufs(card, skb);2341}2342 2343static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count)2344{2345 while (count-- > 0)2346 recycle_rx_buf(card, (struct sk_buff *)(iov++)->iov_base);2347}2348 2349static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb)2350{2351 if (card->iovpool.count < card->iovnr.max) {2352 skb_queue_tail(&card->iovpool.queue, iovb);2353 card->iovpool.count++;2354 } else2355 dev_kfree_skb_any(iovb);2356}2357 2358static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb)2359{2360 skb_unlink(sb, &card->sbpool.queue);2361 if (card->sbfqc < card->sbnr.init) {2362 struct sk_buff *new_sb;2363 if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {2364 NS_PRV_BUFTYPE(new_sb) = BUF_SM;2365 skb_queue_tail(&card->sbpool.queue, new_sb);2366 skb_reserve(new_sb, NS_AAL0_HEADER);2367 push_rxbufs(card, new_sb);2368 }2369 }2370 if (card->sbfqc < card->sbnr.init)2371 {2372 struct sk_buff *new_sb;2373 if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {2374 NS_PRV_BUFTYPE(new_sb) = BUF_SM;2375 skb_queue_tail(&card->sbpool.queue, new_sb);2376 skb_reserve(new_sb, NS_AAL0_HEADER);2377 push_rxbufs(card, new_sb);2378 }2379 }2380}2381 2382static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb)2383{2384 skb_unlink(lb, &card->lbpool.queue);2385 if (card->lbfqc < card->lbnr.init) {2386 struct sk_buff *new_lb;2387 if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {2388 NS_PRV_BUFTYPE(new_lb) = BUF_LG;2389 skb_queue_tail(&card->lbpool.queue, new_lb);2390 skb_reserve(new_lb, NS_SMBUFSIZE);2391 push_rxbufs(card, new_lb);2392 }2393 }2394 if (card->lbfqc < card->lbnr.init)2395 {2396 struct sk_buff *new_lb;2397 if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {2398 NS_PRV_BUFTYPE(new_lb) = BUF_LG;2399 skb_queue_tail(&card->lbpool.queue, new_lb);2400 skb_reserve(new_lb, NS_SMBUFSIZE);2401 push_rxbufs(card, new_lb);2402 }2403 }2404}2405 2406static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page)2407{2408 u32 stat;2409 ns_dev *card;2410 int left;2411 2412 left = (int)*pos;2413 card = (ns_dev *) dev->dev_data;2414 stat = readl(card->membase + STAT);2415 if (!left--)2416 return sprintf(page, "Pool count min init max \n");2417 if (!left--)2418 return sprintf(page, "Small %5d %5d %5d %5d \n",2419 ns_stat_sfbqc_get(stat), card->sbnr.min,2420 card->sbnr.init, card->sbnr.max);2421 if (!left--)2422 return sprintf(page, "Large %5d %5d %5d %5d \n",2423 ns_stat_lfbqc_get(stat), card->lbnr.min,2424 card->lbnr.init, card->lbnr.max);2425 if (!left--)2426 return sprintf(page, "Huge %5d %5d %5d %5d \n",2427 card->hbpool.count, card->hbnr.min,2428 card->hbnr.init, card->hbnr.max);2429 if (!left--)2430 return sprintf(page, "Iovec %5d %5d %5d %5d \n",2431 card->iovpool.count, card->iovnr.min,2432 card->iovnr.init, card->iovnr.max);2433 if (!left--) {2434 int retval;2435 retval =2436 sprintf(page, "Interrupt counter: %u \n", card->intcnt);2437 card->intcnt = 0;2438 return retval;2439 }2440#if 02441 /* Dump 25.6 Mbps PHY registers */2442 /* Now there's a 25.6 Mbps PHY driver this code isn't needed. I left it2443 here just in case it's needed for debugging. */2444 if (card->max_pcr == ATM_25_PCR && !left--) {2445 u32 phy_regs[4];2446 u32 i;2447 2448 for (i = 0; i < 4; i++) {2449 while (CMD_BUSY(card)) ;2450 writel(NS_CMD_READ_UTILITY | 0x00000200 | i,2451 card->membase + CMD);2452 while (CMD_BUSY(card)) ;2453 phy_regs[i] = readl(card->membase + DR0) & 0x000000FF;2454 }2455 2456 return sprintf(page, "PHY regs: 0x%02X 0x%02X 0x%02X 0x%02X \n",2457 phy_regs[0], phy_regs[1], phy_regs[2],2458 phy_regs[3]);2459 }2460#endif /* 0 - Dump 25.6 Mbps PHY registers */2461#if 02462 /* Dump TST */2463 if (left-- < NS_TST_NUM_ENTRIES) {2464 if (card->tste2vc[left + 1] == NULL)2465 return sprintf(page, "%5d - VBR/UBR \n", left + 1);2466 else2467 return sprintf(page, "%5d - %d %d \n", left + 1,2468 card->tste2vc[left + 1]->tx_vcc->vpi,2469 card->tste2vc[left + 1]->tx_vcc->vci);2470 }2471#endif /* 0 */2472 return 0;2473}2474 2475static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg)2476{2477 ns_dev *card;2478 pool_levels pl;2479 long btype;2480 unsigned long flags;2481 2482 card = dev->dev_data;2483 switch (cmd) {2484 case NS_GETPSTAT:2485 if (get_user2486 (pl.buftype, &((pool_levels __user *) arg)->buftype))2487 return -EFAULT;2488 switch (pl.buftype) {2489 case NS_BUFTYPE_SMALL:2490 pl.count =2491 ns_stat_sfbqc_get(readl(card->membase + STAT));2492 pl.level.min = card->sbnr.min;2493 pl.level.init = card->sbnr.init;2494 pl.level.max = card->sbnr.max;2495 break;2496 2497 case NS_BUFTYPE_LARGE:2498 pl.count =2499 ns_stat_lfbqc_get(readl(card->membase + STAT));2500 pl.level.min = card->lbnr.min;2501 pl.level.init = card->lbnr.init;2502 pl.level.max = card->lbnr.max;2503 break;2504 2505 case NS_BUFTYPE_HUGE:2506 pl.count = card->hbpool.count;2507 pl.level.min = card->hbnr.min;2508 pl.level.init = card->hbnr.init;2509 pl.level.max = card->hbnr.max;2510 break;2511 2512 case NS_BUFTYPE_IOVEC:2513 pl.count = card->iovpool.count;2514 pl.level.min = card->iovnr.min;2515 pl.level.init = card->iovnr.init;2516 pl.level.max = card->iovnr.max;2517 break;2518 2519 default:2520 return -ENOIOCTLCMD;2521 2522 }2523 if (!copy_to_user((pool_levels __user *) arg, &pl, sizeof(pl)))2524 return (sizeof(pl));2525 else2526 return -EFAULT;2527 2528 case NS_SETBUFLEV:2529 if (!capable(CAP_NET_ADMIN))2530 return -EPERM;2531 if (copy_from_user(&pl, (pool_levels __user *) arg, sizeof(pl)))2532 return -EFAULT;2533 if (pl.level.min >= pl.level.init2534 || pl.level.init >= pl.level.max)2535 return -EINVAL;2536 if (pl.level.min == 0)2537 return -EINVAL;2538 switch (pl.buftype) {2539 case NS_BUFTYPE_SMALL:2540 if (pl.level.max > TOP_SB)2541 return -EINVAL;2542 card->sbnr.min = pl.level.min;2543 card->sbnr.init = pl.level.init;2544 card->sbnr.max = pl.level.max;2545 break;2546 2547 case NS_BUFTYPE_LARGE:2548 if (pl.level.max > TOP_LB)2549 return -EINVAL;2550 card->lbnr.min = pl.level.min;2551 card->lbnr.init = pl.level.init;2552 card->lbnr.max = pl.level.max;2553 break;2554 2555 case NS_BUFTYPE_HUGE:2556 if (pl.level.max > TOP_HB)2557 return -EINVAL;2558 card->hbnr.min = pl.level.min;2559 card->hbnr.init = pl.level.init;2560 card->hbnr.max = pl.level.max;2561 break;2562 2563 case NS_BUFTYPE_IOVEC:2564 if (pl.level.max > TOP_IOVB)2565 return -EINVAL;2566 card->iovnr.min = pl.level.min;2567 card->iovnr.init = pl.level.init;2568 card->iovnr.max = pl.level.max;2569 break;2570 2571 default:2572 return -EINVAL;2573 2574 }2575 return 0;2576 2577 case NS_ADJBUFLEV:2578 if (!capable(CAP_NET_ADMIN))2579 return -EPERM;2580 btype = (long)arg; /* a long is the same size as a pointer or bigger */2581 switch (btype) {2582 case NS_BUFTYPE_SMALL:2583 while (card->sbfqc < card->sbnr.init) {2584 struct sk_buff *sb;2585 2586 sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);2587 if (sb == NULL)2588 return -ENOMEM;2589 NS_PRV_BUFTYPE(sb) = BUF_SM;2590 skb_queue_tail(&card->sbpool.queue, sb);2591 skb_reserve(sb, NS_AAL0_HEADER);2592 push_rxbufs(card, sb);2593 }2594 break;2595 2596 case NS_BUFTYPE_LARGE:2597 while (card->lbfqc < card->lbnr.init) {2598 struct sk_buff *lb;2599 2600 lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);2601 if (lb == NULL)2602 return -ENOMEM;2603 NS_PRV_BUFTYPE(lb) = BUF_LG;2604 skb_queue_tail(&card->lbpool.queue, lb);2605 skb_reserve(lb, NS_SMBUFSIZE);2606 push_rxbufs(card, lb);2607 }2608 break;2609 2610 case NS_BUFTYPE_HUGE:2611 while (card->hbpool.count > card->hbnr.init) {2612 struct sk_buff *hb;2613 2614 spin_lock_irqsave(&card->int_lock, flags);2615 hb = skb_dequeue(&card->hbpool.queue);2616 card->hbpool.count--;2617 spin_unlock_irqrestore(&card->int_lock, flags);2618 if (hb == NULL)2619 printk2620 ("nicstar%d: huge buffer count inconsistent.\n",2621 card->index);2622 else2623 dev_kfree_skb_any(hb);2624 2625 }2626 while (card->hbpool.count < card->hbnr.init) {2627 struct sk_buff *hb;2628 2629 hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);2630 if (hb == NULL)2631 return -ENOMEM;2632 NS_PRV_BUFTYPE(hb) = BUF_NONE;2633 spin_lock_irqsave(&card->int_lock, flags);2634 skb_queue_tail(&card->hbpool.queue, hb);2635 card->hbpool.count++;2636 spin_unlock_irqrestore(&card->int_lock, flags);2637 }2638 break;2639 2640 case NS_BUFTYPE_IOVEC:2641 while (card->iovpool.count > card->iovnr.init) {2642 struct sk_buff *iovb;2643 2644 spin_lock_irqsave(&card->int_lock, flags);2645 iovb = skb_dequeue(&card->iovpool.queue);2646 card->iovpool.count--;2647 spin_unlock_irqrestore(&card->int_lock, flags);2648 if (iovb == NULL)2649 printk2650 ("nicstar%d: iovec buffer count inconsistent.\n",2651 card->index);2652 else2653 dev_kfree_skb_any(iovb);2654 2655 }2656 while (card->iovpool.count < card->iovnr.init) {2657 struct sk_buff *iovb;2658 2659 iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);2660 if (iovb == NULL)2661 return -ENOMEM;2662 NS_PRV_BUFTYPE(iovb) = BUF_NONE;2663 spin_lock_irqsave(&card->int_lock, flags);2664 skb_queue_tail(&card->iovpool.queue, iovb);2665 card->iovpool.count++;2666 spin_unlock_irqrestore(&card->int_lock, flags);2667 }2668 break;2669 2670 default:2671 return -EINVAL;2672 2673 }2674 return 0;2675 2676 default:2677 if (dev->phy && dev->phy->ioctl) {2678 return dev->phy->ioctl(dev, cmd, arg);2679 } else {2680 printk("nicstar%d: %s == NULL \n", card->index,2681 dev->phy ? "dev->phy->ioctl" : "dev->phy");2682 return -ENOIOCTLCMD;2683 }2684 }2685}2686 2687#ifdef EXTRA_DEBUG2688static void which_list(ns_dev * card, struct sk_buff *skb)2689{2690 printk("skb buf_type: 0x%08x\n", NS_PRV_BUFTYPE(skb));2691}2692#endif /* EXTRA_DEBUG */2693 2694static void ns_poll(struct timer_list *unused)2695{2696 int i;2697 ns_dev *card;2698 unsigned long flags;2699 u32 stat_r, stat_w;2700 2701 PRINTK("nicstar: Entering ns_poll().\n");2702 for (i = 0; i < num_cards; i++) {2703 card = cards[i];2704 if (!spin_trylock_irqsave(&card->int_lock, flags)) {2705 /* Probably it isn't worth spinning */2706 continue;2707 }2708 2709 stat_w = 0;2710 stat_r = readl(card->membase + STAT);2711 if (stat_r & NS_STAT_TSIF)2712 stat_w |= NS_STAT_TSIF;2713 if (stat_r & NS_STAT_EOPDU)2714 stat_w |= NS_STAT_EOPDU;2715 2716 process_tsq(card);2717 process_rsq(card);2718 2719 writel(stat_w, card->membase + STAT);2720 spin_unlock_irqrestore(&card->int_lock, flags);2721 }2722 mod_timer(&ns_timer, jiffies + NS_POLL_PERIOD);2723 PRINTK("nicstar: Leaving ns_poll().\n");2724}2725 2726static void ns_phy_put(struct atm_dev *dev, unsigned char value,2727 unsigned long addr)2728{2729 ns_dev *card;2730 unsigned long flags;2731 2732 card = dev->dev_data;2733 spin_lock_irqsave(&card->res_lock, flags);2734 while (CMD_BUSY(card)) ;2735 writel((u32) value, card->membase + DR0);2736 writel(NS_CMD_WRITE_UTILITY | 0x00000200 | (addr & 0x000000FF),2737 card->membase + CMD);2738 spin_unlock_irqrestore(&card->res_lock, flags);2739}2740 2741static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr)2742{2743 ns_dev *card;2744 unsigned long flags;2745 u32 data;2746 2747 card = dev->dev_data;2748 spin_lock_irqsave(&card->res_lock, flags);2749 while (CMD_BUSY(card)) ;2750 writel(NS_CMD_READ_UTILITY | 0x00000200 | (addr & 0x000000FF),2751 card->membase + CMD);2752 while (CMD_BUSY(card)) ;2753 data = readl(card->membase + DR0) & 0x000000FF;2754 spin_unlock_irqrestore(&card->res_lock, flags);2755 return (unsigned char)data;2756}2757 2758module_init(nicstar_init);2759module_exit(nicstar_cleanup);2760