brintos

brintos / linux-shallow public Read only

0
0
Text · 72.9 KiB · 27153d6 Raw
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