Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / net / aoe.c
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@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., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stddef.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <byteswap.h>
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>
37 #include <ipxe/uri.h>
38 #include <ipxe/open.h>
39 #include <ipxe/ata.h>
40 #include <ipxe/device.h>
41 #include <ipxe/aoe.h>
42
43 /** @file
44  *
45  * AoE protocol
46  *
47  */
48
49 FEATURE ( FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1 );
50
51 struct net_protocol aoe_protocol __net_protocol;
52
53 /******************************************************************************
54  *
55  * AoE devices and commands
56  *
57  ******************************************************************************
58  */
59
60 /** List of all AoE devices */
61 static LIST_HEAD ( aoe_devices );
62
63 /** List of active AoE commands */
64 static LIST_HEAD ( aoe_commands );
65
66 /** An AoE device */
67 struct aoe_device {
68         /** Reference counter */
69         struct refcnt refcnt;
70
71         /** Network device */
72         struct net_device *netdev;
73         /** ATA command issuing interface */
74         struct interface ata;
75
76         /** Major number */
77         uint16_t major;
78         /** Minor number */
79         uint8_t minor;
80         /** Target MAC address */
81         uint8_t target[MAX_LL_ADDR_LEN];
82
83         /** Saved timeout value */
84         unsigned long timeout;
85
86         /** Configuration command interface */
87         struct interface config;
88         /** Device is configued */
89         int configured;
90 };
91
92 /** An AoE command */
93 struct aoe_command {
94         /** Reference count */
95         struct refcnt refcnt;
96         /** AOE device */
97         struct aoe_device *aoedev;
98         /** List of active commands */
99         struct list_head list;
100
101         /** ATA command interface */
102         struct interface ata;
103
104         /** ATA command */
105         struct ata_cmd command;
106         /** Command type */
107         struct aoe_command_type *type;
108         /** Command tag */
109         uint32_t tag;
110
111         /** Retransmission timer */
112         struct retry_timer timer;
113 };
114
115 /** An AoE command type */
116 struct aoe_command_type {
117         /**
118          * Calculate length of AoE command IU
119          *
120          * @v aoecmd            AoE command
121          * @ret len             Length of command IU
122          */
123         size_t ( * cmd_len ) ( struct aoe_command *aoecmd );
124         /**
125          * Build AoE command IU
126          *
127          * @v aoecmd            AoE command
128          * @v data              Command IU
129          * @v len               Length of command IU
130          */
131         void ( * cmd ) ( struct aoe_command *aoecmd, void *data, size_t len );
132         /**
133          * Handle AoE response IU
134          *
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
140          */
141         int ( * rsp ) ( struct aoe_command *aoecmd, const void *data,
142                         size_t len, const void *ll_source );
143 };
144
145 /**
146  * Get reference to AoE device
147  *
148  * @v aoedev            AoE device
149  * @ret aoedev          AoE device
150  */
151 static inline __attribute__ (( always_inline )) struct aoe_device *
152 aoedev_get ( struct aoe_device *aoedev ) {
153         ref_get ( &aoedev->refcnt );
154         return aoedev;
155 }
156
157 /**
158  * Drop reference to AoE device
159  *
160  * @v aoedev            AoE device
161  */
162 static inline __attribute__ (( always_inline )) void
163 aoedev_put ( struct aoe_device *aoedev ) {
164         ref_put ( &aoedev->refcnt );
165 }
166
167 /**
168  * Get reference to AoE command
169  *
170  * @v aoecmd            AoE command
171  * @ret aoecmd          AoE command
172  */
173 static inline __attribute__ (( always_inline )) struct aoe_command *
174 aoecmd_get ( struct aoe_command *aoecmd ) {
175         ref_get ( &aoecmd->refcnt );
176         return aoecmd;
177 }
178
179 /**
180  * Drop reference to AoE command
181  *
182  * @v aoecmd            AoE command
183  */
184 static inline __attribute__ (( always_inline )) void
185 aoecmd_put ( struct aoe_command *aoecmd ) {
186         ref_put ( &aoecmd->refcnt );
187 }
188
189 /**
190  * Name AoE device
191  *
192  * @v aoedev            AoE device
193  * @ret name            AoE device name
194  */
195 static const char * aoedev_name ( struct aoe_device *aoedev ) {
196         static char buf[16];
197
198         snprintf ( buf, sizeof ( buf ), "%s/e%d.%d", aoedev->netdev->name,
199                    aoedev->major, aoedev->minor );
200         return buf;
201 }
202
203 /**
204  * Free AoE command
205  *
206  * @v refcnt            Reference counter
207  */
208 static void aoecmd_free ( struct refcnt *refcnt ) {
209         struct aoe_command *aoecmd =
210                 container_of ( refcnt, struct aoe_command, refcnt );
211
212         assert ( ! timer_running ( &aoecmd->timer ) );
213         assert ( list_empty ( &aoecmd->list ) );
214
215         aoedev_put ( aoecmd->aoedev );
216         free ( aoecmd );
217 }
218
219 /**
220  * Close AoE command
221  *
222  * @v aoecmd            AoE command
223  * @v rc                Reason for close
224  */
225 static void aoecmd_close ( struct aoe_command *aoecmd, int rc ) {
226         struct aoe_device *aoedev = aoecmd->aoedev;
227
228         /* Stop timer */
229         stop_timer ( &aoecmd->timer );
230
231         /* Preserve the timeout value for subsequent commands */
232         aoedev->timeout = aoecmd->timer.timeout;
233
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 );
239         }
240
241         /* Shut down interfaces */
242         intf_shutdown ( &aoecmd->ata, rc );
243 }
244
245 /**
246  * Transmit AoE command request
247  *
248  * @v aoecmd            AoE command
249  * @ret rc              Return status code
250  */
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;
256         size_t cmd_len;
257         int rc;
258
259         /* Sanity check */
260         assert ( netdev != NULL );
261
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
265          * fails.
266          */
267         start_timer ( &aoecmd->timer );
268
269         /* Create outgoing I/O buffer */
270         cmd_len = aoecmd->type->cmd_len ( aoecmd );
271         iobuf = alloc_iob ( MAX_LL_HEADER_LEN + cmd_len );
272         if ( ! iobuf )
273                 return -ENOMEM;
274         iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
275         aoehdr = iob_put ( iobuf, cmd_len );
276
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 ) );
284
285         /* Send packet */
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,
290                        strerror ( rc ) );
291                 return rc;
292         }
293
294         return 0;
295 }
296
297 /**
298  * Receive AoE command response
299  *
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
304  */
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;
309         int rc;
310
311         /* Sanity check */
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 ) );
316                 rc = -EINVAL;
317                 goto done;
318         }
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 );
324                 rc = -EINVAL;
325                 goto done;
326         }
327
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 );
333                 rc = -EIO;
334                 goto done;
335         }
336
337         /* Hand off to command completion handler */
338         if ( ( rc = aoecmd->type->rsp ( aoecmd, iobuf->data, iob_len ( iobuf ),
339                                         ll_source ) ) != 0 )
340                 goto done;
341
342  done:
343         /* Free I/O buffer */
344         free_iob ( iobuf );
345
346         /* Terminate command */
347         aoecmd_close ( aoecmd, rc );
348
349         return rc;
350 }
351
352 /**
353  * Handle AoE retry timer expiry
354  *
355  * @v timer             AoE retry timer
356  * @v fail              Failure indicator
357  */
358 static void aoecmd_expired ( struct retry_timer *timer, int fail ) {
359         struct aoe_command *aoecmd =
360                 container_of ( timer, struct aoe_command, timer );
361
362         if ( fail ) {
363                 aoecmd_close ( aoecmd, -ETIMEDOUT );
364         } else {
365                 aoecmd_tx ( aoecmd );
366         }
367 }
368
369 /**
370  * Calculate length of AoE ATA command IU
371  *
372  * @v aoecmd            AoE command
373  * @ret len             Length of command IU
374  */
375 static size_t aoecmd_ata_cmd_len ( struct aoe_command *aoecmd ) {
376         struct ata_cmd *command = &aoecmd->command;
377
378         return ( sizeof ( struct aoehdr ) + sizeof ( struct aoeata ) +
379                  command->data_out_len );
380 }
381
382 /**
383  * Build AoE ATA command IU
384  *
385  * @v aoecmd            AoE command
386  * @v data              Command IU
387  * @v len               Length of command IU
388  */
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;
395
396         /* Sanity check */
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 ) );
400
401         /* Build IU */
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 );
416
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,
420                 aoeata->lba.u64 );
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" );
426 }
427
428 /**
429  * Handle AoE ATA response IU
430  *
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
436  */
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;
443         size_t data_len;
444
445         /* Sanity check */
446         if ( len < ( sizeof ( *aoehdr ) + sizeof ( *aoeata ) ) ) {
447                 DBGC ( aoedev, "AoE %s/%08x received underlength ATA response "
448                        "(%zd bytes)\n", aoedev_name ( aoedev ),
449                        aoecmd->tag, len );
450                 return -EINVAL;
451         }
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,
455                 data_len );
456
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 );
461                 return -EIO;
462         }
463
464         /* Check data-in length is sufficient.  (There may be trailing
465          * garbage due to Ethernet minimum-frame-size padding.)
466          */
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 );
471                 return -ERANGE;
472         }
473
474         /* Copy out data payload */
475         copy_to_user ( command->data_in, 0, aoeata->data,
476                        command->data_in_len );
477
478         return 0;
479 }
480
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,
486 };
487
488 /**
489  * Calculate length of AoE configuration command IU
490  *
491  * @v aoecmd            AoE command
492  * @ret len             Length of command IU
493  */
494 static size_t aoecmd_cfg_cmd_len ( struct aoe_command *aoecmd __unused ) {
495         return ( sizeof ( struct aoehdr ) + sizeof ( struct aoecfg ) );
496 }
497
498 /**
499  * Build AoE configuration command IU
500  *
501  * @v aoecmd            AoE command
502  * @v data              Command IU
503  * @v len               Length of command IU
504  */
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;
510
511         /* Sanity check */
512         assert ( len == ( sizeof ( *aoehdr ) + sizeof ( *aoecfg ) ) );
513
514         /* Build IU */
515         aoehdr->command = AOE_CMD_CONFIG;
516         memset ( aoecfg, 0, sizeof ( *aoecfg ) );
517
518         DBGC ( aoedev, "AoE %s/%08x CONFIG cmd\n",
519                aoedev_name ( aoedev ), aoecmd->tag );
520 }
521
522 /**
523  * Handle AoE configuration response IU
524  *
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
530  */
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;
537
538         /* Sanity check */
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 );
543                 return -EINVAL;
544         }
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 );
548
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 ) );
553
554         return 0;
555 }
556
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,
562 };
563
564 /** AoE command ATA interface operations */
565 static struct interface_operation aoecmd_ata_op[] = {
566         INTF_OP ( intf_close, struct aoe_command *, aoecmd_close ),
567 };
568
569 /** AoE command ATA interface descriptor */
570 static struct interface_descriptor aoecmd_ata_desc =
571         INTF_DESC ( struct aoe_command, ata, aoecmd_ata_op );
572
573 /**
574  * Identify AoE command by tag
575  *
576  * @v tag               Command tag
577  * @ret aoecmd          AoE command, or NULL
578  */
579 static struct aoe_command * aoecmd_find_tag ( uint32_t tag ) {
580         struct aoe_command *aoecmd;
581
582         list_for_each_entry ( aoecmd, &aoe_commands, list ) {
583                 if ( aoecmd->tag == tag )
584                         return aoecmd;
585         }
586         return NULL;
587 }
588
589 /**
590  * Choose an AoE command tag
591  *
592  * @ret tag             New tag, or negative error
593  */
594 static int aoecmd_new_tag ( void ) {
595         static uint16_t tag_idx;
596         unsigned int i;
597
598         for ( i = 0 ; i < 65536 ; i++ ) {
599                 tag_idx++;
600                 if ( aoecmd_find_tag ( tag_idx ) == NULL )
601                         return ( AOE_TAG_MAGIC | tag_idx );
602         }
603         return -EADDRINUSE;
604 }
605
606 /**
607  * Create AoE command
608  *
609  * @v aoedev            AoE device
610  * @v type              AoE command type
611  * @ret aoecmd          AoE command
612  */
613 static struct aoe_command * aoecmd_create ( struct aoe_device *aoedev,
614                                             struct aoe_command_type *type ) {
615         struct aoe_command *aoecmd;
616         int tag;
617
618         /* Allocate command tag */
619         tag = aoecmd_new_tag();
620         if ( tag < 0 )
621                 return NULL;
622
623         /* Allocate and initialise structure */
624         aoecmd = zalloc ( sizeof ( *aoecmd ) );
625         if ( ! aoecmd )
626                 return NULL;
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 );
632         aoecmd->type = type;
633         aoecmd->tag = tag;
634
635         /* Preserve timeout from last completed command */
636         aoecmd->timer.timeout = aoedev->timeout;
637
638         /* Return already mortalised.  (Reference is held by command list.) */
639         return aoecmd;
640 }
641
642 /**
643  * Issue AoE ATA command
644  *
645  * @v aoedev            AoE device
646  * @v parent            Parent interface
647  * @v command           ATA command
648  * @ret tag             Command tag, or negative error
649  */
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;
655
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 ) );
660                 return -EWOULDBLOCK;
661         }
662
663         /* Create command */
664         aoecmd = aoecmd_create ( aoedev, &aoecmd_ata );
665         if ( ! aoecmd )
666                 return -ENOMEM;
667         memcpy ( &aoecmd->command, command, sizeof ( aoecmd->command ) );
668
669         /* Attempt to send command.  Allow failures to be handled by
670          * the retry timer.
671          */
672         aoecmd_tx ( aoecmd );
673
674         /* Attach to parent interface, leave reference with command
675          * list, and return.
676          */
677         intf_plug_plug ( &aoecmd->ata, parent );
678         return aoecmd->tag;
679 }
680
681 /**
682  * Issue AoE configuration command
683  *
684  * @v aoedev            AoE device
685  * @v parent            Parent interface
686  * @ret tag             Command tag, or negative error
687  */
688 static int aoedev_cfg_command ( struct aoe_device *aoedev,
689                                 struct interface *parent ) {
690         struct aoe_command *aoecmd;
691
692         /* Create command */
693         aoecmd = aoecmd_create ( aoedev, &aoecmd_cfg );
694         if ( ! aoecmd )
695                 return -ENOMEM;
696
697         /* Attempt to send command.  Allow failures to be handled by
698          * the retry timer.
699          */
700         aoecmd_tx ( aoecmd );
701
702         /* Attach to parent interface, leave reference with command
703          * list, and return.
704          */
705         intf_plug_plug ( &aoecmd->ata, parent );
706         return aoecmd->tag;
707 }
708
709 /**
710  * Free AoE device
711  *
712  * @v refcnt            Reference count
713  */
714 static void aoedev_free ( struct refcnt *refcnt ) {
715         struct aoe_device *aoedev =
716                 container_of ( refcnt, struct aoe_device, refcnt );
717
718         netdev_put ( aoedev->netdev );
719         free ( aoedev );
720 }
721
722 /**
723  * Close AoE device
724  *
725  * @v aoedev            AoE device
726  * @v rc                Reason for close
727  */
728 static void aoedev_close ( struct aoe_device *aoedev, int rc ) {
729         struct aoe_command *aoecmd;
730         struct aoe_command *tmp;
731
732         /* Shut down interfaces */
733         intf_shutdown ( &aoedev->ata, rc );
734         intf_shutdown ( &aoedev->config, rc );
735
736         /* Shut down any active commands */
737         list_for_each_entry_safe ( aoecmd, tmp, &aoe_commands, list ) {
738                 if ( aoecmd->aoedev != aoedev )
739                         continue;
740                 aoecmd_get ( aoecmd );
741                 aoecmd_close ( aoecmd, rc );
742                 aoecmd_put ( aoecmd );
743         }
744 }
745
746 /**
747  * Check AoE device flow-control window
748  *
749  * @v aoedev            AoE device
750  * @ret len             Length of window
751  */
752 static size_t aoedev_window ( struct aoe_device *aoedev ) {
753         return ( aoedev->configured ? ~( ( size_t ) 0 ) : 0 );
754 }
755
756 /**
757  * Handle AoE device configuration completion
758  *
759  * @v aoedev            AoE device
760  * @v rc                Reason for completion
761  */
762 static void aoedev_config_done ( struct aoe_device *aoedev, int rc ) {
763
764         /* Shut down interface */
765         intf_shutdown ( &aoedev->config, rc );
766
767         /* Close device on failure */
768         if ( rc != 0 ) {
769                 aoedev_close ( aoedev, rc );
770                 return;
771         }
772
773         /* Mark device as configured */
774         aoedev->configured = 1;
775         xfer_window_changed ( &aoedev->ata );
776 }
777
778 /**
779  * Identify device underlying AoE device
780  *
781  * @v aoedev            AoE device
782  * @ret device          Underlying device
783  */
784 static struct device * aoedev_identify_device ( struct aoe_device *aoedev ) {
785         return aoedev->netdev->dev;
786 }
787
788 /**
789  * Describe AoE device in an ACPI table
790  *
791  * @v aoedev            AoE device
792  * @v acpi              ACPI table
793  * @v len               Length of ACPI table
794  * @ret rc              Return status code
795  */
796 static int aoedev_describe ( struct aoe_device *aoedev,
797                              struct acpi_description_header *acpi,
798                              size_t len ) {
799         struct abft_table *abft =
800                 container_of ( acpi, struct abft_table, acpi );
801
802         /* Sanity check */
803         if ( len < sizeof ( *abft ) )
804                 return -ENOBUFS;
805
806         /* Populate table */
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 ) );
813
814         return 0;
815 }
816
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 ),
825 };
826
827 /** AoE device ATA interface descriptor */
828 static struct interface_descriptor aoedev_ata_desc =
829         INTF_DESC ( struct aoe_device, ata, aoedev_ata_op );
830
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 ),
834 };
835
836 /** AoE device configuration interface descriptor */
837 static struct interface_descriptor aoedev_config_desc =
838         INTF_DESC ( struct aoe_device, config, aoedev_config_op );
839
840 /**
841  * Open AoE device
842  *
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
848  */
849 static int aoedev_open ( struct interface *parent, struct net_device *netdev,
850                          unsigned int major, unsigned int minor ) {
851         struct aoe_device *aoedev;
852         int rc;
853
854         /* Allocate and initialise structure */
855         aoedev = zalloc ( sizeof ( *aoedev ) );
856         if ( ! aoedev ) {
857                 rc = -ENOMEM;
858                 goto err_zalloc;
859         }
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 );
868
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 ) );
873                 goto err_config;
874         }
875
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 ) );
881                 goto err_ata_open;
882         }
883
884         /* Mortalise self and return */
885         ref_put ( &aoedev->refcnt );
886         return 0;
887
888  err_ata_open:
889  err_config:
890         aoedev_close ( aoedev, rc );
891         ref_put ( &aoedev->refcnt );
892  err_zalloc:
893         return rc;
894 }
895
896 /******************************************************************************
897  *
898  * AoE network protocol
899  *
900  ******************************************************************************
901  */
902
903 /**
904  * Process incoming AoE packets
905  *
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
912  */
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;
920         int rc;
921
922         /* Sanity check */
923         if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
924                 DBG ( "AoE received underlength packet (%zd bytes)\n",
925                       iob_len ( iobuf ) );
926                 rc = -EINVAL;
927                 goto err_sanity;
928         }
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;
933                 goto err_sanity;
934         }
935         if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) {
936                 DBG ( "AoE received request packet\n" );
937                 rc = -EOPNOTSUPP;
938                 goto err_sanity;
939         }
940
941         /* Demultiplex amongst active AoE commands */
942         aoecmd = aoecmd_find_tag ( ntohl ( aoehdr->tag ) );
943         if ( ! aoecmd ) {
944                 DBG ( "AoE received packet for unused tag %08x\n",
945                       ntohl ( aoehdr->tag ) );
946                 rc = -ENOENT;
947                 goto err_demux;
948         }
949
950         /* Pass received frame to command */
951         aoecmd_get ( aoecmd );
952         if ( ( rc = aoecmd_rx ( aoecmd, iob_disown ( iobuf ),
953                                 ll_source ) ) != 0 )
954                 goto err_rx;
955
956  err_rx:
957         aoecmd_put ( aoecmd );
958  err_demux:
959  err_sanity:
960         free_iob ( iobuf );
961         return rc;
962 }
963
964 /** AoE protocol */
965 struct net_protocol aoe_protocol __net_protocol = {
966         .name = "AoE",
967         .net_proto = htons ( ETH_P_AOE ),
968         .rx = aoe_rx,
969 };
970
971 /******************************************************************************
972  *
973  * AoE URIs
974  *
975  ******************************************************************************
976  */
977
978 /**
979  * Parse AoE URI
980  *
981  * @v uri               URI
982  * @ret major           Major device number
983  * @ret minor           Minor device number
984  * @ret rc              Return status code
985  *
986  * An AoE URI has the form "aoe:e<major>.<minor>".
987  */
988 static int aoe_parse_uri ( struct uri *uri, unsigned int *major,
989                            unsigned int *minor ) {
990         const char *ptr;
991         char *end;
992
993         /* Check for URI with opaque portion */
994         if ( ! uri->opaque )
995                 return -EINVAL;
996         ptr = uri->opaque;
997
998         /* Check for initial 'e' */
999         if ( *ptr != 'e' )
1000                 return -EINVAL;
1001         ptr++;
1002
1003         /* Parse major device number */
1004         *major = strtoul ( ptr, &end, 10 );
1005         if ( *end != '.' )
1006                 return -EINVAL;
1007         ptr = ( end + 1 );
1008
1009         /* Parse minor device number */
1010         *minor = strtoul ( ptr, &end, 10 );
1011         if ( *end )
1012                 return -EINVAL;
1013
1014         return 0;
1015 }
1016
1017 /**
1018  * Open AoE URI
1019  *
1020  * @v parent            Parent interface
1021  * @v uri               URI
1022  * @ret rc              Return status code
1023  */
1024 static int aoe_open ( struct interface *parent, struct uri *uri ) {
1025         struct net_device *netdev;
1026         unsigned int major;
1027         unsigned int minor;
1028         int rc;
1029
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.
1033          */
1034         netdev = last_opened_netdev();
1035         if ( ! netdev ) {
1036                 DBG ( "AoE cannot identify network device\n" );
1037                 return -ENODEV;
1038         }
1039
1040         /* Parse URI */
1041         if ( ( rc = aoe_parse_uri ( uri, &major, &minor ) ) != 0 ) {
1042                 DBG ( "AoE cannot parse URI\n" );
1043                 return rc;
1044         }
1045
1046         /* Open AoE device */
1047         if ( ( rc = aoedev_open ( parent, netdev, major, minor ) ) != 0 )
1048                 return rc;
1049
1050         return 0;
1051 }
1052
1053 /** AoE URI opener */
1054 struct uri_opener aoe_uri_opener __uri_opener = {
1055         .scheme = "aoe",
1056         .open = aoe_open,
1057 };