2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 FILE_LICENCE ( GPL2_OR_LATER );
29 #include <ipxe/list.h>
30 #include <ipxe/if_ether.h>
31 #include <ipxe/iobuf.h>
32 #include <ipxe/uaccess.h>
33 #include <ipxe/netdevice.h>
34 #include <ipxe/features.h>
35 #include <ipxe/interface.h>
36 #include <ipxe/xfer.h>
38 #include <ipxe/open.h>
40 #include <ipxe/device.h>
49 FEATURE ( FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1 );
51 struct net_protocol aoe_protocol __net_protocol;
53 /******************************************************************************
55 * AoE devices and commands
57 ******************************************************************************
60 /** List of all AoE devices */
61 static LIST_HEAD ( aoe_devices );
63 /** List of active AoE commands */
64 static LIST_HEAD ( aoe_commands );
68 /** Reference counter */
72 struct net_device *netdev;
73 /** ATA command issuing interface */
80 /** Target MAC address */
81 uint8_t target[MAX_LL_ADDR_LEN];
83 /** Saved timeout value */
84 unsigned long timeout;
86 /** Configuration command interface */
87 struct interface config;
88 /** Device is configued */
94 /** Reference count */
97 struct aoe_device *aoedev;
98 /** List of active commands */
99 struct list_head list;
101 /** ATA command interface */
102 struct interface ata;
105 struct ata_cmd command;
107 struct aoe_command_type *type;
111 /** Retransmission timer */
112 struct retry_timer timer;
115 /** An AoE command type */
116 struct aoe_command_type {
118 * Calculate length of AoE command IU
120 * @v aoecmd AoE command
121 * @ret len Length of command IU
123 size_t ( * cmd_len ) ( struct aoe_command *aoecmd );
125 * Build AoE command IU
127 * @v aoecmd AoE command
129 * @v len Length of command IU
131 void ( * cmd ) ( struct aoe_command *aoecmd, void *data, size_t len );
133 * Handle AoE response IU
135 * @v aoecmd AoE command
136 * @v data Response IU
137 * @v len Length of response IU
138 * @v ll_source Link-layer source address
139 * @ret rc Return status code
141 int ( * rsp ) ( struct aoe_command *aoecmd, const void *data,
142 size_t len, const void *ll_source );
146 * Get reference to AoE device
148 * @v aoedev AoE device
149 * @ret aoedev AoE device
151 static inline __attribute__ (( always_inline )) struct aoe_device *
152 aoedev_get ( struct aoe_device *aoedev ) {
153 ref_get ( &aoedev->refcnt );
158 * Drop reference to AoE device
160 * @v aoedev AoE device
162 static inline __attribute__ (( always_inline )) void
163 aoedev_put ( struct aoe_device *aoedev ) {
164 ref_put ( &aoedev->refcnt );
168 * Get reference to AoE command
170 * @v aoecmd AoE command
171 * @ret aoecmd AoE command
173 static inline __attribute__ (( always_inline )) struct aoe_command *
174 aoecmd_get ( struct aoe_command *aoecmd ) {
175 ref_get ( &aoecmd->refcnt );
180 * Drop reference to AoE command
182 * @v aoecmd AoE command
184 static inline __attribute__ (( always_inline )) void
185 aoecmd_put ( struct aoe_command *aoecmd ) {
186 ref_put ( &aoecmd->refcnt );
192 * @v aoedev AoE device
193 * @ret name AoE device name
195 static const char * aoedev_name ( struct aoe_device *aoedev ) {
198 snprintf ( buf, sizeof ( buf ), "%s/e%d.%d", aoedev->netdev->name,
199 aoedev->major, aoedev->minor );
206 * @v refcnt Reference counter
208 static void aoecmd_free ( struct refcnt *refcnt ) {
209 struct aoe_command *aoecmd =
210 container_of ( refcnt, struct aoe_command, refcnt );
212 assert ( ! timer_running ( &aoecmd->timer ) );
213 assert ( list_empty ( &aoecmd->list ) );
215 aoedev_put ( aoecmd->aoedev );
222 * @v aoecmd AoE command
223 * @v rc Reason for close
225 static void aoecmd_close ( struct aoe_command *aoecmd, int rc ) {
226 struct aoe_device *aoedev = aoecmd->aoedev;
229 stop_timer ( &aoecmd->timer );
231 /* Preserve the timeout value for subsequent commands */
232 aoedev->timeout = aoecmd->timer.timeout;
234 /* Remove from list of commands */
235 if ( ! list_empty ( &aoecmd->list ) ) {
236 list_del ( &aoecmd->list );
237 INIT_LIST_HEAD ( &aoecmd->list );
238 aoecmd_put ( aoecmd );
241 /* Shut down interfaces */
242 intf_shutdown ( &aoecmd->ata, rc );
246 * Transmit AoE command request
248 * @v aoecmd AoE command
249 * @ret rc Return status code
251 static int aoecmd_tx ( struct aoe_command *aoecmd ) {
252 struct aoe_device *aoedev = aoecmd->aoedev;
253 struct net_device *netdev = aoedev->netdev;
254 struct io_buffer *iobuf;
255 struct aoehdr *aoehdr;
260 assert ( netdev != NULL );
262 /* If we are transmitting anything that requires a response,
263 * start the retransmission timer. Do this before attempting
264 * to allocate the I/O buffer, in case allocation itself
267 start_timer ( &aoecmd->timer );
269 /* Create outgoing I/O buffer */
270 cmd_len = aoecmd->type->cmd_len ( aoecmd );
271 iobuf = alloc_iob ( MAX_LL_HEADER_LEN + cmd_len );
274 iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
275 aoehdr = iob_put ( iobuf, cmd_len );
277 /* Fill AoE header */
278 memset ( aoehdr, 0, sizeof ( *aoehdr ) );
279 aoehdr->ver_flags = AOE_VERSION;
280 aoehdr->major = htons ( aoedev->major );
281 aoehdr->minor = aoedev->minor;
282 aoehdr->tag = htonl ( aoecmd->tag );
283 aoecmd->type->cmd ( aoecmd, iobuf->data, iob_len ( iobuf ) );
286 if ( ( rc = net_tx ( iobuf, netdev, &aoe_protocol, aoedev->target,
287 netdev->ll_addr ) ) != 0 ) {
288 DBGC ( aoedev, "AoE %s/%08x could not transmit: %s\n",
289 aoedev_name ( aoedev ), aoecmd->tag,
298 * Receive AoE command response
300 * @v aoecmd AoE command
301 * @v iobuf I/O buffer
302 * @v ll_source Link-layer source address
303 * @ret rc Return status code
305 static int aoecmd_rx ( struct aoe_command *aoecmd, struct io_buffer *iobuf,
306 const void *ll_source ) {
307 struct aoe_device *aoedev = aoecmd->aoedev;
308 struct aoehdr *aoehdr = iobuf->data;
312 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
313 DBGC ( aoedev, "AoE %s/%08x received underlength response "
314 "(%zd bytes)\n", aoedev_name ( aoedev ),
315 aoecmd->tag, iob_len ( iobuf ) );
319 if ( ( ntohs ( aoehdr->major ) != aoedev->major ) ||
320 ( aoehdr->minor != aoedev->minor ) ) {
321 DBGC ( aoedev, "AoE %s/%08x received response for incorrect "
322 "device e%d.%d\n", aoedev_name ( aoedev ), aoecmd->tag,
323 ntohs ( aoehdr->major ), aoehdr->minor );
328 /* Catch command failures */
329 if ( aoehdr->ver_flags & AOE_FL_ERROR ) {
330 DBGC ( aoedev, "AoE %s/%08x terminated in error\n",
331 aoedev_name ( aoedev ), aoecmd->tag );
332 aoecmd_close ( aoecmd, -EIO );
337 /* Hand off to command completion handler */
338 if ( ( rc = aoecmd->type->rsp ( aoecmd, iobuf->data, iob_len ( iobuf ),
343 /* Free I/O buffer */
346 /* Terminate command */
347 aoecmd_close ( aoecmd, rc );
353 * Handle AoE retry timer expiry
355 * @v timer AoE retry timer
356 * @v fail Failure indicator
358 static void aoecmd_expired ( struct retry_timer *timer, int fail ) {
359 struct aoe_command *aoecmd =
360 container_of ( timer, struct aoe_command, timer );
363 aoecmd_close ( aoecmd, -ETIMEDOUT );
365 aoecmd_tx ( aoecmd );
370 * Calculate length of AoE ATA command IU
372 * @v aoecmd AoE command
373 * @ret len Length of command IU
375 static size_t aoecmd_ata_cmd_len ( struct aoe_command *aoecmd ) {
376 struct ata_cmd *command = &aoecmd->command;
378 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoeata ) +
379 command->data_out_len );
383 * Build AoE ATA command IU
385 * @v aoecmd AoE command
387 * @v len Length of command IU
389 static void aoecmd_ata_cmd ( struct aoe_command *aoecmd,
390 void *data, size_t len ) {
391 struct aoe_device *aoedev = aoecmd->aoedev;
392 struct ata_cmd *command = &aoecmd->command;
393 struct aoehdr *aoehdr = data;
394 struct aoeata *aoeata = &aoehdr->payload[0].ata;
397 linker_assert ( AOE_FL_DEV_HEAD == ATA_DEV_SLAVE, __fix_ata_h__ );
398 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) +
399 command->data_out_len ) );
402 aoehdr->command = AOE_CMD_ATA;
403 memset ( aoeata, 0, sizeof ( *aoeata ) );
404 aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 ) |
405 ( command->cb.device & ATA_DEV_SLAVE ) |
406 ( command->data_out_len ? AOE_FL_WRITE : 0 ) );
407 aoeata->err_feat = command->cb.err_feat.bytes.cur;
408 aoeata->count = command->cb.count.native;
409 aoeata->cmd_stat = command->cb.cmd_stat;
410 aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
411 if ( ! command->cb.lba48 )
412 aoeata->lba.bytes[3] |=
413 ( command->cb.device & ATA_DEV_MASK );
414 copy_from_user ( aoeata->data, command->data_out, 0,
415 command->data_out_len );
417 DBGC2 ( aoedev, "AoE %s/%08x ATA cmd %02x:%02x:%02x:%02x:%08llx",
418 aoedev_name ( aoedev ), aoecmd->tag, aoeata->aflags,
419 aoeata->err_feat, aoeata->count, aoeata->cmd_stat,
421 if ( command->data_out_len )
422 DBGC2 ( aoedev, " out %04zx", command->data_out_len );
423 if ( command->data_in_len )
424 DBGC2 ( aoedev, " in %04zx", command->data_in_len );
425 DBGC2 ( aoedev, "\n" );
429 * Handle AoE ATA response IU
431 * @v aoecmd AoE command
432 * @v data Response IU
433 * @v len Length of response IU
434 * @v ll_source Link-layer source address
435 * @ret rc Return status code
437 static int aoecmd_ata_rsp ( struct aoe_command *aoecmd, const void *data,
438 size_t len, const void *ll_source __unused ) {
439 struct aoe_device *aoedev = aoecmd->aoedev;
440 struct ata_cmd *command = &aoecmd->command;
441 const struct aoehdr *aoehdr = data;
442 const struct aoeata *aoeata = &aoehdr->payload[0].ata;
446 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) ) {
447 DBGC ( aoedev, "AoE %s/%08x received underlength ATA response "
448 "(%zd bytes)\n", aoedev_name ( aoedev ),
452 data_len = ( len - ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) );
453 DBGC2 ( aoedev, "AoE %s/%08x ATA rsp %02x in %04zx\n",
454 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat,
457 /* Check for command failure */
458 if ( aoeata->cmd_stat & ATA_STAT_ERR ) {
459 DBGC ( aoedev, "AoE %s/%08x status %02x\n",
460 aoedev_name ( aoedev ), aoecmd->tag, aoeata->cmd_stat );
464 /* Check data-in length is sufficient. (There may be trailing
465 * garbage due to Ethernet minimum-frame-size padding.)
467 if ( data_len < command->data_in_len ) {
468 DBGC ( aoedev, "AoE %s/%08x data-in underrun (received %zd, "
469 "expected %zd)\n", aoedev_name ( aoedev ), aoecmd->tag,
470 data_len, command->data_in_len );
474 /* Copy out data payload */
475 copy_to_user ( command->data_in, 0, aoeata->data,
476 command->data_in_len );
481 /** AoE ATA command */
482 static struct aoe_command_type aoecmd_ata = {
483 .cmd_len = aoecmd_ata_cmd_len,
484 .cmd = aoecmd_ata_cmd,
485 .rsp = aoecmd_ata_rsp,
489 * Calculate length of AoE configuration command IU
491 * @v aoecmd AoE command
492 * @ret len Length of command IU
494 static size_t aoecmd_cfg_cmd_len ( struct aoe_command *aoecmd __unused ) {
495 return ( sizeof ( struct aoehdr ) + sizeof ( struct aoecfg ) );
499 * Build AoE configuration command IU
501 * @v aoecmd AoE command
503 * @v len Length of command IU
505 static void aoecmd_cfg_cmd ( struct aoe_command *aoecmd,
506 void *data, size_t len ) {
507 struct aoe_device *aoedev = aoecmd->aoedev;
508 struct aoehdr *aoehdr = data;
509 struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
512 assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) );
515 aoehdr->command = AOE_CMD_CONFIG;
516 memset ( aoecfg, 0, sizeof ( *aoecfg ) );
518 DBGC ( aoedev, "AoE %s/%08x CONFIG cmd\n",
519 aoedev_name ( aoedev ), aoecmd->tag );
523 * Handle AoE configuration response IU
525 * @v aoecmd AoE command
526 * @v data Response IU
527 * @v len Length of response IU
528 * @v ll_source Link-layer source address
529 * @ret rc Return status code
531 static int aoecmd_cfg_rsp ( struct aoe_command *aoecmd, const void *data,
532 size_t len, const void *ll_source ) {
533 struct aoe_device *aoedev = aoecmd->aoedev;
534 struct ll_protocol *ll_protocol = aoedev->netdev->ll_protocol;
535 const struct aoehdr *aoehdr = data;
536 const struct aoecfg *aoecfg = &aoehdr->payload[0].cfg;
539 if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) ) {
540 DBGC ( aoedev, "AoE %s/%08x received underlength "
541 "configuration response (%zd bytes)\n",
542 aoedev_name ( aoedev ), aoecmd->tag, len );
545 DBGC ( aoedev, "AoE %s/%08x CONFIG rsp buf %04x fw %04x scnt %02x\n",
546 aoedev_name ( aoedev ), aoecmd->tag, ntohs ( aoecfg->bufcnt ),
547 aoecfg->fwver, aoecfg->scnt );
549 /* Record target MAC address */
550 memcpy ( aoedev->target, ll_source, ll_protocol->ll_addr_len );
551 DBGC ( aoedev, "AoE %s has MAC address %s\n",
552 aoedev_name ( aoedev ), ll_protocol->ntoa ( aoedev->target ) );
557 /** AoE configuration command */
558 static struct aoe_command_type aoecmd_cfg = {
559 .cmd_len = aoecmd_cfg_cmd_len,
560 .cmd = aoecmd_cfg_cmd,
561 .rsp = aoecmd_cfg_rsp,
564 /** AoE command ATA interface operations */
565 static struct interface_operation aoecmd_ata_op[] = {
566 INTF_OP ( intf_close, struct aoe_command *, aoecmd_close ),
569 /** AoE command ATA interface descriptor */
570 static struct interface_descriptor aoecmd_ata_desc =
571 INTF_DESC ( struct aoe_command, ata, aoecmd_ata_op );
574 * Identify AoE command by tag
577 * @ret aoecmd AoE command, or NULL
579 static struct aoe_command * aoecmd_find_tag ( uint32_t tag ) {
580 struct aoe_command *aoecmd;
582 list_for_each_entry ( aoecmd, &aoe_commands, list ) {
583 if ( aoecmd->tag == tag )
590 * Choose an AoE command tag
592 * @ret tag New tag, or negative error
594 static int aoecmd_new_tag ( void ) {
595 static uint16_t tag_idx;
598 for ( i = 0 ; i < 65536 ; i++ ) {
600 if ( aoecmd_find_tag ( tag_idx ) == NULL )
601 return ( AOE_TAG_MAGIC | tag_idx );
609 * @v aoedev AoE device
610 * @v type AoE command type
611 * @ret aoecmd AoE command
613 static struct aoe_command * aoecmd_create ( struct aoe_device *aoedev,
614 struct aoe_command_type *type ) {
615 struct aoe_command *aoecmd;
618 /* Allocate command tag */
619 tag = aoecmd_new_tag();
623 /* Allocate and initialise structure */
624 aoecmd = zalloc ( sizeof ( *aoecmd ) );
627 ref_init ( &aoecmd->refcnt, aoecmd_free );
628 list_add ( &aoecmd->list, &aoe_commands );
629 intf_init ( &aoecmd->ata, &aoecmd_ata_desc, &aoecmd->refcnt );
630 timer_init ( &aoecmd->timer, aoecmd_expired, &aoecmd->refcnt );
631 aoecmd->aoedev = aoedev_get ( aoedev );
635 /* Preserve timeout from last completed command */
636 aoecmd->timer.timeout = aoedev->timeout;
638 /* Return already mortalised. (Reference is held by command list.) */
643 * Issue AoE ATA command
645 * @v aoedev AoE device
646 * @v parent Parent interface
647 * @v command ATA command
648 * @ret tag Command tag, or negative error
650 static int aoedev_ata_command ( struct aoe_device *aoedev,
651 struct interface *parent,
652 struct ata_cmd *command ) {
653 struct net_device *netdev = aoedev->netdev;
654 struct aoe_command *aoecmd;
656 /* Fail immediately if net device is closed */
657 if ( ! netdev_is_open ( netdev ) ) {
658 DBGC ( aoedev, "AoE %s cannot issue command while net device "
659 "is closed\n", aoedev_name ( aoedev ) );
664 aoecmd = aoecmd_create ( aoedev, &aoecmd_ata );
667 memcpy ( &aoecmd->command, command, sizeof ( aoecmd->command ) );
669 /* Attempt to send command. Allow failures to be handled by
672 aoecmd_tx ( aoecmd );
674 /* Attach to parent interface, leave reference with command
677 intf_plug_plug ( &aoecmd->ata, parent );
682 * Issue AoE configuration command
684 * @v aoedev AoE device
685 * @v parent Parent interface
686 * @ret tag Command tag, or negative error
688 static int aoedev_cfg_command ( struct aoe_device *aoedev,
689 struct interface *parent ) {
690 struct aoe_command *aoecmd;
693 aoecmd = aoecmd_create ( aoedev, &aoecmd_cfg );
697 /* Attempt to send command. Allow failures to be handled by
700 aoecmd_tx ( aoecmd );
702 /* Attach to parent interface, leave reference with command
705 intf_plug_plug ( &aoecmd->ata, parent );
712 * @v refcnt Reference count
714 static void aoedev_free ( struct refcnt *refcnt ) {
715 struct aoe_device *aoedev =
716 container_of ( refcnt, struct aoe_device, refcnt );
718 netdev_put ( aoedev->netdev );
725 * @v aoedev AoE device
726 * @v rc Reason for close
728 static void aoedev_close ( struct aoe_device *aoedev, int rc ) {
729 struct aoe_command *aoecmd;
730 struct aoe_command *tmp;
732 /* Shut down interfaces */
733 intf_shutdown ( &aoedev->ata, rc );
734 intf_shutdown ( &aoedev->config, rc );
736 /* Shut down any active commands */
737 list_for_each_entry_safe ( aoecmd, tmp, &aoe_commands, list ) {
738 if ( aoecmd->aoedev != aoedev )
740 aoecmd_get ( aoecmd );
741 aoecmd_close ( aoecmd, rc );
742 aoecmd_put ( aoecmd );
747 * Check AoE device flow-control window
749 * @v aoedev AoE device
750 * @ret len Length of window
752 static size_t aoedev_window ( struct aoe_device *aoedev ) {
753 return ( aoedev->configured ? ~( ( size_t ) 0 ) : 0 );
757 * Handle AoE device configuration completion
759 * @v aoedev AoE device
760 * @v rc Reason for completion
762 static void aoedev_config_done ( struct aoe_device *aoedev, int rc ) {
764 /* Shut down interface */
765 intf_shutdown ( &aoedev->config, rc );
767 /* Close device on failure */
769 aoedev_close ( aoedev, rc );
773 /* Mark device as configured */
774 aoedev->configured = 1;
775 xfer_window_changed ( &aoedev->ata );
779 * Identify device underlying AoE device
781 * @v aoedev AoE device
782 * @ret device Underlying device
784 static struct device * aoedev_identify_device ( struct aoe_device *aoedev ) {
785 return aoedev->netdev->dev;
789 * Describe AoE device in an ACPI table
791 * @v aoedev AoE device
793 * @v len Length of ACPI table
794 * @ret rc Return status code
796 static int aoedev_describe ( struct aoe_device *aoedev,
797 struct acpi_description_header *acpi,
799 struct abft_table *abft =
800 container_of ( acpi, struct abft_table, acpi );
803 if ( len < sizeof ( *abft ) )
807 abft->acpi.signature = cpu_to_le32 ( ABFT_SIG );
808 abft->acpi.length = cpu_to_le32 ( sizeof ( *abft ) );
809 abft->acpi.revision = 1;
810 abft->shelf = cpu_to_le16 ( aoedev->major );
811 abft->slot = aoedev->minor;
812 memcpy ( abft->mac, aoedev->netdev->ll_addr, sizeof ( abft->mac ) );
817 /** AoE device ATA interface operations */
818 static struct interface_operation aoedev_ata_op[] = {
819 INTF_OP ( ata_command, struct aoe_device *, aoedev_ata_command ),
820 INTF_OP ( xfer_window, struct aoe_device *, aoedev_window ),
821 INTF_OP ( intf_close, struct aoe_device *, aoedev_close ),
822 INTF_OP ( acpi_describe, struct aoe_device *, aoedev_describe ),
823 INTF_OP ( identify_device, struct aoe_device *,
824 aoedev_identify_device ),
827 /** AoE device ATA interface descriptor */
828 static struct interface_descriptor aoedev_ata_desc =
829 INTF_DESC ( struct aoe_device, ata, aoedev_ata_op );
831 /** AoE device configuration interface operations */
832 static struct interface_operation aoedev_config_op[] = {
833 INTF_OP ( intf_close, struct aoe_device *, aoedev_config_done ),
836 /** AoE device configuration interface descriptor */
837 static struct interface_descriptor aoedev_config_desc =
838 INTF_DESC ( struct aoe_device, config, aoedev_config_op );
843 * @v parent Parent interface
844 * @v netdev Network device
845 * @v major Device major number
846 * @v minor Device minor number
847 * @ret rc Return status code
849 static int aoedev_open ( struct interface *parent, struct net_device *netdev,
850 unsigned int major, unsigned int minor ) {
851 struct aoe_device *aoedev;
854 /* Allocate and initialise structure */
855 aoedev = zalloc ( sizeof ( *aoedev ) );
860 ref_init ( &aoedev->refcnt, aoedev_free );
861 intf_init ( &aoedev->ata, &aoedev_ata_desc, &aoedev->refcnt );
862 intf_init ( &aoedev->config, &aoedev_config_desc, &aoedev->refcnt );
863 aoedev->netdev = netdev_get ( netdev );
864 aoedev->major = major;
865 aoedev->minor = minor;
866 memcpy ( aoedev->target, netdev->ll_broadcast,
867 netdev->ll_protocol->ll_addr_len );
869 /* Initiate configuration */
870 if ( ( rc = aoedev_cfg_command ( aoedev, &aoedev->config ) ) < 0 ) {
871 DBGC ( aoedev, "AoE %s could not initiate configuration: %s\n",
872 aoedev_name ( aoedev ), strerror ( rc ) );
876 /* Attach ATA device to parent interface */
877 if ( ( rc = ata_open ( parent, &aoedev->ata, ATA_DEV_MASTER,
878 AOE_MAX_COUNT ) ) != 0 ) {
879 DBGC ( aoedev, "AoE %s could not create ATA device: %s\n",
880 aoedev_name ( aoedev ), strerror ( rc ) );
884 /* Mortalise self and return */
885 ref_put ( &aoedev->refcnt );
890 aoedev_close ( aoedev, rc );
891 ref_put ( &aoedev->refcnt );
896 /******************************************************************************
898 * AoE network protocol
900 ******************************************************************************
904 * Process incoming AoE packets
906 * @v iobuf I/O buffer
907 * @v netdev Network device
908 * @v ll_dest Link-layer destination address
909 * @v ll_source Link-layer source address
910 * @v flags Packet flags
911 * @ret rc Return status code
913 static int aoe_rx ( struct io_buffer *iobuf,
914 struct net_device *netdev __unused,
915 const void *ll_dest __unused,
916 const void *ll_source,
917 unsigned int flags __unused ) {
918 struct aoehdr *aoehdr = iobuf->data;
919 struct aoe_command *aoecmd;
923 if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
924 DBG ( "AoE received underlength packet (%zd bytes)\n",
929 if ( ( aoehdr->ver_flags & AOE_VERSION_MASK ) != AOE_VERSION ) {
930 DBG ( "AoE received packet for unsupported protocol version "
931 "%02x\n", ( aoehdr->ver_flags & AOE_VERSION_MASK ) );
932 rc = -EPROTONOSUPPORT;
935 if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) {
936 DBG ( "AoE received request packet\n" );
941 /* Demultiplex amongst active AoE commands */
942 aoecmd = aoecmd_find_tag ( ntohl ( aoehdr->tag ) );
944 DBG ( "AoE received packet for unused tag %08x\n",
945 ntohl ( aoehdr->tag ) );
950 /* Pass received frame to command */
951 aoecmd_get ( aoecmd );
952 if ( ( rc = aoecmd_rx ( aoecmd, iob_disown ( iobuf ),
957 aoecmd_put ( aoecmd );
965 struct net_protocol aoe_protocol __net_protocol = {
967 .net_proto = htons ( ETH_P_AOE ),
971 /******************************************************************************
975 ******************************************************************************
982 * @ret major Major device number
983 * @ret minor Minor device number
984 * @ret rc Return status code
986 * An AoE URI has the form "aoe:e<major>.<minor>".
988 static int aoe_parse_uri ( struct uri *uri, unsigned int *major,
989 unsigned int *minor ) {
993 /* Check for URI with opaque portion */
998 /* Check for initial 'e' */
1003 /* Parse major device number */
1004 *major = strtoul ( ptr, &end, 10 );
1009 /* Parse minor device number */
1010 *minor = strtoul ( ptr, &end, 10 );
1020 * @v parent Parent interface
1022 * @ret rc Return status code
1024 static int aoe_open ( struct interface *parent, struct uri *uri ) {
1025 struct net_device *netdev;
1030 /* Identify network device. This is something of a hack, but
1031 * the AoE URI scheme that has been in use for some time now
1032 * provides no way to specify a particular device.
1034 netdev = last_opened_netdev();
1036 DBG ( "AoE cannot identify network device\n" );
1041 if ( ( rc = aoe_parse_uri ( uri, &major, &minor ) ) != 0 ) {
1042 DBG ( "AoE cannot parse URI\n" );
1046 /* Open AoE device */
1047 if ( ( rc = aoedev_open ( parent, netdev, major, minor ) ) != 0 )
1053 /** AoE URI opener */
1054 struct uri_opener aoe_uri_opener __uri_opener = {