Annotation of sys/dev/pci/if_san_xilinx.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: if_san_xilinx.c,v 1.18 2006/04/20 20:31:12 miod Exp $ */
! 2:
! 3: /*-
! 4: * Copyright (c) 2001-2004 Sangoma Technologies (SAN)
! 5: * All rights reserved. www.sangoma.com
! 6: *
! 7: * This code is written by Nenad Corbic <ncorbic@sangoma.com> and
! 8: * Alex Feldman <al.feldman@sangoma.com> for SAN.
! 9: *
! 10: * Redistribution and use in source and binary forms, with or without
! 11: * modification, are permitted provided that the following conditions
! 12: * are met:
! 13: * 1. Redistributions of source code must retain the above copyright
! 14: * notice, this list of conditions and the following disclaimer.
! 15: * 2. Redistributions in binary form must reproduce the above
! 16: * copyright notice, this list of conditions and the following disclaimer
! 17: * in the documentation and/or other materials provided with the
! 18: * distribution.
! 19: * 3. Neither the name of Sangoma Technologies nor the names of its
! 20: * contributors may be used to endorse or promote products derived
! 21: * from this software without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY SANGOMA TECHNOLOGIES AND CONTRIBUTORS
! 24: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! 25: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! 26: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
! 27: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! 28: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! 29: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! 30: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! 31: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! 32: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
! 33: * THE POSSIBILITY OF SUCH DAMAGE.
! 34: */
! 35:
! 36: #include <sys/types.h>
! 37: #include <sys/param.h>
! 38: #include <sys/systm.h>
! 39: #include <sys/syslog.h>
! 40: #include <sys/ioccom.h>
! 41: #include <sys/malloc.h>
! 42: #include <sys/errno.h>
! 43: #include <sys/mbuf.h>
! 44: #include <sys/proc.h>
! 45: #include <sys/socket.h>
! 46: #include <sys/kernel.h>
! 47: #include <sys/time.h>
! 48: #include <sys/timeout.h>
! 49:
! 50: #include <net/bpf.h>
! 51: #include <net/if.h>
! 52: #include <net/if_media.h>
! 53: #include <net/netisr.h>
! 54: #include <net/if_sppp.h>
! 55: #include <netinet/in_systm.h>
! 56: #include <netinet/in.h>
! 57: #include <netinet/in_var.h>
! 58: #include <netinet/udp.h>
! 59: #include <netinet/ip.h>
! 60:
! 61: #include <machine/bus.h>
! 62:
! 63: #include <dev/pci/if_san_common.h>
! 64: #include <dev/pci/if_san_obsd.h>
! 65: #include <dev/pci/if_san_xilinx.h>
! 66:
! 67:
! 68: /* Private critical flags */
! 69: enum {
! 70: POLL_CRIT = PRIV_CRIT,
! 71: TX_BUSY,
! 72: RX_BUSY,
! 73: TASK_POLL,
! 74: CARD_DOWN
! 75: };
! 76:
! 77: enum {
! 78: LINK_DOWN,
! 79: DEVICE_DOWN
! 80: };
! 81:
! 82: #define MAX_IP_ERRORS 10
! 83:
! 84: #define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" )
! 85: #define MAX_TX_BUF 10
! 86: #define MAX_RX_BUF 10
! 87:
! 88: #undef DEB_XILINX
! 89:
! 90: #if 1
! 91: # define TRUE_FIFO_SIZE 1
! 92: #else
! 93: # undef TRUE_FIFO_SIZE
! 94: # define HARD_FIFO_CODE 0x01
! 95: #endif
! 96:
! 97: static int aft_rx_copyback = MHLEN;
! 98:
! 99:
! 100: struct xilinx_rx_buffer {
! 101: SIMPLEQ_ENTRY(xilinx_rx_buffer) entry;
! 102: struct mbuf *mbuf;
! 103: bus_dmamap_t dma_map;
! 104: wp_rx_element_t rx_el;
! 105: };
! 106:
! 107: SIMPLEQ_HEAD(xilinx_rx_head, xilinx_rx_buffer);
! 108:
! 109: /*
! 110: * This structure is placed in the private data area of the device structure.
! 111: * The card structure used to occupy the private area but now the following
! 112: * structure will incorporate the card structure along with Protocol specific
! 113: * data
! 114: */
! 115: typedef struct {
! 116: wanpipe_common_t common;
! 117:
! 118: struct ifqueue wp_tx_pending_list;
! 119: struct ifqueue wp_tx_complete_list;
! 120: struct xilinx_rx_head wp_rx_free_list;
! 121: struct xilinx_rx_head wp_rx_complete_list;
! 122: struct xilinx_rx_buffer *wp_rx_buffers;
! 123: struct xilinx_rx_buffer *wp_rx_buffer_last;
! 124: struct xilinx_rx_buffer *rx_dma_buf;
! 125:
! 126: bus_dma_tag_t dmatag;
! 127: bus_dmamap_t tx_dmamap;
! 128: struct mbuf *tx_dma_mbuf;
! 129: u_int8_t tx_dma_cnt;
! 130:
! 131: unsigned long time_slot_map;
! 132: unsigned char num_of_time_slots;
! 133: long logic_ch_num;
! 134:
! 135: unsigned char dma_status;
! 136: unsigned char ignore_modem;
! 137: struct ifqueue udp_queue;
! 138:
! 139: unsigned long router_start_time;
! 140:
! 141: unsigned long tick_counter; /* For 5s timeout counter */
! 142: unsigned long router_up_time;
! 143:
! 144: unsigned char mc; /* Mulitcast support on/off */
! 145: unsigned char udp_pkt_src; /* udp packet processing */
! 146: unsigned short timer_int_enabled;
! 147:
! 148: unsigned char interface_down;
! 149:
! 150: u_int8_t gateway;
! 151: u_int8_t true_if_encoding;
! 152:
! 153: char if_name[IFNAMSIZ+1];
! 154:
! 155: u_int8_t idle_flag;
! 156: u_int16_t max_idle_size;
! 157: u_int8_t idle_start;
! 158:
! 159: u_int8_t pkt_error;
! 160: u_int8_t rx_fifo_err_cnt;
! 161:
! 162: int first_time_slot;
! 163:
! 164: unsigned long tx_dma_addr;
! 165: unsigned int tx_dma_len;
! 166: unsigned char rx_dma;
! 167: unsigned char pci_retry;
! 168:
! 169: unsigned char fifo_size_code;
! 170: unsigned char fifo_base_addr;
! 171: unsigned char fifo_size;
! 172:
! 173: int dma_mtu;
! 174:
! 175: void *prot_ch;
! 176: wan_trace_t trace_info;
! 177: }xilinx_softc_t;
! 178: #define WAN_IFP_TO_SOFTC(ifp) (xilinx_softc_t *)((ifp)->if_softc)
! 179:
! 180: /* Route Status options */
! 181: #define NO_ROUTE 0x00
! 182: #define ADD_ROUTE 0x01
! 183: #define ROUTE_ADDED 0x02
! 184: #define REMOVE_ROUTE 0x03
! 185:
! 186: #define WP_WAIT 0
! 187: #define WP_NO_WAIT 1
! 188:
! 189: /* variable for keeping track of enabling/disabling FT1 monitor status */
! 190: /* static int rCount; */
! 191:
! 192: extern void disable_irq(unsigned int);
! 193: extern void enable_irq(unsigned int);
! 194:
! 195: /**SECTOIN**************************************************
! 196: *
! 197: * Function Prototypes
! 198: *
! 199: ***********************************************************/
! 200:
! 201: /* WAN link driver entry points. These are called by the WAN router module. */
! 202: static int wan_xilinx_release(sdla_t*, struct ifnet *);
! 203:
! 204: /* Network device interface */
! 205: static int wan_xilinx_up(struct ifnet *);
! 206: static int wan_xilinx_down(struct ifnet *);
! 207: static int wan_xilinx_ioctl(struct ifnet *, int cmd, struct ifreq *);
! 208: static int wan_xilinx_send(struct mbuf *, struct ifnet *);
! 209:
! 210: static void handle_front_end_state(void *);
! 211: static void enable_timer(void *);
! 212:
! 213: /* Miscellaneous Functions */
! 214: static void port_set_state (sdla_t *, int);
! 215:
! 216: /* Interrupt handlers */
! 217: static void wp_xilinx_isr (sdla_t *);
! 218:
! 219: /* Miscellaneous functions */
! 220: static int process_udp_mgmt_pkt(sdla_t *, struct ifnet *,
! 221: xilinx_softc_t *, int);
! 222: /* Bottom half handlers */
! 223: static void xilinx_process_packet(xilinx_softc_t *);
! 224:
! 225: static int xilinx_chip_configure(sdla_t *);
! 226: static int xilinx_chip_unconfigure(sdla_t *);
! 227: static int xilinx_dev_configure(sdla_t *, xilinx_softc_t *);
! 228: static void xilinx_dev_unconfigure(sdla_t *, xilinx_softc_t *);
! 229: static int xilinx_dma_rx(sdla_t *, xilinx_softc_t *);
! 230: static void xilinx_dev_enable(sdla_t *, xilinx_softc_t *);
! 231: static void xilinx_dev_close(sdla_t *, xilinx_softc_t *);
! 232: static int xilinx_dma_tx (sdla_t *, xilinx_softc_t *);
! 233: static void xilinx_dma_tx_complete (sdla_t *, xilinx_softc_t *);
! 234: static void xilinx_dma_rx_complete (sdla_t *, xilinx_softc_t *);
! 235: static void xilinx_dma_max_logic_ch(sdla_t *);
! 236: static int xilinx_init_rx_dev_fifo(sdla_t *, xilinx_softc_t *,
! 237: unsigned char);
! 238: static void xilinx_init_tx_dma_descr(sdla_t *, xilinx_softc_t *);
! 239: static int xilinx_init_tx_dev_fifo(sdla_t *, xilinx_softc_t *,
! 240: unsigned char);
! 241: static void xilinx_tx_post_complete(sdla_t *, xilinx_softc_t *,
! 242: struct mbuf *);
! 243: static void xilinx_rx_post_complete(sdla_t *, xilinx_softc_t *,
! 244: struct xilinx_rx_buffer *, struct mbuf **, u_char *);
! 245:
! 246:
! 247: static char request_xilinx_logical_channel_num(sdla_t *, xilinx_softc_t *,
! 248: long *);
! 249: static void free_xilinx_logical_channel_num (sdla_t *, int);
! 250:
! 251:
! 252: static unsigned char read_cpld(sdla_t *, unsigned short);
! 253: static unsigned char write_cpld(sdla_t *, unsigned short, unsigned char);
! 254:
! 255: static void front_end_interrupt(sdla_t *, unsigned long);
! 256: static void enable_data_error_intr(sdla_t *);
! 257: static void disable_data_error_intr(sdla_t *, unsigned char);
! 258:
! 259: static void xilinx_tx_fifo_under_recover(sdla_t *, xilinx_softc_t *);
! 260:
! 261: static int xilinx_write_ctrl_hdlc(sdla_t *, u_int32_t,
! 262: u_int8_t, u_int32_t);
! 263:
! 264: static int set_chan_state(sdla_t*, struct ifnet*, int);
! 265:
! 266: static int fifo_error_interrupt(sdla_t *, unsigned long);
! 267: static int request_fifo_baddr_and_size(sdla_t *, xilinx_softc_t *);
! 268: static int map_fifo_baddr_and_size(sdla_t *,
! 269: unsigned char, unsigned char *);
! 270: static int free_fifo_baddr_and_size(sdla_t *, xilinx_softc_t *);
! 271:
! 272: static void aft_red_led_ctrl(sdla_t *, int);
! 273: static void aft_led_timer(void *);
! 274:
! 275: static int aft_core_ready(sdla_t *);
! 276: static int aft_alloc_rx_buffers(xilinx_softc_t *);
! 277: static void aft_release_rx_buffers(xilinx_softc_t *);
! 278: static int aft_alloc_rx_dma_buff(xilinx_softc_t *, int);
! 279: static void aft_reload_rx_dma_buff(xilinx_softc_t *,
! 280: struct xilinx_rx_buffer *);
! 281: static void aft_release_rx_dma_buff(xilinx_softc_t *,
! 282: struct xilinx_rx_buffer *);
! 283:
! 284:
! 285: /* TE1 Control registers */
! 286: static WRITE_FRONT_END_REG_T write_front_end_reg;
! 287: static READ_FRONT_END_REG_T read_front_end_reg;
! 288:
! 289: static void wan_ifmedia_sts(struct ifnet *, struct ifmediareq *);
! 290: static int wan_ifmedia_upd(struct ifnet *);
! 291:
! 292: static void
! 293: xilinx_delay(int sec)
! 294: {
! 295: #if 0
! 296: unsigned long timeout = ticks;
! 297: while ((ticks - timeout) < (sec * hz)) {
! 298: schedule();
! 299: }
! 300: #endif
! 301: }
! 302:
! 303: void *
! 304: wan_xilinx_init(sdla_t *card)
! 305: {
! 306: xilinx_softc_t *sc;
! 307: struct ifnet *ifp;
! 308:
! 309: /* Verify configuration ID */
! 310: bit_clear((u_int8_t *)&card->critical, CARD_DOWN);
! 311:
! 312: card->u.xilinx.num_of_ch = 0;
! 313: card->u.xilinx.mru_trans = 1500;
! 314: card->u.xilinx.dma_per_ch = 10;
! 315:
! 316: /* TE1 Make special hardware initialization for T1/E1 board */
! 317:
! 318: if (IS_TE1(&card->fe_te.te_cfg)) {
! 319: card->write_front_end_reg = write_front_end_reg;
! 320: card->read_front_end_reg = read_front_end_reg;
! 321: card->te_enable_timer = enable_timer;
! 322: card->te_link_state = handle_front_end_state;
! 323: } else
! 324: card->front_end_status = FE_CONNECTED;
! 325:
! 326: /* WARNING: After this point the init function
! 327: * must return with 0. The following bind
! 328: * functions will cause problems if structures
! 329: * below are not initialized */
! 330:
! 331: card->del_if = &wan_xilinx_release;
! 332: card->iface_up = &wan_xilinx_up;
! 333: card->iface_down = &wan_xilinx_down;
! 334: card->iface_send = &wan_xilinx_send;
! 335: card->iface_ioctl= &wan_xilinx_ioctl;
! 336:
! 337: write_cpld(card, LED_CONTROL_REG, 0x0E);
! 338:
! 339: sdla_getcfg(card->hw, SDLA_BASEADDR, &card->u.xilinx.bar);
! 340:
! 341: xilinx_delay(1);
! 342:
! 343: timeout_set(&card->u.xilinx.led_timer, aft_led_timer, (void *)card);
! 344:
! 345: /* allocate and initialize private data */
! 346: sc = malloc(sizeof(xilinx_softc_t), M_DEVBUF, M_NOWAIT);
! 347: if (sc == NULL)
! 348: return (NULL);
! 349:
! 350: memset(sc, 0, sizeof(xilinx_softc_t));
! 351: ifp = (struct ifnet *)&sc->common.ifp;
! 352: ifp->if_softc = sc;
! 353: sc->common.card = card;
! 354: if (wanpipe_generic_register(card, ifp, card->devname)) {
! 355: free(sc, M_DEVBUF);
! 356: return (NULL);
! 357: }
! 358:
! 359: strlcpy(sc->if_name, ifp->if_xname, IFNAMSIZ);
! 360: sc->first_time_slot = -1;
! 361: sc->time_slot_map = 0;
! 362: sdla_getcfg(card->hw, SDLA_DMATAG, &sc->dmatag);
! 363:
! 364: IFQ_SET_MAXLEN(&sc->wp_tx_pending_list, MAX_TX_BUF);
! 365: sc->wp_tx_pending_list.ifq_len = 0;
! 366: IFQ_SET_MAXLEN(&sc->wp_tx_complete_list, MAX_TX_BUF);
! 367: sc->wp_tx_complete_list.ifq_len = 0;
! 368:
! 369: aft_alloc_rx_buffers(sc);
! 370:
! 371: xilinx_delay(1);
! 372:
! 373: ifmedia_init(&sc->common.ifm, 0, wan_ifmedia_upd, wan_ifmedia_sts);
! 374:
! 375: if (IS_TE1(&card->fe_te.te_cfg)) {
! 376: ifmedia_add(&sc->common.ifm, IFM_TDM|IFM_TDM_T1, 0, NULL);
! 377: ifmedia_add(&sc->common.ifm, IFM_TDM|IFM_TDM_T1_AMI, 0, NULL);
! 378: ifmedia_add(&sc->common.ifm, IFM_TDM|IFM_TDM_E1, 0, NULL);
! 379: ifmedia_add(&sc->common.ifm, IFM_TDM|IFM_TDM_E1_AMI, 0, NULL);
! 380:
! 381: ifmedia_add(&sc->common.ifm,
! 382: IFM_TDM|IFM_TDM_T1|IFM_TDM_PPP, 0, NULL);
! 383: ifmedia_add(&sc->common.ifm,
! 384: IFM_TDM|IFM_TDM_T1_AMI|IFM_TDM_PPP, 0, NULL);
! 385: ifmedia_add(&sc->common.ifm,
! 386: IFM_TDM|IFM_TDM_E1|IFM_TDM_PPP, 0, NULL);
! 387: ifmedia_add(&sc->common.ifm,
! 388: IFM_TDM|IFM_TDM_E1_AMI|IFM_TDM_PPP, 0, NULL);
! 389:
! 390: ifmedia_set(&sc->common.ifm, IFM_TDM|IFM_TDM_T1);
! 391: } else {
! 392: /* Currently we not support ifmedia types for other
! 393: * front end types.
! 394: */
! 395: }
! 396:
! 397: return (sc);
! 398: }
! 399:
! 400: static int
! 401: wan_xilinx_release(sdla_t* card, struct ifnet* ifp)
! 402: {
! 403: xilinx_softc_t *sc = ifp->if_softc;
! 404:
! 405: IF_PURGE(&sc->wp_tx_pending_list);
! 406:
! 407: if (sc->tx_dma_addr && sc->tx_dma_len) {
! 408: sc->tx_dma_addr = 0;
! 409: sc->tx_dma_len = 0;
! 410: }
! 411:
! 412: if (sc->tx_dma_mbuf) {
! 413: log(LOG_INFO, "freeing tx dma mbuf\n");
! 414: bus_dmamap_unload(sc->dmatag, sc->tx_dmamap);
! 415: m_freem(sc->tx_dma_mbuf);
! 416: sc->tx_dma_mbuf = NULL;
! 417: }
! 418:
! 419: #if 0
! 420: bus_dmamap_destroy(sc->dmatag, sc->tx_dmamap);
! 421: #endif
! 422: if (sc->rx_dma_buf) {
! 423: SIMPLEQ_INSERT_TAIL(&sc->wp_rx_free_list,
! 424: sc->rx_dma_buf, entry);
! 425: sc->rx_dma_buf = NULL;
! 426: }
! 427:
! 428: aft_release_rx_buffers(sc);
! 429:
! 430: wanpipe_generic_unregister(ifp);
! 431: ifp->if_softc = NULL;
! 432: free(sc, M_DEVBUF);
! 433:
! 434: return (0);
! 435: }
! 436:
! 437: static void
! 438: wan_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmreq)
! 439: {
! 440: wanpipe_common_t *common = (wanpipe_common_t *)ifp->if_softc;
! 441: struct ifmedia *ifm;
! 442:
! 443: WAN_ASSERT1(common == NULL);
! 444: ifm = &common->ifm;
! 445: ifmreq->ifm_active = ifm->ifm_cur->ifm_media;
! 446: }
! 447:
! 448: static int
! 449: wan_ifmedia_upd(struct ifnet *ifp)
! 450: {
! 451: wanpipe_common_t *common = (wanpipe_common_t *)ifp->if_softc;
! 452: sdla_t *card;
! 453:
! 454: WAN_ASSERT(common == NULL);
! 455: WAN_ASSERT(common->card == NULL);
! 456: card = (sdla_t *)common->card;
! 457:
! 458: if (IS_TE1(&card->fe_te.te_cfg))
! 459: return (sdla_te_setcfg(ifp, &common->ifm));
! 460:
! 461: return (EINVAL);
! 462: }
! 463:
! 464:
! 465: /*
! 466: * KERNEL Device Entry Interfaces
! 467: */
! 468:
! 469: static int
! 470: wan_xilinx_up(struct ifnet *ifp)
! 471: {
! 472: xilinx_softc_t *sc = ifp->if_softc;
! 473: sdla_t *card = NULL;
! 474: struct timeval tv;
! 475: int err = 0;
! 476:
! 477: WAN_ASSERT(sc == NULL);
! 478: WAN_ASSERT(sc->common.card == NULL);
! 479: card = (sdla_t *)sc->common.card;
! 480:
! 481: if (card->state != WAN_DISCONNECTED)
! 482: return (0);
! 483:
! 484: sc->time_slot_map = card->fe_te.te_cfg.active_ch;
! 485: sc->dma_mtu = xilinx_valid_mtu(ifp->if_mtu+100);
! 486:
! 487: if (!sc->dma_mtu) {
! 488: log(LOG_INFO, "%s:%s: Error invalid MTU %lu\n",
! 489: card->devname, sc->if_name, ifp->if_mtu);
! 490: return (EINVAL);
! 491: }
! 492:
! 493: #ifdef DEBUG_INIT
! 494: log(LOG_INFO, "%s: Allocating %d dma mbuf len=%d\n",
! 495: card->devname, card->u.xilinx.dma_per_ch, sc->dma_mtu);
! 496: #endif
! 497: if (aft_alloc_rx_dma_buff(sc, card->u.xilinx.dma_per_ch) == 0)
! 498: return (ENOMEM);
! 499:
! 500: if (bus_dmamap_create(sc->dmatag, sc->dma_mtu, 1, sc->dma_mtu,
! 501: 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->tx_dmamap)) {
! 502: log(LOG_INFO, "%s: Failed to allocate tx dmamap\n",
! 503: sc->if_name);
! 504: return (ENOMEM);
! 505: }
! 506:
! 507: err = xilinx_chip_configure(card);
! 508: if (err)
! 509: return (EINVAL);
! 510:
! 511: card->isr = &wp_xilinx_isr;
! 512:
! 513: err = xilinx_dev_configure(card, sc);
! 514: if (err) {
! 515: xilinx_chip_unconfigure(card);
! 516: return (EINVAL);
! 517: }
! 518: xilinx_delay(1);
! 519:
! 520: /* Initialize the router start time.
! 521: * Used by wanpipemon debugger to indicate
! 522: * how long has the interface been up */
! 523: microtime(&tv);
! 524: sc->router_start_time = tv.tv_sec;
! 525:
! 526: xilinx_init_tx_dma_descr(card, sc);
! 527: xilinx_dev_enable(card, sc);
! 528:
! 529: sc->ignore_modem = 0x0F;
! 530: bit_clear((u_int8_t *)&card->critical, CARD_DOWN);
! 531: port_set_state(card, WAN_CONNECTING);
! 532:
! 533: return (err);
! 534: }
! 535:
! 536: static int
! 537: wan_xilinx_down(struct ifnet *ifp)
! 538: {
! 539: xilinx_softc_t *sc = ifp->if_softc;
! 540: sdla_t *card = (sdla_t *)sc->common.card;
! 541: struct xilinx_rx_buffer *buf;
! 542: int s;
! 543:
! 544: if (card->state == WAN_DISCONNECTED)
! 545: return (0);
! 546:
! 547: xilinx_dev_close(card, sc);
! 548:
! 549: /* Disable DMA ENGINE before we perform
! 550: * core reset. Otherwise, we will receive
! 551: * rx fifo errors on subsequent resetart. */
! 552: disable_data_error_intr(card, DEVICE_DOWN);
! 553:
! 554: bit_set((u_int8_t *)&card->critical, CARD_DOWN);
! 555:
! 556: timeout_del(&card->u.xilinx.led_timer);
! 557:
! 558: /* TE1 - Unconfiging, only on shutdown */
! 559: if (IS_TE1(&card->fe_te.te_cfg))
! 560: sdla_te_unconfig(card);
! 561:
! 562: s = splnet();
! 563:
! 564: card->isr = NULL;
! 565:
! 566: if (sc->tx_dma_addr && sc->tx_dma_len) {
! 567: sc->tx_dma_addr = 0;
! 568: sc->tx_dma_len = 0;
! 569: }
! 570:
! 571: if (sc->tx_dma_mbuf) {
! 572: bus_dmamap_unload(sc->dmatag, sc->tx_dmamap);
! 573: m_freem(sc->tx_dma_mbuf);
! 574: sc->tx_dma_mbuf = NULL;
! 575: }
! 576:
! 577: bus_dmamap_destroy(sc->dmatag, sc->tx_dmamap);
! 578:
! 579: /* If there is something left in rx_dma_buf, then move it to
! 580: * rx_free_list.
! 581: */
! 582: if (sc->rx_dma_buf) {
! 583: aft_reload_rx_dma_buff(sc, sc->rx_dma_buf);
! 584: sc->rx_dma_buf = NULL;
! 585: }
! 586:
! 587: while ((buf = SIMPLEQ_FIRST(&sc->wp_rx_free_list)) != NULL) {
! 588: SIMPLEQ_REMOVE_HEAD(&sc->wp_rx_free_list, entry);
! 589: aft_release_rx_dma_buff(sc, buf);
! 590: }
! 591:
! 592: while ((buf = SIMPLEQ_FIRST(&sc->wp_rx_complete_list)) != NULL) {
! 593: SIMPLEQ_REMOVE_HEAD(&sc->wp_rx_complete_list, entry);
! 594: aft_release_rx_dma_buff(sc, buf);
! 595: }
! 596:
! 597: splx(s);
! 598:
! 599: DELAY(10);
! 600:
! 601: xilinx_dev_unconfigure(card, sc);
! 602: xilinx_chip_unconfigure(card);
! 603:
! 604: port_set_state(card, WAN_DISCONNECTED);
! 605: sc->ignore_modem = 0x00;
! 606: return (0);
! 607: }
! 608:
! 609: static int
! 610: wan_xilinx_send(struct mbuf* m, struct ifnet* ifp)
! 611: {
! 612:
! 613: xilinx_softc_t *sc = ifp->if_softc;
! 614: sdla_t *card = (sdla_t *)sc->common.card;
! 615:
! 616: /* Mark interface as busy. The kernel will not
! 617: * attempt to send any more packets until we clear
! 618: * this condition */
! 619:
! 620: if (m == NULL)
! 621: /* This should never happen. Just a sanity check.
! 622: */
! 623: return (EINVAL);
! 624:
! 625: if (card->state != WAN_CONNECTED) {
! 626: /*
! 627: * The card is still not ready to transmit...
! 628: * drop this packet!
! 629: */
! 630: m_freem(m);
! 631: return (EINVAL);
! 632:
! 633: } else {
! 634: if (IF_QFULL(&sc->wp_tx_pending_list)) {
! 635: int err;
! 636: #ifdef DEBUG_TX
! 637: log(LOG_INFO, "%s: Tx pending queue FULL\n",
! 638: ifp->if_xname);
! 639: #endif
! 640: /*
! 641: * TX pending queue is full. Try to send packet
! 642: * from tx_pending queue (first)
! 643: */
! 644: err = xilinx_dma_tx(card, sc);
! 645: if (!err && !IF_QFULL(&sc->wp_tx_pending_list))
! 646: /*
! 647: * On success, we have place for the new
! 648: * tx packet, try to send it now!
! 649: */
! 650: goto wan_xilinx_dma_tx_try;
! 651:
! 652: /*
! 653: * Tx pedning queue is full. I can't accept new
! 654: * tx packet, drop this packet and set interface
! 655: * queue to OACTIVE
! 656: */
! 657: m_freem(m);
! 658: ifp->if_flags |= IFF_OACTIVE;
! 659:
! 660: return (EBUSY);
! 661: } else {
! 662: wan_xilinx_dma_tx_try:
! 663: IF_ENQUEUE(&sc->wp_tx_pending_list, m);
! 664: xilinx_dma_tx(card, sc);
! 665: }
! 666: }
! 667:
! 668: return (0);
! 669: }
! 670:
! 671: static int
! 672: wan_xilinx_ioctl(struct ifnet *ifp, int cmd, struct ifreq *ifr)
! 673: {
! 674: xilinx_softc_t *sc = (xilinx_softc_t *)ifp->if_softc;
! 675: struct mbuf *m;
! 676: sdla_t *card;
! 677: wan_udp_pkt_t *wan_udp_pkt;
! 678: int err = 0;
! 679:
! 680: if (!sc)
! 681: return (ENODEV);
! 682:
! 683: card = (sdla_t *)sc->common.card;
! 684:
! 685: switch (cmd) {
! 686: case SIOC_WANPIPE_PIPEMON:
! 687:
! 688: if ((err = suser(curproc, 0)) != 0)
! 689: break;
! 690:
! 691: if (IF_QFULL(&sc->udp_queue))
! 692: return (EBUSY);
! 693:
! 694: /*
! 695: * For performance reasons test the critical
! 696: * here before spin lock
! 697: */
! 698: if (bit_test((u_int8_t *)&card->in_isr, 0))
! 699: return (EBUSY);
! 700:
! 701: m = wan_mbuf_alloc(sizeof(wan_udp_pkt_t));
! 702: if (m == NULL)
! 703: return (ENOMEM);
! 704:
! 705: wan_udp_pkt = mtod(m, wan_udp_pkt_t *);
! 706: if (copyin(ifr->ifr_data, &wan_udp_pkt->wan_udp_hdr,
! 707: sizeof(wan_udp_hdr_t))) {
! 708: m_freem(m);
! 709: return (EFAULT);
! 710: }
! 711: IF_ENQUEUE(&sc->udp_queue, m);
! 712:
! 713: process_udp_mgmt_pkt(card, ifp, sc, 1);
! 714:
! 715: if (copyout(&wan_udp_pkt->wan_udp_hdr, ifr->ifr_data,
! 716: sizeof(wan_udp_hdr_t))) {
! 717: m_freem(m);
! 718: return (EFAULT);
! 719: }
! 720:
! 721: IF_DEQUEUE(&sc->udp_queue, m);
! 722: m_freem(m);
! 723: return (0);
! 724:
! 725: default:
! 726: if (card->ioctl)
! 727: err = card->ioctl(ifp, cmd, ifr);
! 728: break;
! 729: }
! 730:
! 731: return (err);
! 732: }
! 733:
! 734: /*
! 735: * Process all "wanpipemon" debugger commands. This function
! 736: * performs all debugging tasks:
! 737: *
! 738: * Line Tracing
! 739: * Line/Hardware Statistics
! 740: * Protocol Statistics
! 741: *
! 742: * "wanpipemon" utility is a user-space program that
! 743: * is used to debug the WANPIPE product.
! 744: */
! 745: static int
! 746: process_udp_mgmt_pkt(sdla_t* card, struct ifnet* ifp,
! 747: xilinx_softc_t* sc, int local_dev )
! 748: {
! 749: struct mbuf *m;
! 750: unsigned short buffer_length;
! 751: wan_udp_pkt_t *wan_udp_pkt;
! 752: wan_trace_t *trace_info = NULL;
! 753: struct timeval tv;
! 754:
! 755: IF_POLL(&sc->udp_queue, m);
! 756: if (m == NULL)
! 757: return (EINVAL);
! 758:
! 759: wan_udp_pkt = mtod(m, wan_udp_pkt_t *);
! 760: trace_info=&sc->trace_info;
! 761:
! 762: {
! 763: struct mbuf *m0;
! 764:
! 765: wan_udp_pkt->wan_udp_opp_flag = 0;
! 766:
! 767: switch (wan_udp_pkt->wan_udp_command) {
! 768:
! 769: case READ_CONFIGURATION:
! 770: case READ_CODE_VERSION:
! 771: wan_udp_pkt->wan_udp_return_code = 0;
! 772: wan_udp_pkt->wan_udp_data_len = 0;
! 773: break;
! 774:
! 775:
! 776: case ENABLE_TRACING:
! 777:
! 778: wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
! 779: wan_udp_pkt->wan_udp_data_len = 0;
! 780:
! 781: if (!bit_test((u_int8_t *)
! 782: &trace_info->tracing_enabled, 0)) {
! 783:
! 784: trace_info->trace_timeout = ticks;
! 785:
! 786: IF_PURGE(&trace_info->ifq);
! 787: if (wan_udp_pkt->wan_udp_data[0] == 0) {
! 788: bit_clear((u_int8_t *)
! 789: &trace_info->tracing_enabled, 1);
! 790: log(LOG_INFO, "%s: ADSL L3 "
! 791: "trace enabled!\n", card->devname);
! 792: } else if (wan_udp_pkt->wan_udp_data[0] == 1) {
! 793: bit_clear((u_int8_t *)
! 794: &trace_info->tracing_enabled, 2 );
! 795: bit_set((u_int8_t *)
! 796: &trace_info->tracing_enabled, 1);
! 797: log(LOG_INFO, "%s: ADSL L2 "
! 798: "trace enabled!\n", card->devname);
! 799: } else {
! 800: bit_clear((u_int8_t *)
! 801: &trace_info->tracing_enabled, 1);
! 802: bit_set((u_int8_t *)
! 803: &trace_info->tracing_enabled, 2);
! 804: log(LOG_INFO, "%s: ADSL L1 "
! 805: "trace enabled!\n", card->devname);
! 806: }
! 807: bit_set((u_int8_t *)&
! 808: trace_info->tracing_enabled, 0);
! 809:
! 810: } else {
! 811: log(LOG_INFO, "%s: Error: AFT "
! 812: "trace running!\n", card->devname);
! 813: wan_udp_pkt->wan_udp_return_code = 2;
! 814: }
! 815:
! 816: break;
! 817:
! 818: case DISABLE_TRACING:
! 819: wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
! 820:
! 821: if (bit_test((u_int8_t *)
! 822: &trace_info->tracing_enabled, 0)) {
! 823: bit_clear((u_int8_t *)
! 824: &trace_info->tracing_enabled, 0);
! 825: bit_clear((u_int8_t *)
! 826: &trace_info->tracing_enabled, 1);
! 827: bit_clear((u_int8_t *)
! 828: &trace_info->tracing_enabled, 2);
! 829: IF_PURGE(&trace_info->ifq);
! 830: log(LOG_INFO, "%s: Disabling ADSL trace\n",
! 831: card->devname);
! 832: } else {
! 833: /*
! 834: * set return code to line trace already
! 835: * disabled
! 836: */
! 837: wan_udp_pkt->wan_udp_return_code = 1;
! 838: }
! 839:
! 840: break;
! 841:
! 842: case GET_TRACE_INFO:
! 843: if (bit_test((u_int8_t *)
! 844: &trace_info->tracing_enabled, 0)) {
! 845: trace_info->trace_timeout = ticks;
! 846: } else {
! 847: log(LOG_INFO, "%s: Error AFT trace "
! 848: "not enabled\n", card->devname);
! 849: /* set return code */
! 850: wan_udp_pkt->wan_udp_return_code = 1;
! 851: break;
! 852: }
! 853:
! 854: buffer_length = 0;
! 855: wan_udp_pkt->wan_udp_aft_num_frames = 0;
! 856: wan_udp_pkt->wan_udp_aft_ismoredata = 0;
! 857:
! 858: while (!IF_IS_EMPTY(&trace_info->ifq)) {
! 859: IF_POLL(&trace_info->ifq, m0);
! 860: if (m0 == NULL) {
! 861: log(LOG_INFO, "%s: No more "
! 862: "trace packets in trace queue!\n",
! 863: card->devname);
! 864: break;
! 865: }
! 866: if ((WAN_MAX_DATA_SIZE - buffer_length) <
! 867: m0->m_pkthdr.len) {
! 868: /*
! 869: * indicate there are more frames
! 870: * on board & exit
! 871: */
! 872: wan_udp_pkt->wan_udp_aft_ismoredata
! 873: = 0x01;
! 874: break;
! 875: }
! 876:
! 877: m_copydata(m0, 0, m0->m_pkthdr.len,
! 878: &wan_udp_pkt->wan_udp_data[buffer_length]);
! 879: buffer_length += m0->m_pkthdr.len;
! 880: IF_DEQUEUE(&trace_info->ifq, m0);
! 881: if (m0)
! 882: m_freem(m0);
! 883: wan_udp_pkt->wan_udp_aft_num_frames++;
! 884: }
! 885: /* set the data length and return code */
! 886: wan_udp_pkt->wan_udp_data_len = buffer_length;
! 887: wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
! 888: break;
! 889:
! 890: case ROUTER_UP_TIME:
! 891: microtime(&tv);
! 892: sc->router_up_time = tv.tv_sec;
! 893: sc->router_up_time -= sc->router_start_time;
! 894: *(unsigned long *)&wan_udp_pkt->wan_udp_data =
! 895: sc->router_up_time;
! 896: wan_udp_pkt->wan_udp_data_len = sizeof(unsigned long);
! 897: wan_udp_pkt->wan_udp_return_code = 0;
! 898: break;
! 899:
! 900: case WAN_GET_MEDIA_TYPE:
! 901: case WAN_FE_GET_STAT:
! 902: case WAN_FE_SET_LB_MODE:
! 903: case WAN_FE_FLUSH_PMON:
! 904: case WAN_FE_GET_CFG:
! 905:
! 906: if (IS_TE1(&card->fe_te.te_cfg)) {
! 907: sdla_te_udp(card,
! 908: &wan_udp_pkt->wan_udp_cmd,
! 909: &wan_udp_pkt->wan_udp_data[0]);
! 910: } else {
! 911: if (wan_udp_pkt->wan_udp_command ==
! 912: WAN_GET_MEDIA_TYPE) {
! 913: wan_udp_pkt->wan_udp_data_len =
! 914: sizeof(unsigned char);
! 915: wan_udp_pkt->wan_udp_return_code =
! 916: WAN_CMD_OK;
! 917: } else {
! 918: wan_udp_pkt->wan_udp_return_code =
! 919: WAN_UDP_INVALID_CMD;
! 920: }
! 921: }
! 922: break;
! 923:
! 924: case WAN_GET_PROTOCOL:
! 925: wan_udp_pkt->wan_udp_aft_num_frames = WANCONFIG_AFT;
! 926: wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
! 927: wan_udp_pkt->wan_udp_data_len = 1;
! 928: break;
! 929:
! 930: case WAN_GET_PLATFORM:
! 931: wan_udp_pkt->wan_udp_data[0] = WAN_PLATFORM_ID;
! 932: wan_udp_pkt->wan_udp_return_code = WAN_CMD_OK;
! 933: wan_udp_pkt->wan_udp_data_len = 1;
! 934: break;
! 935:
! 936: default:
! 937: wan_udp_pkt->wan_udp_data_len = 0;
! 938: wan_udp_pkt->wan_udp_return_code = 0xCD;
! 939:
! 940: log(LOG_INFO, "%s: Warning, Illegal UDP "
! 941: "command attempted from network: %x\n",
! 942: card->devname, wan_udp_pkt->wan_udp_command);
! 943: break;
! 944: }
! 945: }
! 946:
! 947: wan_udp_pkt->wan_udp_request_reply = UDPMGMT_REPLY;
! 948: return (1);
! 949: }
! 950:
! 951: /*
! 952: * FIRMWARE Specific Interface Functions
! 953: */
! 954:
! 955: static int
! 956: xilinx_chip_configure(sdla_t *card)
! 957: {
! 958: u_int32_t reg, tmp;
! 959: int err = 0;
! 960: u_int16_t adapter_type, adptr_security;
! 961:
! 962: #ifdef DEBUG_INIT
! 963: log(LOG_DEBUG, "Xilinx Chip Configuration. -- \n");
! 964: #endif
! 965: xilinx_delay(1);
! 966:
! 967: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 968:
! 969: /* Configure for T1 or E1 front end */
! 970: if (IS_T1(&card->fe_te.te_cfg)) {
! 971: card->u.xilinx.num_of_time_slots = NUM_OF_T1_CHANNELS;
! 972: bit_clear((u_int8_t *)®, INTERFACE_TYPE_T1_E1_BIT);
! 973: bit_set((u_int8_t *)®, FRONT_END_FRAME_FLAG_ENABLE_BIT);
! 974: } else if (IS_E1(&card->fe_te.te_cfg)) {
! 975: card->u.xilinx.num_of_time_slots = NUM_OF_E1_CHANNELS;
! 976: bit_set((u_int8_t *)®, INTERFACE_TYPE_T1_E1_BIT);
! 977: bit_set((u_int8_t *)®, FRONT_END_FRAME_FLAG_ENABLE_BIT);
! 978: } else {
! 979: log(LOG_INFO, "%s: Error: Xilinx doesn't "
! 980: "support non T1/E1 interface!\n", card->devname);
! 981: return (EINVAL);
! 982: }
! 983:
! 984: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 985:
! 986: DELAY(10000);
! 987:
! 988: /* Reset PMC */
! 989: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 990: bit_clear((u_int8_t *)®, FRONT_END_RESET_BIT);
! 991: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 992: DELAY(1000);
! 993:
! 994: bit_set((u_int8_t *)®, FRONT_END_RESET_BIT);
! 995: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 996: DELAY(100);
! 997:
! 998: #ifdef DEBUG_INIT
! 999: log(LOG_DEBUG, "--- Chip Reset. -- \n");
! 1000: #endif
! 1001:
! 1002: /* Reset Chip Core */
! 1003: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 1004: bit_set((u_int8_t *)®, CHIP_RESET_BIT);
! 1005: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1006:
! 1007: DELAY(100);
! 1008:
! 1009: /* Disable the chip/hdlc reset condition */
! 1010: bit_clear((u_int8_t *)®, CHIP_RESET_BIT);
! 1011:
! 1012: /* Disable ALL chip interrupts */
! 1013: bit_clear((u_int8_t *)®, GLOBAL_INTR_ENABLE_BIT);
! 1014: bit_clear((u_int8_t *)®, ERROR_INTR_ENABLE_BIT);
! 1015: bit_clear((u_int8_t *)®, FRONT_END_INTR_ENABLE_BIT);
! 1016:
! 1017: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1018:
! 1019: xilinx_delay(1);
! 1020:
! 1021: sdla_getcfg(card->hw, SDLA_ADAPTERTYPE, &adapter_type);
! 1022: DELAY(100);
! 1023:
! 1024: #ifdef DEBUG_INIT
! 1025: log(LOG_INFO, "%s: Hardware Adapter Type 0x%X\n",
! 1026: card->devname, adapter_type);
! 1027: #endif
! 1028:
! 1029: adptr_security = read_cpld(card, SECURITY_CPLD_REG);
! 1030: adptr_security = adptr_security >> SECURITY_CPLD_SHIFT;
! 1031: adptr_security = adptr_security & SECURITY_CPLD_MASK;
! 1032:
! 1033: #ifdef DEBUG_INIT
! 1034: switch (adptr_security) {
! 1035: case SECURITY_1LINE_UNCH:
! 1036: log(LOG_INFO, "%s: Security 1 Line UnCh\n", card->devname);
! 1037: break;
! 1038: case SECURITY_1LINE_CH:
! 1039: log(LOG_INFO, "%s: Security 1 Line Ch\n", card->devname);
! 1040: break;
! 1041: case SECURITY_2LINE_UNCH:
! 1042: log(LOG_INFO, "%s: Security 2 Line UnCh\n", card->devname);
! 1043: break;
! 1044: case SECURITY_2LINE_CH:
! 1045: log(LOG_INFO, "%s: Security 2 Line Ch\n", card->devname);
! 1046: break;
! 1047: default:
! 1048: log(LOG_INFO, "%s: Error Invalid Security ID = 0x%X\n",
! 1049: card->devname, adptr_security);
! 1050: /* return EINVAL;*/
! 1051: }
! 1052: #endif
! 1053:
! 1054: /* Turn off Onboard RED LED */
! 1055: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 1056: bit_set((u_int8_t *)®, XILINX_RED_LED);
! 1057: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1058: DELAY(10);
! 1059:
! 1060: err = aft_core_ready(card);
! 1061: if (err != 0)
! 1062: log(LOG_INFO, "%s: WARNING: HDLC Core Not Ready: B4 TE CFG!\n",
! 1063: card->devname);
! 1064:
! 1065: log(LOG_INFO, "%s: Configuring A101 PMC T1/E1/J1 Front End\n",
! 1066: card->devname);
! 1067:
! 1068: if (sdla_te_config(card)) {
! 1069: log(LOG_INFO, "%s: Failed %s configuratoin!\n", card->devname,
! 1070: IS_T1(&card->fe_te.te_cfg)?"T1":"E1");
! 1071: return (EINVAL);
! 1072: }
! 1073:
! 1074: xilinx_delay(1);
! 1075:
! 1076: err = aft_core_ready(card);
! 1077: if (err != 0) {
! 1078: log(LOG_INFO, "%s: Error: HDLC Core Not Ready!\n",
! 1079: card->devname);
! 1080:
! 1081: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 1082:
! 1083: /* Disable the chip/hdlc reset condition */
! 1084: bit_set((u_int8_t *)®, CHIP_RESET_BIT);
! 1085:
! 1086: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1087: return (err);
! 1088: }
! 1089:
! 1090: #ifdef DEBUG_INIT
! 1091: log(LOG_INFO, "%s: HDLC Core Ready 0x%08X\n",
! 1092: card->devname, reg);
! 1093: #endif
! 1094:
! 1095: xilinx_delay(1);
! 1096:
! 1097: /* Setup global DMA parameters */
! 1098: reg = 0;
! 1099: reg|=(XILINX_DMA_SIZE << DMA_SIZE_BIT_SHIFT);
! 1100: reg|=(XILINX_DMA_FIFO_UP << DMA_FIFO_HI_MARK_BIT_SHIFT);
! 1101: reg|=(XILINX_DMA_FIFO_LO << DMA_FIFO_LO_MARK_BIT_SHIFT);
! 1102:
! 1103: /*
! 1104: * Enable global DMA engine and set to default
! 1105: * number of active channels. Note: this value will
! 1106: * change in dev configuration
! 1107: */
! 1108: reg|=(XILINX_DEFLT_ACTIVE_CH << DMA_ACTIVE_CHANNEL_BIT_SHIFT);
! 1109: bit_set((u_int8_t *)®, DMA_ENGINE_ENABLE_BIT);
! 1110:
! 1111: #ifdef DEBUG_INIT
! 1112: log(LOG_INFO, "--- Setup DMA control Reg. -- \n");
! 1113: #endif
! 1114:
! 1115: sdla_bus_write_4(card->hw, XILINX_DMA_CONTROL_REG, reg);
! 1116:
! 1117: #ifdef DEBUG_INIT
! 1118: log(LOG_INFO, "--- Tx/Rx global enable. -- \n");
! 1119: #endif
! 1120:
! 1121: xilinx_delay(1);
! 1122:
! 1123: reg = 0;
! 1124: sdla_bus_write_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG, reg);
! 1125:
! 1126: /* Clear interrupt pending registers befor first interrupt enable */
! 1127: sdla_bus_read_4(card->hw, XILINX_DMA_RX_INTR_PENDING_REG, &tmp);
! 1128: sdla_bus_read_4(card->hw, XILINX_DMA_TX_INTR_PENDING_REG, &tmp);
! 1129: sdla_bus_read_4(card->hw, XILINX_HDLC_RX_INTR_PENDING_REG, &tmp);
! 1130: sdla_bus_read_4(card->hw, XILINX_HDLC_TX_INTR_PENDING_REG, &tmp);
! 1131: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, (u_int32_t *)®);
! 1132: if (bit_test((u_int8_t *)®, DMA_INTR_FLAG)) {
! 1133: log(LOG_INFO, "%s: Error: Active DMA Interrupt Pending. !\n",
! 1134: card->devname);
! 1135:
! 1136: reg = 0;
! 1137: /* Disable the chip/hdlc reset condition */
! 1138: bit_set((u_int8_t *)®, CHIP_RESET_BIT);
! 1139: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1140: return (err);
! 1141: }
! 1142: if (bit_test((u_int8_t *)®, ERROR_INTR_FLAG)) {
! 1143: log(LOG_INFO, "%s: Error: Active Error Interrupt Pending. !\n",
! 1144: card->devname);
! 1145:
! 1146: reg = 0;
! 1147: /* Disable the chip/hdlc reset condition */
! 1148: bit_set((u_int8_t *)®, CHIP_RESET_BIT);
! 1149: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1150: return (err);
! 1151: }
! 1152:
! 1153:
! 1154: /* Alawys disable global data and error interrupts */
! 1155: bit_clear((u_int8_t *)®, GLOBAL_INTR_ENABLE_BIT);
! 1156: bit_clear((u_int8_t *)®, ERROR_INTR_ENABLE_BIT);
! 1157:
! 1158: /* Always enable the front end interrupt */
! 1159: bit_set((u_int8_t *)®, FRONT_END_INTR_ENABLE_BIT);
! 1160:
! 1161: #ifdef DEBUG_INIT
! 1162: log(LOG_DEBUG, "--- Set Global Interrupts (0x%X)-- \n", reg);
! 1163: #endif
! 1164:
! 1165: xilinx_delay(1);
! 1166:
! 1167: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1168:
! 1169: return (err);
! 1170: }
! 1171:
! 1172: static int
! 1173: xilinx_chip_unconfigure(sdla_t *card)
! 1174: {
! 1175: u_int32_t reg = 0;
! 1176:
! 1177: sdla_bus_write_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG, reg);
! 1178: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 1179: /* Enable the chip/hdlc reset condition */
! 1180: reg = 0;
! 1181: bit_set((u_int8_t *)®, CHIP_RESET_BIT);
! 1182:
! 1183: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 1184: return (0);
! 1185: }
! 1186:
! 1187: static int
! 1188: xilinx_dev_configure(sdla_t *card, xilinx_softc_t *sc)
! 1189: {
! 1190: u_int32_t reg;
! 1191: long free_logic_ch, i;
! 1192:
! 1193: sc->logic_ch_num=-1;
! 1194:
! 1195: if (!IS_TE1(&card->fe_te.te_cfg))
! 1196: return (EINVAL);
! 1197:
! 1198: if (IS_E1(&card->fe_te.te_cfg)) {
! 1199: log(LOG_DEBUG, "%s: Time Slot Orig 0x%lX Shifted 0x%lX\n",
! 1200: sc->if_name, sc->time_slot_map, sc->time_slot_map << 1);
! 1201: sc->time_slot_map = sc->time_slot_map << 1;
! 1202: bit_clear((u_int8_t *)&sc->time_slot_map, 0);
! 1203: }
! 1204:
! 1205: /*
! 1206: * Channel definition section. If not channels defined
! 1207: * return error
! 1208: */
! 1209: if (sc->time_slot_map == 0) {
! 1210: log(LOG_INFO, "%s: Invalid Channel Selection 0x%lX\n",
! 1211: card->devname, sc->time_slot_map);
! 1212: return (EINVAL);
! 1213: }
! 1214:
! 1215: #ifdef DEBUG_INIT
! 1216: log(LOG_INFO, "%s:%s: Active channels = 0x%lX\n", card->devname,
! 1217: sc->if_name, sc->time_slot_map);
! 1218: #endif
! 1219: xilinx_delay(1);
! 1220:
! 1221: /*
! 1222: * Check that the time slot is not being used. If it is
! 1223: * stop the interface setup. Notice, though we proceed
! 1224: * to check for all timeslots before we start binding
! 1225: * the channels in. This way, we don't have to go back
! 1226: * and clean the time_slot_map
! 1227: */
! 1228: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 1229: if (bit_test((u_int8_t *)&sc->time_slot_map, i)) {
! 1230:
! 1231: if (sc->first_time_slot == -1) {
! 1232: #ifdef DEBUG_INIT
! 1233: log(LOG_INFO, "%s: Setting first time "
! 1234: "slot to %ld\n", card->devname, i);
! 1235: #endif
! 1236: sc->first_time_slot = i;
! 1237: }
! 1238:
! 1239: #ifdef DEBUG_INIT
! 1240: log(LOG_DEBUG, "%s: Configuring %s for timeslot %ld\n",
! 1241: card->devname, sc->if_name,
! 1242: IS_E1(&card->fe_te.te_cfg)?i:i+1);
! 1243: #endif
! 1244: if (bit_test((u_int8_t *)
! 1245: &card->u.xilinx.time_slot_map, i)) {
! 1246: log(LOG_INFO, "%s: Channel/Time Slot "
! 1247: "resource conflict!\n", card->devname);
! 1248: log(LOG_INFO, "%s: %s: Channel/Time Slot "
! 1249: "%ld, aready in use!\n",
! 1250: card->devname, sc->if_name, (i+1));
! 1251:
! 1252: return (EEXIST);
! 1253: }
! 1254:
! 1255: /* Calculate the number of timeslots for this if */
! 1256: ++sc->num_of_time_slots;
! 1257: }
! 1258: }
! 1259:
! 1260: xilinx_delay(1);
! 1261:
! 1262: sc->logic_ch_num = request_xilinx_logical_channel_num(card,
! 1263: sc, &free_logic_ch);
! 1264: if (sc->logic_ch_num == -1)
! 1265: return (EBUSY);
! 1266:
! 1267: xilinx_delay(1);
! 1268:
! 1269: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 1270: if (bit_test((u_int8_t *)&sc->time_slot_map, i)) {
! 1271:
! 1272: bit_set((u_int8_t *)&card->u.xilinx.time_slot_map, i);
! 1273:
! 1274: sdla_bus_read_4(card->hw,
! 1275: XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 1276: reg &= ~TIMESLOT_BIT_MASK;
! 1277:
! 1278: /* FIXME do not hardcode !*/
! 1279: reg &= HDLC_LCH_TIMESLOT_MASK; /* mask not valid bits*/
! 1280:
! 1281: /* Select a Timeslot for configuration */
! 1282: sdla_bus_write_4(card->hw,
! 1283: XILINX_TIMESLOT_HDLC_CHAN_REG,
! 1284: (reg | (i << TIMESLOT_BIT_SHIFT)));
! 1285:
! 1286: reg = sc->logic_ch_num & CONTROL_RAM_DATA_MASK;
! 1287:
! 1288: #ifdef TRUE_FIFO_SIZE
! 1289: reg |= (sc->fifo_size_code & HDLC_FIFO_SIZE_MASK) <<
! 1290: HDLC_FIFO_SIZE_SHIFT;
! 1291: #else
! 1292: reg |= (HARD_FIFO_CODE &
! 1293: HDLC_FIFO_SIZE_MASK) << HDLC_FIFO_SIZE_SHIFT;
! 1294: #endif /* TRUE_FIFO_SIZE */
! 1295:
! 1296: reg |= (sc->fifo_base_addr & HDLC_FIFO_BASE_ADDR_MASK)
! 1297: << HDLC_FIFO_BASE_ADDR_SHIFT;
! 1298:
! 1299: #ifdef DEBUG_INIT
! 1300: log(LOG_INFO, "Setting Timeslot %ld to logic "
! 1301: "ch %ld Reg=0x%X\n", i, sc->logic_ch_num, reg);
! 1302: #endif
! 1303: xilinx_write_ctrl_hdlc(card, i,
! 1304: XILINX_CONTROL_RAM_ACCESS_BUF, reg);
! 1305: }
! 1306: }
! 1307:
! 1308: if (free_logic_ch != -1) {
! 1309:
! 1310: char free_ch_used = 0;
! 1311:
! 1312: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 1313: if (!bit_test((u_int8_t *)
! 1314: &card->u.xilinx.time_slot_map, i)) {
! 1315:
! 1316: sdla_bus_read_4(card->hw,
! 1317: XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 1318:
! 1319: reg &= ~TIMESLOT_BIT_MASK;
! 1320: /* mask not valid bits */
! 1321: reg &= HDLC_LCH_TIMESLOT_MASK;
! 1322:
! 1323: /* Select a Timeslot for configuration */
! 1324: sdla_bus_write_4(card->hw,
! 1325: XILINX_TIMESLOT_HDLC_CHAN_REG,
! 1326: (reg | (i << TIMESLOT_BIT_SHIFT)));
! 1327:
! 1328: reg = free_logic_ch&CONTROL_RAM_DATA_MASK;
! 1329:
! 1330: /* For the rest of the unused logic channels
! 1331: * bind them to timeslot 31 and set the fifo
! 1332: * size to 32 byte = Code = 0x00 */
! 1333: reg |= (FIFO_32B & HDLC_FIFO_SIZE_MASK)
! 1334: << HDLC_FIFO_SIZE_SHIFT;
! 1335:
! 1336: reg |= (free_logic_ch &
! 1337: HDLC_FIFO_BASE_ADDR_MASK) <<
! 1338: HDLC_FIFO_BASE_ADDR_SHIFT;
! 1339:
! 1340: #ifdef DEBUG_INIT
! 1341: log(LOG_INFO, "Setting Timeslot "
! 1342: "%ld to free logic ch %ld Reg=0x%X\n",
! 1343: i, free_logic_ch, reg);
! 1344: #endif
! 1345: xilinx_write_ctrl_hdlc(card, i,
! 1346: XILINX_CONTROL_RAM_ACCESS_BUF, reg);
! 1347:
! 1348: free_ch_used = 1;
! 1349: }
! 1350: }
! 1351:
! 1352: /* We must check if the free logic has been bound
! 1353: * to any timeslots */
! 1354: if (free_ch_used) {
! 1355: #ifdef DEBUG_INIT
! 1356: log(LOG_INFO, "%s: Setting Free CH %ld to idle\n",
! 1357: sc->if_name, free_logic_ch);
! 1358: #endif
! 1359: xilinx_delay(1);
! 1360:
! 1361: /* Setup the free logic channel as IDLE */
! 1362:
! 1363: sdla_bus_read_4(card->hw,
! 1364: XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 1365:
! 1366: reg &= ~HDLC_LOGIC_CH_BIT_MASK;
! 1367:
! 1368: /* mask not valid bits */
! 1369: reg &= HDLC_LCH_TIMESLOT_MASK;
! 1370:
! 1371: sdla_bus_write_4(card->hw,
! 1372: XILINX_TIMESLOT_HDLC_CHAN_REG,
! 1373: (reg|(free_logic_ch&HDLC_LOGIC_CH_BIT_MASK)));
! 1374:
! 1375: reg = 0;
! 1376: bit_clear((u_int8_t *)®, HDLC_RX_PROT_DISABLE_BIT);
! 1377: bit_clear((u_int8_t *)®, HDLC_TX_PROT_DISABLE_BIT);
! 1378:
! 1379: bit_set((u_int8_t *)®, HDLC_RX_ADDR_RECOGN_DIS_BIT);
! 1380:
! 1381: xilinx_write_ctrl_hdlc(card, sc->first_time_slot,
! 1382: XILINX_HDLC_CONTROL_REG, reg);
! 1383: }
! 1384: }
! 1385:
! 1386: /* Select an HDLC logic channel for configuration */
! 1387: sdla_bus_read_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 1388:
! 1389: reg &= ~HDLC_LOGIC_CH_BIT_MASK;
! 1390: reg &= HDLC_LCH_TIMESLOT_MASK; /* mask not valid bits */
! 1391:
! 1392: sdla_bus_write_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG,
! 1393: (reg | (sc->logic_ch_num & HDLC_LOGIC_CH_BIT_MASK)));
! 1394:
! 1395: reg = 0;
! 1396:
! 1397: /* HDLC engine is enabled on the above logical channels */
! 1398: bit_clear((u_int8_t *)®, HDLC_RX_PROT_DISABLE_BIT);
! 1399: bit_clear((u_int8_t *)®, HDLC_TX_PROT_DISABLE_BIT);
! 1400:
! 1401: bit_set((u_int8_t *)®, HDLC_TX_CHAN_ENABLE_BIT);
! 1402: bit_set((u_int8_t *)®, HDLC_RX_ADDR_RECOGN_DIS_BIT);
! 1403:
! 1404: xilinx_write_ctrl_hdlc(card, sc->first_time_slot,
! 1405: XILINX_HDLC_CONTROL_REG, reg);
! 1406:
! 1407: return (0);
! 1408: }
! 1409:
! 1410: static void
! 1411: xilinx_dev_unconfigure(sdla_t *card, xilinx_softc_t *sc)
! 1412: {
! 1413: u_int32_t reg;
! 1414: int i, s;
! 1415:
! 1416: #ifdef DEBUG_INIT
! 1417: log(LOG_DEBUG, "\n-- Unconfigure Xilinx. --\n");
! 1418: #endif
! 1419:
! 1420: /* Select an HDLC logic channel for configuration */
! 1421: if (sc->logic_ch_num != -1) {
! 1422:
! 1423: sdla_bus_read_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 1424: reg &= ~HDLC_LOGIC_CH_BIT_MASK;
! 1425: reg &= HDLC_LCH_TIMESLOT_MASK; /* mask not valid bits */
! 1426:
! 1427: sdla_bus_write_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG,
! 1428: (reg | (sc->logic_ch_num & HDLC_LOGIC_CH_BIT_MASK)));
! 1429:
! 1430: reg = 0x00020000;
! 1431: xilinx_write_ctrl_hdlc(card, sc->first_time_slot,
! 1432: XILINX_HDLC_CONTROL_REG, reg);
! 1433:
! 1434: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 1435: if (bit_test((u_int8_t *)&sc->time_slot_map, i)) {
! 1436: sdla_bus_read_4(card->hw,
! 1437: XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 1438: reg &= ~TIMESLOT_BIT_MASK;
! 1439:
! 1440: /* mask not valid bits */
! 1441: reg &= HDLC_LCH_TIMESLOT_MASK;
! 1442:
! 1443: /* Select a Timeslot for configuration */
! 1444: sdla_bus_write_4(card->hw,
! 1445: XILINX_TIMESLOT_HDLC_CHAN_REG,
! 1446: (reg | (i<<TIMESLOT_BIT_SHIFT)));
! 1447:
! 1448: reg = 31 & CONTROL_RAM_DATA_MASK;
! 1449: reg |= (FIFO_32B & HDLC_FIFO_SIZE_MASK) <<
! 1450: HDLC_FIFO_SIZE_SHIFT;
! 1451: reg |= (31 & HDLC_FIFO_BASE_ADDR_MASK) <<
! 1452: HDLC_FIFO_BASE_ADDR_SHIFT;
! 1453:
! 1454: #ifdef DEBUG_INIT
! 1455: log(LOG_INFO, "Setting Timeslot %d "
! 1456: "to logic ch %d Reg=0x%X\n", i, 31 , reg);
! 1457: #endif
! 1458: xilinx_write_ctrl_hdlc(card, i,
! 1459: XILINX_CONTROL_RAM_ACCESS_BUF, reg);
! 1460: }
! 1461: }
! 1462:
! 1463: /*
! 1464: * Lock to protect the logic ch map to sc device array
! 1465: */
! 1466: s = splnet();
! 1467: free_xilinx_logical_channel_num(card, sc->logic_ch_num);
! 1468: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++)
! 1469: if (bit_test((u_int8_t *)&sc->time_slot_map, i))
! 1470: --sc->num_of_time_slots;
! 1471:
! 1472: free_fifo_baddr_and_size(card, sc);
! 1473: splx(s);
! 1474:
! 1475: sc->logic_ch_num = -1;
! 1476:
! 1477: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++)
! 1478: if (bit_test((u_int8_t *)&sc->time_slot_map, i))
! 1479: bit_clear((u_int8_t *)
! 1480: &card->u.xilinx.time_slot_map, i);
! 1481: }
! 1482: }
! 1483:
! 1484: #define FIFO_RESET_TIMEOUT_CNT 1000
! 1485: #define FIFO_RESET_TIMEOUT_US 10
! 1486: static int
! 1487: xilinx_init_rx_dev_fifo(sdla_t *card, xilinx_softc_t *sc, unsigned char wait)
! 1488: {
! 1489: u_int32_t reg;
! 1490: u_int32_t dma_descr;
! 1491: u_int8_t timeout = 1;
! 1492: u_int16_t i;
! 1493:
! 1494: /* Clean RX DMA fifo */
! 1495: dma_descr = (unsigned long)(sc->logic_ch_num << 4) +
! 1496: XILINX_RxDMA_DESCRIPTOR_HI;
! 1497: reg = 0;
! 1498: bit_set((u_int8_t *)®, INIT_DMA_FIFO_CMD_BIT);
! 1499:
! 1500: #ifdef DEBUG_INIT
! 1501: log(LOG_DEBUG,
! 1502: "%s: Clearing RX Fifo DmaDescr=(0x%X) Reg=(0x%X) (%s)\n",
! 1503: sc->if_name, dma_descr, reg, __FUNCTION__);
! 1504: #endif
! 1505:
! 1506: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1507:
! 1508: if (wait == WP_WAIT) {
! 1509: for (i = 0; i < FIFO_RESET_TIMEOUT_CNT; i++) {
! 1510: sdla_bus_read_4(card->hw, dma_descr, ®);
! 1511: if (bit_test((u_int8_t *)®, INIT_DMA_FIFO_CMD_BIT)) {
! 1512: DELAY(FIFO_RESET_TIMEOUT_US);
! 1513: continue;
! 1514: }
! 1515: timeout = 0;
! 1516: break;
! 1517: }
! 1518:
! 1519: #ifdef DEBUG_INIT
! 1520: if (timeout)
! 1521: log(LOG_INFO, "%s:%s: Error: Rx fifo reset "
! 1522: "timedout %u us\n", card->devname,
! 1523: sc->if_name, i * FIFO_RESET_TIMEOUT_US);
! 1524: else
! 1525: log(LOG_INFO, "%s:%s: Rx Fifo reset "
! 1526: "successful %u us\n", card->devname, sc->if_name,
! 1527: i * FIFO_RESET_TIMEOUT_US);
! 1528: #endif
! 1529: } else
! 1530: timeout = 0;
! 1531:
! 1532: return (timeout);
! 1533: }
! 1534:
! 1535: static int
! 1536: xilinx_init_tx_dev_fifo(sdla_t *card, xilinx_softc_t *sc, unsigned char wait)
! 1537: {
! 1538: u_int32_t reg;
! 1539: u_int32_t dma_descr;
! 1540: u_int8_t timeout = 1;
! 1541: u_int16_t i;
! 1542:
! 1543: /* Clean TX DMA fifo */
! 1544: dma_descr = (unsigned long)(sc->logic_ch_num << 4) +
! 1545: XILINX_TxDMA_DESCRIPTOR_HI;
! 1546: reg = 0;
! 1547: bit_set((u_int8_t *)®, INIT_DMA_FIFO_CMD_BIT);
! 1548:
! 1549: #ifdef DEBUG_INIT
! 1550: log(LOG_DEBUG,
! 1551: "%s: Clearing TX Fifo DmaDescr=(0x%X) Reg=(0x%X) (%s)\n",
! 1552: sc->if_name, dma_descr, reg, __FUNCTION__);
! 1553: #endif
! 1554: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1555:
! 1556: if (wait == WP_WAIT) {
! 1557: for (i = 0; i < FIFO_RESET_TIMEOUT_CNT; i++) {
! 1558: sdla_bus_read_4(card->hw, dma_descr, ®);
! 1559: if (bit_test((u_int8_t *)®, INIT_DMA_FIFO_CMD_BIT)) {
! 1560: DELAY(FIFO_RESET_TIMEOUT_US);
! 1561: continue;
! 1562: }
! 1563: timeout = 0;
! 1564: break;
! 1565: }
! 1566:
! 1567: #ifdef DEBUG_INIT
! 1568: if (timeout)
! 1569: log(LOG_INFO, "%s:%s: Error: Tx fifo reset "
! 1570: "timedout %u us\n", card->devname, sc->if_name,
! 1571: i * FIFO_RESET_TIMEOUT_US);
! 1572: else
! 1573: log(LOG_INFO, "%s:%s: Tx Fifo reset "
! 1574: "successful %u us\n", card->devname, sc->if_name,
! 1575: i * FIFO_RESET_TIMEOUT_US);
! 1576: #endif
! 1577: } else
! 1578: timeout = 0;
! 1579:
! 1580: return (timeout);
! 1581: }
! 1582:
! 1583:
! 1584: static void
! 1585: xilinx_dev_enable(sdla_t *card, xilinx_softc_t *sc)
! 1586: {
! 1587: u_int32_t reg;
! 1588:
! 1589: #ifdef DEBUG_INIT
! 1590: log(LOG_INFO, "%s: Enabling Global Inter Mask !\n", sc->if_name);
! 1591: #endif
! 1592: /* Enable Logic Channel Interrupts for DMA and fifo */
! 1593: sdla_bus_read_4(card->hw, XILINX_GLOBAL_INTER_MASK, ®);
! 1594: bit_set((u_int8_t *)®, sc->logic_ch_num);
! 1595:
! 1596: sdla_bus_write_4(card->hw, XILINX_GLOBAL_INTER_MASK, reg);
! 1597:
! 1598: bit_set((u_int8_t *)&card->u.xilinx.active_ch_map, sc->logic_ch_num);
! 1599: }
! 1600:
! 1601: static void
! 1602: xilinx_dev_close(sdla_t *card, xilinx_softc_t *sc)
! 1603: {
! 1604: u_int32_t reg;
! 1605: unsigned long dma_descr;
! 1606: int s;
! 1607:
! 1608: #ifdef DEBUG_INIT
! 1609: log(LOG_DEBUG, "-- Close Xilinx device. --\n");
! 1610: #endif
! 1611: /* Disable Logic Channel Interrupts for DMA and fifo */
! 1612: sdla_bus_read_4(card->hw, XILINX_GLOBAL_INTER_MASK, ®);
! 1613:
! 1614: bit_clear((u_int8_t *)®, sc->logic_ch_num);
! 1615: bit_clear((u_int8_t *)&card->u.xilinx.active_ch_map, sc->logic_ch_num);
! 1616:
! 1617: /*
! 1618: * We are masking the sc interrupt.
! 1619: * Lock to make sure that the interrupt is
! 1620: * not running
! 1621: */
! 1622: s = splnet();
! 1623: sdla_bus_write_4(card->hw, XILINX_GLOBAL_INTER_MASK, reg);
! 1624: splx(s);
! 1625:
! 1626: reg = 0;
! 1627:
! 1628: /* Select an HDLC logic channel for configuration */
! 1629: sdla_bus_read_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 1630:
! 1631: reg &= ~HDLC_LOGIC_CH_BIT_MASK;
! 1632: reg &= HDLC_LCH_TIMESLOT_MASK; /* mask not valid bits */
! 1633:
! 1634: sdla_bus_write_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG,
! 1635: (reg | (sc->logic_ch_num & HDLC_LOGIC_CH_BIT_MASK)));
! 1636:
! 1637:
! 1638: reg = 0;
! 1639: xilinx_write_ctrl_hdlc(card, sc->first_time_slot,
! 1640: XILINX_HDLC_CONTROL_REG, reg);
! 1641:
! 1642: /* Clear descriptors */
! 1643: reg = 0;
! 1644: dma_descr=(sc->logic_ch_num<<4) + XILINX_RxDMA_DESCRIPTOR_HI;
! 1645: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1646: dma_descr=(sc->logic_ch_num<<4) + XILINX_TxDMA_DESCRIPTOR_HI;
! 1647: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1648:
! 1649: /* FIXME: Cleanp up Tx and Rx buffers */
! 1650: }
! 1651:
! 1652: static int
! 1653: xilinx_dma_rx(sdla_t *card, xilinx_softc_t *sc)
! 1654: {
! 1655: u_int32_t reg;
! 1656: unsigned long dma_descr;
! 1657: unsigned long bus_addr;
! 1658: wp_rx_element_t *rx_el;
! 1659:
! 1660: /* sanity check: make sure that DMA is in ready state */
! 1661: #if 0
! 1662: dma_descr=(sc->logic_ch_num<<4) + XILINX_RxDMA_DESCRIPTOR_HI;
! 1663: sdla_bus_read_4(card->hw, dma_descr, ®);
! 1664:
! 1665: if (bit_test((u_int8_t *)®, RxDMA_HI_DMA_GO_READY_BIT)) {
! 1666: log(LOG_INFO, "%s: Error: RxDMA GO Ready bit set on dma Rx\n",
! 1667: card->devname);
! 1668: return (EFAULT);
! 1669: }
! 1670: #endif
! 1671:
! 1672: if (sc->rx_dma_buf) {
! 1673: log(LOG_INFO, "%s: Critial Error: Rx Dma Buf busy!\n",
! 1674: sc->if_name);
! 1675: return (EINVAL);
! 1676: }
! 1677:
! 1678: sc->rx_dma_buf = SIMPLEQ_FIRST(&sc->wp_rx_free_list);
! 1679:
! 1680: if (sc->rx_dma_buf == NULL) {
! 1681: if (aft_alloc_rx_dma_buff(sc, 1) == 0) {
! 1682: log(LOG_INFO, "%s: Critical Error no rx dma buf!",
! 1683: sc->if_name);
! 1684: return (ENOMEM);
! 1685: }
! 1686: sc->rx_dma_buf = SIMPLEQ_FIRST(&sc->wp_rx_free_list);
! 1687: }
! 1688:
! 1689: SIMPLEQ_REMOVE_HEAD(&sc->wp_rx_free_list, entry);
! 1690:
! 1691: bus_dmamap_sync(sc->dmatag, sc->rx_dma_buf->dma_map, 0, sc->dma_mtu,
! 1692: BUS_DMASYNC_PREREAD);
! 1693:
! 1694: rx_el = &sc->rx_dma_buf->rx_el;
! 1695: memset(rx_el, 0, sizeof(*rx_el));
! 1696:
! 1697: bus_addr = sc->rx_dma_buf->dma_map->dm_segs[0].ds_addr;
! 1698: rx_el->dma_addr = bus_addr;
! 1699:
! 1700: /* Write the pointer of the data packet to the
! 1701: * DMA address register */
! 1702: reg = bus_addr;
! 1703:
! 1704: /* Set the 32bit alignment of the data length.
! 1705: * Since we are setting up for rx, set this value
! 1706: * to Zero */
! 1707: reg &= ~(RxDMA_LO_ALIGNMENT_BIT_MASK);
! 1708:
! 1709: dma_descr = (sc->logic_ch_num<<4) + XILINX_RxDMA_DESCRIPTOR_LO;
! 1710:
! 1711: #ifdef DEBUG_RX
! 1712: log(LOG_INFO, "%s: RxDMA_LO = 0x%X, BusAddr=0x%lX "
! 1713: "DmaDescr=0x%lX (%s)\n", card->devname, reg, bus_addr,
! 1714: dma_descr, __FUNCTION__);
! 1715: #endif
! 1716: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1717:
! 1718: dma_descr=(unsigned long)(sc->logic_ch_num << 4) +
! 1719: XILINX_RxDMA_DESCRIPTOR_HI;
! 1720:
! 1721: reg = 0;
! 1722:
! 1723: reg |= (sc->dma_mtu >> 2) & RxDMA_HI_DMA_DATA_LENGTH_MASK;
! 1724:
! 1725: #ifdef TRUE_FIFO_SIZE
! 1726: reg |= (sc->fifo_size_code & DMA_FIFO_SIZE_MASK) <<
! 1727: DMA_FIFO_SIZE_SHIFT;
! 1728: #else
! 1729:
! 1730: reg |= (HARD_FIFO_CODE & DMA_FIFO_SIZE_MASK) << DMA_FIFO_SIZE_SHIFT;
! 1731: #endif
! 1732: reg |= (sc->fifo_base_addr&DMA_FIFO_BASE_ADDR_MASK) <<
! 1733: DMA_FIFO_BASE_ADDR_SHIFT;
! 1734:
! 1735: bit_set((u_int8_t *)®, RxDMA_HI_DMA_GO_READY_BIT);
! 1736:
! 1737: #ifdef DEBUG_RX
! 1738: log(LOG_INFO, "%s: RXDMA_HI = 0x%X, BusAddr=0x%lX DmaDescr=0x%lX "
! 1739: "(%s)\n", sc->if_name, reg, bus_addr, dma_descr, __FUNCTION__);
! 1740: #endif
! 1741:
! 1742: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1743:
! 1744: bit_set((u_int8_t *)&sc->rx_dma, 0);
! 1745:
! 1746: return (0);
! 1747: }
! 1748:
! 1749:
! 1750: static int
! 1751: xilinx_dma_tx(sdla_t *card, xilinx_softc_t *sc)
! 1752: {
! 1753: u_int32_t reg = 0;
! 1754: struct mbuf *m;
! 1755: unsigned long dma_descr;
! 1756: unsigned char len_align = 0;
! 1757: int len = 0;
! 1758:
! 1759: #ifdef DEBUG_TX
! 1760: log(LOG_INFO, "------ Setup Tx DMA descriptor. --\n");
! 1761: #endif
! 1762:
! 1763: if (bit_test((u_int8_t *)&sc->dma_status, TX_BUSY)) {
! 1764: #ifdef DEBUG_TX
! 1765: log(LOG_INFO, "%s: TX_BUSY set (%s:%d)!\n",
! 1766: sc->if_name, __FUNCTION__, __LINE__);
! 1767: #endif
! 1768: return EBUSY;
! 1769: }
! 1770: bit_set((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1771:
! 1772:
! 1773: /*
! 1774: * Free the previously skb dma mapping.
! 1775: * In this case the tx interrupt didn't finish and we must re-transmit.
! 1776: */
! 1777: if (sc->tx_dma_addr && sc->tx_dma_len) {
! 1778: log(LOG_INFO, "%s: Unmaping tx_dma_addr in %s\n",
! 1779: sc->if_name, __FUNCTION__);
! 1780:
! 1781: sc->tx_dma_addr = 0;
! 1782: sc->tx_dma_len = 0;
! 1783: }
! 1784:
! 1785: /* Free the previously sent tx packet. To
! 1786: * minimize tx isr, the previously transmitted
! 1787: * packet is deallocated here */
! 1788: if (sc->tx_dma_mbuf) {
! 1789: bus_dmamap_unload(sc->dmatag, sc->tx_dmamap);
! 1790: m_freem(sc->tx_dma_mbuf);
! 1791: sc->tx_dma_mbuf = NULL;
! 1792: }
! 1793:
! 1794: /* check queue pointers before starting transmission */
! 1795:
! 1796: /* sanity check: make sure that DMA is in ready state */
! 1797: dma_descr = (sc->logic_ch_num << 4) + XILINX_TxDMA_DESCRIPTOR_HI;
! 1798:
! 1799: #ifdef DEBUG_TX
! 1800: log(LOG_INFO, "%s: sc logic ch=%ld dma_descr=0x%lx set (%s:%d)!\n",
! 1801: sc->if_name, sc->logic_ch_num, dma_descr, __FUNCTION__, __LINE__);
! 1802: #endif
! 1803:
! 1804: sdla_bus_read_4(card->hw, dma_descr, ®);
! 1805:
! 1806: if (bit_test((u_int8_t *)®, TxDMA_HI_DMA_GO_READY_BIT)) {
! 1807: log(LOG_INFO, "%s: Error: TxDMA GO Ready bit set "
! 1808: "on dma Tx 0x%X\n", card->devname, reg);
! 1809: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1810: return (EFAULT);
! 1811: }
! 1812:
! 1813: IF_DEQUEUE(&sc->wp_tx_pending_list, m);
! 1814:
! 1815: if (!m) {
! 1816: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1817: return (ENOBUFS);
! 1818: }
! 1819:
! 1820: len = m->m_len;
! 1821: if (len > MAX_XILINX_TX_DMA_SIZE) {
! 1822: /* FIXME: We need to split this frame into
! 1823: * multiple parts. For now though
! 1824: * just drop it :) */
! 1825: log(LOG_INFO, "%s: Tx len %d > %d (MAX TX DMA LEN)\n",
! 1826: sc->if_name, len, MAX_XILINX_TX_DMA_SIZE);
! 1827: m_freem(m);
! 1828: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1829: return (EINVAL);
! 1830: }
! 1831:
! 1832: if (ADDR_MASK(mtod(m, caddr_t), 0x03)) {
! 1833: /* The mbuf should already be aligned */
! 1834: log(LOG_INFO, "%s: TX packet not aligned!\n",
! 1835: sc->if_name);
! 1836: m_freem(m);
! 1837: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1838: return (EINVAL);
! 1839: }
! 1840:
! 1841: if (bus_dmamap_load(sc->dmatag, sc->tx_dmamap,
! 1842: mtod(m, void *), len, NULL, BUS_DMA_NOWAIT | BUS_DMA_WRITE)) {
! 1843: log(LOG_INFO, "%s: Failed to load TX mbuf for DMA!\n",
! 1844: sc->if_name);
! 1845: m_freem(m);
! 1846: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1847: return (EINVAL);
! 1848: }
! 1849:
! 1850: sc->tx_dma_addr = sc->tx_dmamap->dm_segs[0].ds_addr;
! 1851: sc->tx_dma_len = len;
! 1852:
! 1853: if (sc->tx_dma_addr & 0x03) {
! 1854: log(LOG_INFO, "%s: Error: Tx Ptr not aligned "
! 1855: "to 32bit boundary!\n", card->devname);
! 1856: m_freem(m);
! 1857: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1858: return (EINVAL);
! 1859: }
! 1860:
! 1861: sc->tx_dma_mbuf = m;
! 1862:
! 1863: /* WARNING: Do not use the "skb" pointer from
! 1864: * here on. The skb pointer might not exist if
! 1865: * we are in transparent mode */
! 1866:
! 1867: dma_descr = (sc->logic_ch_num << 4) + XILINX_TxDMA_DESCRIPTOR_LO;
! 1868:
! 1869: /* Write the pointer of the data packet to the
! 1870: * DMA address register */
! 1871: reg = sc->tx_dma_addr;
! 1872:
! 1873: bus_dmamap_sync(sc->dmatag, sc->tx_dmamap, 0, len,
! 1874: BUS_DMASYNC_PREWRITE);
! 1875:
! 1876: /* Set the 32bit alignment of the data length.
! 1877: * Used to pad the tx packet to the 32 bit
! 1878: * boundary */
! 1879: reg &= ~(TxDMA_LO_ALIGNMENT_BIT_MASK);
! 1880: reg |= (len & 0x03);
! 1881:
! 1882: if (len & 0x03)
! 1883: len_align = 1;
! 1884:
! 1885: #ifdef DEBUG_TX
! 1886: log(LOG_INFO, "%s: TXDMA_LO=0x%X PhyAddr=0x%lX DmaDescr=0x%lX (%s)\n",
! 1887: sc->if_name, reg, sc->tx_dma_addr, dma_descr, __FUNCTION__);
! 1888: #endif
! 1889:
! 1890: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1891:
! 1892: dma_descr = (sc->logic_ch_num << 4) + XILINX_TxDMA_DESCRIPTOR_HI;
! 1893:
! 1894: reg = 0;
! 1895: reg |= (((len >> 2) + len_align) & TxDMA_HI_DMA_DATA_LENGTH_MASK);
! 1896:
! 1897: #ifdef TRUE_FIFO_SIZE
! 1898: reg |= (sc->fifo_size_code & DMA_FIFO_SIZE_MASK) <<
! 1899: DMA_FIFO_SIZE_SHIFT;
! 1900: #else
! 1901:
! 1902: reg |= (HARD_FIFO_CODE & DMA_FIFO_SIZE_MASK) << DMA_FIFO_SIZE_SHIFT;
! 1903: #endif
! 1904: reg |= (sc->fifo_base_addr & DMA_FIFO_BASE_ADDR_MASK) <<
! 1905: DMA_FIFO_BASE_ADDR_SHIFT;
! 1906:
! 1907: /*
! 1908: * Only enable the Frame Start/Stop on
! 1909: * non-transparent hdlc configuration
! 1910: */
! 1911: bit_set((u_int8_t *)®, TxDMA_HI_DMA_FRAME_START_BIT);
! 1912: bit_set((u_int8_t *)®, TxDMA_HI_DMA_FRAME_END_BIT);
! 1913:
! 1914: bit_set((u_int8_t *)®, TxDMA_HI_DMA_GO_READY_BIT);
! 1915:
! 1916: #ifdef DEBUG_TX
! 1917: log(LOG_INFO, "%s: TXDMA_HI=0x%X DmaDescr=0x%lX (%s)\n",
! 1918: sc->if_name, reg, dma_descr, __FUNCTION__);
! 1919: #endif
! 1920:
! 1921: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1922:
! 1923: return (0);
! 1924:
! 1925: }
! 1926:
! 1927: static void
! 1928: xilinx_dma_tx_complete(sdla_t *card, xilinx_softc_t *sc)
! 1929: {
! 1930: u_int32_t reg = 0;
! 1931: unsigned long dma_descr;
! 1932:
! 1933: #ifdef DEBUG_TX
! 1934: log(LOG_INFO, "%s: TX DMA complete\n", card->devname);
! 1935: #endif
! 1936: /* DEBUGTX */
! 1937: /* sdla_bus_read_4(card->hw, 0x78, &tmp1); */
! 1938:
! 1939: dma_descr = (sc->logic_ch_num << 4) + XILINX_TxDMA_DESCRIPTOR_HI;
! 1940: sdla_bus_read_4(card->hw, dma_descr, ®);
! 1941:
! 1942: if (sc->tx_dma_mbuf == NULL) {
! 1943: log(LOG_INFO,
! 1944: "%s: Critical Error: Tx DMA intr: no tx mbuf !\n",
! 1945: card->devname);
! 1946: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1947: return;
! 1948: }
! 1949:
! 1950: bus_dmamap_sync(sc->dmatag, sc->tx_dmamap, 0, sc->tx_dma_len,
! 1951: BUS_DMASYNC_POSTWRITE);
! 1952:
! 1953: sc->tx_dma_addr = 0;
! 1954: sc->tx_dma_len = 0;
! 1955:
! 1956: /* Do not free the packet here,
! 1957: * copy the packet dma info into csum
! 1958: * field and let the bh handler analyze
! 1959: * the transmitted packet.
! 1960: */
! 1961:
! 1962: if (reg & TxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT) {
! 1963: log(LOG_INFO, "%s:%s: PCI Error: 'Retry' "
! 1964: "exceeds maximum (64k): Reg=0x%X!\n",
! 1965: card->devname, sc->if_name, reg);
! 1966:
! 1967: if (++sc->pci_retry < 3) {
! 1968: bit_set((u_int8_t *)®,
! 1969: TxDMA_HI_DMA_GO_READY_BIT);
! 1970:
! 1971: log(LOG_INFO, "%s: Retry: TXDMA_HI=0x%X "
! 1972: "DmaDescr=0x%lX (%s)\n",
! 1973: sc->if_name, reg, dma_descr, __FUNCTION__);
! 1974:
! 1975: sdla_bus_write_4(card->hw, dma_descr, reg);
! 1976: return;
! 1977: }
! 1978: }
! 1979:
! 1980: sc->pci_retry = 0;
! 1981: sc->tx_dma_mbuf->m_pkthdr.csum_flags = reg;
! 1982: IF_ENQUEUE(&sc->wp_tx_complete_list, sc->tx_dma_mbuf);
! 1983: sc->tx_dma_mbuf = NULL;
! 1984:
! 1985: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 1986:
! 1987: xilinx_process_packet(sc);
! 1988: }
! 1989:
! 1990: static void
! 1991: xilinx_tx_post_complete(sdla_t *card, xilinx_softc_t *sc, struct mbuf *m)
! 1992: {
! 1993: struct ifnet *ifp;
! 1994: unsigned long reg = m->m_pkthdr.csum_flags;
! 1995:
! 1996: WAN_ASSERT1(sc == NULL);
! 1997: ifp = (struct ifnet *)&sc->common.ifp;
! 1998: if ((bit_test((u_int8_t *)®, TxDMA_HI_DMA_GO_READY_BIT)) ||
! 1999: (reg & TxDMA_HI_DMA_DATA_LENGTH_MASK) ||
! 2000: (reg & TxDMA_HI_DMA_PCI_ERROR_MASK)) {
! 2001:
! 2002: #ifdef DEBUG_TX
! 2003: log(LOG_INFO, "%s:%s: Tx DMA Descriptor=0x%lX\n",
! 2004: card->devname, sc->if_name, reg);
! 2005: #endif
! 2006:
! 2007: /* Checking Tx DMA Go bit. Has to be '0' */
! 2008: if (bit_test((u_int8_t *)®, TxDMA_HI_DMA_GO_READY_BIT))
! 2009: log(LOG_INFO, "%s:%s: Error: TxDMA Intr: "
! 2010: "GO bit set on Tx intr\n",
! 2011: card->devname, sc->if_name);
! 2012:
! 2013: if (reg & TxDMA_HI_DMA_DATA_LENGTH_MASK)
! 2014: log(LOG_INFO, "%s:%s: Error: TxDMA Length "
! 2015: "not equal 0 \n", card->devname, sc->if_name);
! 2016:
! 2017: /* Checking Tx DMA PCI error status. Has to be '0's */
! 2018: if (reg & TxDMA_HI_DMA_PCI_ERROR_MASK) {
! 2019:
! 2020: if (reg & TxDMA_HI_DMA_PCI_ERROR_M_ABRT)
! 2021: log(LOG_INFO, "%s:%s: Tx Error: "
! 2022: "Abort from Master: pci fatal error!\n",
! 2023: card->devname, sc->if_name);
! 2024:
! 2025: if (reg & TxDMA_HI_DMA_PCI_ERROR_T_ABRT)
! 2026: log(LOG_INFO, "%s:%s: Tx Error: "
! 2027: "Abort from Target: pci fatal error!\n",
! 2028: card->devname, sc->if_name);
! 2029:
! 2030: if (reg & TxDMA_HI_DMA_PCI_ERROR_DS_TOUT) {
! 2031: log(LOG_INFO, "%s:%s: Tx Warning: "
! 2032: "PCI Latency Timeout!\n",
! 2033: card->devname, sc->if_name);
! 2034: goto tx_post_ok;
! 2035: }
! 2036: if (reg & TxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT)
! 2037: log(LOG_INFO, "%s:%s: Tx Error: 'Retry' "
! 2038: "exceeds maximum (64k): pci fatal error!\n",
! 2039: card->devname, sc->if_name);
! 2040: }
! 2041: goto tx_post_exit;
! 2042: }
! 2043:
! 2044: tx_post_ok:
! 2045:
! 2046: if (ifp)
! 2047: ifp->if_opackets++;
! 2048:
! 2049: /* Indicate that the first tx frame went
! 2050: * out on the transparent link */
! 2051: bit_set((u_int8_t *)&sc->idle_start, 0);
! 2052:
! 2053: tx_post_exit:
! 2054:
! 2055: if (!xilinx_dma_tx(card, sc)) {
! 2056: /*
! 2057: * If we were able to transmit and the interface is set to
! 2058: * OACTIVE remove this flag and let kernel try to transmit.
! 2059: */
! 2060: if (ifp->if_flags & IFF_OACTIVE)
! 2061: ifp->if_flags &= ~IFF_OACTIVE;
! 2062: }
! 2063: return;
! 2064: }
! 2065:
! 2066: static void
! 2067: xilinx_dma_rx_complete(sdla_t *card, xilinx_softc_t *sc)
! 2068: {
! 2069: struct xilinx_rx_buffer *buf;
! 2070: unsigned long dma_descr;
! 2071: wp_rx_element_t *rx_el;
! 2072:
! 2073: bit_clear((u_int8_t *)&sc->rx_dma, 0);
! 2074:
! 2075: if (sc->rx_dma_buf == NULL) {
! 2076: log(LOG_INFO,
! 2077: "%s: Critical Error: rx_dma_mbuf\n", sc->if_name);
! 2078: return;
! 2079: }
! 2080:
! 2081: rx_el = &sc->rx_dma_buf->rx_el;
! 2082:
! 2083: /* Reading Rx DMA descriptor information */
! 2084: dma_descr=(sc->logic_ch_num << 4) + XILINX_RxDMA_DESCRIPTOR_LO;
! 2085: sdla_bus_read_4(card->hw, dma_descr, &rx_el->align);
! 2086: rx_el->align &= RxDMA_LO_ALIGNMENT_BIT_MASK;
! 2087:
! 2088: dma_descr = (sc->logic_ch_num << 4) + XILINX_RxDMA_DESCRIPTOR_HI;
! 2089: sdla_bus_read_4(card->hw, dma_descr, &rx_el->reg);
! 2090:
! 2091: rx_el->pkt_error = sc->pkt_error;
! 2092: sc->pkt_error = 0;
! 2093:
! 2094: #ifdef DEBUG_RX
! 2095: log(LOG_INFO, "%s: RX HI=0x%X LO=0x%X DMA=0x%lX (%s:%d)\n",
! 2096: sc->if_name, rx_el->reg, rx_el->align, rx_el->dma_addr,
! 2097: __FUNCTION__, __LINE__);
! 2098: #endif
! 2099:
! 2100: buf = sc->rx_dma_buf;
! 2101: sc->rx_dma_buf = NULL;
! 2102:
! 2103: xilinx_dma_rx(card, sc);
! 2104:
! 2105: SIMPLEQ_INSERT_TAIL(&sc->wp_rx_complete_list, buf, entry);
! 2106:
! 2107: xilinx_process_packet(sc);
! 2108:
! 2109: /* sdla_bus_read_4(card->hw, 0x80, &rx_empty); */
! 2110: }
! 2111:
! 2112:
! 2113: static void
! 2114: xilinx_rx_post_complete(sdla_t *card, xilinx_softc_t *sc,
! 2115: struct xilinx_rx_buffer *buf, struct mbuf **new_m, u_char *pkt_error)
! 2116: {
! 2117: struct ifnet *ifp;
! 2118: unsigned int len, data_error = 0;
! 2119: wp_rx_element_t *rx_el = &buf->rx_el;
! 2120: struct mbuf *m = buf->mbuf;
! 2121:
! 2122: WAN_ASSERT1(sc == NULL);
! 2123: ifp = (struct ifnet *)&sc->common.ifp; /*m->m_pkthdr.rcvif;*/
! 2124:
! 2125: #ifdef DEBUG_RX
! 2126: log(LOG_INFO, "%s: RX HI=0x%X LO=0x%X DMA=0x%lX (%s:%d)\n",
! 2127: sc->if_name, rx_el->reg, rx_el->align, rx_el->dma_addr,
! 2128: __FUNCTION__, __LINE__);
! 2129: #endif
! 2130: rx_el->align &= RxDMA_LO_ALIGNMENT_BIT_MASK;
! 2131: *pkt_error = 0;
! 2132: *new_m = NULL;
! 2133:
! 2134:
! 2135: /* Checking Rx DMA Go bit. Has to be '0' */
! 2136: if (bit_test((u_int8_t *)&rx_el->reg, RxDMA_HI_DMA_GO_READY_BIT)) {
! 2137: log(LOG_INFO, "%s: Error: RxDMA Intr: GO bit set on Rx intr\n",
! 2138: card->devname);
! 2139: ifp->if_ierrors++;
! 2140: goto rx_comp_error;
! 2141: }
! 2142:
! 2143: /* Checking Rx DMA PCI error status. Has to be '0's */
! 2144: if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_MASK) {
! 2145: #ifdef DEBUG_ERR
! 2146: if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_M_ABRT)
! 2147: log(LOG_INFO, "%s: Rx Error: Abort from Master: "
! 2148: "pci fatal error!\n", card->devname);
! 2149:
! 2150: if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_T_ABRT)
! 2151: log(LOG_INFO, "%s: Rx Error: Abort from Target: "
! 2152: "pci fatal error!\n", card->devname);
! 2153:
! 2154: if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_DS_TOUT)
! 2155: log(LOG_INFO, "%s: Rx Error: No 'DeviceSelect' "
! 2156: "from target: pci fatal error!\n", card->devname);
! 2157:
! 2158: if (rx_el->reg & RxDMA_HI_DMA_PCI_ERROR_RETRY_TOUT)
! 2159: log(LOG_INFO, "%s: Rx Error: 'Retry' exceeds maximum "
! 2160: "(64k): pci fatal error!\n", card->devname);
! 2161:
! 2162: log(LOG_INFO, "%s: RXDMA PCI ERROR = 0x%x\n",
! 2163: card->devname, rx_el->reg);
! 2164: #endif
! 2165: if (ifp)
! 2166: ifp->if_ierrors++;
! 2167:
! 2168: goto rx_comp_error;
! 2169: }
! 2170:
! 2171: /* Checking Rx DMA Frame start bit. (information for api) */
! 2172: if (!bit_test((u_int8_t *)&rx_el->reg, RxDMA_HI_DMA_FRAME_START_BIT)) {
! 2173: #ifdef DEBUG_ERR
! 2174: log(LOG_INFO, "%s: RxDMA Intr: Start flag missing: "
! 2175: "MTU Mismatch! Reg=0x%X\n", card->devname, rx_el->reg);
! 2176: #endif
! 2177: if (ifp)
! 2178: ifp->if_ierrors++;
! 2179: goto rx_comp_error;
! 2180: }
! 2181:
! 2182: /* Checking Rx DMA Frame end bit. (information for api) */
! 2183: if (!bit_test((u_int8_t *)&rx_el->reg, RxDMA_HI_DMA_FRAME_END_BIT)) {
! 2184: #ifdef DEBUG_ERR
! 2185: log(LOG_INFO, "%s: RxDMA Intr: End flag missing: "
! 2186: "MTU Mismatch! Reg=0x%X\n", card->devname, rx_el->reg);
! 2187: #endif
! 2188: if (ifp)
! 2189: ifp->if_ierrors++;
! 2190: goto rx_comp_error;
! 2191:
! 2192: } else { /* Check CRC error flag only if this is the end of Frame */
! 2193:
! 2194: if (bit_test((u_int8_t *)&rx_el->reg,
! 2195: RxDMA_HI_DMA_CRC_ERROR_BIT)) {
! 2196: #ifdef DEBUG_ERR
! 2197: log(LOG_INFO, "%s: RxDMA Intr: CRC Error! Reg=0x%X\n",
! 2198: card->devname, rx_el->reg);
! 2199: #endif
! 2200: if (ifp)
! 2201: ifp->if_ierrors++;
! 2202:
! 2203: bit_set((u_int8_t *)&rx_el->pkt_error,
! 2204: WP_CRC_ERROR_BIT);
! 2205: data_error = 1;
! 2206: }
! 2207:
! 2208: /* Check if this frame is an abort, if it is
! 2209: * drop it and continue receiving */
! 2210: if (bit_test((u_int8_t *)&rx_el->reg,
! 2211: RxDMA_HI_DMA_FRAME_ABORT_BIT)) {
! 2212: #ifdef DEBUG_ERR
! 2213: log(LOG_INFO, "%s: RxDMA Intr: Abort! Reg=0x%X\n",
! 2214: card->devname, rx_el->reg);
! 2215: #endif
! 2216: if (ifp)
! 2217: ifp->if_ierrors++;
! 2218:
! 2219: bit_set((u_int8_t *)&rx_el->pkt_error,
! 2220: WP_ABORT_ERROR_BIT);
! 2221: data_error = 1;
! 2222: }
! 2223:
! 2224: if (data_error)
! 2225: goto rx_comp_error;
! 2226: }
! 2227:
! 2228: len = rx_el->reg & RxDMA_HI_DMA_DATA_LENGTH_MASK;
! 2229:
! 2230: /* In HDLC mode, calculate rx length based
! 2231: * on alignment value, received from DMA */
! 2232: len = (((sc->dma_mtu >> 2) - len) << 2) -
! 2233: (~(rx_el->align) & RxDMA_LO_ALIGNMENT_BIT_MASK);
! 2234:
! 2235: *pkt_error = rx_el->pkt_error;
! 2236:
! 2237: /* After a RX FIFO overflow, we must mark max 7
! 2238: * subsequent frames since firmware, cannot
! 2239: * guarantee the contents of the fifo */
! 2240:
! 2241: if (bit_test((u_int8_t *)&rx_el->pkt_error, WP_FIFO_ERROR_BIT)) {
! 2242: if (++sc->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES) {
! 2243: sc->rx_fifo_err_cnt = 0;
! 2244: }
! 2245: bit_set((u_int8_t *)pkt_error, WP_FIFO_ERROR_BIT);
! 2246: } else {
! 2247: if (sc->rx_fifo_err_cnt) {
! 2248: if (++sc->rx_fifo_err_cnt >= WP_MAX_FIFO_FRAMES) {
! 2249: sc->rx_fifo_err_cnt = 0;
! 2250: }
! 2251: bit_set((u_int8_t *)pkt_error, WP_FIFO_ERROR_BIT);
! 2252: }
! 2253: }
! 2254:
! 2255: bus_dmamap_sync(sc->dmatag, sc->rx_dma_buf->dma_map, 0, len,
! 2256: BUS_DMASYNC_POSTREAD);
! 2257:
! 2258: m->m_len = m->m_pkthdr.len = len;
! 2259:
! 2260: if (len > aft_rx_copyback) {
! 2261: /* The rx size is big enough, thus
! 2262: * send this buffer up the stack
! 2263: * and allocate another one */
! 2264: *new_m = m;
! 2265: buf->mbuf = NULL;
! 2266: } else {
! 2267: struct mbuf *m0;
! 2268: /* The rx packet is very
! 2269: * small thus, allocate a new
! 2270: * buffer and pass it up */
! 2271: if ((m0 = m_copym2(m, 0, len, M_NOWAIT)) == NULL) {
! 2272: log(LOG_INFO, "%s: Failed to allocate mbuf!\n",
! 2273: sc->if_name);
! 2274: if (ifp)
! 2275: ifp->if_ierrors++;
! 2276: } else
! 2277: *new_m = m0;
! 2278: }
! 2279:
! 2280: rx_comp_error:
! 2281: aft_reload_rx_dma_buff(sc, buf);
! 2282:
! 2283: return;
! 2284: }
! 2285:
! 2286:
! 2287: static char
! 2288: request_xilinx_logical_channel_num(sdla_t *card, xilinx_softc_t *sc,
! 2289: long *free_ch)
! 2290: {
! 2291: char logic_ch = -1, free_logic_ch = -1;
! 2292: int i, err;
! 2293:
! 2294: *free_ch = -1;
! 2295:
! 2296: #ifdef DEBUG_INIT
! 2297: log(LOG_INFO, "-- Request_Xilinx_logic_channel_num:--\n");
! 2298: log(LOG_INFO, "%s: Global Num Timeslots=%d "
! 2299: "Global Logic ch Map 0x%lX (%s:%d)\n",
! 2300: sc->if_name, card->u.xilinx.num_of_time_slots,
! 2301: card->u.xilinx.logic_ch_map, __FUNCTION__, __LINE__);
! 2302: #endif
! 2303:
! 2304: err = request_fifo_baddr_and_size(card, sc);
! 2305: if (err)
! 2306: return (-1);
! 2307:
! 2308: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 2309: if (!bit_test((u_int8_t *)&card->u.xilinx.logic_ch_map, i)) {
! 2310: bit_set((u_int8_t *)&card->u.xilinx.logic_ch_map, i);
! 2311: logic_ch = i;
! 2312: break;
! 2313: }
! 2314: }
! 2315:
! 2316: if (logic_ch == -1)
! 2317: return (logic_ch);
! 2318:
! 2319: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 2320: if (!bit_test((u_int8_t *)&card->u.xilinx.logic_ch_map, i)) {
! 2321: free_logic_ch = HDLC_FREE_LOGIC_CH;
! 2322: break;
! 2323: }
! 2324: }
! 2325:
! 2326: if (card->u.xilinx.dev_to_ch_map[(unsigned char)logic_ch]) {
! 2327: log(LOG_INFO, "%s: Error, request logical ch=%d map busy\n",
! 2328: card->devname, logic_ch);
! 2329: return (-1);
! 2330: }
! 2331:
! 2332: *free_ch = free_logic_ch;
! 2333:
! 2334: card->u.xilinx.dev_to_ch_map[(unsigned char)logic_ch] = (void *)sc;
! 2335:
! 2336: if (logic_ch > card->u.xilinx.top_logic_ch) {
! 2337: card->u.xilinx.top_logic_ch = logic_ch;
! 2338: xilinx_dma_max_logic_ch(card);
! 2339: }
! 2340:
! 2341: return (logic_ch);
! 2342: }
! 2343:
! 2344: static void
! 2345: free_xilinx_logical_channel_num(sdla_t *card, int logic_ch)
! 2346: {
! 2347: bit_clear((u_int8_t *)&card->u.xilinx.logic_ch_map, logic_ch);
! 2348: card->u.xilinx.dev_to_ch_map[logic_ch] = NULL;
! 2349:
! 2350: if (logic_ch >= card->u.xilinx.top_logic_ch) {
! 2351: int i;
! 2352:
! 2353: card->u.xilinx.top_logic_ch = XILINX_DEFLT_ACTIVE_CH;
! 2354:
! 2355: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 2356: if (card->u.xilinx.dev_to_ch_map[logic_ch])
! 2357: card->u.xilinx.top_logic_ch = i;
! 2358: }
! 2359:
! 2360: xilinx_dma_max_logic_ch(card);
! 2361: }
! 2362:
! 2363: }
! 2364:
! 2365: static void
! 2366: xilinx_dma_max_logic_ch(sdla_t *card)
! 2367: {
! 2368: u_int32_t reg;
! 2369:
! 2370: #ifdef DEBUG_INIT
! 2371: log(LOG_INFO, "-- Xilinx_dma_max_logic_ch :--\n");
! 2372: #endif
! 2373:
! 2374: sdla_bus_read_4(card->hw, XILINX_DMA_CONTROL_REG, ®);
! 2375:
! 2376: /* Set up the current highest active logic channel */
! 2377:
! 2378: reg &= DMA_ACTIVE_CHANNEL_BIT_MASK;
! 2379: reg |= (card->u.xilinx.top_logic_ch << DMA_ACTIVE_CHANNEL_BIT_SHIFT);
! 2380:
! 2381: sdla_bus_write_4(card->hw, XILINX_DMA_CONTROL_REG, reg);
! 2382: }
! 2383:
! 2384: static int
! 2385: aft_alloc_rx_buffers(xilinx_softc_t *sc)
! 2386: {
! 2387: struct xilinx_rx_buffer *buf;
! 2388:
! 2389: SIMPLEQ_INIT(&sc->wp_rx_free_list);
! 2390: SIMPLEQ_INIT(&sc->wp_rx_complete_list);
! 2391:
! 2392: /* allocate receive buffers in one cluster */
! 2393: buf = malloc(sizeof(*buf) * MAX_RX_BUF, M_DEVBUF, M_NOWAIT);
! 2394: if (buf == NULL)
! 2395: return (1);
! 2396:
! 2397: bzero(buf, sizeof(*buf) * MAX_RX_BUF);
! 2398: sc->wp_rx_buffers = buf;
! 2399: sc->wp_rx_buffer_last = buf;
! 2400:
! 2401: return (0);
! 2402: }
! 2403:
! 2404: static void
! 2405: aft_release_rx_buffers(xilinx_softc_t *sc)
! 2406: {
! 2407: struct xilinx_rx_buffer *buf;
! 2408:
! 2409: if (sc->wp_rx_buffers == NULL)
! 2410: return;
! 2411:
! 2412: while ((buf = SIMPLEQ_FIRST(&sc->wp_rx_free_list)) != NULL) {
! 2413: SIMPLEQ_REMOVE_HEAD(&sc->wp_rx_free_list, entry);
! 2414: aft_release_rx_dma_buff(sc, buf);
! 2415: }
! 2416:
! 2417: while ((buf = SIMPLEQ_FIRST(&sc->wp_rx_complete_list)) != NULL) {
! 2418: SIMPLEQ_REMOVE_HEAD(&sc->wp_rx_complete_list, entry);
! 2419: aft_release_rx_dma_buff(sc, buf);
! 2420: }
! 2421:
! 2422: free(sc->wp_rx_buffers, M_DEVBUF);
! 2423:
! 2424: sc->wp_rx_buffers = NULL;
! 2425: sc->wp_rx_buffer_last = NULL;
! 2426: }
! 2427:
! 2428: /* Allocate an mbuf and setup dma_map. */
! 2429: static int
! 2430: aft_alloc_rx_dma_buff(xilinx_softc_t *sc, int num)
! 2431: {
! 2432: struct xilinx_rx_buffer *buf, *ebuf;
! 2433: int n;
! 2434:
! 2435: ebuf = sc->wp_rx_buffers + MAX_RX_BUF;
! 2436: buf = sc->wp_rx_buffer_last;
! 2437:
! 2438: for (n = 0; n < num; n++) {
! 2439: int i;
! 2440: for (i = 0; i < MAX_RX_BUF; i++) {
! 2441: if (buf->mbuf == NULL)
! 2442: break;
! 2443: if (++buf == ebuf)
! 2444: buf = sc->wp_rx_buffers;
! 2445: }
! 2446:
! 2447: if (buf->mbuf != NULL)
! 2448: break;
! 2449:
! 2450: sc->wp_rx_buffer_last = buf;
! 2451:
! 2452: buf->mbuf = wan_mbuf_alloc(sc->dma_mtu);
! 2453: if (buf->mbuf == NULL)
! 2454: break;
! 2455:
! 2456: if (bus_dmamap_create(sc->dmatag, sc->dma_mtu, 1, sc->dma_mtu,
! 2457: 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &buf->dma_map)) {
! 2458: m_freem(buf->mbuf);
! 2459: buf->mbuf = NULL;
! 2460: break;
! 2461: }
! 2462:
! 2463: if (bus_dmamap_load(sc->dmatag, buf->dma_map,
! 2464: mtod(buf->mbuf, void *), sc->dma_mtu, NULL,
! 2465: BUS_DMA_NOWAIT | BUS_DMA_READ)) {
! 2466: aft_release_rx_dma_buff(sc, buf);
! 2467: break;
! 2468: }
! 2469:
! 2470: SIMPLEQ_INSERT_TAIL(&sc->wp_rx_free_list, buf, entry);
! 2471: }
! 2472:
! 2473: return (n);
! 2474: }
! 2475:
! 2476: static void
! 2477: aft_reload_rx_dma_buff(xilinx_softc_t *sc, struct xilinx_rx_buffer *buf)
! 2478: {
! 2479: bus_dmamap_unload(sc->dmatag, buf->dma_map);
! 2480: if (buf->mbuf == NULL) {
! 2481: buf->mbuf = wan_mbuf_alloc(sc->dma_mtu);
! 2482: if (buf->mbuf == NULL) {
! 2483: bus_dmamap_destroy(sc->dmatag, buf->dma_map);
! 2484: return;
! 2485: }
! 2486: }
! 2487: if (bus_dmamap_load(sc->dmatag, buf->dma_map, mtod(buf->mbuf, void *),
! 2488: sc->dma_mtu, NULL, BUS_DMA_NOWAIT | BUS_DMA_READ)) {
! 2489: aft_release_rx_dma_buff(sc, buf);
! 2490: return;
! 2491: }
! 2492:
! 2493: SIMPLEQ_INSERT_TAIL(&sc->wp_rx_free_list, buf, entry);
! 2494: }
! 2495:
! 2496: static void
! 2497: aft_release_rx_dma_buff(xilinx_softc_t *sc, struct xilinx_rx_buffer *buf)
! 2498: {
! 2499: bus_dmamap_destroy(sc->dmatag, buf->dma_map);
! 2500: m_freem(buf->mbuf);
! 2501: buf->mbuf = NULL;
! 2502: }
! 2503:
! 2504: static void
! 2505: enable_timer(void *card_id)
! 2506: {
! 2507: sdla_t *card = (sdla_t *)card_id;
! 2508: int s;
! 2509:
! 2510: s = splnet();
! 2511: sdla_te_polling(card);
! 2512: splx(s);
! 2513:
! 2514: return;
! 2515: }
! 2516:
! 2517: static void
! 2518: xilinx_process_packet(xilinx_softc_t *sc)
! 2519: {
! 2520: struct ifnet *ifp;
! 2521: struct mbuf *new_m, *m;
! 2522: unsigned char pkt_error;
! 2523:
! 2524: WAN_ASSERT1(sc == NULL);
! 2525: for (;;) {
! 2526: struct xilinx_rx_buffer *buf;
! 2527: buf = SIMPLEQ_FIRST(&sc->wp_rx_complete_list);
! 2528: if (buf == NULL)
! 2529: break;
! 2530:
! 2531: SIMPLEQ_REMOVE_HEAD(&sc->wp_rx_complete_list, entry);
! 2532:
! 2533: new_m = NULL;
! 2534: pkt_error = 0;
! 2535:
! 2536: xilinx_rx_post_complete(sc->common.card, sc, buf, &new_m,
! 2537: &pkt_error);
! 2538: if (new_m) {
! 2539: ifp = (struct ifnet *)&sc->common.ifp;
! 2540: #ifdef DEBUG_RX
! 2541: log(LOG_INFO, "%s: Receiving packet %d bytes!\n",
! 2542: ifp->if_xname, new_m->m_len);
! 2543: #endif
! 2544: wanpipe_generic_input(ifp, new_m);
! 2545: }
! 2546: }
! 2547:
! 2548: for (;;) {
! 2549: IF_DEQUEUE(&sc->wp_tx_complete_list, m);
! 2550: if (m == NULL)
! 2551: break;
! 2552: xilinx_tx_post_complete(sc->common.card, sc, m);
! 2553: m_freem(m);
! 2554: }
! 2555:
! 2556: return;
! 2557: }
! 2558:
! 2559: static int
! 2560: fifo_error_interrupt(sdla_t *card, unsigned long reg)
! 2561: {
! 2562: u_int32_t rx_status, tx_status;
! 2563: u_int32_t err = 0;
! 2564: u_int32_t i;
! 2565: xilinx_softc_t *sc;
! 2566:
! 2567: #ifdef DEBUG_ERR
! 2568: log(LOG_INFO, "%s: Fifo error interrupt!\n", card->devname);
! 2569: #endif
! 2570:
! 2571: /* Clear HDLC pending registers */
! 2572: sdla_bus_read_4(card->hw, XILINX_HDLC_TX_INTR_PENDING_REG, &tx_status);
! 2573: sdla_bus_read_4(card->hw, XILINX_HDLC_RX_INTR_PENDING_REG, &rx_status);
! 2574:
! 2575: if (card->state != WAN_CONNECTED) {
! 2576: log(LOG_INFO, "%s: Warning: Ignoring Error Intr: link disc!\n",
! 2577: card->devname);
! 2578: return (0);
! 2579: }
! 2580:
! 2581: tx_status &= card->u.xilinx.active_ch_map;
! 2582: rx_status &= card->u.xilinx.active_ch_map;
! 2583:
! 2584: if (tx_status != 0) {
! 2585: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 2586: if (bit_test((u_int8_t *)&tx_status, i) &&
! 2587: bit_test((u_int8_t *)&card->u.xilinx.logic_ch_map,
! 2588: i)) {
! 2589: struct ifnet *ifp;
! 2590:
! 2591: sc = (xilinx_softc_t *)
! 2592: card->u.xilinx.dev_to_ch_map[i];
! 2593: if (!sc) {
! 2594: log(LOG_INFO, "Warning: ignoring tx "
! 2595: "error intr: no dev!\n");
! 2596: continue;
! 2597: }
! 2598:
! 2599: ifp = (struct ifnet *)&sc->common.ifp;
! 2600: #if 0
! 2601: if (!(ifp->if_flags & IFF_UP)) {
! 2602: log(LOG_INFO, "%s: Warning: ignoring "
! 2603: "tx error intr: dev down 0x%X "
! 2604: "UP=0x%X!\n", ifp->if_xname,
! 2605: sc->common.state,
! 2606: sc->ignore_modem);
! 2607: continue;
! 2608: }
! 2609: #endif
! 2610:
! 2611: if (card->state != WAN_CONNECTED) {
! 2612: log(LOG_INFO, "%s: Warning: ignoring "
! 2613: "tx error intr: dev disc!\n",
! 2614: ifp->if_xname);
! 2615: continue;
! 2616: }
! 2617:
! 2618: #ifdef DEBUG_ERR
! 2619: log(LOG_INFO, "%s:%s: Warning TX Fifo Error "
! 2620: "on LogicCh=%ld Slot=%d!\n",
! 2621: card->devname, sc->if_name,
! 2622: sc->logic_ch_num, i);
! 2623: #endif
! 2624: xilinx_tx_fifo_under_recover(card, sc);
! 2625: err=EINVAL;
! 2626: }
! 2627: }
! 2628: }
! 2629:
! 2630:
! 2631: if (rx_status != 0) {
! 2632: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 2633: if (bit_test((u_int8_t *)&rx_status, i) &&
! 2634: bit_test((u_int8_t *)&card->u.xilinx.logic_ch_map,
! 2635: i)) {
! 2636: struct ifnet *ifp;
! 2637: sc = (xilinx_softc_t *)
! 2638: card->u.xilinx.dev_to_ch_map[i];
! 2639: if (!sc)
! 2640: continue;
! 2641:
! 2642: ifp = (struct ifnet *)&sc->common.ifp;
! 2643: #if 0
! 2644: if (!(ifp->if_flags & IFF_UP)) {
! 2645: log(LOG_INFO, "%s: Warning: ignoring "
! 2646: "rx error intr: dev down "
! 2647: "0x%X UP=0x%X!\n", ifp->if_xname,
! 2648: sc->common.state,
! 2649: sc->ignore_modem);
! 2650: continue;
! 2651: }
! 2652: #endif
! 2653:
! 2654: if (card->state != WAN_CONNECTED) {
! 2655: log(LOG_INFO, "%s: Warning: ignoring "
! 2656: "rx error intr: dev disc!\n",
! 2657: ifp->if_xname);
! 2658: continue;
! 2659: }
! 2660:
! 2661: #ifdef DEBUG_ERR
! 2662: log(LOG_INFO, "%s:%s: Warning RX Fifo Error "
! 2663: "on LCh=%ld Slot=%d RxDMA=%d\n",
! 2664: card->devname, sc->if_name,
! 2665: sc->logic_ch_num, i,
! 2666: sc->rx_dma);
! 2667: #endif
! 2668:
! 2669: #if 0
! 2670: {
! 2671: unsigned long dma_descr;
! 2672: unsigned int reg;
! 2673: dma_descr = (sc->logic_ch_num << 4) +
! 2674: XILINX_RxDMA_DESCRIPTOR_HI;
! 2675: sdla_bus_read_4(card->hw, dma_descr, ®);
! 2676: log(LOG_INFO, "%s: Hi Descriptor 0x%X\n",
! 2677: sc->if_name, reg);
! 2678: }
! 2679: #endif
! 2680:
! 2681: bit_set((u_int8_t *)&sc->pkt_error,
! 2682: WP_FIFO_ERROR_BIT);
! 2683: err = EINVAL;
! 2684: }
! 2685: }
! 2686: }
! 2687:
! 2688: return (err);
! 2689: }
! 2690:
! 2691:
! 2692: static void
! 2693: front_end_interrupt(sdla_t *card, unsigned long reg)
! 2694: {
! 2695: sdla_te_intr(card);
! 2696: handle_front_end_state(card);
! 2697: return;
! 2698: }
! 2699:
! 2700: /*
! 2701: * HARDWARE Interrupt Handlers
! 2702: */
! 2703:
! 2704:
! 2705: /*
! 2706: * Main interrupt service routine.
! 2707: * Determine the interrupt received and handle it.
! 2708: */
! 2709: static void
! 2710: wp_xilinx_isr(sdla_t* card)
! 2711: {
! 2712: int i;
! 2713: u_int32_t reg;
! 2714: u_int32_t dma_tx_reg, dma_rx_reg;
! 2715: xilinx_softc_t *sc;
! 2716:
! 2717: if (bit_test((u_int8_t *)&card->critical, CARD_DOWN)) {
! 2718: log(LOG_INFO, "%s: Card down, ignoring interrupt !!!!!!!!\n",
! 2719: card->devname);
! 2720: return;
! 2721: }
! 2722:
! 2723: bit_set((u_int8_t *)&card->in_isr, 0);
! 2724:
! 2725: /* write_cpld(card, LED_CONTROL_REG, 0x0F);*/
! 2726:
! 2727: /*
! 2728: * Disable all chip Interrupts (offset 0x040)
! 2729: * -- "Transmit/Receive DMA Engine" interrupt disable
! 2730: * -- "FiFo/Line Abort Error" interrupt disable
! 2731: */
! 2732: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 2733:
! 2734: if (bit_test((u_int8_t *)®, SECURITY_STATUS_FLAG)) {
! 2735: log(LOG_INFO, "%s: Critical: Chip Security Compromised!\n",
! 2736: card->devname);
! 2737: log(LOG_INFO, "%s: Disabling Driver!\n",
! 2738: card->devname);
! 2739:
! 2740: port_set_state(card, WAN_DISCONNECTED);
! 2741: disable_data_error_intr(card, CARD_DOWN);
! 2742: goto isr_end;
! 2743: }
! 2744:
! 2745: /*
! 2746: * Note: If interrupts are received without pending flags, it usually
! 2747: * indicates that the interrupt * is being shared.
! 2748: */
! 2749: if (bit_test((u_int8_t *)®, FRONT_END_INTR_ENABLE_BIT)) {
! 2750: if (bit_test((u_int8_t *)®, FRONT_END_INTR_FLAG)) {
! 2751: front_end_interrupt(card, reg);
! 2752: if (card->u.xilinx.state_change_exit_isr) {
! 2753: card->u.xilinx.state_change_exit_isr = 0;
! 2754: /*
! 2755: * The state change occured, skip all
! 2756: * other interrupts
! 2757: */
! 2758: goto isr_end;
! 2759: }
! 2760: }
! 2761: }
! 2762:
! 2763: /*
! 2764: * Test Fifo Error Interrupt
! 2765: * If set shutdown all interfaces and reconfigure
! 2766: */
! 2767: if (bit_test((u_int8_t *)®, ERROR_INTR_ENABLE_BIT))
! 2768: if (bit_test((u_int8_t *)®, ERROR_INTR_FLAG))
! 2769: fifo_error_interrupt(card, reg);
! 2770:
! 2771: /*
! 2772: * Checking for Interrupt source:
! 2773: * 1. Receive DMA Engine
! 2774: * 2. Transmit DMA Engine
! 2775: * 3. Error conditions.
! 2776: */
! 2777: if (bit_test((u_int8_t *)®, GLOBAL_INTR_ENABLE_BIT) &&
! 2778: bit_test((u_int8_t *)®, DMA_INTR_FLAG)) {
! 2779:
! 2780: /* Receive DMA Engine */
! 2781: sdla_bus_read_4(card->hw, XILINX_DMA_RX_INTR_PENDING_REG,
! 2782: &dma_rx_reg);
! 2783:
! 2784: dma_rx_reg &= card->u.xilinx.active_ch_map;
! 2785:
! 2786: if (dma_rx_reg == 0)
! 2787: goto isr_rx;
! 2788:
! 2789: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 2790: if (bit_test((u_int8_t *)&dma_rx_reg, i) &&
! 2791: bit_test((u_int8_t *)
! 2792: &card->u.xilinx.logic_ch_map, i)) {
! 2793: sc = (xilinx_softc_t *)
! 2794: card->u.xilinx.dev_to_ch_map[i];
! 2795: if (!sc) {
! 2796: log(LOG_INFO, "%s: Error: No Dev for "
! 2797: "Rx logical ch=%d\n",
! 2798: card->devname, i);
! 2799: continue;
! 2800: }
! 2801:
! 2802: xilinx_dma_rx_complete(card, sc);
! 2803: }
! 2804: }
! 2805: isr_rx:
! 2806:
! 2807: /* Transmit DMA Engine */
! 2808: sdla_bus_read_4(card->hw, XILINX_DMA_TX_INTR_PENDING_REG,
! 2809: &dma_tx_reg);
! 2810:
! 2811: dma_tx_reg &= card->u.xilinx.active_ch_map;
! 2812:
! 2813: if (dma_tx_reg == 0)
! 2814: goto isr_tx;
! 2815:
! 2816: for (i = 0; i < card->u.xilinx.num_of_time_slots; i++) {
! 2817: if (bit_test((u_int8_t *)&dma_tx_reg, i) &&
! 2818: bit_test((u_int8_t *)
! 2819: &card->u.xilinx.logic_ch_map, i)) {
! 2820: sc = (xilinx_softc_t *)
! 2821: card->u.xilinx.dev_to_ch_map[i];
! 2822: if (!sc) {
! 2823: log(LOG_INFO, "%s: Error: No Dev for "
! 2824: "Tx logical ch=%d\n",
! 2825: card->devname, i);
! 2826: continue;
! 2827: }
! 2828:
! 2829: xilinx_dma_tx_complete(card, sc);
! 2830: }
! 2831: }
! 2832: }
! 2833:
! 2834: isr_tx:
! 2835:
! 2836: isr_end:
! 2837:
! 2838: /* write_cpld(card, LED_CONTROL_REG, 0x0E); */
! 2839:
! 2840: bit_clear((u_int8_t *)&card->in_isr, 0);
! 2841: return;
! 2842: }
! 2843:
! 2844:
! 2845: /*
! 2846: * TASK Functions and Triggers
! 2847: */
! 2848:
! 2849: /*
! 2850: * port_set_state
! 2851: *
! 2852: * Set PORT state.
! 2853: *
! 2854: */
! 2855: static void
! 2856: port_set_state(sdla_t *card, int state)
! 2857: {
! 2858: wanpipe_common_t *common;
! 2859:
! 2860: if (card->state != state) {
! 2861: switch (state) {
! 2862: case WAN_CONNECTED:
! 2863: log(LOG_INFO, "%s: Link connected!\n", card->devname);
! 2864: aft_red_led_ctrl(card, AFT_LED_OFF);
! 2865: aft_green_led_ctrl(card, AFT_LED_ON);
! 2866: break;
! 2867:
! 2868: case WAN_CONNECTING:
! 2869: log(LOG_INFO, "%s: Link connecting...\n",
! 2870: card->devname);
! 2871: aft_red_led_ctrl(card, AFT_LED_ON);
! 2872: aft_green_led_ctrl(card, AFT_LED_OFF);
! 2873: break;
! 2874:
! 2875: case WAN_DISCONNECTED:
! 2876: log(LOG_INFO, "%s: Link disconnected!\n",
! 2877: card->devname);
! 2878: aft_red_led_ctrl(card, AFT_LED_ON);
! 2879: aft_green_led_ctrl(card, AFT_LED_OFF);
! 2880: break;
! 2881: }
! 2882: card->state = state;
! 2883: LIST_FOREACH(common, &card->dev_head, next) {
! 2884: struct ifnet *ifp = (struct ifnet *)&common->ifp;
! 2885: if (ifp)
! 2886: set_chan_state(card, ifp, state);
! 2887: }
! 2888: }
! 2889: }
! 2890:
! 2891:
! 2892: /*
! 2893: * handle_front_end_state
! 2894: */
! 2895:
! 2896: static void
! 2897: handle_front_end_state(void *card_id)
! 2898: {
! 2899: sdla_t *card = (sdla_t *)card_id;
! 2900:
! 2901: if (card->front_end_status == FE_CONNECTED) {
! 2902: enable_data_error_intr(card);
! 2903: port_set_state(card, WAN_CONNECTED);
! 2904: card->u.xilinx.state_change_exit_isr = 1;
! 2905: } else {
! 2906: port_set_state(card, WAN_CONNECTING);
! 2907: disable_data_error_intr(card, LINK_DOWN);
! 2908: card->u.xilinx.state_change_exit_isr = 1;
! 2909: }
! 2910: }
! 2911:
! 2912: static unsigned char
! 2913: read_cpld(sdla_t *card, unsigned short cpld_off)
! 2914: {
! 2915: u_int16_t org_off;
! 2916: u_int8_t tmp;
! 2917:
! 2918: cpld_off &= ~BIT_DEV_ADDR_CLEAR;
! 2919: cpld_off |= BIT_DEV_ADDR_CPLD;
! 2920:
! 2921: /* Save the current address. */
! 2922: sdla_bus_read_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, &org_off);
! 2923:
! 2924: sdla_bus_write_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, cpld_off);
! 2925:
! 2926: sdla_bus_read_1(card->hw, XILINX_MCPU_INTERFACE, &tmp);
! 2927:
! 2928: /* Restore original address */
! 2929: sdla_bus_write_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, org_off);
! 2930:
! 2931: return (tmp);
! 2932: }
! 2933:
! 2934: static unsigned char
! 2935: write_cpld(sdla_t *card, unsigned short off, unsigned char data)
! 2936: {
! 2937: u_int16_t org_off;
! 2938:
! 2939: off &= ~BIT_DEV_ADDR_CLEAR;
! 2940: off |= BIT_DEV_ADDR_CPLD;
! 2941:
! 2942: /* Save the current original address */
! 2943: sdla_bus_read_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, &org_off);
! 2944:
! 2945: sdla_bus_write_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, off);
! 2946:
! 2947: /* This delay is required to avoid bridge optimization
! 2948: * (combining two writes together)*/
! 2949: DELAY(5);
! 2950:
! 2951: sdla_bus_write_1(card->hw, XILINX_MCPU_INTERFACE, data);
! 2952:
! 2953: /* This delay is required to avoid bridge optimization
! 2954: * (combining two writes together)*/
! 2955: DELAY(5);
! 2956:
! 2957: /* Restore the original address */
! 2958: sdla_bus_write_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, org_off);
! 2959:
! 2960: return (0);
! 2961: }
! 2962:
! 2963: static unsigned char
! 2964: write_front_end_reg(void *card1, unsigned short off, unsigned char value)
! 2965: {
! 2966: sdla_t *card = (sdla_t *)card1;
! 2967:
! 2968: off &= ~BIT_DEV_ADDR_CLEAR;
! 2969: sdla_bus_write_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, off);
! 2970: /*
! 2971: * These delays are required to avoid bridge optimization
! 2972: * (combining two writes together)
! 2973: */
! 2974: DELAY(5);
! 2975: sdla_bus_write_1(card->hw, XILINX_MCPU_INTERFACE, value);
! 2976: DELAY(5);
! 2977:
! 2978: return (0);
! 2979: }
! 2980:
! 2981:
! 2982: /*
! 2983: * Read TE1/56K Front end registers
! 2984: */
! 2985: static unsigned char
! 2986: read_front_end_reg(void *card1, unsigned short off)
! 2987: {
! 2988: sdla_t* card = (sdla_t *)card1;
! 2989: u_int8_t tmp;
! 2990:
! 2991: off &= ~BIT_DEV_ADDR_CLEAR;
! 2992: sdla_bus_write_2(card->hw, XILINX_MCPU_INTERFACE_ADDR, off);
! 2993: sdla_bus_read_1(card->hw, XILINX_MCPU_INTERFACE, &tmp);
! 2994: DELAY(5);
! 2995:
! 2996: return (tmp);
! 2997: }
! 2998:
! 2999:
! 3000: /*
! 3001: * Run only after the front end comes up from down state.
! 3002: *
! 3003: * Clean the DMA Tx/Rx pending interrupts.
! 3004: * (Ignore since we will reconfigure
! 3005: * all dma descriptors. DMA controler
! 3006: * was already disabled on link down)
! 3007: *
! 3008: * For all channels clean Tx/Rx Fifo
! 3009: *
! 3010: * Enable DMA controler
! 3011: * (This starts the fifo cleaning
! 3012: * process)
! 3013: *
! 3014: * For all channels reprogram Tx/Rx DMA
! 3015: * descriptors.
! 3016: *
! 3017: * Clean the Tx/Rx Error pending interrupts.
! 3018: * (Since dma fifo's are now empty)
! 3019: *
! 3020: * Enable global DMA and Error interrutps.
! 3021: *
! 3022: */
! 3023:
! 3024: static void
! 3025: enable_data_error_intr(sdla_t *card)
! 3026: {
! 3027: wanpipe_common_t *common;
! 3028: struct ifnet *ifp;
! 3029: u_int32_t reg;
! 3030:
! 3031: /* Clean Tx/Rx DMA interrupts */
! 3032: sdla_bus_read_4(card->hw, XILINX_DMA_RX_INTR_PENDING_REG, ®);
! 3033: sdla_bus_read_4(card->hw, XILINX_DMA_TX_INTR_PENDING_REG, ®);
! 3034:
! 3035: /* For all channels clean Tx/Rx fifos */
! 3036: LIST_FOREACH(common, &card->dev_head, next) {
! 3037: xilinx_softc_t *sc;
! 3038:
! 3039: ifp = (struct ifnet *)&common->ifp;
! 3040: if (!ifp || !ifp->if_softc)
! 3041: continue;
! 3042: sc = ifp->if_softc;
! 3043: #if 0
! 3044: if (!(ifp->if_flags & IFF_UP))
! 3045: continue;
! 3046: #endif
! 3047:
! 3048: #ifdef DEBUG_INIT
! 3049: log(LOG_INFO, "%s: Init interface fifo no wait %s\n",
! 3050: sc->if_name, __FUNCTION__);
! 3051: #endif
! 3052: xilinx_init_rx_dev_fifo(card, sc, WP_NO_WAIT);
! 3053: xilinx_init_tx_dev_fifo(card, sc, WP_NO_WAIT);
! 3054: }
! 3055:
! 3056: /*
! 3057: * Enable DMA controler, in order to start the
! 3058: * fifo cleaning
! 3059: */
! 3060: sdla_bus_read_4(card->hw, XILINX_DMA_CONTROL_REG, ®);
! 3061: bit_set((u_int8_t *)®, DMA_ENGINE_ENABLE_BIT);
! 3062: sdla_bus_write_4(card->hw, XILINX_DMA_CONTROL_REG, reg);
! 3063:
! 3064: /* For all channels clean Tx/Rx fifos */
! 3065: LIST_FOREACH(common, &card->dev_head, next) {
! 3066: xilinx_softc_t *sc;
! 3067:
! 3068: ifp = (struct ifnet *)&common->ifp;
! 3069: if (!ifp || ifp->if_softc == NULL)
! 3070: continue;
! 3071: sc = ifp->if_softc;
! 3072: #if 0
! 3073: if (!(ifp->if_flags & IFF_UP))
! 3074: continue;
! 3075: #endif
! 3076:
! 3077:
! 3078: #ifdef DEBUG_INIT
! 3079: log(LOG_INFO, "%s: Init interface fifo %s\n",
! 3080: sc->if_name, __FUNCTION__);
! 3081: #endif
! 3082:
! 3083: xilinx_init_rx_dev_fifo(card, sc, WP_WAIT);
! 3084: xilinx_init_tx_dev_fifo(card, sc, WP_WAIT);
! 3085:
! 3086: #ifdef DEBUG_INIT
! 3087: log(LOG_INFO, "%s: Clearing Fifo and idle_flag %s\n",
! 3088: card->devname, sc->if_name);
! 3089: #endif
! 3090: bit_clear((u_int8_t *)&sc->idle_start, 0);
! 3091: }
! 3092:
! 3093: /* For all channels, reprogram Tx/Rx DMA descriptors.
! 3094: * For Tx also make sure that the BUSY flag is clear
! 3095: * and previoulsy Tx packet is deallocated */
! 3096: LIST_FOREACH(common, &card->dev_head, next) {
! 3097: xilinx_softc_t *sc;
! 3098:
! 3099: ifp = (struct ifnet *)&common->ifp;
! 3100: if (!ifp || !ifp->if_softc)
! 3101: continue;
! 3102: sc = ifp->if_softc;
! 3103: #if 0
! 3104: if (!(ifp->if_flags & IFF_UP)) {
! 3105: continue;
! 3106: }
! 3107: #endif
! 3108:
! 3109: #ifdef DEBUG_INIT
! 3110: log(LOG_INFO, "%s: Init interface %s\n",
! 3111: sc->if_name, __FUNCTION__);
! 3112: #endif
! 3113:
! 3114: if (sc->rx_dma_buf) {
! 3115: aft_reload_rx_dma_buff(sc, sc->rx_dma_buf);
! 3116: sc->rx_dma_buf = NULL;
! 3117: }
! 3118:
! 3119: xilinx_dma_rx(card, sc);
! 3120:
! 3121: if (sc->tx_dma_addr && sc->tx_dma_len) {
! 3122: sc->tx_dma_addr = 0;
! 3123: sc->tx_dma_len = 0;
! 3124: }
! 3125:
! 3126: if (sc->tx_dma_mbuf) {
! 3127: bus_dmamap_unload(sc->dmatag, sc->tx_dmamap);
! 3128: m_freem(sc->tx_dma_mbuf);
! 3129: sc->tx_dma_mbuf = NULL;
! 3130: }
! 3131:
! 3132: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 3133: bit_clear((u_int8_t *)&sc->idle_start, 0);
! 3134:
! 3135: #ifdef DEBUG_INIT
! 3136: log(LOG_INFO, "%s: Clearing Fifo and idle_flag %s\n",
! 3137: card->devname, sc->if_name);
! 3138: #endif
! 3139: }
! 3140:
! 3141: /*
! 3142: * Clean Tx/Rx Error interrupts, since fifos are now
! 3143: * empty, and Tx fifo may generate an underrun which
! 3144: * we want to ignore :)
! 3145: */
! 3146: sdla_bus_read_4(card->hw, XILINX_HDLC_RX_INTR_PENDING_REG, ®);
! 3147: sdla_bus_read_4(card->hw, XILINX_HDLC_TX_INTR_PENDING_REG, ®);
! 3148:
! 3149: /* Enable Global DMA and Error Interrupts */
! 3150: reg = 0;
! 3151: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 3152: bit_set((u_int8_t *)®, GLOBAL_INTR_ENABLE_BIT);
! 3153: bit_set((u_int8_t *)®, ERROR_INTR_ENABLE_BIT);
! 3154: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 3155:
! 3156: return;
! 3157: }
! 3158:
! 3159: static void
! 3160: disable_data_error_intr(sdla_t *card, unsigned char event)
! 3161: {
! 3162: u_int32_t reg;
! 3163:
! 3164: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, ®);
! 3165: bit_clear((u_int8_t *)®, GLOBAL_INTR_ENABLE_BIT);
! 3166: bit_clear((u_int8_t *)®, ERROR_INTR_ENABLE_BIT);
! 3167: if (event == DEVICE_DOWN)
! 3168: bit_clear((u_int8_t *)®, FRONT_END_INTR_ENABLE_BIT);
! 3169:
! 3170: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, reg);
! 3171:
! 3172: sdla_bus_read_4(card->hw, XILINX_DMA_CONTROL_REG, ®);
! 3173: bit_clear((u_int8_t *)®, DMA_ENGINE_ENABLE_BIT);
! 3174: sdla_bus_write_4(card->hw, XILINX_DMA_CONTROL_REG, reg);
! 3175:
! 3176: }
! 3177:
! 3178: static void
! 3179: xilinx_init_tx_dma_descr(sdla_t *card, xilinx_softc_t *sc)
! 3180: {
! 3181: unsigned long dma_descr;
! 3182: unsigned long reg = 0;
! 3183:
! 3184: dma_descr = (sc->logic_ch_num << 4) + XILINX_TxDMA_DESCRIPTOR_HI;
! 3185: sdla_bus_write_4(card->hw, dma_descr, reg);
! 3186: }
! 3187:
! 3188:
! 3189:
! 3190: static void
! 3191: xilinx_tx_fifo_under_recover(sdla_t *card, xilinx_softc_t *sc)
! 3192: {
! 3193: struct ifnet *ifp = (struct ifnet *)&sc->common.ifp;
! 3194: u_int32_t reg = 0;
! 3195: unsigned long dma_descr;
! 3196:
! 3197: #ifdef DEBUG_ERR
! 3198: log(LOG_INFO, "%s:%s: Tx Fifo Recovery \n",
! 3199: card->devname, sc->if_name);
! 3200: #endif
! 3201:
! 3202: /* Initialize Tx DMA descriptor: Stop DMA */
! 3203: dma_descr = (sc->logic_ch_num << 4) + XILINX_TxDMA_DESCRIPTOR_HI;
! 3204: sdla_bus_write_4(card->hw, dma_descr, reg);
! 3205:
! 3206: /* Clean the TX FIFO */
! 3207: xilinx_init_tx_dev_fifo(card, sc, WP_WAIT);
! 3208: if (sc->tx_dma_addr && sc->tx_dma_len) {
! 3209: sc->tx_dma_addr = 0;
! 3210: sc->tx_dma_len = 0;
! 3211: }
! 3212:
! 3213: /* Requeue the current tx packet, for re-transmission */
! 3214: if (sc->tx_dma_mbuf) {
! 3215: IF_PREPEND(&sc->wp_tx_pending_list,
! 3216: (struct mbuf *)sc->tx_dma_mbuf);
! 3217: sc->tx_dma_mbuf = NULL;
! 3218: }
! 3219:
! 3220: /*
! 3221: * Wake up the stack, because tx dma interrupt failed
! 3222: */
! 3223: if (ifp)
! 3224: ifp->if_oerrors++;
! 3225:
! 3226: #ifdef DEBUG_ERR
! 3227: log(LOG_INFO, "%s:%s: Tx Fifo Recovery: Restarting Transmission \n",
! 3228: card->devname, sc->if_name);
! 3229: #endif
! 3230:
! 3231: /* Re-start transmission */
! 3232: bit_clear((u_int8_t *)&sc->dma_status, TX_BUSY);
! 3233: if (!xilinx_dma_tx(card, sc)) {
! 3234: /* If we was able to transmit and the interface is set
! 3235: * to OACTIVE remove this flag and let kernel try to
! 3236: * transmit.
! 3237: */
! 3238: if (ifp->if_flags & IFF_OACTIVE)
! 3239: ifp->if_flags &= ~IFF_OACTIVE;
! 3240: }
! 3241: return;
! 3242: }
! 3243:
! 3244: static int
! 3245: xilinx_write_ctrl_hdlc(sdla_t *card, u_int32_t timeslot,
! 3246: u_int8_t reg_off, u_int32_t data)
! 3247: {
! 3248: u_int32_t reg;
! 3249: u_int32_t ts_orig = timeslot;
! 3250: unsigned long timeout = ticks;
! 3251:
! 3252: if (timeslot == 0)
! 3253: timeslot = card->u.xilinx.num_of_time_slots - 2;
! 3254: else if (timeslot == 1)
! 3255: timeslot = card->u.xilinx.num_of_time_slots - 1;
! 3256: else
! 3257: timeslot -= 2;
! 3258:
! 3259: timeslot = timeslot << XILINX_CURRENT_TIMESLOT_SHIFT;
! 3260: timeslot &= XILINX_CURRENT_TIMESLOT_MASK;
! 3261:
! 3262: for (;;) {
! 3263: sdla_bus_read_4(card->hw, XILINX_TIMESLOT_HDLC_CHAN_REG, ®);
! 3264: reg &= XILINX_CURRENT_TIMESLOT_MASK;
! 3265:
! 3266: if (reg == timeslot) {
! 3267: sdla_bus_write_4(card->hw, reg_off, data);
! 3268: return (0);
! 3269: }
! 3270:
! 3271: if ((ticks-timeout) > 1) {
! 3272: log(LOG_INFO, "%s: Error: Access to timeslot %d "
! 3273: "timed out!\n", card->devname, ts_orig);
! 3274: return (EIO);
! 3275: }
! 3276: }
! 3277:
! 3278: return (EIO);
! 3279: }
! 3280:
! 3281: static int
! 3282: set_chan_state(sdla_t *card, struct ifnet *ifp, int state)
! 3283: {
! 3284: xilinx_softc_t *sc = ifp->if_softc;
! 3285:
! 3286: if (sc == NULL)
! 3287: return (0);
! 3288:
! 3289: if (state == WAN_CONNECTED) {
! 3290: #ifdef DEBUG_INIT
! 3291: log(LOG_INFO, "%s: Setting idle_start to 0\n", sc->if_name);
! 3292: #endif
! 3293: bit_clear((u_int8_t *)&sc->idle_start, 0);
! 3294: sc->common.ifp.pp_up(&sc->common.ifp);
! 3295: } else if (state == WAN_DISCONNECTED)
! 3296: sc->common.ifp.pp_down(&sc->common.ifp);
! 3297:
! 3298: return (0);
! 3299: }
! 3300:
! 3301:
! 3302: static char fifo_size_vector[] = {1, 2, 4, 8, 16, 32};
! 3303: static char fifo_code_vector[] = {0, 1, 3, 7, 0xF, 0x1F};
! 3304:
! 3305: static int
! 3306: request_fifo_baddr_and_size(sdla_t *card, xilinx_softc_t *sc)
! 3307: {
! 3308: unsigned char req_fifo_size, fifo_size;
! 3309: int i;
! 3310:
! 3311: /*
! 3312: * Calculate the optimal fifo size based
! 3313: * on the number of time slots requested
! 3314: */
! 3315:
! 3316: if (IS_T1(&card->fe_te.te_cfg)) {
! 3317: if (sc->num_of_time_slots == NUM_OF_T1_CHANNELS)
! 3318: req_fifo_size = 32;
! 3319: else if (sc->num_of_time_slots == 1)
! 3320: req_fifo_size = 1;
! 3321: else if (sc->num_of_time_slots == 2 ||
! 3322: sc->num_of_time_slots == 3)
! 3323: req_fifo_size = 2;
! 3324: else if (sc->num_of_time_slots >= 4 &&
! 3325: sc->num_of_time_slots <= 7)
! 3326: req_fifo_size = 4;
! 3327: else if (sc->num_of_time_slots >= 8 &&
! 3328: sc->num_of_time_slots <= 15)
! 3329: req_fifo_size = 8;
! 3330: else if (sc->num_of_time_slots >= 16 &&
! 3331: sc->num_of_time_slots <= 23)
! 3332: req_fifo_size = 16;
! 3333: else {
! 3334: log(LOG_INFO, "%s: Invalid number of timeslots %d\n",
! 3335: card->devname, sc->num_of_time_slots);
! 3336: return (EINVAL);
! 3337: }
! 3338: } else {
! 3339: if (sc->num_of_time_slots == (NUM_OF_E1_CHANNELS-1))
! 3340: req_fifo_size = 32;
! 3341: else if (sc->num_of_time_slots == 1)
! 3342: req_fifo_size = 1;
! 3343: else if (sc->num_of_time_slots == 2 ||
! 3344: sc->num_of_time_slots == 3)
! 3345: req_fifo_size = 2;
! 3346: else if (sc->num_of_time_slots >= 4 &&
! 3347: sc->num_of_time_slots <= 7)
! 3348: req_fifo_size = 4;
! 3349: else if (sc->num_of_time_slots >= 8 &&
! 3350: sc->num_of_time_slots <= 15)
! 3351: req_fifo_size = 8;
! 3352: else if (sc->num_of_time_slots >= 16 &&
! 3353: sc->num_of_time_slots <= 31)
! 3354: req_fifo_size = 16;
! 3355: else {
! 3356: log(LOG_INFO,
! 3357: "%s:%s: Invalid number of timeslots %d\n",
! 3358: card->devname, sc->if_name, sc->num_of_time_slots);
! 3359: return (EINVAL);
! 3360: }
! 3361: }
! 3362:
! 3363: #ifdef DEBUG_INIT
! 3364: log(LOG_INFO, "%s:%s: Optimal Fifo Size =%d Timeslots=%d \n",
! 3365: card->devname, sc->if_name, req_fifo_size, sc->num_of_time_slots);
! 3366: #endif
! 3367: fifo_size = map_fifo_baddr_and_size(card, req_fifo_size,
! 3368: &sc->fifo_base_addr);
! 3369:
! 3370: if (fifo_size == 0 || sc->fifo_base_addr == 31) {
! 3371: log(LOG_INFO, "%s:%s: Error: Failed to obtain fifo size %d "
! 3372: "or addr %d\n", card->devname, sc->if_name, fifo_size,
! 3373: sc->fifo_base_addr);
! 3374: return (EINVAL);
! 3375: }
! 3376:
! 3377: #ifdef DEBUG_INIT
! 3378: log(LOG_INFO, "%s:%s: Optimal Fifo Size =%d TS=%d New Fifo Size=%d\n",
! 3379: card->devname, sc->if_name, req_fifo_size, sc->num_of_time_slots,
! 3380: fifo_size);
! 3381: #endif
! 3382:
! 3383: for (i = 0; i < sizeof(fifo_size_vector); i++) {
! 3384: if (fifo_size_vector[i] == fifo_size) {
! 3385: sc->fifo_size_code = fifo_code_vector[i];
! 3386: break;
! 3387: }
! 3388: }
! 3389:
! 3390: if (fifo_size != req_fifo_size)
! 3391: log(LOG_INFO, "%s:%s: WARN: Failed to obtain the req "
! 3392: "fifo %d got %d\n", card->devname, sc->if_name,
! 3393: req_fifo_size, fifo_size);
! 3394:
! 3395: #ifdef DEBUG_INIT
! 3396: log(LOG_INFO, "%s: %s:Fifo Size=%d TS=%d Fifo Code=%d Addr=%d\n",
! 3397: card->devname, sc->if_name, fifo_size, sc->num_of_time_slots,
! 3398: sc->fifo_size_code, sc->fifo_base_addr);
! 3399: #endif
! 3400: sc->fifo_size = fifo_size;
! 3401:
! 3402: return (0);
! 3403: }
! 3404:
! 3405:
! 3406: static int
! 3407: map_fifo_baddr_and_size(sdla_t *card, unsigned char fifo_size,
! 3408: unsigned char *addr)
! 3409: {
! 3410: u_int32_t reg = 0;
! 3411: int i;
! 3412:
! 3413: for (i = 0; i < fifo_size; i++)
! 3414: bit_set((u_int8_t *)®, i);
! 3415:
! 3416: #ifdef DEBUG_INIT
! 3417: log(LOG_INFO, "%s: Trying to MAP 0x%X to 0x%lX\n",
! 3418: card->devname, reg, card->u.xilinx.fifo_addr_map);
! 3419: #endif
! 3420: for (i = 0; i < 32; i += fifo_size) {
! 3421: if (card->u.xilinx.fifo_addr_map & (reg << i))
! 3422: continue;
! 3423: card->u.xilinx.fifo_addr_map |= reg << i;
! 3424: *addr = i;
! 3425:
! 3426: #ifdef DEBUG_INIT
! 3427: log(LOG_INFO, "%s: Card fifo Map 0x%lX Addr =%d\n",
! 3428: card->devname, card->u.xilinx.fifo_addr_map, i);
! 3429: #endif
! 3430: return (fifo_size);
! 3431: }
! 3432:
! 3433: if (fifo_size == 1)
! 3434: return (0);
! 3435:
! 3436: fifo_size = fifo_size >> 1;
! 3437:
! 3438: return map_fifo_baddr_and_size(card, fifo_size, addr);
! 3439: }
! 3440:
! 3441:
! 3442: static int
! 3443: free_fifo_baddr_and_size(sdla_t *card, xilinx_softc_t *sc)
! 3444: {
! 3445: u_int32_t reg = 0;
! 3446: int i;
! 3447:
! 3448: for (i = 0; i < sc->fifo_size; i++)
! 3449: bit_set((u_int8_t *)®, i);
! 3450:
! 3451: #ifdef DEBUG_INIT
! 3452: log(LOG_INFO, "%s: Unmapping 0x%X from 0x%lX\n", card->devname,
! 3453: reg << sc->fifo_base_addr, card->u.xilinx.fifo_addr_map);
! 3454: #endif
! 3455: card->u.xilinx.fifo_addr_map &= ~(reg << sc->fifo_base_addr);
! 3456:
! 3457: #ifdef DEBUG_INIT
! 3458: log(LOG_INFO, "%s: New Map is 0x%lX\n",
! 3459: card->devname, card->u.xilinx.fifo_addr_map);
! 3460: #endif
! 3461:
! 3462: sc->fifo_size = 0;
! 3463: sc->fifo_base_addr = 0;
! 3464:
! 3465: return (0);
! 3466: }
! 3467:
! 3468: static void
! 3469: aft_red_led_ctrl(sdla_t *card, int mode)
! 3470: {
! 3471: unsigned int led;
! 3472:
! 3473: sdla_bus_read_4(card->hw, XILINX_CHIP_CFG_REG, &led);
! 3474:
! 3475: if (mode == AFT_LED_ON)
! 3476: bit_clear((u_int8_t *)&led, XILINX_RED_LED);
! 3477: else if (mode == AFT_LED_OFF)
! 3478: bit_set((u_int8_t *)&led, XILINX_RED_LED);
! 3479: else {
! 3480: if (bit_test((u_int8_t *)&led, XILINX_RED_LED))
! 3481: bit_clear((u_int8_t *)&led, XILINX_RED_LED);
! 3482: else
! 3483: bit_set((u_int8_t *)&led, XILINX_RED_LED);
! 3484: }
! 3485:
! 3486: sdla_bus_write_4(card->hw, XILINX_CHIP_CFG_REG, led);
! 3487: }
! 3488:
! 3489: static void
! 3490: aft_led_timer(void *data)
! 3491: {
! 3492: sdla_t *card=(sdla_t *)data;
! 3493: unsigned int te_alarm;
! 3494:
! 3495: if (bit_test((u_int8_t *)&card->critical, CARD_DOWN))
! 3496: return;
! 3497:
! 3498: if (IS_TE1(&card->fe_te.te_cfg)) {
! 3499: int s = splnet();
! 3500:
! 3501: te_alarm = sdla_te_alarm(card, 0);
! 3502: te_alarm &= ~(BIT_OOSMF_ALARM|BIT_OOCMF_ALARM);
! 3503:
! 3504: if (!te_alarm) {
! 3505: if (card->state == WAN_CONNECTED) {
! 3506: aft_red_led_ctrl(card, AFT_LED_OFF);
! 3507: aft_green_led_ctrl(card, AFT_LED_ON);
! 3508: } else {
! 3509: aft_red_led_ctrl(card, AFT_LED_OFF);
! 3510: aft_green_led_ctrl(card, AFT_LED_TOGGLE);
! 3511: }
! 3512:
CVSweb