Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'cxgb4-fcoe'

Varun Prakash says:

====================
FCoE support in cxgb4 driver

This patch series enables FCoE support in cxgb4 driver, it enables
FCOE_CRC and FCOE_MTU net device features.

This series is created against net-next tree.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+302 -3
+11
drivers/net/ethernet/chelsio/Kconfig
··· 97 97 98 98 If unsure, say N. 99 99 100 + config CHELSIO_T4_FCOE 101 + bool "Fibre Channel over Ethernet (FCoE) Support for Chelsio T5 cards" 102 + default n 103 + depends on CHELSIO_T4 && CHELSIO_T4_DCB && FCOE 104 + ---help--- 105 + Enable FCoE offload features. 106 + Say Y here if you want to enable Fibre Channel over Ethernet (FCoE) support 107 + in the driver. 108 + 109 + If unsure, say N. 110 + 100 111 config CHELSIO_T4VF 101 112 tristate "Chelsio Communications T4/T5 Virtual Function Ethernet support" 102 113 depends on PCI
+1
drivers/net/ethernet/chelsio/cxgb4/Makefile
··· 6 6 7 7 cxgb4-objs := cxgb4_main.o l2t.o t4_hw.o sge.o clip_tbl.o 8 8 cxgb4-$(CONFIG_CHELSIO_T4_DCB) += cxgb4_dcb.o 9 + cxgb4-$(CONFIG_CHELSIO_T4_FCOE) += cxgb4_fcoe.o 9 10 cxgb4-$(CONFIG_DEBUG_FS) += cxgb4_debugfs.o
+7
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
··· 387 387 388 388 #include "cxgb4_dcb.h" 389 389 390 + #ifdef CONFIG_CHELSIO_T4_FCOE 391 + #include "cxgb4_fcoe.h" 392 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 393 + 390 394 struct port_info { 391 395 struct adapter *adapter; 392 396 u16 viid; ··· 410 406 #ifdef CONFIG_CHELSIO_T4_DCB 411 407 struct port_dcb_info dcb; /* Data Center Bridging support */ 412 408 #endif 409 + #ifdef CONFIG_CHELSIO_T4_FCOE 410 + struct cxgb_fcoe fcoe; 411 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 413 412 }; 414 413 415 414 struct dentry;
+122
drivers/net/ethernet/chelsio/cxgb4/cxgb4_fcoe.c
··· 1 + /* 2 + * This file is part of the Chelsio T4 Ethernet driver for Linux. 3 + * 4 + * Copyright (c) 2015 Chelsio Communications, Inc. All rights reserved. 5 + * 6 + * This software is available to you under a choice of one of two 7 + * licenses. You may choose to be licensed under the terms of the GNU 8 + * General Public License (GPL) Version 2, available from the file 9 + * COPYING in the main directory of this source tree, or the 10 + * OpenIB.org BSD license below: 11 + * 12 + * Redistribution and use in source and binary forms, with or 13 + * without modification, are permitted provided that the following 14 + * conditions are met: 15 + * 16 + * - Redistributions of source code must retain the above 17 + * copyright notice, this list of conditions and the following 18 + * disclaimer. 19 + * 20 + * - Redistributions in binary form must reproduce the above 21 + * copyright notice, this list of conditions and the following 22 + * disclaimer in the documentation and/or other materials 23 + * provided with the distribution. 24 + * 25 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 + * SOFTWARE. 33 + */ 34 + 35 + #ifdef CONFIG_CHELSIO_T4_FCOE 36 + 37 + #include <scsi/fc/fc_fs.h> 38 + #include <scsi/libfcoe.h> 39 + #include "cxgb4.h" 40 + 41 + bool cxgb_fcoe_sof_eof_supported(struct adapter *adap, struct sk_buff *skb) 42 + { 43 + struct fcoe_hdr *fcoeh = (struct fcoe_hdr *)skb_network_header(skb); 44 + u8 sof = fcoeh->fcoe_sof; 45 + u8 eof = 0; 46 + 47 + if ((sof != FC_SOF_I3) && (sof != FC_SOF_N3)) { 48 + dev_err(adap->pdev_dev, "Unsupported SOF 0x%x\n", sof); 49 + return 0; 50 + } 51 + 52 + skb_copy_bits(skb, skb->len - 4, &eof, 1); 53 + 54 + if ((eof != FC_EOF_N) && (eof != FC_EOF_T)) { 55 + dev_err(adap->pdev_dev, "Unsupported EOF 0x%x\n", eof); 56 + return 0; 57 + } 58 + 59 + return 1; 60 + } 61 + 62 + /** 63 + * cxgb_fcoe_enable - enable FCoE offload features 64 + * @netdev: net device 65 + * 66 + * Returns 0 on success or -EINVAL on failure. 67 + */ 68 + int cxgb_fcoe_enable(struct net_device *netdev) 69 + { 70 + struct port_info *pi = netdev_priv(netdev); 71 + struct adapter *adap = pi->adapter; 72 + struct cxgb_fcoe *fcoe = &pi->fcoe; 73 + 74 + if (is_t4(adap->params.chip)) 75 + return -EINVAL; 76 + 77 + if (!(adap->flags & FULL_INIT_DONE)) 78 + return -EINVAL; 79 + 80 + dev_info(adap->pdev_dev, "Enabling FCoE offload features\n"); 81 + 82 + netdev->features |= NETIF_F_FCOE_CRC; 83 + netdev->vlan_features |= NETIF_F_FCOE_CRC; 84 + netdev->features |= NETIF_F_FCOE_MTU; 85 + netdev->vlan_features |= NETIF_F_FCOE_MTU; 86 + 87 + netdev_features_change(netdev); 88 + 89 + fcoe->flags |= CXGB_FCOE_ENABLED; 90 + 91 + return 0; 92 + } 93 + 94 + /** 95 + * cxgb_fcoe_disable - disable FCoE offload 96 + * @netdev: net device 97 + * 98 + * Returns 0 on success or -EINVAL on failure. 99 + */ 100 + int cxgb_fcoe_disable(struct net_device *netdev) 101 + { 102 + struct port_info *pi = netdev_priv(netdev); 103 + struct adapter *adap = pi->adapter; 104 + struct cxgb_fcoe *fcoe = &pi->fcoe; 105 + 106 + if (!(fcoe->flags & CXGB_FCOE_ENABLED)) 107 + return -EINVAL; 108 + 109 + dev_info(adap->pdev_dev, "Disabling FCoE offload features\n"); 110 + 111 + fcoe->flags &= ~CXGB_FCOE_ENABLED; 112 + 113 + netdev->features &= ~NETIF_F_FCOE_CRC; 114 + netdev->vlan_features &= ~NETIF_F_FCOE_CRC; 115 + netdev->features &= ~NETIF_F_FCOE_MTU; 116 + netdev->vlan_features &= ~NETIF_F_FCOE_MTU; 117 + 118 + netdev_features_change(netdev); 119 + 120 + return 0; 121 + } 122 + #endif /* CONFIG_CHELSIO_T4_FCOE */
+57
drivers/net/ethernet/chelsio/cxgb4/cxgb4_fcoe.h
··· 1 + /* 2 + * This file is part of the Chelsio T4 Ethernet driver for Linux. 3 + * 4 + * Copyright (c) 2015 Chelsio Communications, Inc. All rights reserved. 5 + * 6 + * This software is available to you under a choice of one of two 7 + * licenses. You may choose to be licensed under the terms of the GNU 8 + * General Public License (GPL) Version 2, available from the file 9 + * COPYING in the main directory of this source tree, or the 10 + * OpenIB.org BSD license below: 11 + * 12 + * Redistribution and use in source and binary forms, with or 13 + * without modification, are permitted provided that the following 14 + * conditions are met: 15 + * 16 + * - Redistributions of source code must retain the above 17 + * copyright notice, this list of conditions and the following 18 + * disclaimer. 19 + * 20 + * - Redistributions in binary form must reproduce the above 21 + * copyright notice, this list of conditions and the following 22 + * disclaimer in the documentation and/or other materials 23 + * provided with the distribution. 24 + * 25 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27 + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29 + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30 + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31 + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32 + * SOFTWARE. 33 + */ 34 + 35 + #ifndef __CXGB4_FCOE_H__ 36 + #define __CXGB4_FCOE_H__ 37 + 38 + #ifdef CONFIG_CHELSIO_T4_FCOE 39 + 40 + #define CXGB_FCOE_TXPKT_CSUM_START 28 41 + #define CXGB_FCOE_TXPKT_CSUM_END 8 42 + 43 + /* fcoe flags */ 44 + enum { 45 + CXGB_FCOE_ENABLED = (1 << 0), 46 + }; 47 + 48 + struct cxgb_fcoe { 49 + u8 flags; 50 + }; 51 + 52 + int cxgb_fcoe_enable(struct net_device *); 53 + int cxgb_fcoe_disable(struct net_device *); 54 + bool cxgb_fcoe_sof_eof_supported(struct adapter *, struct sk_buff *); 55 + 56 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 57 + #endif /* __CXGB4_FCOE_H__ */
+8
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
··· 1271 1271 txq = 0; 1272 1272 } else { 1273 1273 txq = (vlan_tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; 1274 + #ifdef CONFIG_CHELSIO_T4_FCOE 1275 + if (skb->protocol == htons(ETH_P_FCOE)) 1276 + txq = skb->priority & 0x7; 1277 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 1274 1278 } 1275 1279 return txq; 1276 1280 } ··· 4582 4578 #ifdef CONFIG_NET_POLL_CONTROLLER 4583 4579 .ndo_poll_controller = cxgb_netpoll, 4584 4580 #endif 4581 + #ifdef CONFIG_CHELSIO_T4_FCOE 4582 + .ndo_fcoe_enable = cxgb_fcoe_enable, 4583 + .ndo_fcoe_disable = cxgb_fcoe_disable, 4584 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 4585 4585 #ifdef CONFIG_NET_RX_BUSY_POLL 4586 4586 .ndo_busy_poll = cxgb_busy_poll, 4587 4587 #endif
+71 -3
drivers/net/ethernet/chelsio/cxgb4/sge.c
··· 46 46 #ifdef CONFIG_NET_RX_BUSY_POLL 47 47 #include <net/busy_poll.h> 48 48 #endif /* CONFIG_NET_RX_BUSY_POLL */ 49 + #ifdef CONFIG_CHELSIO_T4_FCOE 50 + #include <scsi/fc/fc_fcoe.h> 51 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 49 52 #include "cxgb4.h" 50 53 #include "t4_regs.h" 51 54 #include "t4_values.h" ··· 1047 1044 q->pidx -= q->size; 1048 1045 } 1049 1046 1047 + #ifdef CONFIG_CHELSIO_T4_FCOE 1048 + static inline int 1049 + cxgb_fcoe_offload(struct sk_buff *skb, struct adapter *adap, 1050 + const struct port_info *pi, u64 *cntrl) 1051 + { 1052 + const struct cxgb_fcoe *fcoe = &pi->fcoe; 1053 + 1054 + if (!(fcoe->flags & CXGB_FCOE_ENABLED)) 1055 + return 0; 1056 + 1057 + if (skb->protocol != htons(ETH_P_FCOE)) 1058 + return 0; 1059 + 1060 + skb_reset_mac_header(skb); 1061 + skb->mac_len = sizeof(struct ethhdr); 1062 + 1063 + skb_set_network_header(skb, skb->mac_len); 1064 + skb_set_transport_header(skb, skb->mac_len + sizeof(struct fcoe_hdr)); 1065 + 1066 + if (!cxgb_fcoe_sof_eof_supported(adap, skb)) 1067 + return -ENOTSUPP; 1068 + 1069 + /* FC CRC offload */ 1070 + *cntrl = TXPKT_CSUM_TYPE(TX_CSUM_FCOE) | 1071 + TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS | 1072 + TXPKT_CSUM_START(CXGB_FCOE_TXPKT_CSUM_START) | 1073 + TXPKT_CSUM_END(CXGB_FCOE_TXPKT_CSUM_END) | 1074 + TXPKT_CSUM_LOC(CXGB_FCOE_TXPKT_CSUM_END); 1075 + return 0; 1076 + } 1077 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 1078 + 1050 1079 /** 1051 1080 * t4_eth_xmit - add a packet to an Ethernet Tx queue 1052 1081 * @skb: the packet ··· 1101 1066 const struct skb_shared_info *ssi; 1102 1067 dma_addr_t addr[MAX_SKB_FRAGS + 1]; 1103 1068 bool immediate = false; 1069 + #ifdef CONFIG_CHELSIO_T4_FCOE 1070 + int err; 1071 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 1104 1072 1105 1073 /* 1106 1074 * The chip min packet length is 10 octets but play safe and reject ··· 1120 1082 q = &adap->sge.ethtxq[qidx + pi->first_qset]; 1121 1083 1122 1084 reclaim_completed_tx(adap, &q->q, true); 1085 + cntrl = TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS; 1086 + 1087 + #ifdef CONFIG_CHELSIO_T4_FCOE 1088 + err = cxgb_fcoe_offload(skb, adap, pi, &cntrl); 1089 + if (unlikely(err == -ENOTSUPP)) 1090 + goto out_free; 1091 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 1123 1092 1124 1093 flits = calc_tx_flits(skb); 1125 1094 ndesc = flits_to_desc(flits); ··· 1198 1153 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1199 1154 cntrl = hwcsum(skb) | TXPKT_IPCSUM_DIS; 1200 1155 q->tx_cso++; 1201 - } else 1202 - cntrl = TXPKT_L4CSUM_DIS | TXPKT_IPCSUM_DIS; 1156 + } 1203 1157 } 1204 1158 1205 1159 if (skb_vlan_tag_present(skb)) { 1206 1160 q->vlan_ins++; 1207 1161 cntrl |= TXPKT_VLAN_VLD | TXPKT_VLAN(skb_vlan_tag_get(skb)); 1162 + #ifdef CONFIG_CHELSIO_T4_FCOE 1163 + if (skb->protocol == htons(ETH_P_FCOE)) 1164 + cntrl |= TXPKT_VLAN( 1165 + ((skb->priority & 0x7) << VLAN_PRIO_SHIFT)); 1166 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 1208 1167 } 1209 1168 1210 1169 cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) | ··· 1808 1759 struct sge *s = &q->adap->sge; 1809 1760 int cpl_trace_pkt = is_t4(q->adap->params.chip) ? 1810 1761 CPL_TRACE_PKT : CPL_TRACE_PKT_T5; 1762 + #ifdef CONFIG_CHELSIO_T4_FCOE 1763 + struct port_info *pi; 1764 + #endif 1811 1765 1812 1766 if (unlikely(*(u8 *)rsp == cpl_trace_pkt)) 1813 1767 return handle_trace_pkt(q->adap, si); ··· 1851 1799 skb->ip_summed = CHECKSUM_COMPLETE; 1852 1800 rxq->stats.rx_cso++; 1853 1801 } 1854 - } else 1802 + } else { 1855 1803 skb_checksum_none_assert(skb); 1804 + #ifdef CONFIG_CHELSIO_T4_FCOE 1805 + #define CPL_RX_PKT_FLAGS (RXF_PSH_F | RXF_SYN_F | RXF_UDP_F | \ 1806 + RXF_TCP_F | RXF_IP_F | RXF_IP6_F | RXF_LRO_F) 1807 + 1808 + pi = netdev_priv(skb->dev); 1809 + if (!(pkt->l2info & cpu_to_be32(CPL_RX_PKT_FLAGS))) { 1810 + if ((pkt->l2info & cpu_to_be32(RXF_FCOE_F)) && 1811 + (pi->fcoe.flags & CXGB_FCOE_ENABLED)) { 1812 + if (!(pkt->err_vec & cpu_to_be16(RXERR_CSUM_F))) 1813 + skb->ip_summed = CHECKSUM_UNNECESSARY; 1814 + } 1815 + } 1816 + 1817 + #undef CPL_RX_PKT_FLAGS 1818 + #endif /* CONFIG_CHELSIO_T4_FCOE */ 1819 + } 1856 1820 1857 1821 if (unlikely(pkt->vlan_ex)) { 1858 1822 __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ntohs(pkt->vlan));
+25
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
··· 794 794 __be16 err_vec; 795 795 }; 796 796 797 + #define RXF_PSH_S 20 798 + #define RXF_PSH_V(x) ((x) << RXF_PSH_S) 799 + #define RXF_PSH_F RXF_PSH_V(1U) 800 + 801 + #define RXF_SYN_S 21 802 + #define RXF_SYN_V(x) ((x) << RXF_SYN_S) 803 + #define RXF_SYN_F RXF_SYN_V(1U) 804 + 797 805 #define RXF_UDP_S 22 798 806 #define RXF_UDP_V(x) ((x) << RXF_UDP_S) 799 807 #define RXF_UDP_F RXF_UDP_V(1U) ··· 817 809 #define RXF_IP6_S 25 818 810 #define RXF_IP6_V(x) ((x) << RXF_IP6_S) 819 811 #define RXF_IP6_F RXF_IP6_V(1U) 812 + 813 + #define RXF_SYN_COOKIE_S 26 814 + #define RXF_SYN_COOKIE_V(x) ((x) << RXF_SYN_COOKIE_S) 815 + #define RXF_SYN_COOKIE_F RXF_SYN_COOKIE_V(1U) 816 + 817 + #define RXF_FCOE_S 26 818 + #define RXF_FCOE_V(x) ((x) << RXF_FCOE_S) 819 + #define RXF_FCOE_F RXF_FCOE_V(1U) 820 + 821 + #define RXF_LRO_S 27 822 + #define RXF_LRO_V(x) ((x) << RXF_LRO_S) 823 + #define RXF_LRO_F RXF_LRO_V(1U) 820 824 821 825 /* rx_pkt.l2info fields */ 822 826 #define RX_ETHHDR_LEN_S 0 ··· 865 845 #define RX_IPHDR_LEN_M 0x3FF 866 846 #define RX_IPHDR_LEN_V(x) ((x) << RX_IPHDR_LEN_S) 867 847 #define RX_IPHDR_LEN_G(x) (((x) >> RX_IPHDR_LEN_S) & RX_IPHDR_LEN_M) 848 + 849 + /* rx_pkt.err_vec fields */ 850 + #define RXERR_CSUM_S 13 851 + #define RXERR_CSUM_V(x) ((x) << RXERR_CSUM_S) 852 + #define RXERR_CSUM_F RXERR_CSUM_V(1U) 868 853 869 854 struct cpl_trace_pkt { 870 855 u8 opcode;