|
@@ -101,6 +101,8 @@ enum fcoe_flags {
|
101
|
101
|
FCOE_HAVE_FCF = 0x0002,
|
102
|
102
|
/** We have a FIP-capable FCoE forwarder available to be used */
|
103
|
103
|
FCOE_HAVE_FIP_FCF = 0x0004,
|
|
104
|
+ /** FCoE forwarder supports server-provided MAC addresses */
|
|
105
|
+ FCOE_FCF_ALLOWS_SPMA = 0x0008,
|
104
|
106
|
};
|
105
|
107
|
|
106
|
108
|
struct net_protocol fcoe_protocol __net_protocol;
|
|
@@ -228,8 +230,10 @@ static int fcoe_deliver ( struct fcoe_port *fcoe,
|
228
|
230
|
memset ( fipmac, 0, sizeof ( *fipmac ) );
|
229
|
231
|
fipmac->type = FIP_MAC_ADDRESS;
|
230
|
232
|
fipmac->len = ( sizeof ( *fipmac ) / 4 );
|
231
|
|
- memcpy ( fipmac->mac, fcoe->netdev->ll_addr,
|
232
|
|
- sizeof ( fipmac->mac ) );
|
|
233
|
+ if ( fcoe->flags & FCOE_FCF_ALLOWS_SPMA ) {
|
|
234
|
+ memcpy ( fipmac->mac, fcoe->netdev->ll_addr,
|
|
235
|
+ sizeof ( fipmac->mac ) );
|
|
236
|
+ }
|
233
|
237
|
|
234
|
238
|
/* Create FIP header */
|
235
|
239
|
fiphdr = iob_push ( iobuf, sizeof ( *fiphdr ) );
|
|
@@ -239,7 +243,8 @@ static int fcoe_deliver ( struct fcoe_port *fcoe,
|
239
|
243
|
fiphdr->subcode = FIP_ELS_REQUEST;
|
240
|
244
|
fiphdr->len =
|
241
|
245
|
htons ( ( iob_len ( iobuf ) - sizeof ( *fiphdr ) ) / 4);
|
242
|
|
- fiphdr->flags = htons ( FIP_FP | FIP_SP );
|
|
246
|
+ fiphdr->flags = ( ( fcoe->flags & FCOE_FCF_ALLOWS_SPMA ) ?
|
|
247
|
+ htons ( FIP_SP ) : htons ( FIP_FP ) );
|
243
|
248
|
|
244
|
249
|
/* Send as FIP packet from netdev's own MAC address */
|
245
|
250
|
net_protocol = &fip_protocol;
|
|
@@ -636,17 +641,23 @@ static int fcoe_fip_rx_advertisement ( struct fcoe_port *fcoe,
|
636
|
641
|
} else {
|
637
|
642
|
fcoe->keepalive = ntohl ( fka_adv_p->period );
|
638
|
643
|
}
|
|
644
|
+ fcoe->flags &= ~FCOE_FCF_ALLOWS_SPMA;
|
|
645
|
+ if ( flags & FIP_SP )
|
|
646
|
+ fcoe->flags |= FCOE_FCF_ALLOWS_SPMA;
|
639
|
647
|
memcpy ( fcoe->fcf_mac, mac_address->mac,
|
640
|
648
|
sizeof ( fcoe->fcf_mac ) );
|
641
|
649
|
DBGC ( fcoe, "FCoE %s selected FCF %s (priority %d, ",
|
642
|
650
|
fcoe->netdev->name, eth_ntoa ( fcoe->fcf_mac ),
|
643
|
651
|
fcoe->priority );
|
644
|
652
|
if ( fcoe->keepalive ) {
|
645
|
|
- DBGC ( fcoe, "keepalive %dms)\n",
|
|
653
|
+ DBGC ( fcoe, "keepalive %dms",
|
646
|
654
|
fcoe->keepalive );
|
647
|
655
|
} else {
|
648
|
|
- DBGC ( fcoe, "no keepalive)\n" );
|
|
656
|
+ DBGC ( fcoe, "no keepalive" );
|
649
|
657
|
}
|
|
658
|
+ DBGC ( fcoe, ", %cPMA)\n",
|
|
659
|
+ ( ( fcoe->flags & FCOE_FCF_ALLOWS_SPMA ) ?
|
|
660
|
+ 'S' : 'F' ) );
|
650
|
661
|
}
|
651
|
662
|
|
652
|
663
|
} else if ( fcoe->flags & FCOE_HAVE_FIP_FCF ) {
|
|
@@ -704,6 +715,8 @@ static int fcoe_fip_rx_els_response ( struct fcoe_port *fcoe,
|
704
|
715
|
|
705
|
716
|
/* Record local MAC address */
|
706
|
717
|
memcpy ( fcoe->local_mac, mac_address->mac, sizeof ( fcoe->local_mac ));
|
|
718
|
+ DBGC ( fcoe, "FCoE %s using local MAC %s\n",
|
|
719
|
+ fcoe->netdev->name, eth_ntoa ( fcoe->local_mac ) );
|
707
|
720
|
|
708
|
721
|
/* Hand off via transport interface */
|
709
|
722
|
frame = &flogi->fc;
|