Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)   A FORE Systems 200E-series driver for ATM on Linux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)   Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2003.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)   Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)   This driver simultaneously supports PCA-200E and SBA-200E adapters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)   on i386, alpha (untested), powerpc, sparc and sparc64 architectures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/atmdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/sonet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/atm_suni.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <asm/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #ifdef CONFIG_SBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <asm/idprom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <asm/openprom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <asm/oplib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #if defined(CONFIG_ATM_FORE200E_USE_TASKLET) /* defer interrupt work to a tasklet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define FORE200E_USE_TASKLET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #if 0 /* enable the debugging code of the buffer supply queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define FORE200E_BSQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #if 1 /* ensure correct handling of 52-byte AAL0 SDUs expected by atmdump-like apps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define FORE200E_52BYTE_AAL0_SDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include "fore200e.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include "suni.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define FORE200E_VERSION "0.3e"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define FORE200E         "fore200e: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #if 0 /* override .config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define CONFIG_ATM_FORE200E_DEBUG 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define DPRINTK(level, format, args...)  do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)                                                   printk(FORE200E format, ##args); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define DPRINTK(level, format, args...)  do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define FORE200E_ALIGN(addr, alignment) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)         ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define FORE200E_DMA_INDEX(dma_addr, type, index)  ((dma_addr) + (index) * sizeof(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define FORE200E_INDEX(virt_addr, type, index)     (&((type *)(virt_addr))[ index ])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define FORE200E_NEXT_ENTRY(index, modulo)         (index = ((index) + 1) % (modulo))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define ASSERT(expr)     if (!(expr)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 			     printk(FORE200E "assertion failed! %s[%d]: %s\n", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 				    __func__, __LINE__, #expr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 			     panic(FORE200E "%s", __func__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 			 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define ASSERT(expr)     do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) static const struct atmdev_ops   fore200e_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) static LIST_HEAD(fore200e_boards);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) MODULE_SUPPORTED_DEVICE("PCA-200E, SBA-200E");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)     { BUFFER_S1_NBR, BUFFER_L1_NBR },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)     { BUFFER_S2_NBR, BUFFER_L2_NBR }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) static const int fore200e_rx_buf_size[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)     { BUFFER_S1_SIZE, BUFFER_L1_SIZE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113)     { BUFFER_S2_SIZE, BUFFER_L2_SIZE }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) static const char* fore200e_traffic_class[] = { "NONE", "UBR", "CBR", "VBR", "ABR", "ANY" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) #if 0 /* currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) static int 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) fore200e_fore2atm_aal(enum fore200e_aal aal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)     switch(aal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)     case FORE200E_AAL0:  return ATM_AAL0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)     case FORE200E_AAL34: return ATM_AAL34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)     case FORE200E_AAL5:  return ATM_AAL5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132)     return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) static enum fore200e_aal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) fore200e_atm2fore_aal(int aal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140)     switch(aal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141)     case ATM_AAL0:  return FORE200E_AAL0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142)     case ATM_AAL34: return FORE200E_AAL34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143)     case ATM_AAL1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144)     case ATM_AAL2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145)     case ATM_AAL5:  return FORE200E_AAL5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)     return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) static char*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) fore200e_irq_itoa(int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)     static char str[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)     sprintf(str, "%d", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)     return str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) /* allocate and align a chunk of memory intended to hold the data behing exchanged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162)    between the driver and the adapter (using streaming DVMA) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment, int direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)     unsigned long offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)     if (alignment <= sizeof(int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	alignment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)     chunk->alloc_size = size + alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)     chunk->direction  = direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)     chunk->alloc_addr = kzalloc(chunk->alloc_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)     if (chunk->alloc_addr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)     if (alignment > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	offset = FORE200E_ALIGN(chunk->alloc_addr, alignment); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182)     chunk->align_addr = chunk->alloc_addr + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)     chunk->dma_addr = dma_map_single(fore200e->dev, chunk->align_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 				     size, direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)     if (dma_mapping_error(fore200e->dev, chunk->dma_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	kfree(chunk->alloc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) /* free a chunk of memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)     dma_unmap_single(fore200e->dev, chunk->dma_addr, chunk->dma_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		     chunk->direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201)     kfree(chunk->alloc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  * Allocate a DMA consistent chunk of memory intended to act as a communication
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206)  * mechanism (to hold descriptors, status, queues, etc.) shared by the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207)  * and the adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) fore200e_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		int size, int nbr, int alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	/* returned chunks are page-aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	chunk->alloc_size = size * nbr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	chunk->alloc_addr = dma_alloc_coherent(fore200e->dev, chunk->alloc_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 					       &chunk->dma_addr, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	if (!chunk->alloc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	chunk->align_addr = chunk->alloc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224)  * Free a DMA consistent chunk of memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) fore200e_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	dma_free_coherent(fore200e->dev, chunk->alloc_size, chunk->alloc_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 			  chunk->dma_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) fore200e_spin(int msecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236)     unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237)     while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)     unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)     int           ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)     mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248)     do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	if ((ok = (*addr == val)) || (*addr & STATUS_ERROR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252)     } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)     if (!ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	printk(FORE200E "cmd polling failed, got status 0x%08x, expected 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	       *addr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)     return ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) fore200e_io_poll(struct fore200e* fore200e, volatile u32 __iomem *addr, u32 val, int msecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)     unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269)     int           ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271)     do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	if ((ok = (fore200e->bus->read(addr) == val)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275)     } while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) #if 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278)     if (!ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	printk(FORE200E "I/O polling failed, got status 0x%08x, expected 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	       fore200e->bus->read(addr), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284)     return ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) fore200e_free_rx_buf(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)     int scheme, magn, nbr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)     struct buffer* buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)     for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	    if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		    struct chunk* data = &buffer[ nbr ].data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		    if (data->alloc_addr != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 			fore200e_chunk_free(fore200e, data);
^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) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) fore200e_uninit_bs_queue(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)     int scheme, magn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)     for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	    struct chunk* status    = &fore200e->host_bsq[ scheme ][ magn ].status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	    struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	    if (status->alloc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		fore200e_dma_chunk_free(fore200e, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	    if (rbd_block->alloc_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		fore200e_dma_chunk_free(fore200e, rbd_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) fore200e_reset(struct fore200e* fore200e, int diag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)     int ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)     fore200e->cp_monitor = fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340)     fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342)     fore200e->bus->reset(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344)     if (diag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	if (ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	    printk(FORE200E "device %s self-test failed\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	    return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	printk(FORE200E "device %s self-test passed\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	fore200e->state = FORE200E_STATE_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) fore200e_shutdown(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)     printk(FORE200E "removing device %s at 0x%lx, IRQ %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	   fore200e->name, fore200e->phys_base, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	   fore200e_irq_itoa(fore200e->irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368)     if (fore200e->state > FORE200E_STATE_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	/* first, reset the board to prevent further interrupts or data transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	fore200e_reset(fore200e, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373)     /* then, release all allocated resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374)     switch(fore200e->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376)     case FORE200E_STATE_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	kfree(fore200e->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380)     case FORE200E_STATE_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	free_irq(fore200e->irq, fore200e->atm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)     case FORE200E_STATE_ALLOC_BUF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	fore200e_free_rx_buf(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)     case FORE200E_STATE_INIT_BSQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	fore200e_uninit_bs_queue(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392)     case FORE200E_STATE_INIT_RXQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	fore200e_dma_chunk_free(fore200e, &fore200e->host_rxq.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	fore200e_dma_chunk_free(fore200e, &fore200e->host_rxq.rpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397)     case FORE200E_STATE_INIT_TXQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	fore200e_dma_chunk_free(fore200e, &fore200e->host_txq.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	fore200e_dma_chunk_free(fore200e, &fore200e->host_txq.tpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)     case FORE200E_STATE_INIT_CMDQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	fore200e_dma_chunk_free(fore200e, &fore200e->host_cmdq.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406)     case FORE200E_STATE_INITIALIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	/* nothing to do for that state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409)     case FORE200E_STATE_START_FW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	/* nothing to do for that state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)     case FORE200E_STATE_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	/* nothing to do for that state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415)     case FORE200E_STATE_MAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	fore200e->bus->unmap(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419)     case FORE200E_STATE_CONFIGURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	/* nothing to do for that state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)     case FORE200E_STATE_REGISTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	/* XXX shouldn't we *start* by deregistering the device? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	atm_dev_deregister(fore200e->atm_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)     case FORE200E_STATE_BLANK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	/* nothing to do for that state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) static u32 fore200e_pca_read(volatile u32 __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)     /* on big-endian hosts, the board is configured to convert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)        the endianess of slave RAM accesses  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439)     return le32_to_cpu(readl(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) static void fore200e_pca_write(u32 val, volatile u32 __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445)     /* on big-endian hosts, the board is configured to convert
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)        the endianess of slave RAM accesses  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)     writel(cpu_to_le32(val), addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) fore200e_pca_irq_check(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)     /* this is a 1 bit register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)     int irq_posted = readl(fore200e->regs.pca.psr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) #if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)     if (irq_posted && (readl(fore200e->regs.pca.hcr) & PCA200E_HCR_OUTFULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	DPRINTK(2,"FIFO OUT full, device %d\n", fore200e->atm_dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)     return irq_posted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) fore200e_pca_irq_ack(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469)     writel(PCA200E_HCR_CLRINTR, fore200e->regs.pca.hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) fore200e_pca_reset(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)     writel(PCA200E_HCR_RESET, fore200e->regs.pca.hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)     fore200e_spin(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478)     writel(0, fore200e->regs.pca.hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) static int fore200e_pca_map(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484)     DPRINTK(2, "device %s being mapped in memory\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486)     fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488)     if (fore200e->virt_base == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	printk(FORE200E "can't map device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493)     DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495)     /* gain access to the PCA specific registers  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496)     fore200e->regs.pca.hcr = fore200e->virt_base + PCA200E_HCR_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497)     fore200e->regs.pca.imr = fore200e->virt_base + PCA200E_IMR_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498)     fore200e->regs.pca.psr = fore200e->virt_base + PCA200E_PSR_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500)     fore200e->state = FORE200E_STATE_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) fore200e_pca_unmap(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)     DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)     if (fore200e->virt_base != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	iounmap(fore200e->virt_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) static int fore200e_pca_configure(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517)     struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518)     u8              master_ctrl, latency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)     DPRINTK(2, "device %s being configured\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522)     if ((pci_dev->irq == 0) || (pci_dev->irq == 0xFF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	printk(FORE200E "incorrect IRQ setting - misconfigured PCI-PCI bridge?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527)     pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529)     master_ctrl = master_ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) #if defined(__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	/* request the PCA board to convert the endianess of slave RAM accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	| PCA200E_CTRL_CONVERT_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)         | PCA200E_CTRL_DIS_CACHE_RD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536)         | PCA200E_CTRL_DIS_WRT_INVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537)         | PCA200E_CTRL_ENA_CONT_REQ_MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538)         | PCA200E_CTRL_2_CACHE_WRT_INVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	| PCA200E_CTRL_LARGE_PCI_BURSTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542)     pci_write_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, master_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544)     /* raise latency from 32 (default) to 192, as this seems to prevent NIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545)        lockups (under heavy rx loads) due to continuous 'FIFO OUT full' condition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546)        this may impact the performances of other PCI devices on the same bus, though */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547)     latency = 192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548)     pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)     fore200e->state = FORE200E_STATE_CONFIGURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558)     struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559)     struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560)     struct prom_opcode      opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561)     int                     ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562)     u32                     prom_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564)     FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566)     opcode.opcode = OPCODE_GET_PROM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567)     opcode.pad    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569)     prom_dma = dma_map_single(fore200e->dev, prom, sizeof(struct prom_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 			      DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571)     if (dma_mapping_error(fore200e->dev, prom_dma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)     fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)     *entry->status = STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)     fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.prom_block.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)     ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582)     *entry->status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584)     dma_unmap_single(fore200e->dev, prom_dma, sizeof(struct prom_data), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586)     if (ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) #if defined(__BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) #define swap_here(addr) (*((u32*)(addr)) = swab32( *((u32*)(addr)) ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)     /* MAC address is stored as little-endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596)     swap_here(&prom->mac_addr[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597)     swap_here(&prom->mac_addr[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)     struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609)     return sprintf(page, "   PCI bus/slot/function:\t%d/%d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		   pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) static const struct fore200e_bus fore200e_pci_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	.model_name		= "PCA-200E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	.proc_name		= "pca200e",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	.descr_alignment	= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	.buffer_alignment	= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	.status_alignment	= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	.read			= fore200e_pca_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	.write			= fore200e_pca_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	.configure		= fore200e_pca_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	.map			= fore200e_pca_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	.reset			= fore200e_pca_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	.prom_read		= fore200e_pca_prom_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	.unmap			= fore200e_pca_unmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	.irq_check		= fore200e_pca_irq_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	.irq_ack		= fore200e_pca_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	.proc_read		= fore200e_pca_proc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) #endif /* CONFIG_PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) #ifdef CONFIG_SBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) static u32 fore200e_sba_read(volatile u32 __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636)     return sbus_readl(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)     sbus_writel(val, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) static void fore200e_sba_irq_enable(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) static int fore200e_sba_irq_check(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) static void fore200e_sba_irq_ack(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) static void fore200e_sba_reset(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	fore200e_spin(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	fore200e->bus->write(0, fore200e->regs.sba.hcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) static int __init fore200e_sba_map(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	struct platform_device *op = to_platform_device(fore200e->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	unsigned int bursts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	/* gain access to the SBA specific registers  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	fore200e->virt_base    = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	if (!fore200e->virt_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	/* get the supported DVMA burst sizes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	if (sbus_can_dma_64bit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		sbus_set_sbus64(&op->dev, bursts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	fore200e->state = FORE200E_STATE_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) static void fore200e_sba_unmap(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	struct platform_device *op = to_platform_device(fore200e->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	of_iounmap(&op->resource[3], fore200e->virt_base,    SBA200E_RAM_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) static int __init fore200e_sba_configure(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	fore200e->state = FORE200E_STATE_CONFIGURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	struct platform_device *op = to_platform_device(fore200e->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	const u8 *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	prop = of_get_property(op->dev.of_node, "madaddrlo2", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	memcpy(&prom->mac_addr[4], prop, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	prop = of_get_property(op->dev.of_node, "madaddrhi4", &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (!prop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	memcpy(&prom->mac_addr[2], prop, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	prom->serial_number = of_getintprop_default(op->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 						    "serialnumber", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	prom->hw_revision = of_getintprop_default(op->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 						  "promversion", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	struct platform_device *op = to_platform_device(fore200e->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	const struct linux_prom_registers *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	regs = of_get_property(op->dev.of_node, "reg", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	return sprintf(page, "   SBUS slot/device:\t\t%d/'%pOFn'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		       (regs ? regs->which_io : 0), op->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) static const struct fore200e_bus fore200e_sbus_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	.model_name		= "SBA-200E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	.proc_name		= "sba200e",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	.descr_alignment	= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	.buffer_alignment	= 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	.status_alignment	= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	.read			= fore200e_sba_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	.write			= fore200e_sba_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	.configure		= fore200e_sba_configure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	.map			= fore200e_sba_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	.reset			= fore200e_sba_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	.prom_read		= fore200e_sba_prom_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	.unmap			= fore200e_sba_unmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	.irq_enable		= fore200e_sba_irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	.irq_check		= fore200e_sba_irq_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	.irq_ack		= fore200e_sba_irq_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	.proc_read		= fore200e_sba_proc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) #endif /* CONFIG_SBUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) fore200e_tx_irq(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772)     struct host_txq*        txq = &fore200e->host_txq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773)     struct host_txq_entry*  entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774)     struct atm_vcc*         vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775)     struct fore200e_vc_map* vc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777)     if (fore200e->host_txq.txing == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780)     for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	entry = &txq->host_entry[ txq->tail ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784)         if ((*entry->status & STATUS_COMPLETE) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	DPRINTK(3, "TX COMPLETED: entry = %p [tail = %d], vc_map = %p, skb = %p\n", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 		entry, txq->tail, entry->vc_map, entry->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	/* free copy of misaligned data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	kfree(entry->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	/* remove DMA mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	dma_unmap_single(fore200e->dev, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 				 DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	vc_map = entry->vc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	/* vcc closed since the time the entry was submitted for tx? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	if ((vc_map->vcc == NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	    (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	    DPRINTK(1, "no ready vcc found for PDU sent on device %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		    fore200e->atm_dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	    dev_kfree_skb_any(entry->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	    ASSERT(vc_map->vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	    /* vcc closed then immediately re-opened? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	    if (vc_map->incarn != entry->incarn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		/* when a vcc is closed, some PDUs may be still pending in the tx queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		   if the same vcc is immediately re-opened, those pending PDUs must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		   not be popped after the completion of their emission, as they refer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		   to the prior incarnation of that vcc. otherwise, sk_atm(vcc)->sk_wmem_alloc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		   would be decremented by the size of the (unrelated) skb, possibly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		   leading to a negative sk->sk_wmem_alloc count, ultimately freezing the vcc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		   we thus bind the tx entry to the current incarnation of the vcc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		   when the entry is submitted for tx. When the tx later completes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		   if the incarnation number of the tx entry does not match the one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		   of the vcc, then this implies that the vcc has been closed then re-opened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		   we thus just drop the skb here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		DPRINTK(1, "vcc closed-then-re-opened; dropping PDU sent on device %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			fore200e->atm_dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		dev_kfree_skb_any(entry->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	    else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		vcc = vc_map->vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		ASSERT(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		/* notify tx completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		if (vcc->pop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		    vcc->pop(vcc, entry->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		    dev_kfree_skb_any(entry->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		/* check error condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		if (*entry->status & STATUS_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		    atomic_inc(&vcc->stats->tx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		    atomic_inc(&vcc->stats->tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	*entry->status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	fore200e->host_txq.txing--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	FORE200E_NEXT_ENTRY(txq->tail, QUEUE_SIZE_TX);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) #ifdef FORE200E_BSQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) int bsq_audit(int where, struct host_bsq* bsq, int scheme, int magn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864)     struct buffer* buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865)     int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867)     buffer = bsq->freebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868)     while (buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	if (buffer->supplied) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld supplied but in free list!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		   where, scheme, magn, buffer->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	if (buffer->magn != magn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected magn = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		   where, scheme, magn, buffer->index, buffer->magn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	if (buffer->scheme != scheme) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected scheme = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		   where, scheme, magn, buffer->index, buffer->scheme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	if ((buffer->index < 0) || (buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	    printk(FORE200E "bsq_audit(%d): queue %d.%d, out of range buffer index = %ld !\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		   where, scheme, magn, buffer->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	buffer = buffer->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894)     if (count != bsq->freebuf_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	printk(FORE200E "bsq_audit(%d): queue %d.%d, %d bufs in free list, but freebuf_count = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	       where, scheme, magn, count, bsq->freebuf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) #endif
^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) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) fore200e_supply(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906)     int  scheme, magn, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908)     struct host_bsq*       bsq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909)     struct host_bsq_entry* entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)     struct buffer*         buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912)     for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) #ifdef FORE200E_BSQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	    bsq_audit(1, bsq, scheme, magn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	    while (bsq->freebuf_count >= RBD_BLK_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		DPRINTK(2, "supplying %d rx buffers to queue %d / %d, freebuf_count = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 			RBD_BLK_SIZE, scheme, magn, bsq->freebuf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		entry = &bsq->host_entry[ bsq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		for (i = 0; i < RBD_BLK_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		    /* take the first buffer in the free buffer list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		    buffer = bsq->freebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		    if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			printk(FORE200E "no more free bufs in queue %d.%d, but freebuf_count = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			       scheme, magn, bsq->freebuf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		    bsq->freebuf = buffer->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) #ifdef FORE200E_BSQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		    if (buffer->supplied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			printk(FORE200E "queue %d.%d, buffer %lu already supplied\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			       scheme, magn, buffer->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		    buffer->supplied = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		    entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		    entry->rbd_block->rbd[ i ].handle       = FORE200E_BUF2HDL(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950)  		/* decrease accordingly the number of free rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		bsq->freebuf_count -= RBD_BLK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		*entry->status = STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rpd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964)     struct sk_buff*      skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)     struct buffer*       buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966)     struct fore200e_vcc* fore200e_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967)     int                  i, pdu_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) #ifdef FORE200E_52BYTE_AAL0_SDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969)     u32                  cell_header = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972)     ASSERT(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974)     fore200e_vcc = FORE200E_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975)     ASSERT(fore200e_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) #ifdef FORE200E_52BYTE_AAL0_SDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978)     if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.rxtp.max_sdu == ATM_AAL0_SDU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	cell_header = (rpd->atm_header.gfc << ATM_HDR_GFC_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	              (rpd->atm_header.vpi << ATM_HDR_VPI_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982)                       (rpd->atm_header.vci << ATM_HDR_VCI_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983)                       (rpd->atm_header.plt << ATM_HDR_PTI_SHIFT) | 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984)                        rpd->atm_header.clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	pdu_len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989)     /* compute total PDU length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990)     for (i = 0; i < rpd->nseg; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	pdu_len += rpd->rsd[ i ].length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993)     skb = alloc_skb(pdu_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994)     if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	atomic_inc(&vcc->stats->rx_drop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	return -ENOMEM;
^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)     __net_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) #ifdef FORE200E_52BYTE_AAL0_SDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)     if (cell_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	*((u32*)skb_put(skb, 4)) = cell_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)     /* reassemble segments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)     for (i = 0; i < rpd->nseg; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	/* rebuild rx buffer address from rsd handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	/* Make device DMA transfer visible to CPU.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	dma_sync_single_for_cpu(fore200e->dev, buffer->data.dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 				rpd->rsd[i].length, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	skb_put_data(skb, buffer->data.align_addr, rpd->rsd[i].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	/* Now let the device get at it again.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	dma_sync_single_for_device(fore200e->dev, buffer->data.dma_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 				   rpd->rsd[i].length, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)     DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)     if (pdu_len < fore200e_vcc->rx_min_pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	fore200e_vcc->rx_min_pdu = pdu_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)     if (pdu_len > fore200e_vcc->rx_max_pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	fore200e_vcc->rx_max_pdu = pdu_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)     fore200e_vcc->rx_pdu++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)     /* push PDU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)     if (atm_charge(vcc, skb->truesize) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	DPRINTK(2, "receive buffers saturated for %d.%d.%d - PDU dropped\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		vcc->itf, vcc->vpi, vcc->vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	atomic_inc(&vcc->stats->rx_drop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)     vcc->push(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)     atomic_inc(&vcc->stats->rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) fore200e_collect_rpd(struct fore200e* fore200e, struct rpd* rpd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)     struct host_bsq* bsq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)     struct buffer*   buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)     int              i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)     for (i = 0; i < rpd->nseg; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	/* rebuild rx buffer address from rsd handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	bsq = &fore200e->host_bsq[ buffer->scheme ][ buffer->magn ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) #ifdef FORE200E_BSQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	bsq_audit(2, bsq, buffer->scheme, buffer->magn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (buffer->supplied == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	    printk(FORE200E "queue %d.%d, buffer %ld was not supplied\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		   buffer->scheme, buffer->magn, buffer->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	buffer->supplied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	/* re-insert the buffer into the free buffer list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	buffer->next = bsq->freebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	bsq->freebuf = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	/* then increment the number of free rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	bsq->freebuf_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) fore200e_rx_irq(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)     struct host_rxq*        rxq = &fore200e->host_rxq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)     struct host_rxq_entry*  entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)     struct atm_vcc*         vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)     struct fore200e_vc_map* vc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)     for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	entry = &rxq->host_entry[ rxq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	/* no more received PDUs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	if ((*entry->status & STATUS_COMPLETE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	vc_map = FORE200E_VC_MAP(fore200e, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	if ((vc_map->vcc == NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	    (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	    DPRINTK(1, "no ready VC found for PDU received on %d.%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		    fore200e->atm_dev->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		    entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	    vcc = vc_map->vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	    ASSERT(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	    if ((*entry->status & STATUS_ERROR) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		fore200e_push_rpd(fore200e, vcc, entry->rpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	    else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		DPRINTK(2, "damaged PDU on %d.%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			fore200e->atm_dev->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		atomic_inc(&vcc->stats->rx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	fore200e_collect_rpd(fore200e, entry->rpd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	/* rewrite the rpd address to ack the received PDU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	fore200e->bus->write(entry->rpd_dma, &entry->cp_entry->rpd_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	*entry->status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	fore200e_supply(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)     }
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) #ifndef FORE200E_USE_TASKLET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) fore200e_irq(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)     unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)     spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)     fore200e_rx_irq(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)     spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)     spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)     fore200e_tx_irq(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)     spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) fore200e_interrupt(int irq, void* dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)     struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)     if (fore200e->bus->irq_check(fore200e) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	DPRINTK(3, "interrupt NOT triggered by device %d\n", fore200e->atm_dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)     DPRINTK(3, "interrupt triggered by device %d\n", fore200e->atm_dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) #ifdef FORE200E_USE_TASKLET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)     tasklet_schedule(&fore200e->tx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)     tasklet_schedule(&fore200e->rx_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)     fore200e_irq(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)     fore200e->bus->irq_ack(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)     return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) #ifdef FORE200E_USE_TASKLET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) fore200e_tx_tasklet(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)     struct fore200e* fore200e = (struct fore200e*) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)     unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)     DPRINTK(3, "tx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)     spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)     fore200e_tx_irq(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)     spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) fore200e_rx_tasklet(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)     struct fore200e* fore200e = (struct fore200e*) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)     unsigned long    flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)     DPRINTK(3, "rx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)     spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)     fore200e_rx_irq((struct fore200e*) data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)     spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) fore200e_select_scheme(struct atm_vcc* vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)     /* fairly balance the VCs over (identical) buffer schemes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)     int scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)     DPRINTK(1, "VC %d.%d.%d uses buffer scheme %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	    vcc->itf, vcc->vpi, vcc->vci, scheme);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)     return scheme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static int 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* vcc, int mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)     struct host_cmdq*        cmdq  = &fore200e->host_cmdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)     struct host_cmdq_entry*  entry = &cmdq->host_entry[ cmdq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)     struct activate_opcode   activ_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)     struct deactivate_opcode deactiv_opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)     struct vpvc              vpvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)     int                      ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)     enum fore200e_aal        aal = fore200e_atm2fore_aal(vcc->qos.aal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)     FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)     if (activate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	FORE200E_VCC(vcc)->scheme = fore200e_select_scheme(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	activ_opcode.opcode = OPCODE_ACTIVATE_VCIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	activ_opcode.aal    = aal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	activ_opcode.scheme = FORE200E_VCC(vcc)->scheme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	activ_opcode.pad    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	deactiv_opcode.opcode = OPCODE_DEACTIVATE_VCIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	deactiv_opcode.pad    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)     vpvc.vci = vcc->vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)     vpvc.vpi = vcc->vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)     *entry->status = STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)     if (activate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) #ifdef FORE200E_52BYTE_AAL0_SDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	mtu = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	/* the MTU is not used by the cp, except in the case of AAL0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	fore200e->bus->write(mtu,                        &entry->cp_entry->cmd.activate_block.mtu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	fore200e->bus->write(*(u32*)&vpvc,         (u32 __iomem *)&entry->cp_entry->cmd.activate_block.vpvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	fore200e->bus->write(*(u32*)&activ_opcode, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	fore200e->bus->write(*(u32*)&vpvc,         (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.vpvc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	fore200e->bus->write(*(u32*)&deactiv_opcode, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)     ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)     *entry->status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)     if (ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	printk(FORE200E "unable to %s VC %d.%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	       activate ? "open" : "close", vcc->itf, vcc->vpi, vcc->vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)     DPRINTK(1, "VC %d.%d.%d %sed\n", vcc->itf, vcc->vpi, vcc->vci, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	    activate ? "open" : "clos");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) #define FORE200E_MAX_BACK2BACK_CELLS 255    /* XXX depends on CDVT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)     if (qos->txtp.max_pcr < ATM_OC3_PCR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	/* compute the data cells to idle cells ratio from the tx PCR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	rate->data_cells = qos->txtp.max_pcr * FORE200E_MAX_BACK2BACK_CELLS / ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	rate->idle_cells = FORE200E_MAX_BACK2BACK_CELLS - rate->data_cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	/* disable rate control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	rate->data_cells = rate->idle_cells = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) fore200e_open(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)     struct fore200e*        fore200e = FORE200E_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)     struct fore200e_vcc*    fore200e_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)     struct fore200e_vc_map* vc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)     unsigned long	    flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)     int			    vci = vcc->vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)     short		    vpi = vcc->vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)     ASSERT((vpi >= 0) && (vpi < 1<<FORE200E_VPI_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)     ASSERT((vci >= 0) && (vci < 1<<FORE200E_VCI_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)     spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)     vc_map = FORE200E_VC_MAP(fore200e, vpi, vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)     if (vc_map->vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	printk(FORE200E "VC %d.%d.%d already in use\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	       fore200e->atm_dev->number, vpi, vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)     vc_map->vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)     spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)     fore200e_vcc = kzalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)     if (fore200e_vcc == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	vc_map->vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)     DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	    fore200e_traffic_class[ vcc->qos.txtp.traffic_class ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	    vcc->qos.txtp.min_pcr, vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_cdv, vcc->qos.txtp.max_sdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	    fore200e_traffic_class[ vcc->qos.rxtp.traffic_class ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	    vcc->qos.rxtp.min_pcr, vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_cdv, vcc->qos.rxtp.max_sdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)     /* pseudo-CBR bandwidth requested? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)     if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	mutex_lock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	    mutex_unlock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	    kfree(fore200e_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	    vc_map->vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	    return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	/* reserve bandwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	mutex_unlock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)     vcc->itf = vcc->dev->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)     set_bit(ATM_VF_PARTIAL,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)     set_bit(ATM_VF_ADDR, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)     vcc->dev_data = fore200e_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)     if (fore200e_activate_vcin(fore200e, 1, vcc, vcc->qos.rxtp.max_sdu) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	vc_map->vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	clear_bit(ATM_VF_ADDR, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	clear_bit(ATM_VF_PARTIAL,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	vcc->dev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	kfree(fore200e_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)     /* compute rate control parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)     if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	fore200e_rate_ctrl(&vcc->qos, &fore200e_vcc->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	set_bit(ATM_VF_HASQOS, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	DPRINTK(3, "tx on %d.%d.%d:%d, tx PCR = %d, rx PCR = %d, data_cells = %u, idle_cells = %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		vcc->qos.txtp.max_pcr, vcc->qos.rxtp.max_pcr, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		fore200e_vcc->rate.data_cells, fore200e_vcc->rate.idle_cells);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)     fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = MAX_PDU_SIZE + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)     fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)     fore200e_vcc->tx_pdu     = fore200e_vcc->rx_pdu     = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)     /* new incarnation of the vcc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)     vc_map->incarn = ++fore200e->incarn_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)     /* VC unusable before this flag is set */
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) fore200e_close(struct atm_vcc* vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)     struct fore200e_vcc*    fore200e_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)     struct fore200e*        fore200e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)     struct fore200e_vc_map* vc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)     unsigned long           flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)     ASSERT(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)     fore200e = FORE200E_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)     ASSERT((vcc->vpi >= 0) && (vcc->vpi < 1<<FORE200E_VPI_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)     ASSERT((vcc->vci >= 0) && (vcc->vci < 1<<FORE200E_VCI_BITS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)     DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)     clear_bit(ATM_VF_READY, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)     fore200e_activate_vcin(fore200e, 0, vcc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)     spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)     vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)     /* the vc is no longer considered as "in use" by fore200e_open() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)     vc_map->vcc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)     vcc->itf = vcc->vci = vcc->vpi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)     fore200e_vcc = FORE200E_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)     vcc->dev_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)     spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)     /* release reserved bandwidth, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)     if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	mutex_lock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	mutex_unlock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	clear_bit(ATM_VF_HASQOS, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)     clear_bit(ATM_VF_ADDR, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)     clear_bit(ATM_VF_PARTIAL,&vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)     ASSERT(fore200e_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)     kfree(fore200e_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^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) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)     struct fore200e*        fore200e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)     struct fore200e_vcc*    fore200e_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)     struct fore200e_vc_map* vc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)     struct host_txq*        txq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)     struct host_txq_entry*  entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)     struct tpd*             tpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)     struct tpd_haddr        tpd_haddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)     int                     retry        = CONFIG_ATM_FORE200E_TX_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)     int                     tx_copy      = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)     int                     tx_len       = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)     u32*                    cell_header  = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)     unsigned char*          skb_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)     int                     skb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)     unsigned char*          data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)     unsigned long           flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)     if (!vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)         return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)     fore200e = FORE200E_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)     fore200e_vcc = FORE200E_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)     if (!fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)         return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)     txq = &fore200e->host_txq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)     if (!fore200e_vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)         return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)     if (!test_bit(ATM_VF_READY, &vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	DPRINTK(1, "VC %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) #ifdef FORE200E_52BYTE_AAL0_SDU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)     if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	cell_header = (u32*) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	skb_data    = skb->data + 4;    /* skip 4-byte cell header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	skb_len     = tx_len = skb->len  - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	DPRINTK(3, "user-supplied cell header = 0x%08x\n", *cell_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)     else 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	skb_data = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	skb_len  = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)     if (((unsigned long)skb_data) & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	DPRINTK(2, "misaligned tx PDU on device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	tx_copy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	tx_len  = skb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)     if ((vcc->qos.aal == ATM_AAL0) && (skb_len % ATM_CELL_PAYLOAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)         /* this simply NUKES the PCA board */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	DPRINTK(2, "incomplete tx AAL0 PDU on device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	tx_copy = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	tx_len  = ((skb_len / ATM_CELL_PAYLOAD) + 1) * ATM_CELL_PAYLOAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)     if (tx_copy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	data = kmalloc(tx_len, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	if (data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	    if (vcc->pop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		vcc->pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	    else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	    return -ENOMEM;
^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) 	memcpy(data, skb_data, skb_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	if (skb_len < tx_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	    memset(data + skb_len, 0x00, tx_len - skb_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	data = skb_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)     vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)     ASSERT(vc_map->vcc == vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)   retry_here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)     spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)     entry = &txq->host_entry[ txq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)     if ((*entry->status != STATUS_FREE) || (txq->txing >= QUEUE_SIZE_TX - 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	/* try to free completed tx queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 	fore200e_tx_irq(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	if (*entry->status != STATUS_FREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	    spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	    /* retry once again? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	    if (--retry > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		goto retry_here;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	    atomic_inc(&vcc->stats->tx_err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	    fore200e->tx_sat++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	    DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		    fore200e->name, fore200e->cp_queues->heartbeat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	    if (vcc->pop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		vcc->pop(vcc, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	    else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	    if (tx_copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 		kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	    return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)     entry->incarn = vc_map->incarn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)     entry->vc_map = vc_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)     entry->skb    = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)     entry->data   = tx_copy ? data : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)     tpd = entry->tpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)     tpd->tsd[ 0 ].buffer = dma_map_single(fore200e->dev, data, tx_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 					  DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)     if (dma_mapping_error(fore200e->dev, tpd->tsd[0].buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	if (tx_copy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	    kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)     tpd->tsd[ 0 ].length = tx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)     FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)     txq->txing++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)     /* The dma_map call above implies a dma_sync so the device can use it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)      * thus no explicit dma_sync call is necessary here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)     DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	    tpd->tsd[0].length, skb_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)     if (skb_len < fore200e_vcc->tx_min_pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	fore200e_vcc->tx_min_pdu = skb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)     if (skb_len > fore200e_vcc->tx_max_pdu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	fore200e_vcc->tx_max_pdu = skb_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)     fore200e_vcc->tx_pdu++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)     /* set tx rate control information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)     tpd->rate.data_cells = fore200e_vcc->rate.data_cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)     tpd->rate.idle_cells = fore200e_vcc->rate.idle_cells;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)     if (cell_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	tpd->atm_header.clp = (*cell_header & ATM_HDR_CLP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	tpd->atm_header.plt = (*cell_header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	tpd->atm_header.vci = (*cell_header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	tpd->atm_header.vpi = (*cell_header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	tpd->atm_header.gfc = (*cell_header & ATM_HDR_GFC_MASK) >> ATM_HDR_GFC_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	/* set the ATM header, common to all cells conveying the PDU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	tpd->atm_header.clp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	tpd->atm_header.plt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	tpd->atm_header.vci = vcc->vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	tpd->atm_header.vpi = vcc->vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	tpd->atm_header.gfc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)     tpd->spec.length = tx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)     tpd->spec.nseg   = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)     tpd->spec.aal    = fore200e_atm2fore_aal(vcc->qos.aal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)     tpd->spec.intr   = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)     tpd_haddr.size  = sizeof(struct tpd) / (1<<TPD_HADDR_SHIFT);  /* size is expressed in 32 byte blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)     tpd_haddr.pad   = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)     tpd_haddr.haddr = entry->tpd_dma >> TPD_HADDR_SHIFT;          /* shift the address, as we are in a bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)     *entry->status = STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)     fore200e->bus->write(*(u32*)&tpd_haddr, (u32 __iomem *)&entry->cp_entry->tpd_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)     spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)     return 0;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) fore200e_getstats(struct fore200e* fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)     struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)     struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)     struct stats_opcode     opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)     int                     ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)     u32                     stats_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)     if (fore200e->stats == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	fore200e->stats = kzalloc(sizeof(struct stats), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	if (fore200e->stats == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	    return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)     stats_dma_addr = dma_map_single(fore200e->dev, fore200e->stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 				    sizeof(struct stats), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)     if (dma_mapping_error(fore200e->dev, stats_dma_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)     	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)     FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)     opcode.opcode = OPCODE_GET_STATS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)     opcode.pad    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)     fore200e->bus->write(stats_dma_addr, &entry->cp_entry->cmd.stats_block.stats_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)     *entry->status = STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)     fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.stats_block.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)     ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)     *entry->status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)     dma_unmap_single(fore200e->dev, stats_dma_addr, sizeof(struct stats), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)     if (ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) #if 0 /* currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)     struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)     struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719)     struct oc3_opcode       opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)     int                     ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)     u32                     oc3_regs_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)     oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)     FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)     opcode.opcode = OPCODE_GET_OC3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)     opcode.reg    = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)     opcode.value  = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)     opcode.mask   = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)     fore200e->bus->write(oc3_regs_dma_addr, &entry->cp_entry->cmd.oc3_block.regs_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)     *entry->status = STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)     fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)     ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)     *entry->status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)     fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)     if (ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)     struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)     struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)     struct oc3_opcode       opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)     int                     ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)     DPRINTK(2, "set OC-3 reg = 0x%02x, value = 0x%02x, mask = 0x%02x\n", reg, value, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)     FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)     opcode.opcode = OPCODE_SET_OC3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)     opcode.reg    = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)     opcode.value  = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)     opcode.mask   = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)     fore200e->bus->write(0, &entry->cp_entry->cmd.oc3_block.regs_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)     *entry->status = STATUS_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)     fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.oc3_block.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)     ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)     *entry->status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)     if (ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 	printk(FORE200E "unable to set OC-3 reg 0x%02x of device %s\n", reg, fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) fore200e_setloop(struct fore200e* fore200e, int loop_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)     u32 mct_value, mct_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)     int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)     if (!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 	return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)     switch (loop_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)     case ATM_LM_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	mct_value = 0; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 	mct_mask  = SUNI_MCT_DLE | SUNI_MCT_LLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)     case ATM_LM_LOC_PHY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 	mct_value = mct_mask = SUNI_MCT_DLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)     case ATM_LM_RMT_PHY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	mct_value = mct_mask = SUNI_MCT_LLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)     default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)     error = fore200e_set_oc3(fore200e, SUNI_MCT, mct_value, mct_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)     if (error == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	fore200e->loop_mode = loop_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)     return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)     struct sonet_stats tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)     if (fore200e_getstats(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)     tmp.section_bip = be32_to_cpu(fore200e->stats->oc3.section_bip8_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)     tmp.line_bip    = be32_to_cpu(fore200e->stats->oc3.line_bip24_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)     tmp.path_bip    = be32_to_cpu(fore200e->stats->oc3.path_bip8_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)     tmp.line_febe   = be32_to_cpu(fore200e->stats->oc3.line_febe_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)     tmp.path_febe   = be32_to_cpu(fore200e->stats->oc3.path_febe_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)     tmp.corr_hcs    = be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)     tmp.uncorr_hcs  = be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)     tmp.tx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_transmitted)  +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	              be32_to_cpu(fore200e->stats->aal34.cells_transmitted) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 	              be32_to_cpu(fore200e->stats->aal5.cells_transmitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)     tmp.rx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_received)     +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 	              be32_to_cpu(fore200e->stats->aal34.cells_received)    +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	              be32_to_cpu(fore200e->stats->aal5.cells_received);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)     if (arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void __user * arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)     struct fore200e* fore200e = FORE200E_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)     DPRINTK(2, "ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)     switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)     case SONET_GETSTAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	return fore200e_fetch_stats(fore200e, (struct sonet_stats __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)     case SONET_GETDIAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	return put_user(0, (int __user *)arg) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)     case ATM_SETLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	return fore200e_setloop(fore200e, (int)(unsigned long)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)     case ATM_GETLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	return put_user(fore200e->loop_mode, (int __user *)arg) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)     case ATM_QUERYLOOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 	return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int __user *)arg) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)     return -ENOSYS; /* not implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)     struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)     struct fore200e*     fore200e     = FORE200E_DEV(vcc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)     if (!test_bit(ATM_VF_READY, &vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	DPRINTK(1, "VC %d.%d.%d not ready for QoS change\n", vcc->itf, vcc->vpi, vcc->vpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)     DPRINTK(2, "change_qos %d.%d.%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	    "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	    "available_cell_rate = %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	    vcc->itf, vcc->vpi, vcc->vci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	    fore200e_traffic_class[ qos->txtp.traffic_class ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	    qos->txtp.min_pcr, qos->txtp.max_pcr, qos->txtp.max_cdv, qos->txtp.max_sdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	    fore200e_traffic_class[ qos->rxtp.traffic_class ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	    qos->rxtp.min_pcr, qos->rxtp.max_pcr, qos->rxtp.max_cdv, qos->rxtp.max_sdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	    flags, fore200e->available_cell_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)     if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	mutex_lock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 	if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	    mutex_unlock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	    return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	fore200e->available_cell_rate -= qos->txtp.max_pcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	mutex_unlock(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 	memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	/* update rate control parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	fore200e_rate_ctrl(qos, &fore200e_vcc->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	set_bit(ATM_VF_HASQOS, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)     return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) static int fore200e_irq_request(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)     if (request_irq(fore200e->irq, fore200e_interrupt, IRQF_SHARED, fore200e->name, fore200e->atm_dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	printk(FORE200E "unable to reserve IRQ %s for device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 	       fore200e_irq_itoa(fore200e->irq), fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 	return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)     printk(FORE200E "IRQ %s reserved for device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 	   fore200e_irq_itoa(fore200e->irq), fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) #ifdef FORE200E_USE_TASKLET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)     tasklet_init(&fore200e->tx_tasklet, fore200e_tx_tasklet, (unsigned long)fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)     tasklet_init(&fore200e->rx_tasklet, fore200e_rx_tasklet, (unsigned long)fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)     fore200e->state = FORE200E_STATE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) static int fore200e_get_esi(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)     struct prom_data* prom = kzalloc(sizeof(struct prom_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)     int ok, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)     if (!prom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)     ok = fore200e->bus->prom_read(fore200e, prom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)     if (ok < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	kfree(prom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 	return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)     printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	   fore200e->name, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	   (prom->hw_revision & 0xFF) + '@',    /* probably meaningless with SBA boards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	   prom->serial_number & 0xFFFF, &prom->mac_addr[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)     for (i = 0; i < ESI_LEN; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)     kfree(prom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) static int fore200e_alloc_rx_buf(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)     int scheme, magn, nbr, size, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)     struct host_bsq* bsq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)     struct buffer*   buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)     for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 	    nbr  = fore200e_rx_buf_nbr[ scheme ][ magn ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	    size = fore200e_rx_buf_size[ scheme ][ magn ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 	    DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 	    /* allocate the array of receive buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	    buffer = bsq->buffer = kcalloc(nbr, sizeof(struct buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)                                            GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	    if (buffer == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	    bsq->freebuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 	    for (i = 0; i < nbr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 		buffer[ i ].scheme = scheme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 		buffer[ i ].magn   = magn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) #ifdef FORE200E_BSQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 		buffer[ i ].index  = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 		buffer[ i ].supplied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 		/* allocate the receive buffer body */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 		if (fore200e_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 					 &buffer[ i ].data, size, fore200e->bus->buffer_alignment,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 					 DMA_FROM_DEVICE) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 		    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 		    while (i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 			fore200e_chunk_free(fore200e, &buffer[ --i ].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 		    kfree(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 		    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		    return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 		/* insert the buffer into the free buffer list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		buffer[ i ].next = bsq->freebuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		bsq->freebuf = &buffer[ i ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	    /* all the buffers are free, initially */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	    bsq->freebuf_count = nbr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) #ifdef FORE200E_BSQ_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	    bsq_audit(3, bsq, scheme, magn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)     fore200e->state = FORE200E_STATE_ALLOC_BUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) static int fore200e_init_bs_queue(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)     int scheme, magn, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)     struct host_bsq*     bsq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)     struct cp_bsq_entry __iomem * cp_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)     for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	    DPRINTK(2, "buffer supply queue %d / %d is being initialized\n", scheme, magn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	    /* allocate and align the array of status words */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	    if (fore200e_dma_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 					       &bsq->status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 					       sizeof(enum status), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 					       QUEUE_SIZE_BS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 					       fore200e->bus->status_alignment) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	    /* allocate and align the array of receive buffer descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	    if (fore200e_dma_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 					       &bsq->rbd_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 					       sizeof(struct rbd_block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 					       QUEUE_SIZE_BS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 					       fore200e->bus->descr_alignment) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 		fore200e_dma_chunk_free(fore200e, &bsq->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	    /* get the base address of the cp resident buffer supply queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	    cp_entry = fore200e->virt_base + 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 		       fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	    
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	    /* fill the host resident and cp resident buffer supply queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	    for (i = 0; i < QUEUE_SIZE_BS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		bsq->host_entry[ i ].status = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 		                     FORE200E_INDEX(bsq->status.align_addr, enum status, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	        bsq->host_entry[ i ].rbd_block =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		                     FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 		bsq->host_entry[ i ].rbd_block_dma =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		                     FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 		bsq->host_entry[ i ].cp_entry = &cp_entry[ i ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 		*bsq->host_entry[ i ].status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 				     &cp_entry[ i ].status_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	    }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106)     fore200e->state = FORE200E_STATE_INIT_BSQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) static int fore200e_init_rx_queue(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)     struct host_rxq*     rxq =  &fore200e->host_rxq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114)     struct cp_rxq_entry __iomem * cp_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115)     int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)     DPRINTK(2, "receive queue is being initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)     /* allocate and align the array of status words */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)     if (fore200e_dma_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 				       &rxq->status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 				       sizeof(enum status), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 				       QUEUE_SIZE_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 				       fore200e->bus->status_alignment) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)     /* allocate and align the array of receive PDU descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)     if (fore200e_dma_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 				       &rxq->rpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 				       sizeof(struct rpd), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 				       QUEUE_SIZE_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 				       fore200e->bus->descr_alignment) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	fore200e_dma_chunk_free(fore200e, &rxq->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)     /* get the base address of the cp resident rx queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)     cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_rxq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)     /* fill the host resident and cp resident rx entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)     for (i=0; i < QUEUE_SIZE_RX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	rxq->host_entry[ i ].status = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	                     FORE200E_INDEX(rxq->status.align_addr, enum status, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 	rxq->host_entry[ i ].rpd = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	                     FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	rxq->host_entry[ i ].rpd_dma = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 	                     FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	rxq->host_entry[ i ].cp_entry = &cp_entry[ i ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	*rxq->host_entry[ i ].status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->status.dma_addr, enum status, i), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 			     &cp_entry[ i ].status_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 			     &cp_entry[ i ].rpd_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)     /* set the head entry of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)     rxq->head = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)     fore200e->state = FORE200E_STATE_INIT_RXQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) static int fore200e_init_tx_queue(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)     struct host_txq*     txq =  &fore200e->host_txq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)     struct cp_txq_entry __iomem * cp_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)     int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)     DPRINTK(2, "transmit queue is being initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)     /* allocate and align the array of status words */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)     if (fore200e_dma_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 				       &txq->status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 				       sizeof(enum status), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 				       QUEUE_SIZE_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 				       fore200e->bus->status_alignment) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)     /* allocate and align the array of transmit PDU descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)     if (fore200e_dma_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 				       &txq->tpd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 				       sizeof(struct tpd), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 				       QUEUE_SIZE_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 				       fore200e->bus->descr_alignment) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	fore200e_dma_chunk_free(fore200e, &txq->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)     /* get the base address of the cp resident tx queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)     cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_txq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)     /* fill the host resident and cp resident tx entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)     for (i=0; i < QUEUE_SIZE_TX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	txq->host_entry[ i ].status = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	                     FORE200E_INDEX(txq->status.align_addr, enum status, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	txq->host_entry[ i ].tpd = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	                     FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	txq->host_entry[ i ].tpd_dma  = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)                              FORE200E_DMA_INDEX(txq->tpd.dma_addr, struct tpd, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	txq->host_entry[ i ].cp_entry = &cp_entry[ i ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	*txq->host_entry[ i ].status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	fore200e->bus->write(FORE200E_DMA_INDEX(txq->status.dma_addr, enum status, i), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 			     &cp_entry[ i ].status_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)         /* although there is a one-to-one mapping of tx queue entries and tpds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	   we do not write here the DMA (physical) base address of each tpd into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	   the related cp resident entry, because the cp relies on this write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 	   operation to detect that a new pdu has been submitted for tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)     /* set the head and tail entries of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)     txq->head = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)     txq->tail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)     fore200e->state = FORE200E_STATE_INIT_TXQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) static int fore200e_init_cmd_queue(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)     struct host_cmdq*     cmdq =  &fore200e->host_cmdq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235)     struct cp_cmdq_entry __iomem * cp_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)     int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)     DPRINTK(2, "command queue is being initialized\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)     /* allocate and align the array of status words */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241)     if (fore200e_dma_chunk_alloc(fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 				       &cmdq->status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 				       sizeof(enum status), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 				       QUEUE_SIZE_CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 				       fore200e->bus->status_alignment) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 	return -ENOMEM;
^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)     /* get the base address of the cp resident cmd queue entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)     cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_cmdq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)     /* fill the host resident and cp resident cmd entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)     for (i=0; i < QUEUE_SIZE_CMD; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	cmdq->host_entry[ i ].status   = 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)                               FORE200E_INDEX(cmdq->status.align_addr, enum status, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	*cmdq->host_entry[ i ].status = STATUS_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, enum status, i), 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)                              &cp_entry[ i ].status_haddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)     /* set the head entry of the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)     cmdq->head = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)     fore200e->state = FORE200E_STATE_INIT_CMDQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)     return 0;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) static void fore200e_param_bs_queue(struct fore200e *fore200e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 				    enum buffer_scheme scheme,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 				    enum buffer_magn magn, int queue_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 				    int pool_size, int supply_blksize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)     struct bs_spec __iomem * bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)     fore200e->bus->write(queue_length,                           &bs_spec->queue_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)     fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)     fore200e->bus->write(pool_size,                              &bs_spec->pool_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)     fore200e->bus->write(supply_blksize,                         &bs_spec->supply_blksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) static int fore200e_initialize(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)     struct cp_queues __iomem * cpq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)     int               ok, scheme, magn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)     DPRINTK(2, "device %s being initialized\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)     mutex_init(&fore200e->rate_mtx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)     spin_lock_init(&fore200e->q_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)     cpq = fore200e->cp_queues = fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)     /* enable cp to host interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)     fore200e->bus->write(1, &cpq->imask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)     if (fore200e->bus->irq_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	fore200e->bus->irq_enable(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)     fore200e->bus->write(NBR_CONNECT, &cpq->init.num_connect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)     fore200e->bus->write(QUEUE_SIZE_CMD, &cpq->init.cmd_queue_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)     fore200e->bus->write(QUEUE_SIZE_RX,  &cpq->init.rx_queue_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)     fore200e->bus->write(QUEUE_SIZE_TX,  &cpq->init.tx_queue_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)     fore200e->bus->write(RSD_EXTENSION,  &cpq->init.rsd_extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)     fore200e->bus->write(TSD_EXTENSION,  &cpq->init.tsd_extension);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314)     for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	    fore200e_param_bs_queue(fore200e, scheme, magn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 				    QUEUE_SIZE_BS, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 				    fore200e_rx_buf_nbr[ scheme ][ magn ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 				    RBD_BLK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)     /* issue the initialize command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)     fore200e->bus->write(STATUS_PENDING,    &cpq->init.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)     fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)     ok = fore200e_io_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326)     if (ok == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	printk(FORE200E "device %s initialization failed\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)     printk(FORE200E "device %s initialized\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)     fore200e->state = FORE200E_STATE_INITIALIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) static void fore200e_monitor_putc(struct fore200e *fore200e, char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)     struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)     printk("%c", c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)     fore200e->bus->write(((u32) c) | FORE200E_CP_MONITOR_UART_AVAIL, &monitor->soft_uart.send);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) static int fore200e_monitor_getc(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)     struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)     unsigned long      timeout = jiffies + msecs_to_jiffies(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)     int                c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)     while (time_before(jiffies, timeout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	c = (int) fore200e->bus->read(&monitor->soft_uart.recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	if (c & FORE200E_CP_MONITOR_UART_AVAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	    fore200e->bus->write(FORE200E_CP_MONITOR_UART_FREE, &monitor->soft_uart.recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	    printk("%c", c & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	    return c & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)     return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) }
^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) static void fore200e_monitor_puts(struct fore200e *fore200e, char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)     while (*str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 	/* the i960 monitor doesn't accept any new character if it has something to say */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	while (fore200e_monitor_getc(fore200e) >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	fore200e_monitor_putc(fore200e, *str++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)     while (fore200e_monitor_getc(fore200e) >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) #define FW_EXT ".bin"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) #define FW_EXT "_ecd.bin2"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) static int fore200e_load_and_start_fw(struct fore200e *fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394)     const struct firmware *firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)     const struct fw_header *fw_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)     const __le32 *fw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)     u32 fw_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398)     u32 __iomem *load_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)     char buf[48];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)     int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)     sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)     if ((err = request_firmware(&firmware, buf, fore200e->dev)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)     fw_data = (const __le32 *)firmware->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)     fw_size = firmware->size / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410)     fw_header = (const struct fw_header *)firmware->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)     load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413)     DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	    fore200e->name, load_addr, fw_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416)     if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)     for (; fw_size--; fw_data++, load_addr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)     DPRINTK(2, "device %s firmware being started\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) #if defined(__sparc_v9__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)     /* reported to be required by SBA cards on some sparc64 hosts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)     fore200e_spin(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431)     sprintf(buf, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)     fore200e_monitor_puts(fore200e, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)     if (fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 	printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	goto release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439)     printk(FORE200E "device %s firmware started\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)     fore200e->state = FORE200E_STATE_START_FW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)     err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)     release_firmware(firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)     return err;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) static int fore200e_register(struct fore200e *fore200e, struct device *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452)     struct atm_dev* atm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)     DPRINTK(2, "device %s being registered\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)     atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)                                -1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458)     if (atm_dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	printk(FORE200E "unable to register device %s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463)     atm_dev->dev_data = fore200e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)     fore200e->atm_dev = atm_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)     atm_dev->ci_range.vpi_bits = FORE200E_VPI_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)     atm_dev->ci_range.vci_bits = FORE200E_VCI_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)     fore200e->available_cell_rate = ATM_OC3_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)     fore200e->state = FORE200E_STATE_REGISTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) static int fore200e_init(struct fore200e *fore200e, struct device *parent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478)     if (fore200e_register(fore200e, parent) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)     if (fore200e->bus->configure(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)     if (fore200e->bus->map(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)     if (fore200e_reset(fore200e, 1) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)     if (fore200e_load_and_start_fw(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)     if (fore200e_initialize(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)     if (fore200e_init_cmd_queue(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)     if (fore200e_init_tx_queue(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502)     if (fore200e_init_rx_queue(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505)     if (fore200e_init_bs_queue(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508)     if (fore200e_alloc_rx_buf(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)     if (fore200e_get_esi(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)     if (fore200e_irq_request(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)     fore200e_supply(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)     /* all done, board initialization is now complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)     fore200e->state = FORE200E_STATE_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) #ifdef CONFIG_SBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) static const struct of_device_id fore200e_sba_match[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) static int fore200e_sba_probe(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 	const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	struct fore200e *fore200e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	static int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 	match = of_match_device(fore200e_sba_match, &op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	if (!fore200e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	fore200e->bus = &fore200e_sbus_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 	fore200e->dev = &op->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	fore200e->irq = op->archdata.irqs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 	fore200e->phys_base = op->resource[0].start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 	sprintf(fore200e->name, "SBA-200E-%d", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	err = fore200e_init(fore200e, &op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 		fore200e_shutdown(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		kfree(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	dev_set_drvdata(&op->dev, fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) static int fore200e_sba_remove(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	struct fore200e *fore200e = dev_get_drvdata(&op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	fore200e_shutdown(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 	kfree(fore200e);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) static const struct of_device_id fore200e_sba_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 		.name = SBA200E_PROM_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) MODULE_DEVICE_TABLE(of, fore200e_sba_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) static struct platform_driver fore200e_sba_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 		.name = "fore_200e",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 		.of_match_table = fore200e_sba_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	.probe		= fore200e_sba_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	.remove		= fore200e_sba_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) static int fore200e_pca_detect(struct pci_dev *pci_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 			       const struct pci_device_id *pci_ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)     struct fore200e* fore200e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)     int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)     static int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)     if (pci_enable_device(pci_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)     if (dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)     fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)     if (fore200e == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 	err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 	goto out_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)     fore200e->bus       = &fore200e_pci_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)     fore200e->dev	= &pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)     fore200e->irq       = pci_dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)     fore200e->phys_base = pci_resource_start(pci_dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)     sprintf(fore200e->name, "PCA-200E-%d", index - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)     pci_set_master(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)     printk(FORE200E "device PCA-200E found at 0x%lx, IRQ %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	   fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)     sprintf(fore200e->name, "PCA-200E-%d", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)     err = fore200e_init(fore200e, &pci_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)     if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	fore200e_shutdown(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)     ++index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)     pci_set_drvdata(pci_dev, fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)     return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640)     kfree(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) out_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642)     pci_disable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)     goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) static void fore200e_pca_remove_one(struct pci_dev *pci_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649)     struct fore200e *fore200e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)     fore200e = pci_get_drvdata(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)     fore200e_shutdown(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)     kfree(fore200e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655)     pci_disable_device(pci_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) static const struct pci_device_id fore200e_pca_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)     { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)     { 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) MODULE_DEVICE_TABLE(pci, fore200e_pca_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) static struct pci_driver fore200e_pca_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)     .name =     "fore_200e",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)     .probe =    fore200e_pca_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669)     .remove =   fore200e_pca_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)     .id_table = fore200e_pca_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) static int __init fore200e_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) #ifdef CONFIG_SBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	err = platform_driver_register(&fore200e_sba_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	err = pci_register_driver(&fore200e_pca_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) #ifdef CONFIG_SBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 		platform_driver_unregister(&fore200e_sba_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) static void __exit fore200e_module_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 	pci_unregister_driver(&fore200e_pca_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) #ifdef CONFIG_SBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	platform_driver_unregister(&fore200e_sba_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)     struct fore200e*     fore200e  = FORE200E_DEV(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)     struct fore200e_vcc* fore200e_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)     struct atm_vcc*      vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)     int                  i, len, left = *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)     unsigned long        flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)     if (!left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	if (fore200e_getstats(fore200e) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	    return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 	len = sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 		       " device:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 		       "   internal name:\t\t%s\n", fore200e->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 	/* print bus-specific information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 	if (fore200e->bus->proc_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	    len += fore200e->bus->proc_read(fore200e, page + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	len += sprintf(page + len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 		"   interrupt line:\t\t%s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		"   physical base address:\t0x%p\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 		"   virtual base address:\t0x%p\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 		"   factory address (ESI):\t%pM\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 		"   board serial number:\t\t%d\n\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 		fore200e_irq_itoa(fore200e->irq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 		(void*)fore200e->phys_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 		fore200e->virt_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 		fore200e->esi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 		fore200e->esi[4] * 256 + fore200e->esi[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 	return sprintf(page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 		       "   free small bufs, scheme 1:\t%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 		       "   free large bufs, scheme 1:\t%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		       "   free small bufs, scheme 2:\t%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 		       "   free large bufs, scheme 2:\t%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].freebuf_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].freebuf_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].freebuf_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].freebuf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)     if (!left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	len = sprintf(page,"\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		      " cell processor:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 		      "   heartbeat state:\t\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	if (hb >> 16 != 0xDEAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	    len += sprintf(page + len, "0x%08x\n", hb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	    len += sprintf(page + len, "*** FATAL ERROR %04x ***\n", hb & 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)     if (!left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 	static const char* media_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	    "unshielded twisted pair",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	    "multimode optical fiber ST",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 	    "multimode optical fiber SC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	    "single-mode optical fiber ST",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	    "single-mode optical fiber SC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	    "unknown"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	static const char* oc3_mode[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	    "normal operation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	    "diagnostic loopback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	    "line loopback",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	    "unknown"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	u32 fw_release     = fore200e->bus->read(&fore200e->cp_queues->fw_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 	u32 mon960_release = fore200e->bus->read(&fore200e->cp_queues->mon960_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	u32 oc3_revision   = fore200e->bus->read(&fore200e->cp_queues->oc3_revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	u32 media_index    = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	u32 oc3_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 	if (media_index > 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 		media_index = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	switch (fore200e->loop_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	    case ATM_LM_NONE:    oc3_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 		                 break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	    case ATM_LM_LOC_PHY: oc3_index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 		                 break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	    case ATM_LM_RMT_PHY: oc3_index = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 		                 break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	    default:             oc3_index = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	return sprintf(page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 		       "   firmware release:\t\t%d.%d.%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		       "   monitor release:\t\t%d.%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 		       "   media type:\t\t\t%s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 		       "   OC-3 revision:\t\t0x%x\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)                        "   OC-3 mode:\t\t\t%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 		       fw_release >> 16, fw_release << 16 >> 24,  fw_release << 24 >> 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 		       mon960_release >> 16, mon960_release << 16 >> 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		       media_name[ media_index ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 		       oc3_revision,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 		       oc3_mode[ oc3_index ]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)     if (!left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	struct cp_monitor __iomem * cp_monitor = fore200e->cp_monitor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	return sprintf(page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 		       "\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 		       " monitor:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		       "   version number:\t\t%d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		       "   boot status word:\t\t0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 		       fore200e->bus->read(&cp_monitor->mon_version),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		       fore200e->bus->read(&cp_monitor->bstat));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	return sprintf(page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 		       "\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		       " device statistics:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		       "  4b5b:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 		       "     crc_header_errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 		       "     framing_errors:\t\t%10u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 		       be32_to_cpu(fore200e->stats->phy.crc_header_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 		       be32_to_cpu(fore200e->stats->phy.framing_errors));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	return sprintf(page, "\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 		       "  OC-3:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 		       "     section_bip8_errors:\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 		       "     path_bip8_errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		       "     line_bip24_errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 		       "     line_febe_errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 		       "     path_febe_errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 		       "     corr_hcs_errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 		       "     ucorr_hcs_errors:\t\t%10u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		       be32_to_cpu(fore200e->stats->oc3.section_bip8_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 		       be32_to_cpu(fore200e->stats->oc3.path_bip8_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 		       be32_to_cpu(fore200e->stats->oc3.line_bip24_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		       be32_to_cpu(fore200e->stats->oc3.line_febe_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 		       be32_to_cpu(fore200e->stats->oc3.path_febe_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		       be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 		       be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	return sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 		       "   ATM:\t\t\t\t     cells\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 		       "     TX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 		       "     RX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 		       "     vpi out of range:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 		       "     vpi no conn:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 		       "     vci out of range:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		       "     vci no conn:\t\t%10u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 		       be32_to_cpu(fore200e->stats->atm.cells_transmitted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 		       be32_to_cpu(fore200e->stats->atm.cells_received),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 		       be32_to_cpu(fore200e->stats->atm.vpi_bad_range),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 		       be32_to_cpu(fore200e->stats->atm.vpi_no_conn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 		       be32_to_cpu(fore200e->stats->atm.vci_bad_range),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		       be32_to_cpu(fore200e->stats->atm.vci_no_conn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 	return sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 		       "   AAL0:\t\t\t     cells\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 		       "     TX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 		       "     RX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		       "     dropped:\t\t\t%10u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 		       be32_to_cpu(fore200e->stats->aal0.cells_transmitted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 		       be32_to_cpu(fore200e->stats->aal0.cells_received),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 		       be32_to_cpu(fore200e->stats->aal0.cells_dropped));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	return sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 		       "   AAL3/4:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 		       "     SAR sublayer:\t\t     cells\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 		       "       TX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 		       "       RX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 		       "       dropped:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 		       "       CRC errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 		       "       protocol errors:\t\t%10u\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 		       "     CS  sublayer:\t\t      PDUs\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 		       "       TX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 		       "       RX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 		       "       dropped:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 		       "       protocol errors:\t\t%10u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 		       be32_to_cpu(fore200e->stats->aal34.cells_transmitted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		       be32_to_cpu(fore200e->stats->aal34.cells_received),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 		       be32_to_cpu(fore200e->stats->aal34.cells_dropped),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 		       be32_to_cpu(fore200e->stats->aal34.cells_crc_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		       be32_to_cpu(fore200e->stats->aal34.cells_protocol_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 		       be32_to_cpu(fore200e->stats->aal34.cspdus_transmitted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 		       be32_to_cpu(fore200e->stats->aal34.cspdus_received),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 		       be32_to_cpu(fore200e->stats->aal34.cspdus_dropped),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 		       be32_to_cpu(fore200e->stats->aal34.cspdus_protocol_errors));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	return sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 		       "   AAL5:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 		       "     SAR sublayer:\t\t     cells\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 		       "       TX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		       "       RX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		       "       dropped:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		       "       congestions:\t\t%10u\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 		       "     CS  sublayer:\t\t      PDUs\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 		       "       TX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 		       "       RX:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 		       "       dropped:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 		       "       CRC errors:\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 		       "       protocol errors:\t\t%10u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 		       be32_to_cpu(fore200e->stats->aal5.cells_transmitted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 		       be32_to_cpu(fore200e->stats->aal5.cells_received),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 		       be32_to_cpu(fore200e->stats->aal5.cells_dropped),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 		       be32_to_cpu(fore200e->stats->aal5.congestion_experienced),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 		       be32_to_cpu(fore200e->stats->aal5.cspdus_transmitted),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 		       be32_to_cpu(fore200e->stats->aal5.cspdus_received),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		       be32_to_cpu(fore200e->stats->aal5.cspdus_dropped),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 		       be32_to_cpu(fore200e->stats->aal5.cspdus_crc_errors),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 		       be32_to_cpu(fore200e->stats->aal5.cspdus_protocol_errors));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	return sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		       "   AUX:\t\t       allocation failures\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		       "     small b1:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 		       "     large b1:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 		       "     small b2:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 		       "     large b2:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		       "     RX PDUs:\t\t\t%10u\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		       "     TX PDUs:\t\t\t%10lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 		       be32_to_cpu(fore200e->stats->aux.small_b1_failed),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 		       be32_to_cpu(fore200e->stats->aux.large_b1_failed),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 		       be32_to_cpu(fore200e->stats->aux.small_b2_failed),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 		       be32_to_cpu(fore200e->stats->aux.large_b2_failed),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 		       be32_to_cpu(fore200e->stats->aux.rpd_alloc_failed),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 		       fore200e->tx_sat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950)     if (!left--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	return sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 		       " receive carrier:\t\t\t%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 		       fore200e->stats->aux.receive_carrier ? "ON" : "OFF!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955)     if (!left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)         return sprintf(page,"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 		       " VCCs:\n  address   VPI VCI   AAL "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 		       "TX PDUs   TX min/max size  RX PDUs   RX min/max size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)     for (i = 0; i < NBR_CONNECT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 	vcc = fore200e->vc_map[i].vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	if (vcc == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	    continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	spin_lock_irqsave(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	if (vcc && test_bit(ATM_VF_READY, &vcc->flags) && !left--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 	    fore200e_vcc = FORE200E_VCC(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	    ASSERT(fore200e_vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 	    len = sprintf(page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 			  "  %pK  %03d %05d %1d   %09lu %05d/%05d      %09lu %05d/%05d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 			  vcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 			  vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 			  fore200e_vcc->tx_pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 			  fore200e_vcc->tx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->tx_min_pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 			  fore200e_vcc->tx_max_pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 			  fore200e_vcc->rx_pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 			  fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 			  fore200e_vcc->rx_max_pdu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	    spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	    return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	spin_unlock_irqrestore(&fore200e->q_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993)     return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) module_init(fore200e_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) module_exit(fore200e_module_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) static const struct atmdev_ops fore200e_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	.open       = fore200e_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	.close      = fore200e_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	.ioctl      = fore200e_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	.send       = fore200e_send,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	.change_qos = fore200e_change_qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	.proc_read  = fore200e_proc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 	.owner      = THIS_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) #ifdef __LITTLE_ENDIAN__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) MODULE_FIRMWARE("pca200e.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) MODULE_FIRMWARE("pca200e_ecd.bin2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) #endif /* CONFIG_PCI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) #ifdef CONFIG_SBUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) MODULE_FIRMWARE("sba200e_ecd.bin2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) #endif