1/* -*- linux-c -*- */ 2/* 3 * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. 9 * 10 **/ 11 12#include <linux/module.h> 13#include <linux/kernel.h> 14#include <linux/pci.h> 15#include <linux/stddef.h> 16#include <linux/string.h> 17#include <linux/sockios.h> 18#include <asm/io.h> 19#include <asm/byteorder.h> 20#include <asm/pgtable.h> 21#include <linux/skbuff.h> 22#include <linux/if_arp.h> 23#include <linux/fs.h> 24#include <linux/sched.h> 25#include <asm/uaccess.h> 26#include <linux/version.h> 27#include <linux/etherdevice.h> 28#include "Reg9050.h" 29#include "8253xctl.h" 30#include "ring.h" 31#include "8253x.h" 32#include "crc32dcl.h" 33 34 /* turns network packet into a pseudoethernet */ 35 /* frame -- does ethernet stuff that 8253x does */ 36 /* not do -- makes minimum 64 bytes add crc, etc*/ 37int 38sab8253xn_write2(struct sk_buff *skb, struct net_device *dev) 39{ 40 size_t cnt; 41 unsigned int flags; 42 SAB_PORT *priv = (SAB_PORT*) dev->priv; 43 struct sk_buff *substitute; 44 45#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) 46 if(dev->tbusy != 0) /* something of an error */ 47 { 48 ++(priv->Counters.tx_drops); 49 dev_kfree_skb_any(skb); 50 return -EBUSY; /* only during release */ 51 } 52#endif 53 54 if(priv->active2.transmit == NULL) 55 { 56 return -ENOMEM; 57 } 58 59 DEBUGPRINT((KERN_ALERT "sab8253x: sending IP packet(bytes):\n")); 60 61 DEBUGPRINT((KERN_ALERT "sab8253x: start address is %p.\n", skb->data)); 62 63 cnt = skb->tail - skb->data; 64 cnt = MIN(cnt, sab8253xn_rbufsize); 65 if(cnt < ETH_ZLEN) 66 { 67 if((skb->end - skb->data) >= ETH_ZLEN) 68 { 69 skb->tail = (skb->data + ETH_ZLEN); 70 cnt = ETH_ZLEN; 71 } 72 else 73 { 74 substitute = dev_alloc_skb(ETH_ZLEN); 75 if(substitute == NULL) 76 { 77 dev_kfree_skb_any(skb); 78 return 0; 79 } 80 substitute->tail = (substitute->data + ETH_ZLEN); 81 memcpy(substitute->data, skb->data, cnt); 82 cnt = ETH_ZLEN; 83 dev_kfree_skb_any(skb); 84 skb = substitute; 85 } 86 } 87 88 save_flags(flags); cli(); 89 if((priv->active2.transmit->Count & OWNER) == OWN_SAB) 90 { 91 ++(priv->Counters.tx_drops); 92#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) 93 dev->tbusy = 1; 94#else 95 netif_stop_queue (dev); 96#endif 97 priv->tx_full = 1; 98 restore_flags(flags); 99 return 1; 100 } 101 restore_flags(flags); 102#ifndef FREEINTERRUPT 103 if(priv->active2.transmit->HostVaddr != NULL) 104 { 105 register RING_DESCRIPTOR *freeme; 106 107 freeme = priv->active2.transmit; 108 do 109 { 110 skb_unlink((struct sk_buff*)freeme->HostVaddr); 111 dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr); 112 freeme->HostVaddr = NULL; 113 freeme = (RING_DESCRIPTOR*) freeme->VNext; 114 } 115 while(((freeme->Count & OWNER) != OWN_SAB) && 116 (freeme->HostVaddr != NULL)); 117 } 118#endif 119 dev->trans_start = jiffies; 120 skb_queue_head(priv->sab8253xbuflist, skb); 121 priv->active2.transmit->HostVaddr = skb; 122 priv->active2.transmit->sendcrc = 1; 123 priv->active2.transmit->crcindex = 0; 124 priv->active2.transmit->crc = fn_calc_memory_crc32(skb->data, cnt); 125 priv->active2.transmit->Count = (OWN_SAB|cnt); /* must be this order */ 126 priv->active2.transmit = 127 (RING_DESCRIPTOR*) priv->active2.transmit->VNext; 128 priv->Counters.transmitbytes += cnt; 129 sab8253x_start_txS(priv); 130 return 0; 131} 132 133 /* packetizes the received character */ 134 /* stream */ 135static void sab8253x_receive_charsN(struct sab_port *port, 136 union sab8253x_irq_status *stat) 137{ 138 unsigned char buf[32]; 139 int free_fifo = 0; 140 int reset_fifo = 0; 141 int msg_done = 0; 142 int msg_bad = 0; 143 int count = 0; 144 int total_size = 0; 145 int rstatus = 0; 146 struct sk_buff *skb; 147 148 /* Read number of BYTES (Character + Status) available. */ 149 150 if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) ) 151 { 152 ++msg_bad; 153 ++free_fifo; 154 ++reset_fifo; 155 } 156 else 157 { 158 if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 159 { 160 count = port->recv_fifo_size; 161 ++free_fifo; 162 } 163 164 if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 165 { 166 count = READB(port,rbcl); 167 count &= (port->recv_fifo_size - 1); 168 ++msg_done; 169 ++free_fifo; 170 171 total_size = READB(port, rbch); 172 if(total_size & SAB82532_RBCH_OV) 173 { 174 msg_bad++; 175 } 176 177 rstatus = READB(port, rsta); 178 if((rstatus & SAB82532_RSTA_VFR) == 0) 179 { 180 msg_bad++; 181 } 182 if(rstatus & SAB82532_RSTA_RDO) 183 { 184 msg_bad++; 185 } 186 if((rstatus & SAB82532_RSTA_CRC) == 0) 187 { 188 msg_bad++; 189 } 190 if(rstatus & SAB82532_RSTA_RAB) 191 { 192 msg_bad++; 193 } 194 } 195 } 196 197 /* Read the FIFO. */ 198 (*port->readfifo)(port, buf, count); 199 200 /* Issue Receive Message Complete command. */ 201 202 if (free_fifo) 203 { 204 sab8253x_cec_wait(port); 205 WRITEB(port, cmdr, SAB82532_CMDR_RMC); 206 } 207 208 if(reset_fifo) 209 { 210 sab8253x_cec_wait(port); 211 WRITEB(port, cmdr, SAB82532_CMDR_RHR); 212 } 213 214 if(port->active2.receive == NULL) 215 { 216 return; 217 } 218 219 if(msg_bad) 220 { 221 ++(port->Counters.rx_drops); 222 port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; /* clear the buffer */ 223 port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB; 224 return; 225 } 226 227 memcpy(port->active2.receive->HostVaddr->tail, buf, count); 228 port->active2.receive->HostVaddr->tail += count; 229 230 if(msg_done) 231 { 232 port->active2.receive->Count = 233 (port->active2.receive->HostVaddr->tail - port->active2.receive->HostVaddr->data); 234 if((port->active2.receive->Count < (ETH_ZLEN+4+3)) || /* 4 is the CRC32 size 3 bytes from the SAB part */ 235 (skb = dev_alloc_skb(sab8253xn_rbufsize), skb == NULL)) 236 { 237 ++(port->Counters.rx_drops); 238 port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 239 /* clear the buffer */ 240 port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB; 241 } 242 else 243 { 244 port->active2.receive->Count -= 3; 245 port->active2.receive->HostVaddr->len = port->active2.receive->Count; 246 port->active2.receive->HostVaddr->pkt_type = PACKET_HOST; 247 port->active2.receive->HostVaddr->dev = port->dev; 248 port->active2.receive->HostVaddr->protocol = 249 eth_type_trans(port->active2.receive->HostVaddr, port->dev); 250 port->active2.receive->HostVaddr->tail -= 3; 251 ++(port->Counters.receivepacket); 252 port->Counters.receivebytes += port->active2.receive->Count; 253 skb_unlink(port->active2.receive->HostVaddr); 254 255 netif_rx(port->active2.receive->HostVaddr); 256 257 skb_queue_head(port->sab8253xbuflist, skb); 258 port->active2.receive->HostVaddr = skb; 259 port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB; 260 } 261 } 262} 263 264static void sab8253x_check_statusN(struct sab_port *port, 265 union sab8253x_irq_status *stat) 266{ 267 int modem_change = 0; 268 mctlsig_t *sig; 269 270 271 if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 272 { 273 port->icount.buf_overrun++; 274 } 275 276 /* Checking DCD */ 277 sig = &port->dcd; 278 if (stat->images[sig->irq] & sig->irqmask) 279 { 280 sig->val = ISON(port,dcd); 281 port->icount.dcd++; 282 modem_change++; 283 } 284 /* Checking CTS */ 285 sig = &port->cts; 286 if (stat->images[sig->irq] & sig->irqmask) 287 { 288 sig->val = ISON(port,cts); 289 port->icount.cts++; 290 modem_change++; 291 } 292 /* Checking DSR */ 293 sig = &port->dsr; 294 if (stat->images[sig->irq] & sig->irqmask) 295 { 296 sig->val = ISON(port,dsr); 297 port->icount.dsr++; 298 modem_change++; 299 } 300 if (modem_change) 301 { 302 wake_up_interruptible(&port->delta_msr_wait); 303 } 304 305 sig = &port->dcd; 306 if ((port->flags & FLAG8253X_CHECK_CD) && 307 (stat->images[sig->irq] & sig->irqmask)) 308 { 309 310 if (sig->val) 311 { 312 netif_carrier_on(port->dev); 313 } 314 else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) && 315 (port->flags & FLAG8253X_CALLOUT_NOHUP))) 316 { 317 netif_carrier_off(port->dev); 318 } 319 } 320} 321 322static void Sab8253xCollectStats(struct net_device *dev) 323{ 324 325 struct net_device_stats *statsp = 326 &((SAB_PORT*) dev->priv)->stats; 327 328 memset(statsp, 0, sizeof(struct net_device_stats)); 329 330 statsp->rx_packets += 331 ((SAB_PORT*)dev->priv)->Counters.receivepacket; 332 statsp->tx_packets += 333 ((SAB_PORT*)dev->priv)->Counters.transmitpacket; 334 statsp->tx_dropped += 335 ((SAB_PORT*)dev->priv)->Counters.tx_drops; 336 statsp->rx_dropped += 337 ((SAB_PORT*)dev->priv)->Counters.rx_drops; 338} 339 340struct net_device_stats *sab8253xn_stats(struct net_device *dev) 341{ 342 SAB_PORT *priv = (SAB_PORT*) dev->priv; 343 344 Sab8253xCollectStats(dev); 345 return &priv->stats; 346} 347 348/* minimal ioctls -- more to be added later */ 349int sab8253xn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 350{ 351 352 SAB_PORT *priv = (SAB_PORT*) dev->priv; 353 354 switch(cmd) 355 { 356 case SAB8253XCLEARCOUNTERS: 357 memset(&priv->Counters, 0, sizeof(struct counters)); 358 break; 359 360 default: 361 break; 362 } 363 return 0; 364} 365 366 367int sab8253x_startupN(struct sab_port *port) 368{ 369 unsigned long flags; 370 int retval = 0; 371 372 save_flags(flags); cli(); 373 374 if (port->flags & FLAG8253X_INITIALIZED) 375 { 376 goto errout; 377 } 378 379 if (!port->regs) 380 { 381 retval = -ENODEV; 382 goto errout; 383 } 384 /* 385 * Initialize the Hardware 386 */ 387 sab8253x_init_lineS(port); /* nothing in this function 388 * refers to tty structure */ 389 390 /* Activate RTS */ 391 RAISE(port,rts); 392 /* Activate DTR */ 393 RAISE(port,dtr); 394 /* 395 * Initialize the modem signals values 396 */ 397 port->dcd.val=ISON(port,dcd); 398 port->cts.val=ISON(port,cts); 399 port->dsr.val=ISON(port,dsr); 400 /* 401 * Finally, enable interrupts 402 */ 403 404 port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE | 405 SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC; 406 /*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); */ 407 408 WRITEB(port,imr0,port->interrupt_mask0); 409 port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR | 410 SAB82532_IMR1_TIN | SAB82532_IMR1_XPR; 411 WRITEB(port, imr1, port->interrupt_mask1); 412 port->all_sent = 1; 413 414 415 /* 416 * and set the speed of the serial port 417 */ 418 sab8253x_change_speedN(port); 419 420 port->flags |= FLAG8253X_INITIALIZED; /* bad name for indicating to other functionalities status */ 421 port->receive_chars = sab8253x_receive_charsN; 422 port->transmit_chars = sab8253x_transmit_charsS; 423 port->check_status = sab8253x_check_statusN; 424 port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF); 425 port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR | 426 SAB82532_ISR1_XDU | SAB82532_ISR1_CSC); 427 port->check_status_test = (SAB82532_ISR1_CSC); 428 429 /*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? 0 : SAB82532_ISR0_CDSC));*/ 430 431 restore_flags(flags); 432 return 0; 433 434 errout: 435 restore_flags(flags); 436 return retval; 437} 438 439int sab8253xn_open(struct net_device *dev) 440{ 441 unsigned int retval; 442 SAB_PORT *priv = (SAB_PORT*) dev->priv; 443 444 if(priv->function != FUNCTION_NR) 445 { 446 return -ENODEV; /* only allowed if there are no restrictions on the port */ 447 } 448 449 450 if(priv->flags & FLAG8253X_CLOSING) /* try again after the TTY close finishes */ 451 { 452#ifdef SERIAL_DO_RESTART 453 return ((priv->flags & FLAG8253X_HUP_NOTIFY) ? 454 -EAGAIN : -ERESTARTSYS); /* The ifconfig UP will just fail */ 455#else 456 return -EAGAIN; 457#endif 458 } 459 460 /* 461 * Maybe start up serial port -- may already be running a TTY 462 */ 463 if(priv->flags & FLAG8253X_NORMAL_ACTIVE) /* probably should be a test open at all */ 464 { 465 return -EBUSY; /* can't reopen in NET */ 466 } 467 468 if(Sab8253xSetUpLists(priv)) 469 { 470 return -ENODEV; 471 } 472 473 if(Sab8253xInitDescriptors2(priv, sab8253xn_listsize, sab8253xn_rbufsize)) 474 { 475 Sab8253xCleanUpTransceiveN(priv); 476 return -ENODEV; 477 } 478 netif_carrier_off(dev); 479 480 priv->open_type = OPEN_SYNC_NET; 481 priv->tty = 0; 482 483 retval = sab8253x_startupN(priv); 484 if (retval) 485 { 486 Sab8253xCleanUpTransceiveN(priv); 487 return retval; 488 } 489 490 priv->flags |= FLAG8253X_NETWORK; /* flag the call out driver that it has to reinitialize the port */ 491 priv->tx_full = 0; 492#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) 493 dev->start = 1; 494 dev->tbusy = 0; 495#else 496 netif_start_queue(dev); 497#endif 498 499 priv->flags |= FLAG8253X_NORMAL_ACTIVE; /* is this a good flag? */ 500 MOD_INC_USE_COUNT; 501 return 0; /* success */ 502} 503/* stop the PPC, free all skbuffers */ 504int sab8253xn_release(struct net_device *dev) /* stop */ 505{ 506 SAB_PORT *priv = (SAB_PORT*) dev->priv; 507 unsigned long flags; 508 509 printk(KERN_ALERT "sab8253xn: network interface going down.\n"); 510 save_flags(flags); cli(); 511 512#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) 513 dev->start = 0; 514 dev->tbusy = 1; 515#else 516 netif_stop_queue (dev); 517#endif 518 519 sab8253x_shutdownN(priv); 520 Sab8253xCleanUpTransceiveN(priv); 521 netif_carrier_off(dev); 522 priv->flags &= ~FLAG8253X_NETWORK; 523 priv->flags &= ~(FLAG8253X_NORMAL_ACTIVE|/*FLAG8253X_CALLOUT_ACTIVE|*/ 524 FLAG8253X_CLOSING); 525 priv->open_type = OPEN_NOT; 526 MOD_DEC_USE_COUNT; 527 restore_flags(flags); 528 return 0; 529} 530 531SAB_PORT *current_sab_port = NULL; 532 533int sab8253xn_init(struct net_device *dev) 534{ 535 536 SAB_PORT *priv; 537 538 printk(KERN_ALERT "sab8253xn: initializing SAB8253X network driver instance.\n"); 539 540 priv = current_sab_port; 541 dev->priv = priv; 542 543 if(dev->priv == NULL) 544 { 545 printk(KERN_ALERT "sab8253xn: could not find active port!\n"); 546 return -ENOMEM; 547 } 548 priv->dev = dev; 549 550 ether_setup(dev); 551 552 dev->irq = priv->irq; 553 dev->hard_start_xmit = sab8253xn_write2; 554 dev->do_ioctl = sab8253xn_ioctl; 555 dev->open = sab8253xn_open; 556 dev->stop = sab8253xn_release; 557 dev->get_stats = sab8253xn_stats; 558 dev->base_addr = (unsigned) priv->regs; 559 /* should I do a request region here */ 560 priv->next_dev = Sab8253xRoot; 561 Sab8253xRoot = dev; 562 return 0; 563} 564 565