From patchwork Mon Oct 9 09:37:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kalderon, Michal" X-Patchwork-Id: 9992459 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C5A8C60223 for ; Mon, 9 Oct 2017 09:39:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5BEC2877B for ; Mon, 9 Oct 2017 09:39:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A87C828786; Mon, 9 Oct 2017 09:39:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CA6F32877B for ; Mon, 9 Oct 2017 09:39:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751598AbdJIJjP (ORCPT ); Mon, 9 Oct 2017 05:39:15 -0400 Received: from mail-dm3nam03on0079.outbound.protection.outlook.com ([104.47.41.79]:7744 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751738AbdJIJjM (ORCPT ); Mon, 9 Oct 2017 05:39:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=LXy2jNq4+4AlzHv49kTnxbten2Vh/saLn4xWSKyctSw=; b=lJuEvjirPT9w46uLoasn4dQQgtiyygyLh0DI1lTZ1giO9PPfhIo2xCWV+wriZmroDK2WlY1VemNMIUoeA0CBhTzk0XGWTgU0EHAAbzdA07fsFbIQ8CDdlcYB/grz1ero/IIxPrzyjPE43msyeRhgAIc2L0A9/VDrGhk86lloSqs= Received: from DM5PR07CA0044.namprd07.prod.outlook.com (10.168.109.30) by BY2PR0701MB1944.namprd07.prod.outlook.com (10.163.155.157) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.7; Mon, 9 Oct 2017 09:39:09 +0000 Received: from BL2FFO11FD023.protection.gbl (2a01:111:f400:7c09::110) by DM5PR07CA0044.outlook.office365.com (2603:10b6:3:16::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.56.11 via Frontend Transport; Mon, 9 Oct 2017 09:39:09 +0000 Authentication-Results: spf=none (sender IP is 50.232.66.26) smtp.mailfrom=cavium.com; vger.kernel.org; dkim=none (message not signed) header.d=none; vger.kernel.org; dmarc=none action=none header.from=cavium.com; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) Received: from CAEXCH02.caveonetworks.com (50.232.66.26) by BL2FFO11FD023.mail.protection.outlook.com (10.173.161.102) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.20.77.10 via Frontend Transport; Mon, 9 Oct 2017 09:39:09 +0000 Received: from lb-tlvb-michal.il.qlogic.com.com (10.185.6.89) by CAEXCH02.caveonetworks.com (10.17.4.29) with Microsoft SMTP Server id 14.2.347.0; Mon, 9 Oct 2017 02:39:05 -0700 From: Michal Kalderon To: CC: , , , Michal Kalderon , "Ariel Elior" Subject: [PATCH v3 net-next 09/12] qed: Add unaligned and packed packet processing Date: Mon, 9 Oct 2017 12:37:51 +0300 Message-ID: <1507541874-18344-10-git-send-email-Michal.Kalderon@cavium.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1507541874-18344-1-git-send-email-Michal.Kalderon@cavium.com> References: <1507541874-18344-1-git-send-email-Michal.Kalderon@cavium.com> MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:50.232.66.26; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(376002)(346002)(2980300002)(428002)(199003)(189002)(45074003)(48376002)(316002)(86362001)(5003940100001)(189998001)(50466002)(50986999)(47776003)(105586002)(76176999)(5660300001)(36756003)(101416001)(2351001)(69596002)(6916009)(4326008)(6666003)(2950100002)(8936002)(77096006)(356003)(305945005)(478600001)(106466001)(2906002)(81166006)(8676002)(81156014)(104016004)(50226002)(72206003)(107886003)(16586007)(54906003); DIR:OUT; SFP:1101; SCL:1; SRVR:BY2PR0701MB1944; H:CAEXCH02.caveonetworks.com; FPR:; SPF:None; PTR:50-232-66-26-static.hfc.comcastbusiness.net; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD023; 1:3EgtlixJBV1Vb8SmIxk5gOKpEG3F65Nc7VNK/fndS6+J9hcWIZf/BrOmz00B8zJTxIlAHBdRGHlS5arX7jrQ2r7fJgyV3yhxrnSJQz3V2h3Q6X7U4GoRNiK6CRuxe7xL X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: eb9b6f12-30d6-47a1-93fa-08d50ef99792 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075); SRVR:BY2PR0701MB1944; X-Microsoft-Exchange-Diagnostics: 1; BY2PR0701MB1944; 3:/tt2wa4e9VM9nZ5OleQQgf1WeQyceVZMRFd6Gt8quK7z8t0vwMGV1d1mi8rdrAvgy/PYxPlxFFWrunLZDCBmJ+02wfJ2AhlagAAfXCvg98mTQk/PvfYpLlWCQp8Y6HpalAFQk2qCOmEGuUDsUeVuTI2vxHB3FgtKRbMwGCAjsLnRRamIoZAup8KvvoQGglBatRRJigO6aqhudt4l8fM4s0UPKdWVHCWuuWOrL762vMVvqMHXox5NanZEaG39VZxMNDF6daO679EYnYHkq7OVfNfPwTGL1vgGE2UdvYJaiUFRuRV1jw5JJUCV7P5rsM6Wa5pGCB15H3Spf2qjXS3z/RufJ8xduwJtGQWAquDk3QY=; 25:QTsa0yxmyiWwzs8JjnzwCVi3+d+RKXI4JcB17SqOfANYGhC8fYoQikK2Yd2xWiyeg/uJbFy5Ml/f+2fWfXi1qtCl/b5EIrHfUolCbO+o6qZCsFHr5/J3llFvJx81tz6+Aiau+NO0s6wktzlGuSz2yE3UV1Db2bRH38U4rdsMUo5f9ifQBMoZV/dLca8arjuyuim0D9PWRLtp5U8LQrrqVg2FRJxmcHpCH0h29kWaAEbivhu/bmJvNZHIzS5iK6F1cTH908rRd/CldM8DthvrBGK+eqyT6U9wSXBx2htA/nlxmV0lx3lfSa7HNn4Wd1mT+dzBOoLiEW2T7rDR+VuX8g== X-MS-TrafficTypeDiagnostic: BY2PR0701MB1944: X-Microsoft-Exchange-Diagnostics: 1; BY2PR0701MB1944; 31:wRf8pVyzCSiIELYMBd8edfT1OLwDoNsEZrgsra/QXrnNhhJIhMdZyAxkiptS4NaDT2outoucxA/2KpUFP794oTFzh20rCqcwAG/buq5D+yiTYkswmeifSK8WsCHSQxyjtHG3E6D6S0y5iih/88ItsEimG+CA8X/fjHDxpzmPVEx9yhupQCmL1p8xohMGGcZ0xmbL3Ib02W/+77RSYe8241um0NwHQw6Tn+VwYjybqqM=; 20:FJOyQyvqVwKehO3NuI2g3eqvtkTFXLS5dzAvBJds1sTE/fmwtSj31DBZjvcUsky88IecatXWSEEkVXMd8ELlT4s7UY5XGb1iZb//v6WexrJoOsEQOzDEt+hgxg+JPpsNx+EeImdiokYuNvTo8HGlkH4m44Icvne7WnTSzIG5rDmit6yVGBF110mbzcO2IDor5BIQWJ3oiP8/pGqdZbuZn91cT2gtq3PqvJDu/1/ns+2VrwNzVy92ZDPGXajyhA2kxM5ueIHX5hwL5MoSz38QLGrRo+ubl8g3XBO7xbxAy3KiFcjsYWJjdFOHqQEJERo7Mg6FPFmTRTI5prB+g5Zn1Zi0r8UcB9AhNBTsGb5+NalAgX578yY0nu2tkfCMWSOvpmydYVaxQ60jOvZ6k8hqjWASsUSoiVRA9h263qk0G+80Sy/8239uP98iYQi2sggZsKXJkYHz/ojQv9R9hRX2lkhwaRchcthRQeSt1VVeV8/KnkOjj6bxPm/5hLuWPOwm X-Exchange-Antispam-Report-Test: UriScan:; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(93006095)(93001095)(3002001)(100000703101)(100105400095)(10201501046)(6041248)(20161123558100)(20161123560025)(20161123555025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:BY2PR0701MB1944; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:BY2PR0701MB1944; X-Microsoft-Exchange-Diagnostics: 1; BY2PR0701MB1944; 4:CUqx5zl4rSLhMtX2T/ecYhB5X8SzoKSJG8FqRRDKT/GbN4A2H0WbM9v/YH1ZF6zMWR2vSWnwVhVOb2vaopCEZH4iCYUle5eKiFv9EqU4ylFaMIVn65pLLFEbbW+m2Sa065IdWjVKW07MXGiVhXwvYrPfblLi+OuXXLj2kBoDpWT3vEuz49PT1nctw3JhINzOhWzk4/ve30ZOM3F73kMc2PNkprgpOnTUP2RVqMckorzrqytQYboxUXAb6jUvoNwv X-Forefront-PRVS: 045584D28C X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR0701MB1944; 23:gG32E10V1G0RD2YM0jQGPQK4uvuxpXT6jvhRdln?= =?us-ascii?Q?6e6RWBwM5ut2oPyNd0UHZ5eMI4QDaEbTXJXX5fqBbHrlZEk6wmTax34A0/Rl?= =?us-ascii?Q?VfjO1uOW7TXRKhBuTNMH+njApIyVfxGoYNr9IRy9QsCtNdD63Ueyh1EJyFSS?= =?us-ascii?Q?DgmFrt2/ZDIfKChSG2lC20l0WIKH0o3m+z7AAcSa9xgHlr5yD3nyl86N6Whu?= =?us-ascii?Q?7HzLhKGzMtAmCpaBmfGu3QgLlRSsOpEPsU4MvRLl57RewiDIGZSTrgl6lCaj?= =?us-ascii?Q?WDbpiohiQGd82m3sF/enr7fOOyfaG4/FZvuJw5D/2cW4qAjtXPpKqwa8BW0Y?= =?us-ascii?Q?2z91ParZ+vZcfwkua/qZs4RB2Pah0eZCaUD5nertaFmt1kN+z8PXqWqkYK2D?= =?us-ascii?Q?DmYf2b0uVa5MrZHrl/zo9MUQu2hHrIcjMYjDlhfn4IDY2QKTm/69ngpKTY0J?= =?us-ascii?Q?pDIfm92Lw2hbnZ1r/mdH7u8nMgrpQqHOuVnlFIVL1lTrcwvjcu74CY/FqVDm?= =?us-ascii?Q?pJJMDx9J0fDuHNGLtlX25hpMx+N5ktAtytdCyAnAkn6oJ2P0dD/28kkkv/aS?= =?us-ascii?Q?HGvtA+5mQUqxyCxXHA28tXyRNUx3vE05qxVA2aGH4YayGRXEF4xSSEnL2n1k?= =?us-ascii?Q?8ZhOyqQqEx8D46oxlrOygkkyUemUfa01f2OlkTVASQHUXOtYOKD/MRPjoTGg?= =?us-ascii?Q?HAY4FXvvmDV41BU9OG/j6Wpl9usv0bng2GVTJSyeAtcMCGl2NmPTP7obFgc8?= =?us-ascii?Q?3VxiVYS67CvLQNU28r75LYngXDBi0dtmVxUuCPnGxxGyjBqVQQ0XkfvHb22t?= =?us-ascii?Q?2zrV4fB0KtZ+bVSTBN8mCIufPTANLYwOQIlEK41f+OxoNZBt5bLJZ3WDzLDt?= =?us-ascii?Q?Ardfe8JWAfCLx3UQM9GWZtYlWXmgTJOju5cRbxETfOC/3MIBpRAZ/iYZHATQ?= =?us-ascii?Q?zfAZvU7AH6y+pEc1hi/a8iXEg2DoSyoLN5uDK74MmsuWALIZF5i5H9wSbC/b?= =?us-ascii?Q?kZVy6uZmINlnnpO1d8kpht7EaUvpIL5E9zDkGCpeIz5r8gA=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; BY2PR0701MB1944; 6:6u5huSAN+ov02I+sTBXsgUh6Ht+5LZcrlteuQdRG8eS5PY9jnnsRvXzeqi8lQaCdsgCYS5rNPyTpDYqggVl9gbctn7YvTKVcTvdgI+tU+b1m82aPyoqBvDOm27S7Gn+ODgZCpEiXdW0P1eRVlxJd543SIf2duWK9x0Tig9xr3qjmApS9qjQWDbpYmUAM8J0GNUI3/cSi0b7kuZC5AUsX4aenc2VS8gQ5LauuJuG61mNNPVT4HwptaMzwinNepnHJXrXJL3BxGqLWW73/laVAASeLRANwAdI6C7qDDlfbl2F4GBjeBgWZHk1llxiulm50Dcq+C4uZhM1XncP4NmEJoQ==; 5:HDFdAn9DUrlugo7j//sVywFkr5ojgLyLAkxlIIllEwdR0v3cj/Zd3/C7g8U+cs3n2ai6AXxH1T2MU2MH3rZZ2bZ07rl1ltJG1TMEMbuuRdgqm3GrMGvhSrrU1MhVOFPMYkrLTeC/akT0TOH44AUSDw==; 24:AvGw+OWN+Kx3duPvjaxxYZS7sg3c+Aqp3xvb4nu9z7lmqoZlsY56GI+i/XEyRBuHpHWvZgbRextaRNkBJCsD+Om3RIQAPujzQqX59WtgzMc=; 7:15mvokL1qeW2HEXepvm1L8j2SfYaGa9JkWHASAPhG8ib78cjXuHZC08AHzfmjBM/yNKY8M2XDIgijcFwQLPthKecG9Awt1h+k8QtJLo0r2Gg1UeE90cOLbJnLfdrzmiAPwLG/wyVIxk3IND5YtBbQ4GnEEghif+l/ddsN7EVduKS0woa05jJhxnJMmJ7iUHjd4SjnL9Q/Ik+vzQVG8Fx1LyPitMY2LpdaBL4BvJ8Lxo= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 09 Oct 2017 09:39:09.1972 (UTC) X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=711e4ccf-2e9b-4bcf-a551-4094005b6194; Ip=[50.232.66.26]; Helo=[CAEXCH02.caveonetworks.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR0701MB1944 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The fpdu data structure is preallocated per connection. Each connection stores the current status of the connection: either nothing pending, or there is a partial fpdu that is waiting for the rest of the fpdu (incomplete bytes != 0). The same structure is also used for splitting a packet when there are packed fpdus. The structure is initialized with all data required for sending the fpdu back to the FW. A fpdu will always be spanned across a maximum of 3 tx bds. One for the header, one for the partial fdpu received and one for the remainder (unaligned) packet. In case of packed fpdu's, two fragments are used, one for the header and one for the data. Corner cases are not handled in the patch for clarity, and will be added as a separate patch. Signed-off-by: Michal Kalderon Signed-off-by: Ariel Elior --- drivers/net/ethernet/qlogic/qed/qed_iwarp.c | 257 ++++++++++++++++++++++++++++ drivers/net/ethernet/qlogic/qed/qed_iwarp.h | 13 ++ 2 files changed, 270 insertions(+) diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c index efd4861..83b147f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c @@ -1419,6 +1419,7 @@ void qed_iwarp_resc_free(struct qed_hwfn *p_hwfn) qed_rdma_bmap_free(p_hwfn, &p_hwfn->p_rdma_info->tcp_cid_map, 1); kfree(iwarp_info->mpa_bufs); + kfree(iwarp_info->partial_fpdus); } int qed_iwarp_accept(void *rdma_cxt, struct qed_iwarp_accept_in *iparams) @@ -1716,8 +1717,170 @@ int qed_iwarp_reject(void *rdma_cxt, struct qed_iwarp_reject_in *iparams) return 0; } +static struct qed_iwarp_fpdu *qed_iwarp_get_curr_fpdu(struct qed_hwfn *p_hwfn, + u16 cid) +{ + struct qed_iwarp_info *iwarp_info = &p_hwfn->p_rdma_info->iwarp; + struct qed_iwarp_fpdu *partial_fpdu; + u32 idx; + + idx = cid - qed_cxt_get_proto_cid_start(p_hwfn, PROTOCOLID_IWARP); + if (idx >= iwarp_info->max_num_partial_fpdus) { + DP_ERR(p_hwfn, "Invalid cid %x max_num_partial_fpdus=%x\n", cid, + iwarp_info->max_num_partial_fpdus); + return NULL; + } + + partial_fpdu = &iwarp_info->partial_fpdus[idx]; + + return partial_fpdu; +} + +enum qed_iwarp_mpa_pkt_type { + QED_IWARP_MPA_PKT_PACKED, + QED_IWARP_MPA_PKT_PARTIAL, + QED_IWARP_MPA_PKT_UNALIGNED +}; + +#define QED_IWARP_MPA_FPDU_LENGTH_SIZE (2) +#define QED_IWARP_MPA_CRC32_DIGEST_SIZE (4) + +/* Pad to multiple of 4 */ +#define QED_IWARP_PDU_DATA_LEN_WITH_PAD(data_len) ALIGN(data_len, 4) +#define QED_IWARP_FPDU_LEN_WITH_PAD(_mpa_len) \ + (QED_IWARP_PDU_DATA_LEN_WITH_PAD((_mpa_len) + \ + QED_IWARP_MPA_FPDU_LENGTH_SIZE) + \ + QED_IWARP_MPA_CRC32_DIGEST_SIZE) + /* fpdu can be fragmented over maximum 3 bds: header, partial mpa, unaligned */ #define QED_IWARP_MAX_BDS_PER_FPDU 3 + +char *pkt_type_str[] = { + "QED_IWARP_MPA_PKT_PACKED", + "QED_IWARP_MPA_PKT_PARTIAL", + "QED_IWARP_MPA_PKT_UNALIGNED" +}; + +static enum qed_iwarp_mpa_pkt_type +qed_iwarp_mpa_classify(struct qed_hwfn *p_hwfn, + struct qed_iwarp_fpdu *fpdu, + u16 tcp_payload_len, u8 *mpa_data) +{ + enum qed_iwarp_mpa_pkt_type pkt_type; + u16 mpa_len; + + if (fpdu->incomplete_bytes) { + pkt_type = QED_IWARP_MPA_PKT_UNALIGNED; + goto out; + } + + mpa_len = ntohs(*((u16 *)(mpa_data))); + fpdu->fpdu_length = QED_IWARP_FPDU_LEN_WITH_PAD(mpa_len); + + if (fpdu->fpdu_length <= tcp_payload_len) + pkt_type = QED_IWARP_MPA_PKT_PACKED; + else + pkt_type = QED_IWARP_MPA_PKT_PARTIAL; + +out: + DP_VERBOSE(p_hwfn, QED_MSG_RDMA, + "MPA_ALIGN: %s: fpdu_length=0x%x tcp_payload_len:0x%x\n", + pkt_type_str[pkt_type], fpdu->fpdu_length, tcp_payload_len); + + return pkt_type; +} + +static void +qed_iwarp_init_fpdu(struct qed_iwarp_ll2_buff *buf, + struct qed_iwarp_fpdu *fpdu, + struct unaligned_opaque_data *pkt_data, + u16 tcp_payload_size, u8 placement_offset) +{ + fpdu->mpa_buf = buf; + fpdu->pkt_hdr = buf->data_phys_addr + placement_offset; + fpdu->pkt_hdr_size = pkt_data->tcp_payload_offset; + fpdu->mpa_frag = buf->data_phys_addr + pkt_data->first_mpa_offset; + fpdu->mpa_frag_virt = (u8 *)(buf->data) + pkt_data->first_mpa_offset; + + if (tcp_payload_size < fpdu->fpdu_length) + fpdu->incomplete_bytes = fpdu->fpdu_length - tcp_payload_size; + else + fpdu->incomplete_bytes = 0; /* complete fpdu */ + + fpdu->mpa_frag_len = fpdu->fpdu_length - fpdu->incomplete_bytes; +} + +static int +qed_iwarp_send_fpdu(struct qed_hwfn *p_hwfn, + struct qed_iwarp_fpdu *fpdu, + struct unaligned_opaque_data *curr_pkt, + struct qed_iwarp_ll2_buff *buf, + u16 tcp_payload_size, enum qed_iwarp_mpa_pkt_type pkt_type) +{ + struct qed_ll2_tx_pkt_info tx_pkt; + u8 ll2_handle; + int rc; + + memset(&tx_pkt, 0, sizeof(tx_pkt)); + + /* An unaligned packet means it's split over two tcp segments. So the + * complete packet requires 3 bds, one for the header, one for the + * part of the fpdu of the first tcp segment, and the last fragment + * will point to the remainder of the fpdu. A packed pdu, requires only + * two bds, one for the header and one for the data. + */ + tx_pkt.num_of_bds = (pkt_type == QED_IWARP_MPA_PKT_UNALIGNED) ? 3 : 2; + tx_pkt.tx_dest = QED_LL2_TX_DEST_LB; + tx_pkt.l4_hdr_offset_w = fpdu->pkt_hdr_size >> 2; /* offset in words */ + + /* Send the mpa_buf only with the last fpdu (in case of packed) */ + if (pkt_type == QED_IWARP_MPA_PKT_UNALIGNED || + tcp_payload_size <= fpdu->fpdu_length) + tx_pkt.cookie = fpdu->mpa_buf; + + tx_pkt.first_frag = fpdu->pkt_hdr; + tx_pkt.first_frag_len = fpdu->pkt_hdr_size; + tx_pkt.enable_ip_cksum = true; + tx_pkt.enable_l4_cksum = true; + tx_pkt.calc_ip_len = true; + /* vlan overload with enum iwarp_ll2_tx_queues */ + tx_pkt.vlan = IWARP_LL2_ALIGNED_TX_QUEUE; + + ll2_handle = p_hwfn->p_rdma_info->iwarp.ll2_mpa_handle; + + /* Set first fragment to header */ + rc = qed_ll2_prepare_tx_packet(p_hwfn, ll2_handle, &tx_pkt, true); + if (rc) + goto out; + + /* Set second fragment to first part of packet */ + rc = qed_ll2_set_fragment_of_tx_packet(p_hwfn, ll2_handle, + fpdu->mpa_frag, + fpdu->mpa_frag_len); + if (rc) + goto out; + + if (!fpdu->incomplete_bytes) + goto out; + + /* Set third fragment to second part of the packet */ + rc = qed_ll2_set_fragment_of_tx_packet(p_hwfn, + ll2_handle, + buf->data_phys_addr + + curr_pkt->first_mpa_offset, + fpdu->incomplete_bytes); +out: + DP_VERBOSE(p_hwfn, + QED_MSG_RDMA, + "MPA_ALIGN: Sent FPDU num_bds=%d first_frag_len=%x, mpa_frag_len=0x%x, incomplete_bytes:0x%x rc=%d\n", + tx_pkt.num_of_bds, + tx_pkt.first_frag_len, + fpdu->mpa_frag_len, + fpdu->incomplete_bytes, rc); + + return rc; +} + static void qed_iwarp_mpa_get_data(struct qed_hwfn *p_hwfn, struct unaligned_opaque_data *curr_pkt, @@ -1741,9 +1904,79 @@ int qed_iwarp_reject(void *rdma_cxt, struct qed_iwarp_reject_in *iparams) qed_iwarp_process_mpa_pkt(struct qed_hwfn *p_hwfn, struct qed_iwarp_ll2_mpa_buf *mpa_buf) { + struct unaligned_opaque_data *curr_pkt = &mpa_buf->data; struct qed_iwarp_ll2_buff *buf = mpa_buf->ll2_buf; + enum qed_iwarp_mpa_pkt_type pkt_type; + struct qed_iwarp_fpdu *fpdu; int rc = -EINVAL; + u8 *mpa_data; + + fpdu = qed_iwarp_get_curr_fpdu(p_hwfn, curr_pkt->cid & 0xffff); + if (!fpdu) { /* something corrupt with cid, post rx back */ + DP_ERR(p_hwfn, "Invalid cid, drop and post back to rx cid=%x\n", + curr_pkt->cid); + goto err; + } + do { + mpa_data = ((u8 *)(buf->data) + curr_pkt->first_mpa_offset); + + pkt_type = qed_iwarp_mpa_classify(p_hwfn, fpdu, + mpa_buf->tcp_payload_len, + mpa_data); + + switch (pkt_type) { + case QED_IWARP_MPA_PKT_PARTIAL: + qed_iwarp_init_fpdu(buf, fpdu, + curr_pkt, + mpa_buf->tcp_payload_len, + mpa_buf->placement_offset); + + mpa_buf->tcp_payload_len = 0; + break; + case QED_IWARP_MPA_PKT_PACKED: + qed_iwarp_init_fpdu(buf, fpdu, + curr_pkt, + mpa_buf->tcp_payload_len, + mpa_buf->placement_offset); + + rc = qed_iwarp_send_fpdu(p_hwfn, fpdu, curr_pkt, buf, + mpa_buf->tcp_payload_len, + pkt_type); + if (rc) { + DP_VERBOSE(p_hwfn, QED_MSG_RDMA, + "Can't send FPDU:reset rc=%d\n", rc); + memset(fpdu, 0, sizeof(*fpdu)); + break; + } + + mpa_buf->tcp_payload_len -= fpdu->fpdu_length; + curr_pkt->first_mpa_offset += fpdu->fpdu_length; + break; + case QED_IWARP_MPA_PKT_UNALIGNED: + rc = qed_iwarp_send_fpdu(p_hwfn, fpdu, curr_pkt, buf, + mpa_buf->tcp_payload_len, + pkt_type); + if (rc) { + DP_VERBOSE(p_hwfn, QED_MSG_RDMA, + "Can't send FPDU:delay rc=%d\n", rc); + /* don't reset fpdu -> we need it for next + * classify + */ + break; + } + + mpa_buf->tcp_payload_len -= fpdu->incomplete_bytes; + curr_pkt->first_mpa_offset += fpdu->incomplete_bytes; + /* The framed PDU was sent - no more incomplete bytes */ + fpdu->incomplete_bytes = 0; + break; + } + } while (mpa_buf->tcp_payload_len && !rc); + + return rc; + +err: qed_iwarp_ll2_post_rx(p_hwfn, buf, p_hwfn->p_rdma_info->iwarp.ll2_mpa_handle); @@ -1989,11 +2222,27 @@ static void qed_iwarp_ll2_rel_tx_pkt(void *cxt, u8 connection_handle, kfree(buffer); } +/* The only slowpath for iwarp ll2 is unalign flush. When this completion + * is received, need to reset the FPDU. + */ void qed_iwarp_ll2_slowpath(void *cxt, u8 connection_handle, u32 opaque_data_0, u32 opaque_data_1) { + struct unaligned_opaque_data unalign_data; + struct qed_hwfn *p_hwfn = cxt; + struct qed_iwarp_fpdu *fpdu; + + qed_iwarp_mpa_get_data(p_hwfn, &unalign_data, + opaque_data_0, opaque_data_1); + + DP_VERBOSE(p_hwfn, QED_MSG_RDMA, "(0x%x) Flush fpdu\n", + unalign_data.cid); + + fpdu = qed_iwarp_get_curr_fpdu(p_hwfn, (u16)unalign_data.cid); + if (fpdu) + memset(fpdu, 0, sizeof(*fpdu)); } static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) @@ -2194,6 +2443,14 @@ static int qed_iwarp_ll2_stop(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) iwarp_info->ll2_mpa_handle); if (rc) goto err; + + iwarp_info->partial_fpdus = kcalloc((u16)p_hwfn->p_rdma_info->num_qps, + sizeof(*iwarp_info->partial_fpdus), + GFP_KERNEL); + if (!iwarp_info->partial_fpdus) + goto err; + + iwarp_info->max_num_partial_fpdus = (u16)p_hwfn->p_rdma_info->num_qps; /* The mpa_bufs array serves for pending RX packets received on the * mpa ll2 that don't have place on the tx ring and require later * processing. We can't fail on allocation of such a struct therefore diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h index 2c53fe4..858755c 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.h @@ -68,6 +68,17 @@ struct qed_iwarp_ll2_mpa_buf { u8 placement_offset; }; +struct qed_iwarp_fpdu { + struct qed_iwarp_ll2_buff *mpa_buf; + void *mpa_frag_virt; + dma_addr_t mpa_frag; + dma_addr_t pkt_hdr; + u16 mpa_frag_len; + u16 fpdu_length; + u16 incomplete_bytes; + u8 pkt_hdr_size; +}; + struct qed_iwarp_info { struct list_head listen_list; /* qed_iwarp_listener */ struct list_head ep_list; /* qed_iwarp_ep */ @@ -87,7 +98,9 @@ struct qed_iwarp_info { u8 peer2peer; enum mpa_negotiation_mode mpa_rev; enum mpa_rtr_type rtr_type; + struct qed_iwarp_fpdu *partial_fpdus; struct qed_iwarp_ll2_mpa_buf *mpa_bufs; + u16 max_num_partial_fpdus; }; enum qed_iwarp_ep_state {