Vasu Dev wrote:
> If ndo_get_storage_address function is provided by netdev_ops
> for a fcoe interface then reads the spma mode mac address and
> sets up added fc->ctlr.spma flag and stores spma mode address
> in ctl_src_addr.
> 
> In case the spma flag is set then:-
> 
>  1. Adds spma mode MAC address in ctl_src_addr as secondary
>     MAC address, the FLOGI for FIP and pre-FIP will go out
>     using this address.
>  2. Cleans up stored spma MAC address in ctl_src_addr in
>  3. Sets up spma bit in fip_flags for FIP solicitations along
>     with exiting FPMA bit setting.
>  4. Initialize FIP MAC descriptor to stored spma MAC address
>     in ctl_src_addr. This is used as offered address from
>     initiator in FLOGI request along with both SPMA and FPMA
>     bit set in FIP solicitation, the switch may grant any
>     FPMA or SPMA mode MAC address back to initiator.
>     fcoe_netdev_cleanup.
> 
> Removes FIP descriptor type checking against ELS type
> ELS_FLOGI in fcoe_ctlr_encaps to update a FIP MAC descriptor,
> instead now only check for spma flag to update MAC descriptor.
> 
> I could test this with available only FPMA supported switch
> but since data_src_addr is updated in same manner as it used
> to be for both FPMA and SPMA modes with FIP or pre-FIP links,
> so it will work with SPMA switch also provided that switch
> grants back a valid MAC address.
> 
> Signed-off-by: Vasu Dev <[email protected]>
> ---
> 
>  drivers/scsi/fcoe/fcoe.c    |   18 ++++++++++++++++--
>  drivers/scsi/fcoe/libfcoe.c |   10 ++++++++--
>  include/scsi/libfcoe.h      |    2 ++
>  3 files changed, 26 insertions(+), 4 deletions(-)
> 
> 
> diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
> index 1cd3d57..cb42043 100644
> --- a/drivers/scsi/fcoe/fcoe.c
> +++ b/drivers/scsi/fcoe/fcoe.c
> @@ -238,6 +238,9 @@ void fcoe_netdev_cleanup(struct fcoe_softc *fc)
>       if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
>               dev_unicast_delete(fc->real_dev,
>                                  fc->ctlr.data_src_addr, ETH_ALEN);
> +     if (fc->ctlr.spma)
> +             dev_unicast_delete(fc->real_dev,
> +                                fc->ctlr.ctl_src_addr, ETH_ALEN);
>       dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
>       rtnl_unlock();
>  }
> @@ -313,9 +316,18 @@ static int fcoe_netdev_config(struct fc_lport *lp, 
> struct net_device *netdev)
>       skb_queue_head_init(&fc->fcoe_pending_queue);
>       fc->fcoe_pending_queue_active = 0;
>  
> +     if (netdev->netdev_ops && netdev->netdev_ops->ndo_get_storage_address) {
> +             memcpy(fc->ctlr.ctl_src_addr,
> +                    netdev->netdev_ops->ndo_get_storage_address(netdev),
> +                    ETH_ALEN);
> +             if (is_valid_ether_addr(fc->ctlr.ctl_src_addr))
> +                     fc->ctlr.spma = 1;
> +     }

If SPMA was a requirement, we could just set the SPMA flag even
without a special MAC address.  The above code seems to have little
to do with SPMA and just allows the LLD to provide another MAC
address to be used for FIP and FCoE.

That part of the patch could be separated from the rest.

> +
>       /* setup Source Mac Address */
> -     memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
> -            fc->real_dev->addr_len);
> +     if (!fc->ctlr.spma)
> +             memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
> +                    fc->real_dev->addr_len);
>  
>       wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
>       fc_set_wwnn(lp, wwnn);
> @@ -331,6 +343,8 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct 
> net_device *netdev)
>       rtnl_lock();
>       memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
>       dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
> +     if (fc->ctlr.spma)
> +             dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr, ETH_ALEN);
>       rtnl_unlock();
>  
>       /*
> diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
> index f410f4a..b8028b1 100644
> --- a/drivers/scsi/fcoe/libfcoe.c
> +++ b/drivers/scsi/fcoe/libfcoe.c
> @@ -198,6 +198,8 @@ static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, 
> struct fcoe_fcf *fcf)
>       sol->fip.fip_subcode = FIP_SC_SOL;
>       sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
>       sol->fip.fip_flags = htons(FIP_FL_FPMA);
> +     if (fip->spma)
> +             sol->fip.fip_flags |= htons(FIP_FL_SPMA);
>  
>       sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
>       sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
> @@ -350,6 +352,8 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr 
> *fip, int ports, u8 *sa)
>       kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
>                                   ports * sizeof(*vn)) / FIP_BPW);
>       kal->fip.fip_flags = htons(FIP_FL_FPMA);
> +     if (fip->spma)
> +             kal->fip.fip_flags |= htons(FIP_FL_SPMA);
>  
>       kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
>       kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
> @@ -413,6 +417,8 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
>       cap->fip.fip_subcode = FIP_SC_REQ;
>       cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
>       cap->fip.fip_flags = htons(FIP_FL_FPMA);
> +     if (fip->spma)
> +             cap->fip.fip_flags |= htons(FIP_FL_SPMA);
>  
>       cap->encaps.fd_desc.fip_dtype = dtype;
>       cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
> @@ -421,8 +427,8 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
>       memset(mac, 0, sizeof(mac));
>       mac->fd_desc.fip_dtype = FIP_DT_MAC;
>       mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
> -     if (dtype != ELS_FLOGI)
> -             memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
> +     if (fip->spma)
> +             memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
>  
>       skb->protocol = htons(ETH_P_802_3);
>       skb_reset_mac_header(skb);
> diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
> index 666cc13..b241060 100644
> --- a/include/scsi/libfcoe.h
> +++ b/include/scsi/libfcoe.h
> @@ -73,6 +73,7 @@ enum fip_state {
>   * @link:    current link status for libfc.
>   * @last_link:       last link state reported to libfc.
>   * @map_dest:        use the FC_MAP mode for destination MAC addresses.
> + * @spma:    supports SPMA server-provided MACs mode
>   * @dest_addr:       MAC address of the selected FC forwarder.
>   * @ctl_src_addr: the native MAC address of our local port.
>   * @data_src_addr: the assigned MAC address for the local port after FLOGI.
> @@ -104,6 +105,7 @@ struct fcoe_ctlr {
>       u8 link;
>       u8 last_link;
>       u8 map_dest;
> +     u8 spma;
>       u8 dest_addr[ETH_ALEN];
>       u8 ctl_src_addr[ETH_ALEN];
>       u8 data_src_addr[ETH_ALEN];
> 
> _______________________________________________
> devel mailing list
> [email protected]
> http://www.open-fcoe.org/mailman/listinfo/devel

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to