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;

Wouldn't it be a bug in the LLD to give an invalid MAC here?
It's OK to check, though.

> +     }
> +
>       /* 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);

Lets's add a u16 capability field in the fcoe_ctlr, which would
contain FPMA or SPMA or both, and here we would just use that to set the
flags in the packet.  We could use a be16 field, but u16 is better so
we can test it instead of using fip->spma.

        sol->fip.fip_flags = htons(fip->capability);

>       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);

For non-FLOGI, non-SPMA, I think we want the data_src address still.

>       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