[tcp] Ignore duplicate ACKs in TCP ESTABLISHED state
[people/oremanj/gpxe.git] / 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stddef.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <byteswap.h>
28 #include <gpxe/list.h>
29 #include <gpxe/if_ether.h>
30 #include <gpxe/ethernet.h>
31 #include <gpxe/iobuf.h>
32 #include <gpxe/uaccess.h>
33 #include <gpxe/ata.h>
34 #include <gpxe/netdevice.h>
35 #include <gpxe/process.h>
36 #include <gpxe/features.h>
37 #include <gpxe/aoe.h>
38
39 /** @file
40  *
41  * AoE protocol
42  *
43  */
44
45 FEATURE ( FEATURE_PROTOCOL, "AoE", DHCP_EB_FEATURE_AOE, 1 );
46
47 struct net_protocol aoe_protocol;
48
49 /** List of all AoE sessions */
50 static LIST_HEAD ( aoe_sessions );
51
52 static void aoe_free ( struct refcnt *refcnt ) {
53         struct aoe_session *aoe =
54                 container_of ( refcnt, struct aoe_session, refcnt );
55
56         netdev_put ( aoe->netdev );
57         free ( aoe );
58 }
59
60 /**
61  * Mark current AoE command complete
62  *
63  * @v aoe               AoE session
64  * @v rc                Return status code
65  */
66 static void aoe_done ( struct aoe_session *aoe, int rc ) {
67
68         /* Record overall command status */
69         if ( aoe->command ) {
70                 aoe->command->cb.cmd_stat = aoe->status;
71                 aoe->command = NULL;
72         }
73
74         /* Stop retransmission timer */
75         stop_timer ( &aoe->timer );
76
77         /* Mark operation as complete */
78         aoe->rc = rc;
79 }
80
81 /**
82  * Send AoE command
83  *
84  * @v aoe               AoE session
85  * @ret rc              Return status code
86  *
87  * This transmits an AoE command packet.  It does not wait for a
88  * response.
89  */
90 static int aoe_send_command ( struct aoe_session *aoe ) {
91         struct ata_command *command = aoe->command;
92         struct io_buffer *iobuf;
93         struct aoehdr *aoehdr;
94         union aoecmd *aoecmd;
95         struct aoeata *aoeata;
96         unsigned int count;
97         unsigned int data_out_len;
98         unsigned int aoecmdlen;
99
100         /* Fail immediately if we have no netdev to send on */
101         if ( ! aoe->netdev ) {
102                 aoe_done ( aoe, -ENETUNREACH );
103                 return -ENETUNREACH;
104         }
105
106         /* If we are transmitting anything that requires a response,
107          * start the retransmission timer.  Do this before attempting
108          * to allocate the I/O buffer, in case allocation itself
109          * fails.
110          */
111         start_timer ( &aoe->timer );
112
113         /* Calculate count and data_out_len for this subcommand */
114         switch ( aoe->aoe_cmd_type ) {
115         case AOE_CMD_ATA:
116                 count = command->cb.count.native;
117                 if ( count > AOE_MAX_COUNT )
118                         count = AOE_MAX_COUNT;
119                 data_out_len = ( command->data_out ?
120                                  ( count * ATA_SECTOR_SIZE ) : 0 );
121                 aoecmdlen = sizeof ( aoecmd->ata );
122                 break;
123         case AOE_CMD_CONFIG:
124                 count = 0;
125                 data_out_len = 0;
126                 aoecmdlen = sizeof ( aoecmd->cfg );
127                 break;
128         default:
129                 return -ENOTSUP;
130         }
131
132         /* Create outgoing I/O buffer */
133         iobuf = alloc_iob ( ETH_HLEN + sizeof ( *aoehdr ) +
134                             aoecmdlen + data_out_len );
135
136         if ( ! iobuf )
137                 return -ENOMEM;
138         iob_reserve ( iobuf, ETH_HLEN );
139         aoehdr = iob_put ( iobuf, sizeof ( *aoehdr ) );
140         aoecmd = iob_put ( iobuf, aoecmdlen );
141         memset ( aoehdr, 0, ( sizeof ( *aoehdr ) + aoecmdlen ) );
142
143         /* Fill AoE header */
144         aoehdr->ver_flags = AOE_VERSION;
145         aoehdr->major = htons ( aoe->major );
146         aoehdr->minor = aoe->minor;
147         aoehdr->command = aoe->aoe_cmd_type;
148         aoehdr->tag = htonl ( ++aoe->tag );
149
150         /* Fill AoE payload */
151         switch ( aoe->aoe_cmd_type ) {
152         case AOE_CMD_ATA:
153                 /* Fill AoE command */
154                 aoeata = &aoecmd->ata;
155                 linker_assert ( AOE_FL_DEV_HEAD == ATA_DEV_SLAVE,
156                                 __fix_ata_h__ );
157                 aoeata->aflags = ( ( command->cb.lba48 ? AOE_FL_EXTENDED : 0 )|
158                                    ( command->cb.device & ATA_DEV_SLAVE ) |
159                                    ( data_out_len ? AOE_FL_WRITE : 0 ) );
160                 aoeata->err_feat = command->cb.err_feat.bytes.cur;
161                 aoeata->count = count;
162                 aoeata->cmd_stat = command->cb.cmd_stat;
163                 aoeata->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
164                 if ( ! command->cb.lba48 )
165                         aoeata->lba.bytes[3] |=
166                                 ( command->cb.device & ATA_DEV_MASK );
167
168                 /* Fill data payload */
169                 copy_from_user ( iob_put ( iobuf, data_out_len ),
170                                  command->data_out, aoe->command_offset,
171                                  data_out_len );
172                 break;
173         case AOE_CMD_CONFIG:
174                 /* Nothing to do */
175                 break;
176         default:
177                 assert ( 0 );
178         }
179
180         /* Send packet */
181         return net_tx ( iobuf, aoe->netdev, &aoe_protocol, aoe->target );
182 }
183
184 /**
185  * Handle AoE retry timer expiry
186  *
187  * @v timer             AoE retry timer
188  * @v fail              Failure indicator
189  */
190 static void aoe_timer_expired ( struct retry_timer *timer, int fail ) {
191         struct aoe_session *aoe =
192                 container_of ( timer, struct aoe_session, timer );
193
194         if ( fail ) {
195                 aoe_done ( aoe, -ETIMEDOUT );
196         } else {
197                 aoe_send_command ( aoe );
198         }
199 }
200
201 /**
202  * Handle AoE configuration command response
203  *
204  * @v aoe               AoE session
205  * @v ll_source         Link-layer source address
206  * @ret rc              Return status code
207  */
208 static int aoe_rx_cfg ( struct aoe_session *aoe, const void *ll_source ) {
209
210         /* Record target MAC address */
211         memcpy ( aoe->target, ll_source, sizeof ( aoe->target ) );
212         DBGC ( aoe, "AoE %p target MAC address %s\n",
213                aoe, eth_ntoa ( aoe->target ) );
214
215         /* Mark config request as complete */
216         aoe_done ( aoe, 0 );
217
218         return 0;
219 }
220
221 /**
222  * Handle AoE ATA command response
223  *
224  * @v aoe               AoE session
225  * @v aoeata            AoE ATA command
226  * @v len               Length of AoE ATA command
227  * @ret rc              Return status code
228  */
229 static int aoe_rx_ata ( struct aoe_session *aoe, struct aoeata *aoeata,
230                         size_t len ) {
231         struct ata_command *command = aoe->command;
232         unsigned int rx_data_len;
233         unsigned int count;
234         unsigned int data_len;
235
236         /* Sanity check */
237         if ( len < sizeof ( *aoeata ) ) {
238                 /* Ignore packet; allow timer to trigger retransmit */
239                 return -EINVAL;
240         }
241         rx_data_len = ( len - sizeof ( *aoeata ) );
242
243         /* Calculate count and data_len for this subcommand */
244         count = command->cb.count.native;
245         if ( count > AOE_MAX_COUNT )
246                 count = AOE_MAX_COUNT;
247         data_len = count * ATA_SECTOR_SIZE;
248
249         /* Merge into overall ATA status */
250         aoe->status |= aoeata->cmd_stat;
251
252         /* Copy data payload */
253         if ( command->data_in ) {
254                 if ( rx_data_len > data_len )
255                         rx_data_len = data_len;
256                 copy_to_user ( command->data_in, aoe->command_offset,
257                                aoeata->data, rx_data_len );
258         }
259
260         /* Update ATA command and offset */
261         aoe->command_offset += data_len;
262         command->cb.lba.native += count;
263         command->cb.count.native -= count;
264
265         /* Check for operation complete */
266         if ( ! command->cb.count.native ) {
267                 aoe_done ( aoe, 0 );
268                 return 0;
269         }
270
271         /* Transmit next portion of request */
272         stop_timer ( &aoe->timer );
273         aoe_send_command ( aoe );
274
275         return 0;
276 }
277
278 /**
279  * Process incoming AoE packets
280  *
281  * @v iobuf             I/O buffer
282  * @v netdev            Network device
283  * @v ll_source         Link-layer source address
284  * @ret rc              Return status code
285  *
286  */
287 static int aoe_rx ( struct io_buffer *iobuf,
288                     struct net_device *netdev __unused,
289                     const void *ll_source ) {
290         struct aoehdr *aoehdr = iobuf->data;
291         struct aoe_session *aoe;
292         int rc = 0;
293
294         /* Sanity checks */
295         if ( iob_len ( iobuf ) < sizeof ( *aoehdr ) ) {
296                 rc = -EINVAL;
297                 goto done;
298         }
299         if ( ( aoehdr->ver_flags & AOE_VERSION_MASK ) != AOE_VERSION ) {
300                 rc = -EPROTONOSUPPORT;
301                 goto done;
302         }
303         if ( ! ( aoehdr->ver_flags & AOE_FL_RESPONSE ) ) {
304                 /* Ignore AoE requests that we happen to see */
305                 goto done;
306         }
307         iob_pull ( iobuf, sizeof ( *aoehdr ) );
308
309         /* Demultiplex amongst active AoE sessions */
310         list_for_each_entry ( aoe, &aoe_sessions, list ) {
311                 if ( ntohs ( aoehdr->major ) != aoe->major )
312                         continue;
313                 if ( aoehdr->minor != aoe->minor )
314                         continue;
315                 if ( ntohl ( aoehdr->tag ) != aoe->tag )
316                         continue;
317                 if ( aoehdr->ver_flags & AOE_FL_ERROR ) {
318                         aoe_done ( aoe, -EIO );
319                         break;
320                 }
321                 switch ( aoehdr->command ) {
322                 case AOE_CMD_ATA:
323                         rc = aoe_rx_ata ( aoe, iobuf->data, iob_len ( iobuf ));
324                         break;
325                 case AOE_CMD_CONFIG:
326                         rc = aoe_rx_cfg ( aoe, ll_source );
327                         break;
328                 default:
329                         DBGC ( aoe, "AoE %p ignoring command %02x\n",
330                                aoe, aoehdr->command );
331                         break;
332                 }
333                 break;
334         }
335
336  done:
337         free_iob ( iobuf );
338         return rc;
339 }
340
341 /** AoE protocol */
342 struct net_protocol aoe_protocol __net_protocol = {
343         .name = "AoE",
344         .net_proto = htons ( ETH_P_AOE ),
345         .rx = aoe_rx,
346 };
347
348 /**
349  * Issue ATA command via an open AoE session
350  *
351  * @v ata               ATA device
352  * @v command           ATA command
353  * @ret rc              Return status code
354  */
355 static int aoe_command ( struct ata_device *ata,
356                          struct ata_command *command ) {
357         struct aoe_session *aoe =
358                 container_of ( ata->backend, struct aoe_session, refcnt );
359         int rc;
360
361         aoe->command = command;
362         aoe->status = 0;
363         aoe->command_offset = 0;
364         aoe->aoe_cmd_type = AOE_CMD_ATA;
365
366         aoe_send_command ( aoe );
367
368         aoe->rc = -EINPROGRESS;
369         while ( aoe->rc == -EINPROGRESS )
370                 step();
371         rc = aoe->rc;
372
373         return rc;
374 }
375
376
377 /**
378  * Issue AoE config query for AoE target discovery
379  *
380  * @v aoe               AoE session
381  * @ret rc              Return status code
382  */
383 static int aoe_discover ( struct aoe_session *aoe ) {
384         int rc;
385
386         aoe->status = 0;
387         aoe->aoe_cmd_type = AOE_CMD_CONFIG;
388         aoe->command = NULL;
389
390         aoe_send_command ( aoe );
391
392         aoe->rc = -EINPROGRESS;
393         while ( aoe->rc == -EINPROGRESS )
394                 step();
395         rc = aoe->rc;
396
397         return rc;
398 }
399
400 static int aoe_detached_command ( struct ata_device *ata __unused,
401                                   struct ata_command *command __unused ) {
402         return -ENODEV;
403 }
404
405 void aoe_detach ( struct ata_device *ata ) {
406         struct aoe_session *aoe =
407                 container_of ( ata->backend, struct aoe_session, refcnt );
408
409         stop_timer ( &aoe->timer );
410         ata->command = aoe_detached_command;
411         list_del ( &aoe->list );
412         ref_put ( ata->backend );
413         ata->backend = NULL;
414 }
415
416 static int aoe_parse_root_path ( struct aoe_session *aoe,
417                                  const char *root_path ) {
418         char *ptr;
419
420         if ( strncmp ( root_path, "aoe:", 4 ) != 0 )
421                 return -EINVAL;
422         ptr = ( ( char * ) root_path + 4 );
423
424         if ( *ptr++ != 'e' )
425                 return -EINVAL;
426
427         aoe->major = strtoul ( ptr, &ptr, 10 );
428         if ( *ptr++ != '.' )
429                 return -EINVAL;
430
431         aoe->minor = strtoul ( ptr, &ptr, 10 );
432         if ( *ptr )
433                 return -EINVAL;
434
435         return 0;
436 }
437
438 int aoe_attach ( struct ata_device *ata, struct net_device *netdev,
439                  const char *root_path ) {
440         struct aoe_session *aoe;
441         int rc;
442
443         /* Allocate and initialise structure */
444         aoe = zalloc ( sizeof ( *aoe ) );
445         if ( ! aoe )
446                 return -ENOMEM;
447         aoe->refcnt.free = aoe_free;
448         aoe->netdev = netdev_get ( netdev );
449         memcpy ( aoe->target, ethernet_protocol.ll_broadcast,
450                  sizeof ( aoe->target ) );
451         aoe->tag = AOE_TAG_MAGIC;
452         aoe->timer.expired = aoe_timer_expired;
453
454         /* Parse root path */
455         if ( ( rc = aoe_parse_root_path ( aoe, root_path ) ) != 0 )
456                 goto err;
457
458         /* Attach parent interface, transfer reference to connection
459          * list, and return
460          */
461         ata->backend = ref_get ( &aoe->refcnt );
462         ata->command = aoe_command;
463         list_add ( &aoe->list, &aoe_sessions );
464
465         /* Send discovery packet to find the target MAC address.
466          * Ideally, this ought to be done asynchronously, but the
467          * block device interface does not yet support asynchronous
468          * operation.
469          */
470         if ( ( rc = aoe_discover( aoe ) ) != 0 )
471                goto err;
472
473         return 0;
474
475  err:
476         ref_put ( &aoe->refcnt );
477         return rc;
478 }