| /* Copyright (C) 2003-2005 SBE, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| |
| #include <linux/slab.h> |
| #include <asm/io.h> |
| #include <asm/byteorder.h> |
| #include <linux/netdevice.h> |
| #include <linux/delay.h> |
| #include <linux/hdlc.h> |
| #include "pmcc4_sysdep.h" |
| #include "sbecom_inline_linux.h" |
| #include "libsbew.h" |
| #include "pmcc4.h" |
| |
| |
| #ifdef SBE_INCLUDE_SYMBOLS |
| #define STATIC |
| #else |
| #define STATIC static |
| #endif |
| |
| #if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \ |
| defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE) |
| #define _v7_hdlc_ 1 |
| #else |
| #define _v7_hdlc_ 0 |
| #endif |
| |
| #if _v7_hdlc_ |
| #define V7(x) (x ## _v7) |
| extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *); |
| extern int register_hdlc_device_v7 (hdlc_device *); |
| extern int unregister_hdlc_device_v7 (hdlc_device *); |
| |
| #else |
| #define V7(x) x |
| #endif |
| |
| |
| #ifndef USE_MAX_INT_DELAY |
| static int dummy = 0; |
| |
| #endif |
| |
| extern int log_level; |
| extern int drvr_state; |
| |
| |
| #if 1 |
| u_int32_t |
| pci_read_32 (u_int32_t *p) |
| { |
| #ifdef FLOW_DEBUG |
| u_int32_t v; |
| |
| FLUSH_PCI_READ (); |
| v = le32_to_cpu (*p); |
| if (log_level >= LOG_DEBUG) |
| pr_info("pci_read : %x = %x\n", (u_int32_t) p, v); |
| return v; |
| #else |
| FLUSH_PCI_READ (); /* */ |
| return le32_to_cpu (*p); |
| #endif |
| } |
| |
| void |
| pci_write_32 (u_int32_t *p, u_int32_t v) |
| { |
| #ifdef FLOW_DEBUG |
| if (log_level >= LOG_DEBUG) |
| pr_info("pci_write: %x = %x\n", (u_int32_t) p, v); |
| #endif |
| *p = cpu_to_le32 (v); |
| FLUSH_PCI_WRITE (); /* This routine is called from routines |
| * which do multiple register writes |
| * which themselves need flushing between |
| * writes in order to guarantee write |
| * ordering. It is less code-cumbersome |
| * to flush here-in then to investigate |
| * and code the many other register |
| * writing routines. */ |
| } |
| #endif |
| |
| |
| void |
| pci_flush_write (ci_t * ci) |
| { |
| volatile u_int32_t v; |
| |
| /* issue a PCI read to flush PCI write thru bridge */ |
| v = *(u_int32_t *) &ci->reg->glcd; /* any address would do */ |
| |
| /* |
| * return nothing, this just reads PCI bridge interface to flush |
| * previously written data |
| */ |
| } |
| |
| |
| STATIC void |
| watchdog_func (unsigned long arg) |
| { |
| struct watchdog *wd = (void *) arg; |
| |
| if (drvr_state != SBE_DRVR_AVAILABLE) |
| { |
| if (log_level >= LOG_MONITOR) |
| pr_warning("%s: drvr not available (%x)\n", __func__, drvr_state); |
| return; |
| } |
| schedule_work (&wd->work); |
| mod_timer (&wd->h, jiffies + wd->ticks); |
| } |
| |
| int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *), void *c, int usec) |
| { |
| wdp->func = f; |
| wdp->softc = c; |
| wdp->ticks = (HZ) * (usec / 1000) / 1000; |
| INIT_WORK(&wdp->work, (void *)f); |
| init_timer (&wdp->h); |
| { |
| ci_t *ci = (ci_t *) c; |
| |
| wdp->h.data = (unsigned long) &ci->wd; |
| } |
| wdp->h.function = watchdog_func; |
| return 0; |
| } |
| |
| void |
| OS_uwait (int usec, char *description) |
| { |
| int tmp; |
| |
| if (usec >= 1000) |
| { |
| mdelay (usec / 1000); |
| /* now delay residual */ |
| tmp = (usec / 1000) * 1000; /* round */ |
| tmp = usec - tmp; /* residual */ |
| if (tmp) |
| { /* wait on residual */ |
| udelay (tmp); |
| } |
| } else |
| { |
| udelay (usec); |
| } |
| } |
| |
| /* dummy short delay routine called as a subroutine so that compiler |
| * does not optimize/remove its intent (a short delay) |
| */ |
| |
| void |
| OS_uwait_dummy (void) |
| { |
| #ifndef USE_MAX_INT_DELAY |
| dummy++; |
| #else |
| udelay (1); |
| #endif |
| } |
| |
| |
| void |
| OS_sem_init (void *sem, int state) |
| { |
| switch (state) |
| { |
| case SEM_TAKEN: |
| init_MUTEX_LOCKED ((struct semaphore *) sem); |
| break; |
| case SEM_AVAILABLE: |
| init_MUTEX ((struct semaphore *) sem); |
| break; |
| default: /* otherwise, set sem.count to state's |
| * value */ |
| sema_init (sem, state); |
| break; |
| } |
| } |
| |
| |
| int |
| sd_line_is_ok (void *user) |
| { |
| struct net_device *ndev = (struct net_device *) user; |
| |
| return (netif_carrier_ok (ndev)); |
| } |
| |
| void |
| sd_line_is_up (void *user) |
| { |
| struct net_device *ndev = (struct net_device *) user; |
| |
| netif_carrier_on (ndev); |
| return; |
| } |
| |
| void |
| sd_line_is_down (void *user) |
| { |
| struct net_device *ndev = (struct net_device *) user; |
| |
| netif_carrier_off (ndev); |
| return; |
| } |
| |
| void |
| sd_disable_xmit (void *user) |
| { |
| struct net_device *dev = (struct net_device *) user; |
| |
| netif_stop_queue (dev); |
| return; |
| } |
| |
| void |
| sd_enable_xmit (void *user) |
| { |
| struct net_device *dev = (struct net_device *) user; |
| |
| netif_wake_queue (dev); |
| return; |
| } |
| |
| int |
| sd_queue_stopped (void *user) |
| { |
| struct net_device *ndev = (struct net_device *) user; |
| |
| return (netif_queue_stopped (ndev)); |
| } |
| |
| void sd_recv_consume(void *token, size_t len, void *user) |
| { |
| struct net_device *ndev = user; |
| struct sk_buff *skb = token; |
| |
| skb->dev = ndev; |
| skb_put (skb, len); |
| skb->protocol = hdlc_type_trans(skb, ndev); |
| netif_rx(skb); |
| } |
| |
| |
| /** |
| ** Read some reserved location w/in the COMET chip as a usable |
| ** VMETRO trigger point or other trace marking event. |
| **/ |
| |
| #include "comet.h" |
| |
| extern ci_t *CI; /* dummy pointer to board ZERO's data */ |
| void |
| VMETRO_TRACE (void *x) |
| { |
| u_int32_t y = (u_int32_t) x; |
| |
| pci_write_32 ((u_int32_t *) &CI->cpldbase->leds, y); |
| } |
| |
| |
| void |
| VMETRO_TRIGGER (ci_t * ci, int x) |
| { |
| comet_t *comet; |
| volatile u_int32_t data; |
| |
| comet = ci->port[0].cometbase; /* default to COMET # 0 */ |
| |
| switch (x) |
| { |
| default: |
| case 0: |
| data = pci_read_32 ((u_int32_t *) &comet->__res24); /* 0x90 */ |
| break; |
| case 1: |
| data = pci_read_32 ((u_int32_t *) &comet->__res25); /* 0x94 */ |
| break; |
| case 2: |
| data = pci_read_32 ((u_int32_t *) &comet->__res26); /* 0x98 */ |
| break; |
| case 3: |
| data = pci_read_32 ((u_int32_t *) &comet->__res27); /* 0x9C */ |
| break; |
| case 4: |
| data = pci_read_32 ((u_int32_t *) &comet->__res88); /* 0x220 */ |
| break; |
| case 5: |
| data = pci_read_32 ((u_int32_t *) &comet->__res89); /* 0x224 */ |
| break; |
| case 6: |
| data = pci_read_32 ((u_int32_t *) &comet->__res8A); /* 0x228 */ |
| break; |
| case 7: |
| data = pci_read_32 ((u_int32_t *) &comet->__res8B); /* 0x22C */ |
| break; |
| case 8: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA0); /* 0x280 */ |
| break; |
| case 9: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA1); /* 0x284 */ |
| break; |
| case 10: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA2); /* 0x288 */ |
| break; |
| case 11: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA3); /* 0x28C */ |
| break; |
| case 12: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA4); /* 0x290 */ |
| break; |
| case 13: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA5); /* 0x294 */ |
| break; |
| case 14: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA6); /* 0x298 */ |
| break; |
| case 15: |
| data = pci_read_32 ((u_int32_t *) &comet->__resA7); /* 0x29C */ |
| break; |
| case 16: |
| data = pci_read_32 ((u_int32_t *) &comet->__res74); /* 0x1D0 */ |
| break; |
| case 17: |
| data = pci_read_32 ((u_int32_t *) &comet->__res75); /* 0x1D4 */ |
| break; |
| case 18: |
| data = pci_read_32 ((u_int32_t *) &comet->__res76); /* 0x1D8 */ |
| break; |
| case 19: |
| data = pci_read_32 ((u_int32_t *) &comet->__res77); /* 0x1DC */ |
| break; |
| } |
| } |
| |
| |
| /*** End-of-File ***/ |