1 /* 2 * Copyright (C) 2006 Michael Brown <mbrown (at) fensystems.co.uk>. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 */ 18 19 FILE_LICENCE ( GPL2_OR_LATER ); 20 21 #include <stdint.h> 22 #include <stdlib.h> 23 #include <stdio.h> 24 #include <byteswap.h> 25 #include <string.h> 26 #include <errno.h> 27 #include <gpxe/if_ether.h> 28 #include <gpxe/iobuf.h> 29 #include <gpxe/tables.h> 30 #include <gpxe/process.h> 31 #include <gpxe/init.h> 32 #include <gpxe/device.h> 33 #include <gpxe/errortab.h> 34 #include <gpxe/netdevice.h> 35 36 /** @file 37 * 38 * Network device management 39 * 40 */ 41 42 /** List of network devices */ 43 struct list_head net_devices = LIST_HEAD_INIT ( net_devices ); 44 45 /** List of open network devices, in reverse order of opening */ 46 static struct list_head open_net_devices = LIST_HEAD_INIT ( open_net_devices ); 47 48 /** Default link status code */ 49 #define EUNKNOWN_LINK_STATUS EINPROGRESS 50 51 /** Human-readable message for the default link status */ 52 struct errortab netdev_errors[] __errortab = { 53 { EUNKNOWN_LINK_STATUS, "Unknown" }, 54 }; 55 56 /** 57 * Mark network device as having link down 58 * 59 * @v netdev Network device 60 */ 61 void netdev_link_down ( struct net_device *netdev ) { 62 63 switch ( netdev->link_rc ) { 64 case 0: 65 case -EUNKNOWN_LINK_STATUS: 66 netdev->link_rc = -ENOTCONN; 67 break; 68 default: 69 /* Avoid clobbering a more detailed link status code, 70 * if one is already set. 71 */ 72 break; 73 } 74 } 75 76 /** 77 * Record network device statistic 78 * 79 * @v stats Network device statistics 80 * @v rc Status code 81 */ 82 static void netdev_record_stat ( struct net_device_stats *stats, int rc ) { 83 struct net_device_error *error; 84 struct net_device_error *least_common_error; 85 unsigned int i; 86 87 /* If this is not an error, just update the good counter */ 88 if ( rc == 0 ) { 89 stats->good++; 90 return; 91 } 92 93 /* Update the bad counter */ 94 stats->bad++; 95 96 /* Locate the appropriate error record */ 97 least_common_error = &stats->errors[0]; 98 for ( i = 0 ; i < ( sizeof ( stats->errors ) / 99 sizeof ( stats->errors[0] ) ) ; i++ ) { 100 error = &stats->errors[i]; 101 /* Update matching record, if found */ 102 if ( error->rc == rc ) { 103 error->count++; 104 return; 105 } 106 if ( error->count < least_common_error->count ) 107 least_common_error = error; 108 } 109 110 /* Overwrite the least common error record */ 111 least_common_error->rc = rc; 112 least_common_error->count = 1; 113 } 114 115 /** 116 * Transmit raw packet via network device 117 * 118 * @v netdev Network device 119 * @v iobuf I/O buffer 120 * @ret rc Return status code 121 * 122 * Transmits the packet via the specified network device. This 123 * function takes ownership of the I/O buffer. 124 */ 125 int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) { 126 int rc; 127 128 DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n", 129 netdev, iobuf, iobuf->data, iob_len ( iobuf ) ); 130 131 list_add_tail ( &iobuf->list, &netdev->tx_queue ); 132 133 if ( ! ( netdev->state & NETDEV_OPEN ) ) { 134 rc = -ENETUNREACH; 135 goto err; 136 } 137 138 if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 ) 139 goto err; 140 141 return 0; 142 143 err: 144 netdev_tx_complete_err ( netdev, iobuf, rc ); 145 return rc; 146 } 147 148 /** 149 * Complete network transmission 150 * 151 * @v netdev Network device 152 * @v iobuf I/O buffer 153 * @v rc Packet status code 154 * 155 * The packet must currently be in the network device's TX queue. 156 */ 157 void netdev_tx_complete_err ( struct net_device *netdev, 158 struct io_buffer *iobuf, int rc ) { 159 160 /* Update statistics counter */ 161 netdev_record_stat ( &netdev->tx_stats, rc ); 162 if ( rc == 0 ) { 163 DBGC ( netdev, "NETDEV %p transmission %p complete\n", 164 netdev, iobuf ); 165 } else { 166 DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n", 167 netdev, iobuf, strerror ( rc ) ); 168 } 169 170 /* Catch data corruption as early as possible */ 171 assert ( iobuf->list.next != NULL ); 172 assert ( iobuf->list.prev != NULL ); 173 174 /* Dequeue and free I/O buffer */ 175 list_del ( &iobuf->list ); 176 free_iob ( iobuf ); 177 } 178 179 /** 180 * Complete network transmission 181 * 182 * @v netdev Network device 183 * @v rc Packet status code 184 * 185 * Completes the oldest outstanding packet in the TX queue. 186 */ 187 void netdev_tx_complete_next_err ( struct net_device *netdev, int rc ) { 188 struct io_buffer *iobuf; 189 190 list_for_each_entry ( iobuf, &netdev->tx_queue, list ) { 191 netdev_tx_complete_err ( netdev, iobuf, rc ); 192 return; 193 } 194 } 195 196 /** 197 * Flush device's transmit queue 198 * 199 * @v netdev Network device 200 */ 201 static void netdev_tx_flush ( struct net_device *netdev ) { 202 203 /* Discard any packets in the TX queue */ 204 while ( ! list_empty ( &netdev->tx_queue ) ) { 205 netdev_tx_complete_next_err ( netdev, -ECANCELED ); 206 } 207 } 208 209 /** 210 * Add packet to receive queue 211 * 212 * @v netdev Network device 213 * @v iobuf I/O buffer, or NULL 214 * 215 * The packet is added to the network device's RX queue. This 216 * function takes ownership of the I/O buffer. 217 */ 218 void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) { 219 220 DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n", 221 netdev, iobuf, iobuf->data, iob_len ( iobuf ) ); 222 223 /* Enqueue packet */ 224 list_add_tail ( &iobuf->list, &netdev->rx_queue ); 225 226 /* Update statistics counter */ 227 netdev_record_stat ( &netdev->rx_stats, 0 ); 228 } 229 230 /** 231 * Discard received packet 232 * 233 * @v netdev Network device 234 * @v iobuf I/O buffer, or NULL 235 * @v rc Packet status code 236 * 237 * The packet is discarded and an RX error is recorded. This function 238 * takes ownership of the I/O buffer. @c iobuf may be NULL if, for 239 * example, the net device wishes to report an error due to being 240 * unable to allocate an I/O buffer. 241 */ 242 void netdev_rx_err ( struct net_device *netdev, 243 struct io_buffer *iobuf, int rc ) { 244 245 DBGC ( netdev, "NETDEV %p failed to receive %p: %s\n", 246 netdev, iobuf, strerror ( rc ) ); 247 248 /* Discard packet */ 249 free_iob ( iobuf ); 250 251 /* Update statistics counter */ 252 netdev_record_stat ( &netdev->rx_stats, rc ); 253 } 254 255 /** 256 * Poll for completed and received packets on network device 257 * 258 * @v netdev Network device 259 * 260 * Polls the network device for completed transmissions and received 261 * packets. Any received packets will be added to the RX packet queue 262 * via netdev_rx(). 263 */ 264 void netdev_poll ( struct net_device *netdev ) { 265 266 if ( netdev->state & NETDEV_OPEN ) 267 netdev->op->poll ( netdev ); 268 } 269 270 /** 271 * Remove packet from device's receive queue 272 * 273 * @v netdev Network device 274 * @ret iobuf I/O buffer, or NULL 275 * 276 * Removes the first packet from the device's RX queue and returns it. 277 * Ownership of the packet is transferred to the caller. 278 */ 279 struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) { 280 struct io_buffer *iobuf; 281 282 list_for_each_entry ( iobuf, &netdev->rx_queue, list ) { 283 list_del ( &iobuf->list ); 284 return iobuf; 285 } 286 return NULL; 287 } 288 289 /** 290 * Flush device's receive queue 291 * 292 * @v netdev Network device 293 */ 294 static void netdev_rx_flush ( struct net_device *netdev ) { 295 struct io_buffer *iobuf; 296 297 /* Discard any packets in the RX queue */ 298 while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) { 299 netdev_rx_err ( netdev, iobuf, -ECANCELED ); 300 } 301 } 302 303 /** 304 * Free network device 305 * 306 * @v refcnt Network device reference counter 307 */ 308 static void free_netdev ( struct refcnt *refcnt ) { 309 struct net_device *netdev = 310 container_of ( refcnt, struct net_device, refcnt ); 311 312 netdev_tx_flush ( netdev ); 313 netdev_rx_flush ( netdev ); 314 clear_settings ( netdev_settings ( netdev ) ); 315 free ( netdev ); 316 } 317 318 /** 319 * Allocate network device 320 * 321 * @v priv_size Size of private data area (net_device::priv) 322 * @ret netdev Network device, or NULL 323 * 324 * Allocates space for a network device and its private data area. 325 */ 326 struct net_device * alloc_netdev ( size_t priv_size ) { 327 struct net_device *netdev; 328 size_t total_len; 329 330 total_len = ( sizeof ( *netdev ) + priv_size ); 331 netdev = zalloc ( total_len ); 332 if ( netdev ) { 333 netdev->refcnt.free = free_netdev; 334 netdev->link_rc = -EUNKNOWN_LINK_STATUS; 335 INIT_LIST_HEAD ( &netdev->tx_queue ); 336 INIT_LIST_HEAD ( &netdev->rx_queue ); 337 netdev_settings_init ( netdev ); 338 netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) ); 339 } 340 return netdev; 341 } 342 343 /** 344 * Register network device 345 * 346 * @v netdev Network device 347 * @ret rc Return status code 348 * 349 * Gives the network device a name and adds it to the list of network 350 * devices. 351 */ 352 int register_netdev ( struct net_device *netdev ) { 353 static unsigned int ifindex = 0; 354 int rc; 355 356 /* Create device name */ 357 snprintf ( netdev->name, sizeof ( netdev->name ), "net%d", 358 ifindex++ ); 359 360 /* Set initial link-layer address */ 361 netdev->ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr ); 362 363 /* Register per-netdev configuration settings */ 364 if ( ( rc = register_settings ( netdev_settings ( netdev ), 365 NULL ) ) != 0 ) { 366 DBGC ( netdev, "NETDEV %p could not register settings: %s\n", 367 netdev, strerror ( rc ) ); 368 return rc; 369 } 370 371 /* Add to device list */ 372 netdev_get ( netdev ); 373 list_add_tail ( &netdev->list, &net_devices ); 374 DBGC ( netdev, "NETDEV %p registered as %s (phys %s hwaddr %s)\n", 375 netdev, netdev->name, netdev->dev->name, 376 netdev_addr ( netdev ) ); 377 378 return 0; 379 } 380 381 /** 382 * Open network device 383 * 384 * @v netdev Network device 385 * @ret rc Return status code 386 */ 387 int netdev_open ( struct net_device *netdev ) { 388 int rc; 389 390 /* Do nothing if device is already open */ 391 if ( netdev->state & NETDEV_OPEN ) 392 return 0; 393 394 DBGC ( netdev, "NETDEV %p opening\n", netdev ); 395 396 /* Open the device */ 397 if ( ( rc = netdev->op->open ( netdev ) ) != 0 ) 398 return rc; 399 400 /* Mark as opened */ 401 netdev->state |= NETDEV_OPEN; 402 403 /* Add to head of open devices list */ 404 list_add ( &netdev->open_list, &open_net_devices ); 405 406 return 0; 407 } 408 409 /** 410 * Close network device 411 * 412 * @v netdev Network device 413 */ 414 void netdev_close ( struct net_device *netdev ) { 415 416 /* Do nothing if device is already closed */ 417 if ( ! ( netdev->state & NETDEV_OPEN ) ) 418 return; 419 420 DBGC ( netdev, "NETDEV %p closing\n", netdev ); 421 422 /* Close the device */ 423 netdev->op->close ( netdev ); 424 425 /* Flush TX and RX queues */ 426 netdev_tx_flush ( netdev ); 427 netdev_rx_flush ( netdev ); 428 429 /* Mark as closed */ 430 netdev->state &= ~NETDEV_OPEN; 431 432 /* Remove from open devices list */ 433 list_del ( &netdev->open_list ); 434 } 435 436 /** 437 * Unregister network device 438 * 439 * @v netdev Network device 440 * 441 * Removes the network device from the list of network devices. 442 */ 443 void unregister_netdev ( struct net_device *netdev ) { 444 445 /* Ensure device is closed */ 446 netdev_close ( netdev ); 447 448 /* Unregister per-netdev configuration settings */ 449 unregister_settings ( netdev_settings ( netdev ) ); 450 451 /* Remove from device list */ 452 list_del ( &netdev->list ); 453 netdev_put ( netdev ); 454 DBGC ( netdev, "NETDEV %p unregistered\n", netdev ); 455 } 456 457 /** Enable or disable interrupts 458 * 459 * @v netdev Network device 460 * @v enable Interrupts should be enabled 461 */ 462 void netdev_irq ( struct net_device *netdev, int enable ) { 463 netdev->op->irq ( netdev, enable ); 464 } 465 466 /** 467 * Get network device by name 468 * 469 * @v name Network device name 470 * @ret netdev Network device, or NULL 471 */ 472 struct net_device * find_netdev ( const char *name ) { 473 struct net_device *netdev; 474 475 list_for_each_entry ( netdev, &net_devices, list ) { 476 if ( strcmp ( netdev->name, name ) == 0 ) 477 return netdev; 478 } 479 480 return NULL; 481 } 482 483 /** 484 * Get network device by PCI bus:dev.fn address 485 * 486 * @v bus_type Bus type 487 * @v location Bus location 488 * @ret netdev Network device, or NULL 489 */ 490 struct net_device * find_netdev_by_location ( unsigned int bus_type, 491 unsigned int location ) { 492 struct net_device *netdev; 493 494 list_for_each_entry ( netdev, &net_devices, list ) { 495 if ( ( netdev->dev->desc.bus_type == bus_type ) && 496 ( netdev->dev->desc.location == location ) ) 497 return netdev; 498 } 499 500 return NULL; 501 } 502 503 /** 504 * Get most recently opened network device 505 * 506 * @ret netdev Most recently opened network device, or NULL 507 */ 508 struct net_device * last_opened_netdev ( void ) { 509 struct net_device *netdev; 510 511 list_for_each_entry ( netdev, &open_net_devices, open_list ) { 512 assert ( netdev->state & NETDEV_OPEN ); 513 return netdev; 514 } 515 516 return NULL; 517 } 518 519 /** 520 * Transmit network-layer packet 521 * 522 * @v iobuf I/O buffer 523 * @v netdev Network device 524 * @v net_protocol Network-layer protocol 525 * @v ll_dest Destination link-layer address 526 * @ret rc Return status code 527 * 528 * Prepends link-layer headers to the I/O buffer and transmits the 529 * packet via the specified network device. This function takes 530 * ownership of the I/O buffer. 531 */ 532 int net_tx ( struct io_buffer *iobuf, struct net_device *netdev, 533 struct net_protocol *net_protocol, const void *ll_dest ) { 534 struct ll_protocol *ll_protocol = netdev->ll_protocol; 535 int rc; 536 537 /* Force a poll on the netdevice to (potentially) clear any 538 * backed-up TX completions. This is needed on some network 539 * devices to avoid excessive losses due to small TX ring 540 * sizes. 541 */ 542 netdev_poll ( netdev ); 543 544 /* Add link-layer header */ 545 if ( ( rc = ll_protocol->push ( netdev, iobuf, ll_dest, netdev->ll_addr, 546 net_protocol->net_proto ) ) != 0 ) { 547 free_iob ( iobuf ); 548 return rc; 549 } 550 551 /* Transmit packet */ 552 return netdev_tx ( netdev, iobuf ); 553 } 554 555 /** 556 * Process received network-layer packet 557 * 558 * @v iobuf I/O buffer 559 * @v netdev Network device 560 * @v net_proto Network-layer protocol, in network-byte order 561 * @v ll_source Source link-layer address 562 * @ret rc Return status code 563 */ 564 int net_rx ( struct io_buffer *iobuf, struct net_device *netdev, 565 uint16_t net_proto, const void *ll_source ) { 566 struct net_protocol *net_protocol; 567 568 /* Hand off to network-layer protocol, if any */ 569 for_each_table_entry ( net_protocol, NET_PROTOCOLS ) { 570 if ( net_protocol->net_proto == net_proto ) 571 return net_protocol->rx ( iobuf, netdev, ll_source ); 572 } 573 574 DBGC ( netdev, "NETDEV %p unknown network protocol %04x\n", 575 netdev, ntohs ( net_proto ) ); 576 free_iob ( iobuf ); 577 return 0; 578 } 579 580 /** 581 * Single-step the network stack 582 * 583 * @v process Network stack process 584 * 585 * This polls all interfaces for received packets, and processes 586 * packets from the RX queue. 587 */ 588 static void net_step ( struct process *process __unused ) { 589 struct net_device *netdev; 590 struct io_buffer *iobuf; 591 struct ll_protocol *ll_protocol; 592 const void *ll_dest; 593 const void *ll_source; 594 uint16_t net_proto; 595 int rc; 596 597 /* Poll and process each network device */ 598 list_for_each_entry ( netdev, &net_devices, list ) { 599 600 /* Poll for new packets */ 601 netdev_poll ( netdev ); 602 603 /* Process at most one received packet. Give priority 604 * to getting packets out of the NIC over processing 605 * the received packets, because we advertise a window 606 * that assumes that we can receive packets from the 607 * NIC faster than they arrive. 608 */ 609 if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) { 610 611 DBGC ( netdev, "NETDEV %p processing %p (%p+%zx)\n", 612 netdev, iobuf, iobuf->data, 613 iob_len ( iobuf ) ); 614 615 /* Remove link-layer header */ 616 ll_protocol = netdev->ll_protocol; 617 if ( ( rc = ll_protocol->pull ( netdev, iobuf, 618 &ll_dest, &ll_source, 619 &net_proto ) ) != 0 ) { 620 free_iob ( iobuf ); 621 continue; 622 } 623 624 net_rx ( iobuf, netdev, net_proto, ll_source ); 625 } 626 } 627 } 628 629 /** Networking stack process */ 630 struct process net_process __permanent_process = { 631 .list = LIST_HEAD_INIT ( net_process.list ), 632 .step = net_step, 633 }; 634