1*6b40aba3SKrzysztof Hałasa /* 2*6b40aba3SKrzysztof Hałasa * Hitachi SCA HD64570 and HD64572 common driver for Linux 3*6b40aba3SKrzysztof Hałasa * 4*6b40aba3SKrzysztof Hałasa * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl> 5*6b40aba3SKrzysztof Hałasa * 6*6b40aba3SKrzysztof Hałasa * This program is free software; you can redistribute it and/or modify it 7*6b40aba3SKrzysztof Hałasa * under the terms of version 2 of the GNU General Public License 8*6b40aba3SKrzysztof Hałasa * as published by the Free Software Foundation. 9*6b40aba3SKrzysztof Hałasa * 10*6b40aba3SKrzysztof Hałasa * Sources of information: 11*6b40aba3SKrzysztof Hałasa * Hitachi HD64570 SCA User's Manual 12*6b40aba3SKrzysztof Hałasa * Hitachi HD64572 SCA-II User's Manual 13*6b40aba3SKrzysztof Hałasa * 14*6b40aba3SKrzysztof Hałasa * We use the following SCA memory map: 15*6b40aba3SKrzysztof Hałasa * 16*6b40aba3SKrzysztof Hałasa * Packet buffer descriptor rings - starting from winbase or win0base: 17*6b40aba3SKrzysztof Hałasa * rx_ring_buffers * sizeof(pkt_desc) = logical channel #0 RX ring 18*6b40aba3SKrzysztof Hałasa * tx_ring_buffers * sizeof(pkt_desc) = logical channel #0 TX ring 19*6b40aba3SKrzysztof Hałasa * rx_ring_buffers * sizeof(pkt_desc) = logical channel #1 RX ring (if used) 20*6b40aba3SKrzysztof Hałasa * tx_ring_buffers * sizeof(pkt_desc) = logical channel #1 TX ring (if used) 21*6b40aba3SKrzysztof Hałasa * 22*6b40aba3SKrzysztof Hałasa * Packet data buffers - starting from winbase + buff_offset: 23*6b40aba3SKrzysztof Hałasa * rx_ring_buffers * HDLC_MAX_MRU = logical channel #0 RX buffers 24*6b40aba3SKrzysztof Hałasa * tx_ring_buffers * HDLC_MAX_MRU = logical channel #0 TX buffers 25*6b40aba3SKrzysztof Hałasa * rx_ring_buffers * HDLC_MAX_MRU = logical channel #0 RX buffers (if used) 26*6b40aba3SKrzysztof Hałasa * tx_ring_buffers * HDLC_MAX_MRU = logical channel #0 TX buffers (if used) 27*6b40aba3SKrzysztof Hałasa */ 28*6b40aba3SKrzysztof Hałasa 29*6b40aba3SKrzysztof Hałasa #include <linux/module.h> 30*6b40aba3SKrzysztof Hałasa #include <linux/kernel.h> 31*6b40aba3SKrzysztof Hałasa #include <linux/slab.h> 32*6b40aba3SKrzysztof Hałasa #include <linux/jiffies.h> 33*6b40aba3SKrzysztof Hałasa #include <linux/types.h> 34*6b40aba3SKrzysztof Hałasa #include <linux/fcntl.h> 35*6b40aba3SKrzysztof Hałasa #include <linux/interrupt.h> 36*6b40aba3SKrzysztof Hałasa #include <linux/in.h> 37*6b40aba3SKrzysztof Hałasa #include <linux/string.h> 38*6b40aba3SKrzysztof Hałasa #include <linux/errno.h> 39*6b40aba3SKrzysztof Hałasa #include <linux/init.h> 40*6b40aba3SKrzysztof Hałasa #include <linux/ioport.h> 41*6b40aba3SKrzysztof Hałasa #include <linux/bitops.h> 42*6b40aba3SKrzysztof Hałasa 43*6b40aba3SKrzysztof Hałasa #include <asm/system.h> 44*6b40aba3SKrzysztof Hałasa #include <asm/uaccess.h> 45*6b40aba3SKrzysztof Hałasa #include <asm/io.h> 46*6b40aba3SKrzysztof Hałasa 47*6b40aba3SKrzysztof Hałasa #include <linux/netdevice.h> 48*6b40aba3SKrzysztof Hałasa #include <linux/skbuff.h> 49*6b40aba3SKrzysztof Hałasa 50*6b40aba3SKrzysztof Hałasa #include <linux/hdlc.h> 51*6b40aba3SKrzysztof Hałasa 52*6b40aba3SKrzysztof Hałasa #if (!defined (__HD64570_H) && !defined (__HD64572_H)) || \ 53*6b40aba3SKrzysztof Hałasa (defined (__HD64570_H) && defined (__HD64572_H)) 54*6b40aba3SKrzysztof Hałasa #error Either hd64570.h or hd64572.h must be included 55*6b40aba3SKrzysztof Hałasa #endif 56*6b40aba3SKrzysztof Hałasa 57*6b40aba3SKrzysztof Hałasa #define get_msci(port) (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) 58*6b40aba3SKrzysztof Hałasa #define get_dmac_rx(port) (phy_node(port) ? DMAC1RX_OFFSET : DMAC0RX_OFFSET) 59*6b40aba3SKrzysztof Hałasa #define get_dmac_tx(port) (phy_node(port) ? DMAC1TX_OFFSET : DMAC0TX_OFFSET) 60*6b40aba3SKrzysztof Hałasa 61*6b40aba3SKrzysztof Hałasa #define SCA_INTR_MSCI(node) (node ? 0x10 : 0x01) 62*6b40aba3SKrzysztof Hałasa #define SCA_INTR_DMAC_RX(node) (node ? 0x20 : 0x02) 63*6b40aba3SKrzysztof Hałasa #define SCA_INTR_DMAC_TX(node) (node ? 0x40 : 0x04) 64*6b40aba3SKrzysztof Hałasa 65*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H /* HD64570 */ 66*6b40aba3SKrzysztof Hałasa #define sca_outa(value, reg, card) sca_outw(value, reg, card) 67*6b40aba3SKrzysztof Hałasa #define sca_ina(reg, card) sca_inw(reg, card) 68*6b40aba3SKrzysztof Hałasa #define writea(value, ptr) writew(value, ptr) 69*6b40aba3SKrzysztof Hałasa 70*6b40aba3SKrzysztof Hałasa #else /* HD64572 */ 71*6b40aba3SKrzysztof Hałasa #define sca_outa(value, reg, card) sca_outl(value, reg, card) 72*6b40aba3SKrzysztof Hałasa #define sca_ina(reg, card) sca_inl(reg, card) 73*6b40aba3SKrzysztof Hałasa #define writea(value, ptr) writel(value, ptr) 74*6b40aba3SKrzysztof Hałasa #endif 75*6b40aba3SKrzysztof Hałasa 76*6b40aba3SKrzysztof Hałasa static inline struct net_device *port_to_dev(port_t *port) 77*6b40aba3SKrzysztof Hałasa { 78*6b40aba3SKrzysztof Hałasa return port->dev; 79*6b40aba3SKrzysztof Hałasa } 80*6b40aba3SKrzysztof Hałasa 81*6b40aba3SKrzysztof Hałasa static inline int sca_intr_status(card_t *card) 82*6b40aba3SKrzysztof Hałasa { 83*6b40aba3SKrzysztof Hałasa u8 result = 0; 84*6b40aba3SKrzysztof Hałasa 85*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H /* HD64570 */ 86*6b40aba3SKrzysztof Hałasa u8 isr0 = sca_in(ISR0, card); 87*6b40aba3SKrzysztof Hałasa u8 isr1 = sca_in(ISR1, card); 88*6b40aba3SKrzysztof Hałasa 89*6b40aba3SKrzysztof Hałasa if (isr1 & 0x03) result |= SCA_INTR_DMAC_RX(0); 90*6b40aba3SKrzysztof Hałasa if (isr1 & 0x0C) result |= SCA_INTR_DMAC_TX(0); 91*6b40aba3SKrzysztof Hałasa if (isr1 & 0x30) result |= SCA_INTR_DMAC_RX(1); 92*6b40aba3SKrzysztof Hałasa if (isr1 & 0xC0) result |= SCA_INTR_DMAC_TX(1); 93*6b40aba3SKrzysztof Hałasa if (isr0 & 0x0F) result |= SCA_INTR_MSCI(0); 94*6b40aba3SKrzysztof Hałasa if (isr0 & 0xF0) result |= SCA_INTR_MSCI(1); 95*6b40aba3SKrzysztof Hałasa 96*6b40aba3SKrzysztof Hałasa #else /* HD64572 */ 97*6b40aba3SKrzysztof Hałasa u32 isr0 = sca_inl(ISR0, card); 98*6b40aba3SKrzysztof Hałasa 99*6b40aba3SKrzysztof Hałasa if (isr0 & 0x0000000F) result |= SCA_INTR_DMAC_RX(0); 100*6b40aba3SKrzysztof Hałasa if (isr0 & 0x000000F0) result |= SCA_INTR_DMAC_TX(0); 101*6b40aba3SKrzysztof Hałasa if (isr0 & 0x00000F00) result |= SCA_INTR_DMAC_RX(1); 102*6b40aba3SKrzysztof Hałasa if (isr0 & 0x0000F000) result |= SCA_INTR_DMAC_TX(1); 103*6b40aba3SKrzysztof Hałasa if (isr0 & 0x003E0000) result |= SCA_INTR_MSCI(0); 104*6b40aba3SKrzysztof Hałasa if (isr0 & 0x3E000000) result |= SCA_INTR_MSCI(1); 105*6b40aba3SKrzysztof Hałasa 106*6b40aba3SKrzysztof Hałasa #endif /* HD64570 vs HD64572 */ 107*6b40aba3SKrzysztof Hałasa 108*6b40aba3SKrzysztof Hałasa if (!(result & SCA_INTR_DMAC_TX(0))) 109*6b40aba3SKrzysztof Hałasa if (sca_in(DSR_TX(0), card) & DSR_EOM) 110*6b40aba3SKrzysztof Hałasa result |= SCA_INTR_DMAC_TX(0); 111*6b40aba3SKrzysztof Hałasa if (!(result & SCA_INTR_DMAC_TX(1))) 112*6b40aba3SKrzysztof Hałasa if (sca_in(DSR_TX(1), card) & DSR_EOM) 113*6b40aba3SKrzysztof Hałasa result |= SCA_INTR_DMAC_TX(1); 114*6b40aba3SKrzysztof Hałasa 115*6b40aba3SKrzysztof Hałasa return result; 116*6b40aba3SKrzysztof Hałasa } 117*6b40aba3SKrzysztof Hałasa 118*6b40aba3SKrzysztof Hałasa static inline port_t* dev_to_port(struct net_device *dev) 119*6b40aba3SKrzysztof Hałasa { 120*6b40aba3SKrzysztof Hałasa return dev_to_hdlc(dev)->priv; 121*6b40aba3SKrzysztof Hałasa } 122*6b40aba3SKrzysztof Hałasa 123*6b40aba3SKrzysztof Hałasa static inline u16 next_desc(port_t *port, u16 desc, int transmit) 124*6b40aba3SKrzysztof Hałasa { 125*6b40aba3SKrzysztof Hałasa return (desc + 1) % (transmit ? port_to_card(port)->tx_ring_buffers 126*6b40aba3SKrzysztof Hałasa : port_to_card(port)->rx_ring_buffers); 127*6b40aba3SKrzysztof Hałasa } 128*6b40aba3SKrzysztof Hałasa 129*6b40aba3SKrzysztof Hałasa 130*6b40aba3SKrzysztof Hałasa 131*6b40aba3SKrzysztof Hałasa static inline u16 desc_abs_number(port_t *port, u16 desc, int transmit) 132*6b40aba3SKrzysztof Hałasa { 133*6b40aba3SKrzysztof Hałasa u16 rx_buffs = port_to_card(port)->rx_ring_buffers; 134*6b40aba3SKrzysztof Hałasa u16 tx_buffs = port_to_card(port)->tx_ring_buffers; 135*6b40aba3SKrzysztof Hałasa 136*6b40aba3SKrzysztof Hałasa desc %= (transmit ? tx_buffs : rx_buffs); // called with "X + 1" etc. 137*6b40aba3SKrzysztof Hałasa return log_node(port) * (rx_buffs + tx_buffs) + 138*6b40aba3SKrzysztof Hałasa transmit * rx_buffs + desc; 139*6b40aba3SKrzysztof Hałasa } 140*6b40aba3SKrzysztof Hałasa 141*6b40aba3SKrzysztof Hałasa 142*6b40aba3SKrzysztof Hałasa 143*6b40aba3SKrzysztof Hałasa static inline u16 desc_offset(port_t *port, u16 desc, int transmit) 144*6b40aba3SKrzysztof Hałasa { 145*6b40aba3SKrzysztof Hałasa /* Descriptor offset always fits in 16 bytes */ 146*6b40aba3SKrzysztof Hałasa return desc_abs_number(port, desc, transmit) * sizeof(pkt_desc); 147*6b40aba3SKrzysztof Hałasa } 148*6b40aba3SKrzysztof Hałasa 149*6b40aba3SKrzysztof Hałasa 150*6b40aba3SKrzysztof Hałasa 151*6b40aba3SKrzysztof Hałasa static inline pkt_desc __iomem *desc_address(port_t *port, u16 desc, int transmit) 152*6b40aba3SKrzysztof Hałasa { 153*6b40aba3SKrzysztof Hałasa #ifdef PAGE0_ALWAYS_MAPPED 154*6b40aba3SKrzysztof Hałasa return (pkt_desc __iomem *)(win0base(port_to_card(port)) 155*6b40aba3SKrzysztof Hałasa + desc_offset(port, desc, transmit)); 156*6b40aba3SKrzysztof Hałasa #else 157*6b40aba3SKrzysztof Hałasa return (pkt_desc __iomem *)(winbase(port_to_card(port)) 158*6b40aba3SKrzysztof Hałasa + desc_offset(port, desc, transmit)); 159*6b40aba3SKrzysztof Hałasa #endif 160*6b40aba3SKrzysztof Hałasa } 161*6b40aba3SKrzysztof Hałasa 162*6b40aba3SKrzysztof Hałasa 163*6b40aba3SKrzysztof Hałasa 164*6b40aba3SKrzysztof Hałasa static inline u32 buffer_offset(port_t *port, u16 desc, int transmit) 165*6b40aba3SKrzysztof Hałasa { 166*6b40aba3SKrzysztof Hałasa return port_to_card(port)->buff_offset + 167*6b40aba3SKrzysztof Hałasa desc_abs_number(port, desc, transmit) * (u32)HDLC_MAX_MRU; 168*6b40aba3SKrzysztof Hałasa } 169*6b40aba3SKrzysztof Hałasa 170*6b40aba3SKrzysztof Hałasa 171*6b40aba3SKrzysztof Hałasa static inline void sca_set_carrier(port_t *port) 172*6b40aba3SKrzysztof Hałasa { 173*6b40aba3SKrzysztof Hałasa if (!(sca_in(get_msci(port) + ST3, port_to_card(port)) & ST3_DCD)) { 174*6b40aba3SKrzysztof Hałasa #ifdef DEBUG_LINK 175*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "%s: sca_set_carrier on\n", 176*6b40aba3SKrzysztof Hałasa port_to_dev(port)->name); 177*6b40aba3SKrzysztof Hałasa #endif 178*6b40aba3SKrzysztof Hałasa netif_carrier_on(port_to_dev(port)); 179*6b40aba3SKrzysztof Hałasa } else { 180*6b40aba3SKrzysztof Hałasa #ifdef DEBUG_LINK 181*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "%s: sca_set_carrier off\n", 182*6b40aba3SKrzysztof Hałasa port_to_dev(port)->name); 183*6b40aba3SKrzysztof Hałasa #endif 184*6b40aba3SKrzysztof Hałasa netif_carrier_off(port_to_dev(port)); 185*6b40aba3SKrzysztof Hałasa } 186*6b40aba3SKrzysztof Hałasa } 187*6b40aba3SKrzysztof Hałasa 188*6b40aba3SKrzysztof Hałasa 189*6b40aba3SKrzysztof Hałasa static void sca_init_sync_port(port_t *port) 190*6b40aba3SKrzysztof Hałasa { 191*6b40aba3SKrzysztof Hałasa card_t *card = port_to_card(port); 192*6b40aba3SKrzysztof Hałasa int transmit, i; 193*6b40aba3SKrzysztof Hałasa 194*6b40aba3SKrzysztof Hałasa port->rxin = 0; 195*6b40aba3SKrzysztof Hałasa port->txin = 0; 196*6b40aba3SKrzysztof Hałasa port->txlast = 0; 197*6b40aba3SKrzysztof Hałasa 198*6b40aba3SKrzysztof Hałasa #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) 199*6b40aba3SKrzysztof Hałasa openwin(card, 0); 200*6b40aba3SKrzysztof Hałasa #endif 201*6b40aba3SKrzysztof Hałasa 202*6b40aba3SKrzysztof Hałasa for (transmit = 0; transmit < 2; transmit++) { 203*6b40aba3SKrzysztof Hałasa u16 dmac = transmit ? get_dmac_tx(port) : get_dmac_rx(port); 204*6b40aba3SKrzysztof Hałasa u16 buffs = transmit ? card->tx_ring_buffers 205*6b40aba3SKrzysztof Hałasa : card->rx_ring_buffers; 206*6b40aba3SKrzysztof Hałasa 207*6b40aba3SKrzysztof Hałasa for (i = 0; i < buffs; i++) { 208*6b40aba3SKrzysztof Hałasa pkt_desc __iomem *desc = desc_address(port, i, transmit); 209*6b40aba3SKrzysztof Hałasa u16 chain_off = desc_offset(port, i + 1, transmit); 210*6b40aba3SKrzysztof Hałasa u32 buff_off = buffer_offset(port, i, transmit); 211*6b40aba3SKrzysztof Hałasa 212*6b40aba3SKrzysztof Hałasa writea(chain_off, &desc->cp); 213*6b40aba3SKrzysztof Hałasa writel(buff_off, &desc->bp); 214*6b40aba3SKrzysztof Hałasa writew(0, &desc->len); 215*6b40aba3SKrzysztof Hałasa writeb(0, &desc->stat); 216*6b40aba3SKrzysztof Hałasa } 217*6b40aba3SKrzysztof Hałasa 218*6b40aba3SKrzysztof Hałasa /* DMA disable - to halt state */ 219*6b40aba3SKrzysztof Hałasa sca_out(0, transmit ? DSR_TX(phy_node(port)) : 220*6b40aba3SKrzysztof Hałasa DSR_RX(phy_node(port)), card); 221*6b40aba3SKrzysztof Hałasa /* software ABORT - to initial state */ 222*6b40aba3SKrzysztof Hałasa sca_out(DCR_ABORT, transmit ? DCR_TX(phy_node(port)) : 223*6b40aba3SKrzysztof Hałasa DCR_RX(phy_node(port)), card); 224*6b40aba3SKrzysztof Hałasa 225*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 226*6b40aba3SKrzysztof Hałasa sca_out(0, dmac + CPB, card); /* pointer base */ 227*6b40aba3SKrzysztof Hałasa #endif 228*6b40aba3SKrzysztof Hałasa /* current desc addr */ 229*6b40aba3SKrzysztof Hałasa sca_outa(desc_offset(port, 0, transmit), dmac + CDAL, card); 230*6b40aba3SKrzysztof Hałasa if (!transmit) 231*6b40aba3SKrzysztof Hałasa sca_outa(desc_offset(port, buffs - 1, transmit), 232*6b40aba3SKrzysztof Hałasa dmac + EDAL, card); 233*6b40aba3SKrzysztof Hałasa else 234*6b40aba3SKrzysztof Hałasa sca_outa(desc_offset(port, 0, transmit), dmac + EDAL, 235*6b40aba3SKrzysztof Hałasa card); 236*6b40aba3SKrzysztof Hałasa 237*6b40aba3SKrzysztof Hałasa /* clear frame end interrupt counter */ 238*6b40aba3SKrzysztof Hałasa sca_out(DCR_CLEAR_EOF, transmit ? DCR_TX(phy_node(port)) : 239*6b40aba3SKrzysztof Hałasa DCR_RX(phy_node(port)), card); 240*6b40aba3SKrzysztof Hałasa 241*6b40aba3SKrzysztof Hałasa if (!transmit) { /* Receive */ 242*6b40aba3SKrzysztof Hałasa /* set buffer length */ 243*6b40aba3SKrzysztof Hałasa sca_outw(HDLC_MAX_MRU, dmac + BFLL, card); 244*6b40aba3SKrzysztof Hałasa /* Chain mode, Multi-frame */ 245*6b40aba3SKrzysztof Hałasa sca_out(0x14, DMR_RX(phy_node(port)), card); 246*6b40aba3SKrzysztof Hałasa sca_out(DIR_EOME | DIR_BOFE, DIR_RX(phy_node(port)), 247*6b40aba3SKrzysztof Hałasa card); 248*6b40aba3SKrzysztof Hałasa /* DMA enable */ 249*6b40aba3SKrzysztof Hałasa sca_out(DSR_DE, DSR_RX(phy_node(port)), card); 250*6b40aba3SKrzysztof Hałasa } else { /* Transmit */ 251*6b40aba3SKrzysztof Hałasa /* Chain mode, Multi-frame */ 252*6b40aba3SKrzysztof Hałasa sca_out(0x14, DMR_TX(phy_node(port)), card); 253*6b40aba3SKrzysztof Hałasa /* enable underflow interrupts */ 254*6b40aba3SKrzysztof Hałasa sca_out(DIR_BOFE, DIR_TX(phy_node(port)), card); 255*6b40aba3SKrzysztof Hałasa } 256*6b40aba3SKrzysztof Hałasa } 257*6b40aba3SKrzysztof Hałasa sca_set_carrier(port); 258*6b40aba3SKrzysztof Hałasa } 259*6b40aba3SKrzysztof Hałasa 260*6b40aba3SKrzysztof Hałasa 261*6b40aba3SKrzysztof Hałasa 262*6b40aba3SKrzysztof Hałasa #ifdef NEED_SCA_MSCI_INTR 263*6b40aba3SKrzysztof Hałasa /* MSCI interrupt service */ 264*6b40aba3SKrzysztof Hałasa static inline void sca_msci_intr(port_t *port) 265*6b40aba3SKrzysztof Hałasa { 266*6b40aba3SKrzysztof Hałasa u16 msci = get_msci(port); 267*6b40aba3SKrzysztof Hałasa card_t* card = port_to_card(port); 268*6b40aba3SKrzysztof Hałasa u8 stat = sca_in(msci + ST1, card); /* read MSCI ST1 status */ 269*6b40aba3SKrzysztof Hałasa 270*6b40aba3SKrzysztof Hałasa /* Reset MSCI TX underrun and CDCD status bit */ 271*6b40aba3SKrzysztof Hałasa sca_out(stat & (ST1_UDRN | ST1_CDCD), msci + ST1, card); 272*6b40aba3SKrzysztof Hałasa 273*6b40aba3SKrzysztof Hałasa if (stat & ST1_UDRN) { 274*6b40aba3SKrzysztof Hałasa /* TX Underrun error detected */ 275*6b40aba3SKrzysztof Hałasa port_to_dev(port)->stats.tx_errors++; 276*6b40aba3SKrzysztof Hałasa port_to_dev(port)->stats.tx_fifo_errors++; 277*6b40aba3SKrzysztof Hałasa } 278*6b40aba3SKrzysztof Hałasa 279*6b40aba3SKrzysztof Hałasa if (stat & ST1_CDCD) 280*6b40aba3SKrzysztof Hałasa sca_set_carrier(port); 281*6b40aba3SKrzysztof Hałasa } 282*6b40aba3SKrzysztof Hałasa #endif 283*6b40aba3SKrzysztof Hałasa 284*6b40aba3SKrzysztof Hałasa 285*6b40aba3SKrzysztof Hałasa 286*6b40aba3SKrzysztof Hałasa static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u16 rxin) 287*6b40aba3SKrzysztof Hałasa { 288*6b40aba3SKrzysztof Hałasa struct net_device *dev = port_to_dev(port); 289*6b40aba3SKrzysztof Hałasa struct sk_buff *skb; 290*6b40aba3SKrzysztof Hałasa u16 len; 291*6b40aba3SKrzysztof Hałasa u32 buff; 292*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 293*6b40aba3SKrzysztof Hałasa u32 maxlen; 294*6b40aba3SKrzysztof Hałasa u8 page; 295*6b40aba3SKrzysztof Hałasa #endif 296*6b40aba3SKrzysztof Hałasa 297*6b40aba3SKrzysztof Hałasa len = readw(&desc->len); 298*6b40aba3SKrzysztof Hałasa skb = dev_alloc_skb(len); 299*6b40aba3SKrzysztof Hałasa if (!skb) { 300*6b40aba3SKrzysztof Hałasa dev->stats.rx_dropped++; 301*6b40aba3SKrzysztof Hałasa return; 302*6b40aba3SKrzysztof Hałasa } 303*6b40aba3SKrzysztof Hałasa 304*6b40aba3SKrzysztof Hałasa buff = buffer_offset(port, rxin, 0); 305*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 306*6b40aba3SKrzysztof Hałasa page = buff / winsize(card); 307*6b40aba3SKrzysztof Hałasa buff = buff % winsize(card); 308*6b40aba3SKrzysztof Hałasa maxlen = winsize(card) - buff; 309*6b40aba3SKrzysztof Hałasa 310*6b40aba3SKrzysztof Hałasa openwin(card, page); 311*6b40aba3SKrzysztof Hałasa 312*6b40aba3SKrzysztof Hałasa if (len > maxlen) { 313*6b40aba3SKrzysztof Hałasa memcpy_fromio(skb->data, winbase(card) + buff, maxlen); 314*6b40aba3SKrzysztof Hałasa openwin(card, page + 1); 315*6b40aba3SKrzysztof Hałasa memcpy_fromio(skb->data + maxlen, winbase(card), len - maxlen); 316*6b40aba3SKrzysztof Hałasa } else 317*6b40aba3SKrzysztof Hałasa #endif 318*6b40aba3SKrzysztof Hałasa memcpy_fromio(skb->data, winbase(card) + buff, len); 319*6b40aba3SKrzysztof Hałasa 320*6b40aba3SKrzysztof Hałasa #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) 321*6b40aba3SKrzysztof Hałasa /* select pkt_desc table page back */ 322*6b40aba3SKrzysztof Hałasa openwin(card, 0); 323*6b40aba3SKrzysztof Hałasa #endif 324*6b40aba3SKrzysztof Hałasa skb_put(skb, len); 325*6b40aba3SKrzysztof Hałasa #ifdef DEBUG_PKT 326*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "%s RX(%i):", dev->name, skb->len); 327*6b40aba3SKrzysztof Hałasa debug_frame(skb); 328*6b40aba3SKrzysztof Hałasa #endif 329*6b40aba3SKrzysztof Hałasa dev->stats.rx_packets++; 330*6b40aba3SKrzysztof Hałasa dev->stats.rx_bytes += skb->len; 331*6b40aba3SKrzysztof Hałasa skb->protocol = hdlc_type_trans(skb, dev); 332*6b40aba3SKrzysztof Hałasa netif_rx(skb); 333*6b40aba3SKrzysztof Hałasa } 334*6b40aba3SKrzysztof Hałasa 335*6b40aba3SKrzysztof Hałasa 336*6b40aba3SKrzysztof Hałasa 337*6b40aba3SKrzysztof Hałasa /* Receive DMA interrupt service */ 338*6b40aba3SKrzysztof Hałasa static inline void sca_rx_intr(port_t *port) 339*6b40aba3SKrzysztof Hałasa { 340*6b40aba3SKrzysztof Hałasa struct net_device *dev = port_to_dev(port); 341*6b40aba3SKrzysztof Hałasa u16 dmac = get_dmac_rx(port); 342*6b40aba3SKrzysztof Hałasa card_t *card = port_to_card(port); 343*6b40aba3SKrzysztof Hałasa u8 stat = sca_in(DSR_RX(phy_node(port)), card); /* read DMA Status */ 344*6b40aba3SKrzysztof Hałasa 345*6b40aba3SKrzysztof Hałasa /* Reset DSR status bits */ 346*6b40aba3SKrzysztof Hałasa sca_out((stat & (DSR_EOT | DSR_EOM | DSR_BOF | DSR_COF)) | DSR_DWE, 347*6b40aba3SKrzysztof Hałasa DSR_RX(phy_node(port)), card); 348*6b40aba3SKrzysztof Hałasa 349*6b40aba3SKrzysztof Hałasa if (stat & DSR_BOF) 350*6b40aba3SKrzysztof Hałasa /* Dropped one or more frames */ 351*6b40aba3SKrzysztof Hałasa dev->stats.rx_over_errors++; 352*6b40aba3SKrzysztof Hałasa 353*6b40aba3SKrzysztof Hałasa while (1) { 354*6b40aba3SKrzysztof Hałasa u32 desc_off = desc_offset(port, port->rxin, 0); 355*6b40aba3SKrzysztof Hałasa pkt_desc __iomem *desc; 356*6b40aba3SKrzysztof Hałasa u32 cda = sca_ina(dmac + CDAL, card); 357*6b40aba3SKrzysztof Hałasa 358*6b40aba3SKrzysztof Hałasa if ((cda >= desc_off) && (cda < desc_off + sizeof(pkt_desc))) 359*6b40aba3SKrzysztof Hałasa break; /* No frame received */ 360*6b40aba3SKrzysztof Hałasa 361*6b40aba3SKrzysztof Hałasa desc = desc_address(port, port->rxin, 0); 362*6b40aba3SKrzysztof Hałasa stat = readb(&desc->stat); 363*6b40aba3SKrzysztof Hałasa if (!(stat & ST_RX_EOM)) 364*6b40aba3SKrzysztof Hałasa port->rxpart = 1; /* partial frame received */ 365*6b40aba3SKrzysztof Hałasa else if ((stat & ST_ERROR_MASK) || port->rxpart) { 366*6b40aba3SKrzysztof Hałasa dev->stats.rx_errors++; 367*6b40aba3SKrzysztof Hałasa if (stat & ST_RX_OVERRUN) 368*6b40aba3SKrzysztof Hałasa dev->stats.rx_fifo_errors++; 369*6b40aba3SKrzysztof Hałasa else if ((stat & (ST_RX_SHORT | ST_RX_ABORT | 370*6b40aba3SKrzysztof Hałasa ST_RX_RESBIT)) || port->rxpart) 371*6b40aba3SKrzysztof Hałasa dev->stats.rx_frame_errors++; 372*6b40aba3SKrzysztof Hałasa else if (stat & ST_RX_CRC) 373*6b40aba3SKrzysztof Hałasa dev->stats.rx_crc_errors++; 374*6b40aba3SKrzysztof Hałasa if (stat & ST_RX_EOM) 375*6b40aba3SKrzysztof Hałasa port->rxpart = 0; /* received last fragment */ 376*6b40aba3SKrzysztof Hałasa } else 377*6b40aba3SKrzysztof Hałasa sca_rx(card, port, desc, port->rxin); 378*6b40aba3SKrzysztof Hałasa 379*6b40aba3SKrzysztof Hałasa /* Set new error descriptor address */ 380*6b40aba3SKrzysztof Hałasa sca_outa(desc_off, dmac + EDAL, card); 381*6b40aba3SKrzysztof Hałasa port->rxin = next_desc(port, port->rxin, 0); 382*6b40aba3SKrzysztof Hałasa } 383*6b40aba3SKrzysztof Hałasa 384*6b40aba3SKrzysztof Hałasa /* make sure RX DMA is enabled */ 385*6b40aba3SKrzysztof Hałasa sca_out(DSR_DE, DSR_RX(phy_node(port)), card); 386*6b40aba3SKrzysztof Hałasa } 387*6b40aba3SKrzysztof Hałasa 388*6b40aba3SKrzysztof Hałasa 389*6b40aba3SKrzysztof Hałasa 390*6b40aba3SKrzysztof Hałasa /* Transmit DMA interrupt service */ 391*6b40aba3SKrzysztof Hałasa static inline void sca_tx_intr(port_t *port) 392*6b40aba3SKrzysztof Hałasa { 393*6b40aba3SKrzysztof Hałasa struct net_device *dev = port_to_dev(port); 394*6b40aba3SKrzysztof Hałasa u16 dmac = get_dmac_tx(port); 395*6b40aba3SKrzysztof Hałasa card_t* card = port_to_card(port); 396*6b40aba3SKrzysztof Hałasa u8 stat; 397*6b40aba3SKrzysztof Hałasa 398*6b40aba3SKrzysztof Hałasa spin_lock(&port->lock); 399*6b40aba3SKrzysztof Hałasa 400*6b40aba3SKrzysztof Hałasa stat = sca_in(DSR_TX(phy_node(port)), card); /* read DMA Status */ 401*6b40aba3SKrzysztof Hałasa 402*6b40aba3SKrzysztof Hałasa /* Reset DSR status bits */ 403*6b40aba3SKrzysztof Hałasa sca_out((stat & (DSR_EOT | DSR_EOM | DSR_BOF | DSR_COF)) | DSR_DWE, 404*6b40aba3SKrzysztof Hałasa DSR_TX(phy_node(port)), card); 405*6b40aba3SKrzysztof Hałasa 406*6b40aba3SKrzysztof Hałasa while (1) { 407*6b40aba3SKrzysztof Hałasa pkt_desc __iomem *desc; 408*6b40aba3SKrzysztof Hałasa 409*6b40aba3SKrzysztof Hałasa u32 desc_off = desc_offset(port, port->txlast, 1); 410*6b40aba3SKrzysztof Hałasa u32 cda = sca_ina(dmac + CDAL, card); 411*6b40aba3SKrzysztof Hałasa if ((cda >= desc_off) && (cda < desc_off + sizeof(pkt_desc))) 412*6b40aba3SKrzysztof Hałasa break; /* Transmitter is/will_be sending this frame */ 413*6b40aba3SKrzysztof Hałasa 414*6b40aba3SKrzysztof Hałasa desc = desc_address(port, port->txlast, 1); 415*6b40aba3SKrzysztof Hałasa dev->stats.tx_packets++; 416*6b40aba3SKrzysztof Hałasa dev->stats.tx_bytes += readw(&desc->len); 417*6b40aba3SKrzysztof Hałasa writeb(0, &desc->stat); /* Free descriptor */ 418*6b40aba3SKrzysztof Hałasa port->txlast = next_desc(port, port->txlast, 1); 419*6b40aba3SKrzysztof Hałasa } 420*6b40aba3SKrzysztof Hałasa 421*6b40aba3SKrzysztof Hałasa netif_wake_queue(dev); 422*6b40aba3SKrzysztof Hałasa spin_unlock(&port->lock); 423*6b40aba3SKrzysztof Hałasa } 424*6b40aba3SKrzysztof Hałasa 425*6b40aba3SKrzysztof Hałasa 426*6b40aba3SKrzysztof Hałasa 427*6b40aba3SKrzysztof Hałasa static irqreturn_t sca_intr(int irq, void* dev_id) 428*6b40aba3SKrzysztof Hałasa { 429*6b40aba3SKrzysztof Hałasa card_t *card = dev_id; 430*6b40aba3SKrzysztof Hałasa int i; 431*6b40aba3SKrzysztof Hałasa u8 stat; 432*6b40aba3SKrzysztof Hałasa int handled = 0; 433*6b40aba3SKrzysztof Hałasa 434*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 435*6b40aba3SKrzysztof Hałasa u8 page = sca_get_page(card); 436*6b40aba3SKrzysztof Hałasa #endif 437*6b40aba3SKrzysztof Hałasa 438*6b40aba3SKrzysztof Hałasa while((stat = sca_intr_status(card)) != 0) { 439*6b40aba3SKrzysztof Hałasa handled = 1; 440*6b40aba3SKrzysztof Hałasa for (i = 0; i < 2; i++) { 441*6b40aba3SKrzysztof Hałasa port_t *port = get_port(card, i); 442*6b40aba3SKrzysztof Hałasa if (port) { 443*6b40aba3SKrzysztof Hałasa if (stat & SCA_INTR_MSCI(i)) 444*6b40aba3SKrzysztof Hałasa sca_msci_intr(port); 445*6b40aba3SKrzysztof Hałasa 446*6b40aba3SKrzysztof Hałasa if (stat & SCA_INTR_DMAC_RX(i)) 447*6b40aba3SKrzysztof Hałasa sca_rx_intr(port); 448*6b40aba3SKrzysztof Hałasa 449*6b40aba3SKrzysztof Hałasa if (stat & SCA_INTR_DMAC_TX(i)) 450*6b40aba3SKrzysztof Hałasa sca_tx_intr(port); 451*6b40aba3SKrzysztof Hałasa } 452*6b40aba3SKrzysztof Hałasa } 453*6b40aba3SKrzysztof Hałasa } 454*6b40aba3SKrzysztof Hałasa 455*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 456*6b40aba3SKrzysztof Hałasa openwin(card, page); /* Restore original page */ 457*6b40aba3SKrzysztof Hałasa #endif 458*6b40aba3SKrzysztof Hałasa return IRQ_RETVAL(handled); 459*6b40aba3SKrzysztof Hałasa } 460*6b40aba3SKrzysztof Hałasa 461*6b40aba3SKrzysztof Hałasa 462*6b40aba3SKrzysztof Hałasa 463*6b40aba3SKrzysztof Hałasa static void sca_set_port(port_t *port) 464*6b40aba3SKrzysztof Hałasa { 465*6b40aba3SKrzysztof Hałasa card_t* card = port_to_card(port); 466*6b40aba3SKrzysztof Hałasa u16 msci = get_msci(port); 467*6b40aba3SKrzysztof Hałasa u8 md2 = sca_in(msci + MD2, card); 468*6b40aba3SKrzysztof Hałasa unsigned int tmc, br = 10, brv = 1024; 469*6b40aba3SKrzysztof Hałasa 470*6b40aba3SKrzysztof Hałasa 471*6b40aba3SKrzysztof Hałasa if (port->settings.clock_rate > 0) { 472*6b40aba3SKrzysztof Hałasa /* Try lower br for better accuracy*/ 473*6b40aba3SKrzysztof Hałasa do { 474*6b40aba3SKrzysztof Hałasa br--; 475*6b40aba3SKrzysztof Hałasa brv >>= 1; /* brv = 2^9 = 512 max in specs */ 476*6b40aba3SKrzysztof Hałasa 477*6b40aba3SKrzysztof Hałasa /* Baud Rate = CLOCK_BASE / TMC / 2^BR */ 478*6b40aba3SKrzysztof Hałasa tmc = CLOCK_BASE / brv / port->settings.clock_rate; 479*6b40aba3SKrzysztof Hałasa }while (br > 1 && tmc <= 128); 480*6b40aba3SKrzysztof Hałasa 481*6b40aba3SKrzysztof Hałasa if (tmc < 1) { 482*6b40aba3SKrzysztof Hałasa tmc = 1; 483*6b40aba3SKrzysztof Hałasa br = 0; /* For baud=CLOCK_BASE we use tmc=1 br=0 */ 484*6b40aba3SKrzysztof Hałasa brv = 1; 485*6b40aba3SKrzysztof Hałasa } else if (tmc > 255) 486*6b40aba3SKrzysztof Hałasa tmc = 256; /* tmc=0 means 256 - low baud rates */ 487*6b40aba3SKrzysztof Hałasa 488*6b40aba3SKrzysztof Hałasa port->settings.clock_rate = CLOCK_BASE / brv / tmc; 489*6b40aba3SKrzysztof Hałasa } else { 490*6b40aba3SKrzysztof Hałasa br = 9; /* Minimum clock rate */ 491*6b40aba3SKrzysztof Hałasa tmc = 256; /* 8bit = 0 */ 492*6b40aba3SKrzysztof Hałasa port->settings.clock_rate = CLOCK_BASE / (256 * 512); 493*6b40aba3SKrzysztof Hałasa } 494*6b40aba3SKrzysztof Hałasa 495*6b40aba3SKrzysztof Hałasa port->rxs = (port->rxs & ~CLK_BRG_MASK) | br; 496*6b40aba3SKrzysztof Hałasa port->txs = (port->txs & ~CLK_BRG_MASK) | br; 497*6b40aba3SKrzysztof Hałasa port->tmc = tmc; 498*6b40aba3SKrzysztof Hałasa 499*6b40aba3SKrzysztof Hałasa /* baud divisor - time constant*/ 500*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 501*6b40aba3SKrzysztof Hałasa sca_out(port->tmc, msci + TMC, card); 502*6b40aba3SKrzysztof Hałasa #else 503*6b40aba3SKrzysztof Hałasa sca_out(port->tmc, msci + TMCR, card); 504*6b40aba3SKrzysztof Hałasa sca_out(port->tmc, msci + TMCT, card); 505*6b40aba3SKrzysztof Hałasa #endif 506*6b40aba3SKrzysztof Hałasa 507*6b40aba3SKrzysztof Hałasa /* Set BRG bits */ 508*6b40aba3SKrzysztof Hałasa sca_out(port->rxs, msci + RXS, card); 509*6b40aba3SKrzysztof Hałasa sca_out(port->txs, msci + TXS, card); 510*6b40aba3SKrzysztof Hałasa 511*6b40aba3SKrzysztof Hałasa if (port->settings.loopback) 512*6b40aba3SKrzysztof Hałasa md2 |= MD2_LOOPBACK; 513*6b40aba3SKrzysztof Hałasa else 514*6b40aba3SKrzysztof Hałasa md2 &= ~MD2_LOOPBACK; 515*6b40aba3SKrzysztof Hałasa 516*6b40aba3SKrzysztof Hałasa sca_out(md2, msci + MD2, card); 517*6b40aba3SKrzysztof Hałasa 518*6b40aba3SKrzysztof Hałasa } 519*6b40aba3SKrzysztof Hałasa 520*6b40aba3SKrzysztof Hałasa 521*6b40aba3SKrzysztof Hałasa 522*6b40aba3SKrzysztof Hałasa static void sca_open(struct net_device *dev) 523*6b40aba3SKrzysztof Hałasa { 524*6b40aba3SKrzysztof Hałasa port_t *port = dev_to_port(dev); 525*6b40aba3SKrzysztof Hałasa card_t* card = port_to_card(port); 526*6b40aba3SKrzysztof Hałasa u16 msci = get_msci(port); 527*6b40aba3SKrzysztof Hałasa u8 md0, md2; 528*6b40aba3SKrzysztof Hałasa 529*6b40aba3SKrzysztof Hałasa switch(port->encoding) { 530*6b40aba3SKrzysztof Hałasa case ENCODING_NRZ: md2 = MD2_NRZ; break; 531*6b40aba3SKrzysztof Hałasa case ENCODING_NRZI: md2 = MD2_NRZI; break; 532*6b40aba3SKrzysztof Hałasa case ENCODING_FM_MARK: md2 = MD2_FM_MARK; break; 533*6b40aba3SKrzysztof Hałasa case ENCODING_FM_SPACE: md2 = MD2_FM_SPACE; break; 534*6b40aba3SKrzysztof Hałasa default: md2 = MD2_MANCHESTER; 535*6b40aba3SKrzysztof Hałasa } 536*6b40aba3SKrzysztof Hałasa 537*6b40aba3SKrzysztof Hałasa if (port->settings.loopback) 538*6b40aba3SKrzysztof Hałasa md2 |= MD2_LOOPBACK; 539*6b40aba3SKrzysztof Hałasa 540*6b40aba3SKrzysztof Hałasa switch(port->parity) { 541*6b40aba3SKrzysztof Hałasa case PARITY_CRC16_PR0: md0 = MD0_HDLC | MD0_CRC_16_0; break; 542*6b40aba3SKrzysztof Hałasa case PARITY_CRC16_PR1: md0 = MD0_HDLC | MD0_CRC_16; break; 543*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 544*6b40aba3SKrzysztof Hałasa case PARITY_CRC16_PR0_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU_0; break; 545*6b40aba3SKrzysztof Hałasa #else 546*6b40aba3SKrzysztof Hałasa case PARITY_CRC32_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU32; break; 547*6b40aba3SKrzysztof Hałasa #endif 548*6b40aba3SKrzysztof Hałasa case PARITY_CRC16_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU; break; 549*6b40aba3SKrzysztof Hałasa default: md0 = MD0_HDLC | MD0_CRC_NONE; 550*6b40aba3SKrzysztof Hałasa } 551*6b40aba3SKrzysztof Hałasa 552*6b40aba3SKrzysztof Hałasa sca_out(CMD_RESET, msci + CMD, card); 553*6b40aba3SKrzysztof Hałasa sca_out(md0, msci + MD0, card); 554*6b40aba3SKrzysztof Hałasa sca_out(0x00, msci + MD1, card); /* no address field check */ 555*6b40aba3SKrzysztof Hałasa sca_out(md2, msci + MD2, card); 556*6b40aba3SKrzysztof Hałasa sca_out(0x7E, msci + IDL, card); /* flag character 0x7E */ 557*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 558*6b40aba3SKrzysztof Hałasa sca_out(CTL_IDLE, msci + CTL, card); 559*6b40aba3SKrzysztof Hałasa #else 560*6b40aba3SKrzysztof Hałasa /* Skip the rest of underrun frame */ 561*6b40aba3SKrzysztof Hałasa sca_out(CTL_IDLE | CTL_URCT | CTL_URSKP, msci + CTL, card); 562*6b40aba3SKrzysztof Hałasa #endif 563*6b40aba3SKrzysztof Hałasa 564*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 565*6b40aba3SKrzysztof Hałasa /* Allow at least 8 bytes before requesting RX DMA operation */ 566*6b40aba3SKrzysztof Hałasa /* TX with higher priority and possibly with shorter transfers */ 567*6b40aba3SKrzysztof Hałasa sca_out(0x07, msci + RRC, card); /* +1=RXRDY/DMA activation condition*/ 568*6b40aba3SKrzysztof Hałasa sca_out(0x10, msci + TRC0, card); /* = TXRDY/DMA activation condition*/ 569*6b40aba3SKrzysztof Hałasa sca_out(0x14, msci + TRC1, card); /* +1=TXRDY/DMA deactiv condition */ 570*6b40aba3SKrzysztof Hałasa #else 571*6b40aba3SKrzysztof Hałasa sca_out(0x0F, msci + RNR, card); /* +1=RX DMA activation condition */ 572*6b40aba3SKrzysztof Hałasa sca_out(0x3C, msci + TFS, card); /* +1 = TX start */ 573*6b40aba3SKrzysztof Hałasa sca_out(0x38, msci + TCR, card); /* =Critical TX DMA activ condition */ 574*6b40aba3SKrzysztof Hałasa sca_out(0x38, msci + TNR0, card); /* =TX DMA activation condition */ 575*6b40aba3SKrzysztof Hałasa sca_out(0x3F, msci + TNR1, card); /* +1=TX DMA deactivation condition*/ 576*6b40aba3SKrzysztof Hałasa #endif 577*6b40aba3SKrzysztof Hałasa 578*6b40aba3SKrzysztof Hałasa /* We're using the following interrupts: 579*6b40aba3SKrzysztof Hałasa - TXINT (DMAC completed all transmisions, underrun or DCD change) 580*6b40aba3SKrzysztof Hałasa - all DMA interrupts 581*6b40aba3SKrzysztof Hałasa */ 582*6b40aba3SKrzysztof Hałasa 583*6b40aba3SKrzysztof Hałasa sca_set_carrier(port); 584*6b40aba3SKrzysztof Hałasa 585*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 586*6b40aba3SKrzysztof Hałasa /* MSCI TX INT and RX INT A IRQ enable */ 587*6b40aba3SKrzysztof Hałasa sca_out(IE0_TXINT | IE0_RXINTA, msci + IE0, card); 588*6b40aba3SKrzysztof Hałasa sca_out(IE1_UDRN | IE1_CDCD, msci + IE1, card); 589*6b40aba3SKrzysztof Hałasa sca_out(sca_in(IER0, card) | (phy_node(port) ? 0xC0 : 0x0C), 590*6b40aba3SKrzysztof Hałasa IER0, card); /* TXINT and RXINT */ 591*6b40aba3SKrzysztof Hałasa /* enable DMA IRQ */ 592*6b40aba3SKrzysztof Hałasa sca_out(sca_in(IER1, card) | (phy_node(port) ? 0xF0 : 0x0F), 593*6b40aba3SKrzysztof Hałasa IER1, card); 594*6b40aba3SKrzysztof Hałasa #else 595*6b40aba3SKrzysztof Hałasa /* MSCI TXINT and RXINTA interrupt enable */ 596*6b40aba3SKrzysztof Hałasa sca_outl(IE0_TXINT | IE0_RXINTA | IE0_UDRN | IE0_CDCD, msci + IE0, 597*6b40aba3SKrzysztof Hałasa card); 598*6b40aba3SKrzysztof Hałasa /* DMA & MSCI IRQ enable */ 599*6b40aba3SKrzysztof Hałasa sca_outl(sca_inl(IER0, card) | 600*6b40aba3SKrzysztof Hałasa (phy_node(port) ? 0x0A006600 : 0x000A0066), IER0, card); 601*6b40aba3SKrzysztof Hałasa #endif 602*6b40aba3SKrzysztof Hałasa 603*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 604*6b40aba3SKrzysztof Hałasa sca_out(port->tmc, msci + TMC, card); /* Restore registers */ 605*6b40aba3SKrzysztof Hałasa #else 606*6b40aba3SKrzysztof Hałasa sca_out(port->tmc, msci + TMCR, card); 607*6b40aba3SKrzysztof Hałasa sca_out(port->tmc, msci + TMCT, card); 608*6b40aba3SKrzysztof Hałasa #endif 609*6b40aba3SKrzysztof Hałasa sca_out(port->rxs, msci + RXS, card); 610*6b40aba3SKrzysztof Hałasa sca_out(port->txs, msci + TXS, card); 611*6b40aba3SKrzysztof Hałasa sca_out(CMD_TX_ENABLE, msci + CMD, card); 612*6b40aba3SKrzysztof Hałasa sca_out(CMD_RX_ENABLE, msci + CMD, card); 613*6b40aba3SKrzysztof Hałasa 614*6b40aba3SKrzysztof Hałasa netif_start_queue(dev); 615*6b40aba3SKrzysztof Hałasa } 616*6b40aba3SKrzysztof Hałasa 617*6b40aba3SKrzysztof Hałasa 618*6b40aba3SKrzysztof Hałasa 619*6b40aba3SKrzysztof Hałasa static void sca_close(struct net_device *dev) 620*6b40aba3SKrzysztof Hałasa { 621*6b40aba3SKrzysztof Hałasa port_t *port = dev_to_port(dev); 622*6b40aba3SKrzysztof Hałasa card_t* card = port_to_card(port); 623*6b40aba3SKrzysztof Hałasa 624*6b40aba3SKrzysztof Hałasa /* reset channel */ 625*6b40aba3SKrzysztof Hałasa sca_out(CMD_RESET, get_msci(port) + CMD, port_to_card(port)); 626*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 627*6b40aba3SKrzysztof Hałasa /* disable MSCI interrupts */ 628*6b40aba3SKrzysztof Hałasa sca_out(sca_in(IER0, card) & (phy_node(port) ? 0x0F : 0xF0), 629*6b40aba3SKrzysztof Hałasa IER0, card); 630*6b40aba3SKrzysztof Hałasa /* disable DMA interrupts */ 631*6b40aba3SKrzysztof Hałasa sca_out(sca_in(IER1, card) & (phy_node(port) ? 0x0F : 0xF0), 632*6b40aba3SKrzysztof Hałasa IER1, card); 633*6b40aba3SKrzysztof Hałasa #else 634*6b40aba3SKrzysztof Hałasa /* disable DMA & MSCI IRQ */ 635*6b40aba3SKrzysztof Hałasa sca_outl(sca_inl(IER0, card) & 636*6b40aba3SKrzysztof Hałasa (phy_node(port) ? 0x00FF00FF : 0xFF00FF00), IER0, card); 637*6b40aba3SKrzysztof Hałasa #endif 638*6b40aba3SKrzysztof Hałasa netif_stop_queue(dev); 639*6b40aba3SKrzysztof Hałasa } 640*6b40aba3SKrzysztof Hałasa 641*6b40aba3SKrzysztof Hałasa 642*6b40aba3SKrzysztof Hałasa 643*6b40aba3SKrzysztof Hałasa static int sca_attach(struct net_device *dev, unsigned short encoding, 644*6b40aba3SKrzysztof Hałasa unsigned short parity) 645*6b40aba3SKrzysztof Hałasa { 646*6b40aba3SKrzysztof Hałasa if (encoding != ENCODING_NRZ && 647*6b40aba3SKrzysztof Hałasa encoding != ENCODING_NRZI && 648*6b40aba3SKrzysztof Hałasa encoding != ENCODING_FM_MARK && 649*6b40aba3SKrzysztof Hałasa encoding != ENCODING_FM_SPACE && 650*6b40aba3SKrzysztof Hałasa encoding != ENCODING_MANCHESTER) 651*6b40aba3SKrzysztof Hałasa return -EINVAL; 652*6b40aba3SKrzysztof Hałasa 653*6b40aba3SKrzysztof Hałasa if (parity != PARITY_NONE && 654*6b40aba3SKrzysztof Hałasa parity != PARITY_CRC16_PR0 && 655*6b40aba3SKrzysztof Hałasa parity != PARITY_CRC16_PR1 && 656*6b40aba3SKrzysztof Hałasa #ifdef __HD64570_H 657*6b40aba3SKrzysztof Hałasa parity != PARITY_CRC16_PR0_CCITT && 658*6b40aba3SKrzysztof Hałasa #else 659*6b40aba3SKrzysztof Hałasa parity != PARITY_CRC32_PR1_CCITT && 660*6b40aba3SKrzysztof Hałasa #endif 661*6b40aba3SKrzysztof Hałasa parity != PARITY_CRC16_PR1_CCITT) 662*6b40aba3SKrzysztof Hałasa return -EINVAL; 663*6b40aba3SKrzysztof Hałasa 664*6b40aba3SKrzysztof Hałasa dev_to_port(dev)->encoding = encoding; 665*6b40aba3SKrzysztof Hałasa dev_to_port(dev)->parity = parity; 666*6b40aba3SKrzysztof Hałasa return 0; 667*6b40aba3SKrzysztof Hałasa } 668*6b40aba3SKrzysztof Hałasa 669*6b40aba3SKrzysztof Hałasa 670*6b40aba3SKrzysztof Hałasa 671*6b40aba3SKrzysztof Hałasa #ifdef DEBUG_RINGS 672*6b40aba3SKrzysztof Hałasa static void sca_dump_rings(struct net_device *dev) 673*6b40aba3SKrzysztof Hałasa { 674*6b40aba3SKrzysztof Hałasa port_t *port = dev_to_port(dev); 675*6b40aba3SKrzysztof Hałasa card_t *card = port_to_card(port); 676*6b40aba3SKrzysztof Hałasa u16 cnt; 677*6b40aba3SKrzysztof Hałasa #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) 678*6b40aba3SKrzysztof Hałasa u8 page; 679*6b40aba3SKrzysztof Hałasa #endif 680*6b40aba3SKrzysztof Hałasa 681*6b40aba3SKrzysztof Hałasa #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) 682*6b40aba3SKrzysztof Hałasa page = sca_get_page(card); 683*6b40aba3SKrzysztof Hałasa openwin(card, 0); 684*6b40aba3SKrzysztof Hałasa #endif 685*6b40aba3SKrzysztof Hałasa 686*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "RX ring: CDA=%u EDA=%u DSR=%02X in=%u %sactive", 687*6b40aba3SKrzysztof Hałasa sca_ina(get_dmac_rx(port) + CDAL, card), 688*6b40aba3SKrzysztof Hałasa sca_ina(get_dmac_rx(port) + EDAL, card), 689*6b40aba3SKrzysztof Hałasa sca_in(DSR_RX(phy_node(port)), card), port->rxin, 690*6b40aba3SKrzysztof Hałasa sca_in(DSR_RX(phy_node(port)), card) & DSR_DE?"":"in"); 691*6b40aba3SKrzysztof Hałasa for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++) 692*6b40aba3SKrzysztof Hałasa printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat))); 693*6b40aba3SKrzysztof Hałasa 694*6b40aba3SKrzysztof Hałasa printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u " 695*6b40aba3SKrzysztof Hałasa "last=%u %sactive", 696*6b40aba3SKrzysztof Hałasa sca_ina(get_dmac_tx(port) + CDAL, card), 697*6b40aba3SKrzysztof Hałasa sca_ina(get_dmac_tx(port) + EDAL, card), 698*6b40aba3SKrzysztof Hałasa sca_in(DSR_TX(phy_node(port)), card), port->txin, port->txlast, 699*6b40aba3SKrzysztof Hałasa sca_in(DSR_TX(phy_node(port)), card) & DSR_DE ? "" : "in"); 700*6b40aba3SKrzysztof Hałasa 701*6b40aba3SKrzysztof Hałasa for (cnt = 0; cnt < port_to_card(port)->tx_ring_buffers; cnt++) 702*6b40aba3SKrzysztof Hałasa printk(" %02X", readb(&(desc_address(port, cnt, 1)->stat))); 703*6b40aba3SKrzysztof Hałasa printk("\n"); 704*6b40aba3SKrzysztof Hałasa 705*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x, " 706*6b40aba3SKrzysztof Hałasa "ST: %02x %02x %02x %02x" 707*6b40aba3SKrzysztof Hałasa #ifdef __HD64572_H 708*6b40aba3SKrzysztof Hałasa " %02x" 709*6b40aba3SKrzysztof Hałasa #endif 710*6b40aba3SKrzysztof Hałasa ", FST: %02x CST: %02x %02x\n", 711*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + MD0, card), 712*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + MD1, card), 713*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + MD2, card), 714*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + ST0, card), 715*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + ST1, card), 716*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + ST2, card), 717*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + ST3, card), 718*6b40aba3SKrzysztof Hałasa #ifdef __HD64572_H 719*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + ST4, card), 720*6b40aba3SKrzysztof Hałasa #endif 721*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + FST, card), 722*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + CST0, card), 723*6b40aba3SKrzysztof Hałasa sca_in(get_msci(port) + CST1, card)); 724*6b40aba3SKrzysztof Hałasa 725*6b40aba3SKrzysztof Hałasa #ifdef __HD64572_H 726*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "ILAR: %02x ISR: %08x %08x\n", sca_in(ILAR, card), 727*6b40aba3SKrzysztof Hałasa sca_inl(ISR0, card), sca_inl(ISR1, card)); 728*6b40aba3SKrzysztof Hałasa #else 729*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "ISR: %02x %02x %02x\n", sca_in(ISR0, card), 730*6b40aba3SKrzysztof Hałasa sca_in(ISR1, card), sca_in(ISR2, card)); 731*6b40aba3SKrzysztof Hałasa #endif 732*6b40aba3SKrzysztof Hałasa 733*6b40aba3SKrzysztof Hałasa #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) 734*6b40aba3SKrzysztof Hałasa openwin(card, page); /* Restore original page */ 735*6b40aba3SKrzysztof Hałasa #endif 736*6b40aba3SKrzysztof Hałasa } 737*6b40aba3SKrzysztof Hałasa #endif /* DEBUG_RINGS */ 738*6b40aba3SKrzysztof Hałasa 739*6b40aba3SKrzysztof Hałasa 740*6b40aba3SKrzysztof Hałasa 741*6b40aba3SKrzysztof Hałasa static int sca_xmit(struct sk_buff *skb, struct net_device *dev) 742*6b40aba3SKrzysztof Hałasa { 743*6b40aba3SKrzysztof Hałasa port_t *port = dev_to_port(dev); 744*6b40aba3SKrzysztof Hałasa card_t *card = port_to_card(port); 745*6b40aba3SKrzysztof Hałasa pkt_desc __iomem *desc; 746*6b40aba3SKrzysztof Hałasa u32 buff, len; 747*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 748*6b40aba3SKrzysztof Hałasa u8 page; 749*6b40aba3SKrzysztof Hałasa u32 maxlen; 750*6b40aba3SKrzysztof Hałasa #endif 751*6b40aba3SKrzysztof Hałasa 752*6b40aba3SKrzysztof Hałasa spin_lock_irq(&port->lock); 753*6b40aba3SKrzysztof Hałasa 754*6b40aba3SKrzysztof Hałasa desc = desc_address(port, port->txin + 1, 1); 755*6b40aba3SKrzysztof Hałasa if (readb(&desc->stat)) { /* allow 1 packet gap */ 756*6b40aba3SKrzysztof Hałasa /* should never happen - previous xmit should stop queue */ 757*6b40aba3SKrzysztof Hałasa #ifdef DEBUG_PKT 758*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name); 759*6b40aba3SKrzysztof Hałasa #endif 760*6b40aba3SKrzysztof Hałasa netif_stop_queue(dev); 761*6b40aba3SKrzysztof Hałasa spin_unlock_irq(&port->lock); 762*6b40aba3SKrzysztof Hałasa return 1; /* request packet to be queued */ 763*6b40aba3SKrzysztof Hałasa } 764*6b40aba3SKrzysztof Hałasa 765*6b40aba3SKrzysztof Hałasa #ifdef DEBUG_PKT 766*6b40aba3SKrzysztof Hałasa printk(KERN_DEBUG "%s TX(%i):", dev->name, skb->len); 767*6b40aba3SKrzysztof Hałasa debug_frame(skb); 768*6b40aba3SKrzysztof Hałasa #endif 769*6b40aba3SKrzysztof Hałasa 770*6b40aba3SKrzysztof Hałasa desc = desc_address(port, port->txin, 1); 771*6b40aba3SKrzysztof Hałasa buff = buffer_offset(port, port->txin, 1); 772*6b40aba3SKrzysztof Hałasa len = skb->len; 773*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 774*6b40aba3SKrzysztof Hałasa page = buff / winsize(card); 775*6b40aba3SKrzysztof Hałasa buff = buff % winsize(card); 776*6b40aba3SKrzysztof Hałasa maxlen = winsize(card) - buff; 777*6b40aba3SKrzysztof Hałasa 778*6b40aba3SKrzysztof Hałasa openwin(card, page); 779*6b40aba3SKrzysztof Hałasa if (len > maxlen) { 780*6b40aba3SKrzysztof Hałasa memcpy_toio(winbase(card) + buff, skb->data, maxlen); 781*6b40aba3SKrzysztof Hałasa openwin(card, page + 1); 782*6b40aba3SKrzysztof Hałasa memcpy_toio(winbase(card), skb->data + maxlen, len - maxlen); 783*6b40aba3SKrzysztof Hałasa } 784*6b40aba3SKrzysztof Hałasa else 785*6b40aba3SKrzysztof Hałasa #endif 786*6b40aba3SKrzysztof Hałasa memcpy_toio(winbase(card) + buff, skb->data, len); 787*6b40aba3SKrzysztof Hałasa 788*6b40aba3SKrzysztof Hałasa #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED) 789*6b40aba3SKrzysztof Hałasa openwin(card, 0); /* select pkt_desc table page back */ 790*6b40aba3SKrzysztof Hałasa #endif 791*6b40aba3SKrzysztof Hałasa writew(len, &desc->len); 792*6b40aba3SKrzysztof Hałasa writeb(ST_TX_EOM, &desc->stat); 793*6b40aba3SKrzysztof Hałasa dev->trans_start = jiffies; 794*6b40aba3SKrzysztof Hałasa 795*6b40aba3SKrzysztof Hałasa port->txin = next_desc(port, port->txin, 1); 796*6b40aba3SKrzysztof Hałasa sca_outa(desc_offset(port, port->txin, 1), 797*6b40aba3SKrzysztof Hałasa get_dmac_tx(port) + EDAL, card); 798*6b40aba3SKrzysztof Hałasa 799*6b40aba3SKrzysztof Hałasa sca_out(DSR_DE, DSR_TX(phy_node(port)), card); /* Enable TX DMA */ 800*6b40aba3SKrzysztof Hałasa 801*6b40aba3SKrzysztof Hałasa desc = desc_address(port, port->txin + 1, 1); 802*6b40aba3SKrzysztof Hałasa if (readb(&desc->stat)) /* allow 1 packet gap */ 803*6b40aba3SKrzysztof Hałasa netif_stop_queue(dev); 804*6b40aba3SKrzysztof Hałasa 805*6b40aba3SKrzysztof Hałasa spin_unlock_irq(&port->lock); 806*6b40aba3SKrzysztof Hałasa 807*6b40aba3SKrzysztof Hałasa dev_kfree_skb(skb); 808*6b40aba3SKrzysztof Hałasa return 0; 809*6b40aba3SKrzysztof Hałasa } 810*6b40aba3SKrzysztof Hałasa 811*6b40aba3SKrzysztof Hałasa 812*6b40aba3SKrzysztof Hałasa 813*6b40aba3SKrzysztof Hałasa #ifdef NEED_DETECT_RAM 814*6b40aba3SKrzysztof Hałasa static u32 __devinit sca_detect_ram(card_t *card, u8 __iomem *rambase, u32 ramsize) 815*6b40aba3SKrzysztof Hałasa { 816*6b40aba3SKrzysztof Hałasa /* Round RAM size to 32 bits, fill from end to start */ 817*6b40aba3SKrzysztof Hałasa u32 i = ramsize &= ~3; 818*6b40aba3SKrzysztof Hałasa 819*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 820*6b40aba3SKrzysztof Hałasa u32 size = winsize(card); 821*6b40aba3SKrzysztof Hałasa 822*6b40aba3SKrzysztof Hałasa openwin(card, (i - 4) / size); /* select last window */ 823*6b40aba3SKrzysztof Hałasa #endif 824*6b40aba3SKrzysztof Hałasa do { 825*6b40aba3SKrzysztof Hałasa i -= 4; 826*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 827*6b40aba3SKrzysztof Hałasa if ((i + 4) % size == 0) 828*6b40aba3SKrzysztof Hałasa openwin(card, i / size); 829*6b40aba3SKrzysztof Hałasa writel(i ^ 0x12345678, rambase + i % size); 830*6b40aba3SKrzysztof Hałasa #else 831*6b40aba3SKrzysztof Hałasa writel(i ^ 0x12345678, rambase + i); 832*6b40aba3SKrzysztof Hałasa #endif 833*6b40aba3SKrzysztof Hałasa }while (i > 0); 834*6b40aba3SKrzysztof Hałasa 835*6b40aba3SKrzysztof Hałasa for (i = 0; i < ramsize ; i += 4) { 836*6b40aba3SKrzysztof Hałasa #ifndef ALL_PAGES_ALWAYS_MAPPED 837*6b40aba3SKrzysztof Hałasa if (i % size == 0) 838*6b40aba3SKrzysztof Hałasa openwin(card, i / size); 839*6b40aba3SKrzysztof Hałasa 840*6b40aba3SKrzysztof Hałasa if (readl(rambase + i % size) != (i ^ 0x12345678)) 841*6b40aba3SKrzysztof Hałasa break; 842*6b40aba3SKrzysztof Hałasa #else 843*6b40aba3SKrzysztof Hałasa if (readl(rambase + i) != (i ^ 0x12345678)) 844*6b40aba3SKrzysztof Hałasa break; 845*6b40aba3SKrzysztof Hałasa #endif 846*6b40aba3SKrzysztof Hałasa } 847*6b40aba3SKrzysztof Hałasa 848*6b40aba3SKrzysztof Hałasa return i; 849*6b40aba3SKrzysztof Hałasa } 850*6b40aba3SKrzysztof Hałasa #endif /* NEED_DETECT_RAM */ 851*6b40aba3SKrzysztof Hałasa 852*6b40aba3SKrzysztof Hałasa 853*6b40aba3SKrzysztof Hałasa 854*6b40aba3SKrzysztof Hałasa static void __devinit sca_init(card_t *card, int wait_states) 855*6b40aba3SKrzysztof Hałasa { 856*6b40aba3SKrzysztof Hałasa sca_out(wait_states, WCRL, card); /* Wait Control */ 857*6b40aba3SKrzysztof Hałasa sca_out(wait_states, WCRM, card); 858*6b40aba3SKrzysztof Hałasa sca_out(wait_states, WCRH, card); 859*6b40aba3SKrzysztof Hałasa 860*6b40aba3SKrzysztof Hałasa sca_out(0, DMER, card); /* DMA Master disable */ 861*6b40aba3SKrzysztof Hałasa sca_out(0x03, PCR, card); /* DMA priority */ 862*6b40aba3SKrzysztof Hałasa sca_out(0, DSR_RX(0), card); /* DMA disable - to halt state */ 863*6b40aba3SKrzysztof Hałasa sca_out(0, DSR_TX(0), card); 864*6b40aba3SKrzysztof Hałasa sca_out(0, DSR_RX(1), card); 865*6b40aba3SKrzysztof Hałasa sca_out(0, DSR_TX(1), card); 866*6b40aba3SKrzysztof Hałasa sca_out(DMER_DME, DMER, card); /* DMA Master enable */ 867*6b40aba3SKrzysztof Hałasa } 868