at v3.7 356 lines 8.5 kB view raw
1/* Copyright (C) 2003-2005 SBE, Inc. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation; either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15 16#include <linux/slab.h> 17#include <asm/io.h> 18#include <asm/byteorder.h> 19#include <linux/netdevice.h> 20#include <linux/delay.h> 21#include <linux/hdlc.h> 22#include "pmcc4_sysdep.h" 23#include "sbecom_inline_linux.h" 24#include "libsbew.h" 25#include "pmcc4.h" 26 27 28#ifdef SBE_INCLUDE_SYMBOLS 29#define STATIC 30#else 31#define STATIC static 32#endif 33 34#if defined(CONFIG_SBE_HDLC_V7) || defined(CONFIG_SBE_WAN256T3_HDLC_V7) || \ 35 defined(CONFIG_SBE_HDLC_V7_MODULE) || defined(CONFIG_SBE_WAN256T3_HDLC_V7_MODULE) 36#define _v7_hdlc_ 1 37#else 38#define _v7_hdlc_ 0 39#endif 40 41#if _v7_hdlc_ 42#define V7(x) (x ## _v7) 43extern int hdlc_netif_rx_v7 (hdlc_device *, struct sk_buff *); 44extern int register_hdlc_device_v7 (hdlc_device *); 45extern int unregister_hdlc_device_v7 (hdlc_device *); 46 47#else 48#define V7(x) x 49#endif 50 51 52#ifndef USE_MAX_INT_DELAY 53static int dummy = 0; 54 55#endif 56 57extern int cxt1e1_log_level; 58extern int drvr_state; 59 60 61#if 1 62u_int32_t 63pci_read_32 (u_int32_t *p) 64{ 65#ifdef FLOW_DEBUG 66 u_int32_t v; 67 68 FLUSH_PCI_READ (); 69 v = le32_to_cpu (*p); 70 if (cxt1e1_log_level >= LOG_DEBUG) 71 pr_info("pci_read : %x = %x\n", (u_int32_t) p, v); 72 return v; 73#else 74 FLUSH_PCI_READ (); /* */ 75 return le32_to_cpu (*p); 76#endif 77} 78 79void 80pci_write_32 (u_int32_t *p, u_int32_t v) 81{ 82#ifdef FLOW_DEBUG 83 if (cxt1e1_log_level >= LOG_DEBUG) 84 pr_info("pci_write: %x = %x\n", (u_int32_t) p, v); 85#endif 86 *p = cpu_to_le32 (v); 87 FLUSH_PCI_WRITE (); /* This routine is called from routines 88 * which do multiple register writes 89 * which themselves need flushing between 90 * writes in order to guarantee write 91 * ordering. It is less code-cumbersome 92 * to flush here-in then to investigate 93 * and code the many other register 94 * writing routines. */ 95} 96#endif 97 98 99void 100pci_flush_write (ci_t * ci) 101{ 102 volatile u_int32_t v; 103 104 /* issue a PCI read to flush PCI write thru bridge */ 105 v = *(u_int32_t *) &ci->reg->glcd; /* any address would do */ 106 107 /* 108 * return nothing, this just reads PCI bridge interface to flush 109 * previously written data 110 */ 111} 112 113 114STATIC void 115watchdog_func (unsigned long arg) 116{ 117 struct watchdog *wd = (void *) arg; 118 119 if (drvr_state != SBE_DRVR_AVAILABLE) 120 { 121 if (cxt1e1_log_level >= LOG_MONITOR) 122 pr_warning("%s: drvr not available (%x)\n", __func__, drvr_state); 123 return; 124 } 125 schedule_work (&wd->work); 126 mod_timer (&wd->h, jiffies + wd->ticks); 127} 128 129int OS_init_watchdog(struct watchdog *wdp, void (*f) (void *), void *c, int usec) 130{ 131 wdp->func = f; 132 wdp->softc = c; 133 wdp->ticks = (HZ) * (usec / 1000) / 1000; 134 INIT_WORK(&wdp->work, (void *)f); 135 init_timer (&wdp->h); 136 { 137 ci_t *ci = (ci_t *) c; 138 139 wdp->h.data = (unsigned long) &ci->wd; 140 } 141 wdp->h.function = watchdog_func; 142 return 0; 143} 144 145void 146OS_uwait (int usec, char *description) 147{ 148 int tmp; 149 150 if (usec >= 1000) 151 { 152 mdelay (usec / 1000); 153 /* now delay residual */ 154 tmp = (usec / 1000) * 1000; /* round */ 155 tmp = usec - tmp; /* residual */ 156 if (tmp) 157 { /* wait on residual */ 158 udelay (tmp); 159 } 160 } else 161 { 162 udelay (usec); 163 } 164} 165 166/* dummy short delay routine called as a subroutine so that compiler 167 * does not optimize/remove its intent (a short delay) 168 */ 169 170void 171OS_uwait_dummy (void) 172{ 173#ifndef USE_MAX_INT_DELAY 174 dummy++; 175#else 176 udelay (1); 177#endif 178} 179 180 181void 182OS_sem_init (void *sem, int state) 183{ 184 switch (state) 185 { 186 case SEM_TAKEN: 187 sema_init((struct semaphore *) sem, 0); 188 break; 189 case SEM_AVAILABLE: 190 sema_init((struct semaphore *) sem, 1); 191 break; 192 default: /* otherwise, set sem.count to state's 193 * value */ 194 sema_init (sem, state); 195 break; 196 } 197} 198 199 200int 201sd_line_is_ok (void *user) 202{ 203 struct net_device *ndev = (struct net_device *) user; 204 205 return (netif_carrier_ok (ndev)); 206} 207 208void 209sd_line_is_up (void *user) 210{ 211 struct net_device *ndev = (struct net_device *) user; 212 213 netif_carrier_on (ndev); 214 return; 215} 216 217void 218sd_line_is_down (void *user) 219{ 220 struct net_device *ndev = (struct net_device *) user; 221 222 netif_carrier_off (ndev); 223 return; 224} 225 226void 227sd_disable_xmit (void *user) 228{ 229 struct net_device *dev = (struct net_device *) user; 230 231 netif_stop_queue (dev); 232 return; 233} 234 235void 236sd_enable_xmit (void *user) 237{ 238 struct net_device *dev = (struct net_device *) user; 239 240 netif_wake_queue (dev); 241 return; 242} 243 244int 245sd_queue_stopped (void *user) 246{ 247 struct net_device *ndev = (struct net_device *) user; 248 249 return (netif_queue_stopped (ndev)); 250} 251 252void sd_recv_consume(void *token, size_t len, void *user) 253{ 254 struct net_device *ndev = user; 255 struct sk_buff *skb = token; 256 257 skb->dev = ndev; 258 skb_put (skb, len); 259 skb->protocol = hdlc_type_trans(skb, ndev); 260 netif_rx(skb); 261} 262 263 264/** 265 ** Read some reserved location w/in the COMET chip as a usable 266 ** VMETRO trigger point or other trace marking event. 267 **/ 268 269#include "comet.h" 270 271extern ci_t *CI; /* dummy pointer to board ZERO's data */ 272void 273VMETRO_TRACE (void *x) 274{ 275 u_int32_t y = (u_int32_t) x; 276 277 pci_write_32 ((u_int32_t *) &CI->cpldbase->leds, y); 278} 279 280 281void 282VMETRO_TRIGGER (ci_t * ci, int x) 283{ 284 comet_t *comet; 285 volatile u_int32_t data; 286 287 comet = ci->port[0].cometbase; /* default to COMET # 0 */ 288 289 switch (x) 290 { 291 default: 292 case 0: 293 data = pci_read_32 ((u_int32_t *) &comet->__res24); /* 0x90 */ 294 break; 295 case 1: 296 data = pci_read_32 ((u_int32_t *) &comet->__res25); /* 0x94 */ 297 break; 298 case 2: 299 data = pci_read_32 ((u_int32_t *) &comet->__res26); /* 0x98 */ 300 break; 301 case 3: 302 data = pci_read_32 ((u_int32_t *) &comet->__res27); /* 0x9C */ 303 break; 304 case 4: 305 data = pci_read_32 ((u_int32_t *) &comet->__res88); /* 0x220 */ 306 break; 307 case 5: 308 data = pci_read_32 ((u_int32_t *) &comet->__res89); /* 0x224 */ 309 break; 310 case 6: 311 data = pci_read_32 ((u_int32_t *) &comet->__res8A); /* 0x228 */ 312 break; 313 case 7: 314 data = pci_read_32 ((u_int32_t *) &comet->__res8B); /* 0x22C */ 315 break; 316 case 8: 317 data = pci_read_32 ((u_int32_t *) &comet->__resA0); /* 0x280 */ 318 break; 319 case 9: 320 data = pci_read_32 ((u_int32_t *) &comet->__resA1); /* 0x284 */ 321 break; 322 case 10: 323 data = pci_read_32 ((u_int32_t *) &comet->__resA2); /* 0x288 */ 324 break; 325 case 11: 326 data = pci_read_32 ((u_int32_t *) &comet->__resA3); /* 0x28C */ 327 break; 328 case 12: 329 data = pci_read_32 ((u_int32_t *) &comet->__resA4); /* 0x290 */ 330 break; 331 case 13: 332 data = pci_read_32 ((u_int32_t *) &comet->__resA5); /* 0x294 */ 333 break; 334 case 14: 335 data = pci_read_32 ((u_int32_t *) &comet->__resA6); /* 0x298 */ 336 break; 337 case 15: 338 data = pci_read_32 ((u_int32_t *) &comet->__resA7); /* 0x29C */ 339 break; 340 case 16: 341 data = pci_read_32 ((u_int32_t *) &comet->__res74); /* 0x1D0 */ 342 break; 343 case 17: 344 data = pci_read_32 ((u_int32_t *) &comet->__res75); /* 0x1D4 */ 345 break; 346 case 18: 347 data = pci_read_32 ((u_int32_t *) &comet->__res76); /* 0x1D8 */ 348 break; 349 case 19: 350 data = pci_read_32 ((u_int32_t *) &comet->__res77); /* 0x1DC */ 351 break; 352 } 353} 354 355 356/*** End-of-File ***/