162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * This file is part of the Chelsio T4 Ethernet driver for Linux. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2015 Chelsio Communications, Inc. All rights reserved. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * This software is available to you under a choice of one of two 762306a36Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 862306a36Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 962306a36Sopenharmony_ci * COPYING in the main directory of this source tree, or the 1062306a36Sopenharmony_ci * OpenIB.org BSD license below: 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or 1362306a36Sopenharmony_ci * without modification, are permitted provided that the following 1462306a36Sopenharmony_ci * conditions are met: 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * - Redistributions of source code must retain the above 1762306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 1862306a36Sopenharmony_ci * disclaimer. 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * - Redistributions in binary form must reproduce the above 2162306a36Sopenharmony_ci * copyright notice, this list of conditions and the following 2262306a36Sopenharmony_ci * disclaimer in the documentation and/or other materials 2362306a36Sopenharmony_ci * provided with the distribution. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 2662306a36Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2762306a36Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 2862306a36Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 2962306a36Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 3062306a36Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 3162306a36Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 3262306a36Sopenharmony_ci * SOFTWARE. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#ifdef CONFIG_CHELSIO_T4_FCOE 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#include <scsi/fc/fc_fs.h> 3862306a36Sopenharmony_ci#include <scsi/libfcoe.h> 3962306a36Sopenharmony_ci#include "cxgb4.h" 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cibool cxgb_fcoe_sof_eof_supported(struct adapter *adap, struct sk_buff *skb) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci struct fcoe_hdr *fcoeh = (struct fcoe_hdr *)skb_network_header(skb); 4462306a36Sopenharmony_ci u8 sof = fcoeh->fcoe_sof; 4562306a36Sopenharmony_ci u8 eof = 0; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci if ((sof != FC_SOF_I3) && (sof != FC_SOF_N3)) { 4862306a36Sopenharmony_ci dev_err(adap->pdev_dev, "Unsupported SOF 0x%x\n", sof); 4962306a36Sopenharmony_ci return false; 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci skb_copy_bits(skb, skb->len - 4, &eof, 1); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci if ((eof != FC_EOF_N) && (eof != FC_EOF_T)) { 5562306a36Sopenharmony_ci dev_err(adap->pdev_dev, "Unsupported EOF 0x%x\n", eof); 5662306a36Sopenharmony_ci return false; 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci return true; 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/** 6362306a36Sopenharmony_ci * cxgb_fcoe_enable - enable FCoE offload features 6462306a36Sopenharmony_ci * @netdev: net device 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * Returns 0 on success or -EINVAL on failure. 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_ciint cxgb_fcoe_enable(struct net_device *netdev) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci struct port_info *pi = netdev_priv(netdev); 7162306a36Sopenharmony_ci struct adapter *adap = pi->adapter; 7262306a36Sopenharmony_ci struct cxgb_fcoe *fcoe = &pi->fcoe; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci if (is_t4(adap->params.chip)) 7562306a36Sopenharmony_ci return -EINVAL; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (!(adap->flags & CXGB4_FULL_INIT_DONE)) 7862306a36Sopenharmony_ci return -EINVAL; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci dev_info(adap->pdev_dev, "Enabling FCoE offload features\n"); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci netdev->features |= NETIF_F_FCOE_CRC; 8362306a36Sopenharmony_ci netdev->vlan_features |= NETIF_F_FCOE_CRC; 8462306a36Sopenharmony_ci netdev->features |= NETIF_F_FCOE_MTU; 8562306a36Sopenharmony_ci netdev->vlan_features |= NETIF_F_FCOE_MTU; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci netdev_features_change(netdev); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci fcoe->flags |= CXGB_FCOE_ENABLED; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci return 0; 9262306a36Sopenharmony_ci} 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci/** 9562306a36Sopenharmony_ci * cxgb_fcoe_disable - disable FCoE offload 9662306a36Sopenharmony_ci * @netdev: net device 9762306a36Sopenharmony_ci * 9862306a36Sopenharmony_ci * Returns 0 on success or -EINVAL on failure. 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_ciint cxgb_fcoe_disable(struct net_device *netdev) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci struct port_info *pi = netdev_priv(netdev); 10362306a36Sopenharmony_ci struct adapter *adap = pi->adapter; 10462306a36Sopenharmony_ci struct cxgb_fcoe *fcoe = &pi->fcoe; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci if (!(fcoe->flags & CXGB_FCOE_ENABLED)) 10762306a36Sopenharmony_ci return -EINVAL; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci dev_info(adap->pdev_dev, "Disabling FCoE offload features\n"); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci fcoe->flags &= ~CXGB_FCOE_ENABLED; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci netdev->features &= ~NETIF_F_FCOE_CRC; 11462306a36Sopenharmony_ci netdev->vlan_features &= ~NETIF_F_FCOE_CRC; 11562306a36Sopenharmony_ci netdev->features &= ~NETIF_F_FCOE_MTU; 11662306a36Sopenharmony_ci netdev->vlan_features &= ~NETIF_F_FCOE_MTU; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci netdev_features_change(netdev); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci return 0; 12162306a36Sopenharmony_ci} 12262306a36Sopenharmony_ci#endif /* CONFIG_CHELSIO_T4_FCOE */ 123