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