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