From patchwork Wed Oct 11 20:36:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Madhani, Himanshu" X-Patchwork-Id: 10000629 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 EF4FF6037F for ; Wed, 11 Oct 2017 20:37:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E134828B4B for ; Wed, 11 Oct 2017 20:37:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D4EE228B69; Wed, 11 Oct 2017 20:37:10 +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.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI 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 4853728B4B for ; Wed, 11 Oct 2017 20:37:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752697AbdJKUhI (ORCPT ); Wed, 11 Oct 2017 16:37:08 -0400 Received: from mail-co1nam03on0073.outbound.protection.outlook.com ([104.47.40.73]:17744 "EHLO NAM03-CO1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752525AbdJKUhG (ORCPT ); Wed, 11 Oct 2017 16:37:06 -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=DrkiceQIw28ZB+mm7JxcQzr5oPaTXpnhfDhZBiJL12w=; b=ar7a+ZvkDvG6Di7hjkitMrMfcscnQ4uVRVGA2BoQLHnjI/0I1xCi5jgOR45nT4QzwJPCBExau9EV8AinR4RvcAiXAbPyVSZS2vIl/357U0DLG8cHu7GWfYPCT+Gd+o8EwaLTp2PX1R7kyQt7HseswmSEHdgIUkYvAXCOnJ1vuJ4= Received: from CY1PR07CA0020.namprd07.prod.outlook.com (2a01:111:e400:c60a::30) by CY4PR0701MB3809.namprd07.prod.outlook.com (2603:10b6:910:94::27) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.7; Wed, 11 Oct 2017 20:37:05 +0000 Received: from BY2FFO11FD044.protection.gbl (2a01:111:f400:7c0c::160) by CY1PR07CA0020.outlook.office365.com (2a01:111:e400:c60a::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.77.7 via Frontend Transport; Wed, 11 Oct 2017 20:37:04 +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 BY2FFO11FD044.mail.protection.outlook.com (10.1.14.229) 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; Wed, 11 Oct 2017 20:37:04 +0000 Received: from dut1171.mv.qlogic.com (172.29.51.171) by CAEXCH02.caveonetworks.com (10.17.4.29) with Microsoft SMTP Server id 14.2.347.0; Wed, 11 Oct 2017 13:36:51 -0700 Received: from dut1171.mv.qlogic.com (localhost [127.0.0.1]) by dut1171.mv.qlogic.com (8.14.7/8.14.7) with ESMTP id v9BKapvX023680; Wed, 11 Oct 2017 13:36:51 -0700 Received: (from root@localhost) by dut1171.mv.qlogic.com (8.14.7/8.14.7/Submit) id v9BKapc9023679; Wed, 11 Oct 2017 13:36:51 -0700 From: "Madhani, Himanshu" To: , CC: , Subject: [PATCH 4/5] qla2xxx: Changes to support N2N logins Date: Wed, 11 Oct 2017 13:36:49 -0700 Message-ID: <20171011203650.23629-5-himanshu.madhani@cavium.com> X-Mailer: git-send-email 2.12.0 In-Reply-To: <20171011203650.23629-1-himanshu.madhani@cavium.com> References: <20171011203650.23629-1-himanshu.madhani@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)(346002)(376002)(2980300002)(428002)(189002)(199003)(305945005)(1076002)(16586007)(5003940100001)(575784001)(86362001)(87636003)(478600001)(50466002)(80596001)(2950100002)(105586002)(316002)(106466001)(4326008)(36756003)(110136005)(72206003)(69596002)(42186006)(81166006)(81156014)(47776003)(356003)(50986999)(8676002)(5660300001)(189998001)(33646002)(54906003)(101416001)(48376002)(8936002)(50226002)(76176999)(2906002); DIR:OUT; SFP:1101; SCL:1; SRVR:CY4PR0701MB3809; H:CAEXCH02.caveonetworks.com; FPR:; SPF:None; PTR:50-232-66-26-static.hfc.comcastbusiness.net; MX:1; A:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BY2FFO11FD044; 1:d9OnVDvooV6pW7N8KCFvbwhd+KbproIVepxsUzbKzK2gtUtjxajeWrLrVO1ICS1R2KDUT4RWCsTdpNqAHB4hrFR92Ra8QcVHetGJOwQhtyLHBeYenAyfBpGOo10/RLVV X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 0d5c2379-9ae9-48b5-2e29-08d510e7d558 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075); SRVR:CY4PR0701MB3809; X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3809; 3:edBnPJOcin6duUx6kmMNaD89BJw/Wngb+qdB1v6iZjTKKmNxSdkY+hfD7dHXPhV6gs0SLEM3SmnbZwTxrTXjaIkOXaSR0IaLCSi4xJP3mNEqVadvIpl8MX41Sl/xXnY2JIWOVKJyqTkYRQyK332ZESzFg7eGCqbn1PH648kfu4EklOX74wZOxOr6Qm75HwzmK0QZrZyirjgsaml7lva1lvgxxqg9SenhqvR98s/RtS8M0kbGTUmZ92MemejDw6VoQzHS5TWRnlYaHeKd8ads8Z3z0euK2lx1sUYELkiqkHqMUYwpatneDmpBp0zfAqTVMkUxcZWN1cEEuCzGi4AoRjqPf54rYvp7jXcqeSOMnxI=; 25:ncCQDw/cEVDOaXEVqCMbO8lTenYEo10pfk1x9epVJtMnb1ljS5WuoQpou0XVujTH9l0Dzgojb3zDUP7TuwetE25Vv//CjmHrd0+r0nDjlryY6oFoC+MkpxSviXWTDUG8KU6PLk0eYFYpvouHQNMivsDnx9WVYTTV8rKP+AlW994LNEgs2ETdlKn1YQN1+Co4YX5h8iumnPo49Y3Jj5Z6iYiDw0v9BIzcdmn7qke43MNaWNeSRvbU9/Cuq2sfd9A/YQfNNaG8EcIvI6OgoApqEmHH+L4YJVKrxz9HE4kBaNtGeMlaVCt1TbjGSPw1La5b6UXFEYuCZ43W+o37R3T+kA== X-MS-TrafficTypeDiagnostic: CY4PR0701MB3809: X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3809; 31:WHZCxmZjRS26Fprw9O3eAnlzHsY9DzGEx5QAErfgS3TKFF7H+/jq314xuV10730++3JDZXg7ymDGBNanpSnzpbb7IVbdi4jryL5efVpeHXAvp8fMc2Lcr8uUQGhnEe8sVnmPQ+hAGVqXGSRdHO8ltJVvw9qnv3u5aBJRAiHwiuDB/6KoIy8GUBAlX73xX1uObPezCVr+pCaKISoEfX9vC3lFl25TFBB0GM4708UPEUY=; 20:l41JRcJZAcHMh9fAFzt36yvIkzganqn/I84uVypE6Wk/AZhEchWGWZ18RZkTuJxaC25KoPYVoV2aWyNzaBqtSy0ZIvdodhfmvdOPQex4h4gP7DWcea+fNFN87LasY88mRe3WGcdNcwlYG54xrCQzLFxBiWoG/XWHlqXTJGuOGu7YAt62Msb0SnmBAIzjgcZhtlbl4hsOJwc32X1LuXlaB8julmj6USKk0GcLwfwytai5LiT4hl/FSRFqoSdLo0ZukPPPp+fB4mI+7mFjH6+cQ9JCktf235UD1oRrw8h0Si61ncYQCU9+3Gvv87NZnLFD6cwemCs1YZIZ2i5XyoLYj2Ya+9qf/uZg3Hxyek2plep/+PJla3wxppwGVjFL5jONy1uj8yJz/ClyG/TSi0/X32bsEDCtA6oFcMUzM3rr3Y1NZKUb4Cr/p2fqiMjXyjYYZ9ulSAYApV3hLXB7DL3yDsPMup8nbRdizBrkWqTekUtK3PrXDIKkb3pqFtoBE0um X-Exchange-Antispam-Report-Test: UriScan:(21532816269658); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(100000703101)(100105400095)(6041248)(20161123564025)(20161123558100)(20161123555025)(20161123560025)(20161123562025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:CY4PR0701MB3809; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:CY4PR0701MB3809; X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3809; 4:eXIMqUXQwxv1PHDDDUrN9M+xQ16SoVu1CRMdlmKlPXxiOnNy2RtjHzXVRwbHyXwJBSJ6J9yxMb8p9LjoDG+QbbF5C8fA8J58YhRaMML3o2fXzoC1Cfqh/V4yqnwbwk5kFcRKDaQH+XqlQbi9TnY2cZLSgmAJ6fxxugA0lkC0sqJfuJc/kq3pMKDVX5RisilnMK/ae3IdujQkbNBEOrIpR5nR3JpCxJhQ3mqeRruQcjlcIw7uYsQE1l19UK7DuUWKG47VKNyCslBrXRW+M9S5S0y+md8v5aEs4gWRY0YJIQI= X-Forefront-PRVS: 0457F11EAF X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; CY4PR0701MB3809; 23:EmfY3RqTcIDOdilqZomVdn4R0k+huvE4tNYzGsM?= =?us-ascii?Q?vFyi+6qrLXVT72jkgHMz/kuz02BMaTzwU2GJvyJz6sFzagBFD94X3PpZMziH?= =?us-ascii?Q?djWFVC8eJHYKapA8Aecptm5JliN3qNy0FhXmF1cGPbhsOXbKjgc8CQQJugqH?= =?us-ascii?Q?cesOzaUOTU5egBjVG8aS/KNLpLvIIf41YADWydsgU86C0ZDBxOGEDlSlzssz?= =?us-ascii?Q?PZuQxuLsk1UPawX1NqfOuevxgiLjPs3HIT1NcWK+2YUAk+bX7nbzfdMyaq5I?= =?us-ascii?Q?76dF13jPYi25EWqCa9vtj5u9YMUF1+bkRZCknz4GZt+NvsiDF6La16ytxy3L?= =?us-ascii?Q?TcCbADrgMhBMUtbU88HU2LxwZ8HrtAtAUUZ3Bvf4sFXAI8zoml7xgXW8Oi0w?= =?us-ascii?Q?gB2sW1LodIkT7ZtdIf2/CZM1NaoKCoLX+e7TvtqBIMfZo5AU3WSkpHsJbgvs?= =?us-ascii?Q?AWdHzbN1ppg0Ik+1jTDm6bUj+s2lu8cyr5T/Sle2HmorzGgXtxObZ/p8pjy9?= =?us-ascii?Q?BfU5Xcc1uDlqscOsNxrDqFIerCEihQts9I3pH3H0EU7GCjyLQW10ZsM5cHHB?= =?us-ascii?Q?n8wocgKJ6itIyATpoibsObt4eMI0bILMApk3LJ5rb7MYVVueFdN+/vgDJKme?= =?us-ascii?Q?84fOHyUyK+7rgw0xGil9g6qKUoHAaeND6R/TrApLMdMXSfPU7fw1uNRShfxt?= =?us-ascii?Q?qG/krPMsL2SlIPdUsYYX4Z+4r88QiE3bvcYwrnzp8k50Pc42ckPv2Ykzh8VO?= =?us-ascii?Q?oymmsPTcwpY/yLDk2I46FJBkmUvYdF19xnxCFPA3ZXZ/HMObgbvepM89nuft?= =?us-ascii?Q?y5yyBxtS+T2OJpRjsiVN9gShD0WI4h6Z29IJ0RF2V61Q0HUkgw/3Wyo43JP7?= =?us-ascii?Q?0Bp9oIGyDeBJvJeG0NaHoSH3JnLqR1+FV/1lRuFIE2JlJi8Ei2j5akYpkxDG?= =?us-ascii?Q?creIgvooUcWTCBiWTwvekL59yj4zoI23/OkrG8AffNiAA2I+siIDLiHmyFRd?= =?us-ascii?Q?RMM4s/xuyfOU125PSNU+w4m7dbh4IFj3WwVcAdINPveQRcQ=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY4PR0701MB3809; 6:tGqqK3isFYTDaszMiaUq/aQZwtcyjG3BxrYjMLLUfouf5QecQa+w5Q9LEGiBU4T70SKWPQCrijRJj2iLPmORtd0Sr7sWtYb3Y9Zdhr6xUaKAqx3sRiqjGB/nuqJrfJymJwMp5j8+2lODnowCKQCcl/T9L+eng5gWJJp+aS7ejwrHZrJnFf528M1AhH5kuX3/sT182bvnWDvjRiA/FodbXYypUY7x7qAtGgJA2W6O2/3Lx4YE6+Sb+rxMa+f7FMioYJmQRRv2WP3wx2Ypc/pBUC0y01VS2eqXbvwhwUWwY/X4RM7BqCwa2HkDl2G2+2QMF0IALDw7B4MzcRO+35IyiQ==; 5:Ms2/hQ8e0A6EURewjm3VX77tssuaiKkIciqePKPzPbP/QZP7Qo0D/paOQ3MxQzI040vzPeZxJRa7A42bcQSW77qz/BPrfgZJvYFDuEGHTyGHE4sxHcSgZ40Kk/ZjADjsH6YXUwD4HyReLmiXoWLGjyPqFXWo6fdK5S99AlVHz9k=; 24:637nmsISKLJPVjXA/4uEO56ea93OerNB1qIRYl6tFkNrNeSpgPs3r4AYRJ2zbeO5ktkOLJtgb6B7I0WmBhX7dnTYzBpnAidOdrEuWdqVs8Y=; 7:cVP2nAhQY/f2FBczkaqv9ku0QdM7Uno/nxsiZAGagluBoRMFQ1niO/rKn8eJwJK0I1MY068MTCRjEtMqo595utNQCOUUHczTDaDRsnCjuPZR1vMXZhl+vNZPsG2C4WkfvqNvH2O2ldqqbmTLQN8tZwbN0FtNVyAjOgES0cgVm66jWQT8Nx796vx3a158qRsK5XrNGwTbmg5ShJMonNsZzwFPj+zXsPOZK/qi1SQdiYM= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Oct 2017 20:37:04.3424 (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: CY4PR0701MB3809 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Duane Grigsby If we discovered a topology that is N2N then we will issue a login to the target. If our WWPN is bigger than the target's WWPN then we will initiate login, otherwise we will just wait for the target to initiate login. Signed-off-by: Duane Grigsby Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Reviewed-by: Johannes Thumshirn --- drivers/scsi/qla2xxx/qla_def.h | 24 +++++ drivers/scsi/qla2xxx/qla_fw.h | 4 +- drivers/scsi/qla2xxx/qla_gbl.h | 4 + drivers/scsi/qla2xxx/qla_init.c | 135 +++++++++++++++++++++++++++- drivers/scsi/qla2xxx/qla_iocb.c | 195 +++++++++++++++++++++++++++++++++++++--- drivers/scsi/qla2xxx/qla_isr.c | 42 ++++++++- drivers/scsi/qla2xxx/qla_mbx.c | 76 ++++++++++++++++ 7 files changed, 459 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index f712c0cd46d6..01a9b8971e88 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -323,6 +323,12 @@ struct els_logo_payload { uint8_t wwpn[WWN_SIZE]; }; +struct els_plogi_payload { + uint8_t opcode; + uint8_t rsvd[3]; + uint8_t data[112]; +}; + struct ct_arg { void *iocb; u16 nport_handle; @@ -358,6 +364,19 @@ struct srb_iocb { dma_addr_t els_logo_pyld_dma; } els_logo; struct { +#define ELS_DCMD_PLOGI 0x3 + uint32_t flags; + uint32_t els_cmd; + struct completion comp; + struct els_plogi_payload *els_plogi_pyld; + struct els_plogi_payload *els_resp_pyld; + dma_addr_t els_plogi_pyld_dma; + dma_addr_t els_resp_pyld_dma; + uint32_t fw_status[3]; + __le16 comp_status; + __le16 len; + } els_plogi; + struct { /* * Values for flags field below are as * defined in tsk_mgmt_entry struct @@ -2349,6 +2368,7 @@ typedef struct fc_port { uint8_t fc4_type; uint8_t fc4f_nvme; uint8_t scan_state; + uint8_t n2n_flag; unsigned long last_queue_full; unsigned long last_ramp_up; @@ -2372,6 +2392,7 @@ typedef struct fc_port { u8 iocb[IOCB_SIZE]; u8 current_login_state; u8 last_login_state; + struct completion n2n_done; } fc_port_t; #define QLA_FCPORT_SCAN 1 @@ -4228,6 +4249,9 @@ typedef struct scsi_qla_host { wait_queue_head_t fcport_waitQ; wait_queue_head_t vref_waitq; uint8_t min_link_speed_feat; + uint8_t n2n_node_name[WWN_SIZE]; + uint8_t n2n_port_name[WWN_SIZE]; + uint16_t n2n_id; } scsi_qla_host_t; struct qla27xx_image_status { diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index bec641aae7b3..d5cef0727e72 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -753,9 +753,7 @@ struct els_entry_24xx { uint8_t reserved_2; uint8_t port_id[3]; - uint8_t reserved_3; - - uint16_t reserved_4; + uint8_t s_id[3]; uint16_t control_flags; /* Control flags. */ #define ECF_PAYLOAD_DESCR_MASK (BIT_15|BIT_14|BIT_13) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 46c7822c20fc..1e35e961683f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -45,6 +45,8 @@ extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); extern int qla24xx_els_dcmd_iocb(scsi_qla_host_t *, int, port_id_t); +extern int qla24xx_els_dcmd2_iocb(scsi_qla_host_t *, int, fc_port_t *, + port_id_t); extern void qla2x00_update_fcports(scsi_qla_host_t *); @@ -487,6 +489,8 @@ int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t, uint16_t *); int __qla24xx_parse_gpdb(struct scsi_qla_host *, fc_port_t *, struct port_database_24xx *); +int qla24xx_get_port_login_templ(scsi_qla_host_t *, dma_addr_t, + void *, uint16_t); extern int qla27xx_get_zio_threshold(scsi_qla_host_t *, uint16_t *); extern int qla27xx_set_zio_threshold(scsi_qla_host_t *, uint16_t); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 4c53199db371..b2a391f93775 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1433,6 +1433,14 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) qla24xx_post_gpdb_work(vha, ea->fcport, 0); break; default: + if (ea->fcport->n2n_flag) { + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post fc4 prli\n", + __func__, __LINE__, ea->fcport->port_name); + ea->fcport->fc4f_nvme = 0; + ea->fcport->n2n_flag = 0; + qla24xx_post_prli_work(vha, ea->fcport); + } ql_dbg(ql_dbg_disc, vha, 0x2119, "%s %d %8phC unhandle event of %x\n", __func__, __LINE__, ea->fcport->port_name, ea->data[0]); @@ -4366,7 +4374,109 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) return (rval); } +/* + * N2N Login + * Updates Fibre Channel Device Database with local loop devices. + * + * Input: + * ha = adapter block pointer. + * + * Returns: + */ +static int qla24xx_n2n_handle_login(struct scsi_qla_host *vha, + fc_port_t *fcport) +{ + struct qla_hw_data *ha = vha->hw; + int res = QLA_SUCCESS, rval; + int greater_wwpn = 0; + int logged_in = 0; + + if (ha->current_topology != ISP_CFG_N) + return res; + + if (wwn_to_u64(vha->port_name) > + wwn_to_u64(vha->n2n_port_name)) { + ql_dbg(ql_dbg_disc, vha, 0x2002, + "HBA WWPN is greater %llx > target %llx\n", + wwn_to_u64(vha->port_name), + wwn_to_u64(vha->n2n_port_name)); + greater_wwpn = 1; + fcport->d_id.b24 = vha->n2n_id; + } + + fcport->loop_id = vha->loop_id; + fcport->fc4f_nvme = 0; + fcport->query = 1; + + ql_dbg(ql_dbg_disc, vha, 0x4001, + "Initiate N2N login handler: HBA port_id=%06x loopid=%d\n", + fcport->d_id.b24, vha->loop_id); + + /* Fill in member data. */ + if (!greater_wwpn) { + rval = qla2x00_get_port_database(vha, fcport, 0); + ql_dbg(ql_dbg_disc, vha, 0x1051, + "Remote login-state (%x/%x) port_id=%06x loop_id=%x, rval=%d\n", + fcport->current_login_state, fcport->last_login_state, + fcport->d_id.b24, fcport->loop_id, rval); + + if (((fcport->current_login_state & 0xf) == 0x4) || + ((fcport->current_login_state & 0xf) == 0x6)) + logged_in = 1; + } + + if (logged_in || greater_wwpn) { + if (!vha->nvme_local_port && vha->flags.nvme_enabled) + qla_nvme_register_hba(vha); + + /* Set connected N_Port d_id */ + if (vha->flags.nvme_enabled) + fcport->fc4f_nvme = 1; + + fcport->scan_state = QLA_FCPORT_FOUND; + fcport->fw_login_state = DSC_LS_PORT_UNAVAIL; + fcport->disc_state = DSC_GNL; + fcport->n2n_flag = 1; + fcport->flags = 3; + vha->hw->flags.gpsc_supported = 0; + + if (greater_wwpn) { + ql_dbg(ql_dbg_disc, vha, 0x20e5, + "%s %d PLOGI ELS %8phC\n", + __func__, __LINE__, fcport->port_name); + + res = qla24xx_els_dcmd2_iocb(vha, ELS_DCMD_PLOGI, + fcport, fcport->d_id); + } + + if (res != QLA_SUCCESS) { + ql_log(ql_log_info, vha, 0xd04d, + "PLOGI Failed: portid=%06x - retrying\n", + fcport->d_id.b24); + res = QLA_SUCCESS; + } else { + /* State 0x6 means FCP PRLI complete */ + if ((fcport->current_login_state & 0xf) == 0x6) { + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post GPDB work\n", + __func__, __LINE__, fcport->port_name); + fcport->chip_reset = + vha->hw->base_qpair->chip_reset; + qla24xx_post_gpdb_work(vha, fcport, 0); + } else { + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post NVMe PRLI\n", + __func__, __LINE__, fcport->port_name); + qla24xx_post_prli_work(vha, fcport); + } + } + } else { + /* Wait for next database change */ + set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); + } + return res; +} /* * qla2x00_configure_local_loop @@ -4437,6 +4547,14 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) } } + /* Inititae N2N login. */ + if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) { + rval = qla24xx_n2n_handle_login(vha, new_fcport); + if (rval != QLA_SUCCESS) + goto cleanup_allocation; + return QLA_SUCCESS; + } + /* Add devices to port list. */ id_iter = (char *)ha->gid_list; for (index = 0; index < entries; index++) { @@ -4478,10 +4596,13 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) "Failed to retrieve fcport information " "-- get_port_database=%x, loop_id=0x%04x.\n", rval2, new_fcport->loop_id); - ql_dbg(ql_dbg_disc, vha, 0x2105, - "Scheduling resync.\n"); - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); - continue; + /* Skip retry if N2N */ + if (ha->current_topology != ISP_CFG_N) { + ql_dbg(ql_dbg_disc, vha, 0x2105, + "Scheduling resync.\n"); + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + continue; + } } spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); @@ -7554,6 +7675,12 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) if (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha)) icb->firmware_options_3 |= BIT_0; + if (IS_QLA27XX(ha)) { + icb->firmware_options_3 |= BIT_8; + ql_dbg(ql_log_info, vha, 0x0075, + "Enabling direct connection.\n"); + } + if (rval) { ql_log(ql_log_warn, vha, 0x0076, "NVRAM configuration failed.\n"); diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 2f94159186d7..6e57c48f8d95 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2518,6 +2518,7 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) { scsi_qla_host_t *vha = sp->vha; struct srb_iocb *elsio = &sp->u.iocb_cmd; + uint32_t dsd_len = 24; els_iocb->entry_type = ELS_IOCB_TYPE; els_iocb->entry_count = 1; @@ -2534,24 +2535,198 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) els_iocb->port_id[0] = sp->fcport->d_id.b.al_pa; els_iocb->port_id[1] = sp->fcport->d_id.b.area; els_iocb->port_id[2] = sp->fcport->d_id.b.domain; + els_iocb->s_id[0] = vha->d_id.b.al_pa; + els_iocb->s_id[1] = vha->d_id.b.area; + els_iocb->s_id[2] = vha->d_id.b.domain; els_iocb->control_flags = 0; - els_iocb->tx_byte_count = sizeof(struct els_logo_payload); - els_iocb->tx_address[0] = - cpu_to_le32(LSD(elsio->u.els_logo.els_logo_pyld_dma)); - els_iocb->tx_address[1] = - cpu_to_le32(MSD(elsio->u.els_logo.els_logo_pyld_dma)); - els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload)); + if (elsio->u.els_logo.els_cmd == ELS_DCMD_PLOGI) { + els_iocb->tx_byte_count = sizeof(struct els_plogi_payload); + els_iocb->tx_address[0] = + cpu_to_le32(LSD(elsio->u.els_plogi.els_plogi_pyld_dma)); + els_iocb->tx_address[1] = + cpu_to_le32(MSD(elsio->u.els_plogi.els_plogi_pyld_dma)); + els_iocb->tx_len = dsd_len; + + els_iocb->rx_dsd_count = 1; + els_iocb->rx_byte_count = sizeof(struct els_plogi_payload); + els_iocb->rx_address[0] = + cpu_to_le32(LSD(elsio->u.els_plogi.els_resp_pyld_dma)); + els_iocb->rx_address[1] = + cpu_to_le32(MSD(elsio->u.els_plogi.els_resp_pyld_dma)); + els_iocb->rx_len = dsd_len; + ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, + "PLOGI ELS IOCB:\n"); + ql_dump_buffer(ql_log_info, vha, 0x0109, + (uint8_t *)els_iocb, 0x70); + } else { + els_iocb->tx_byte_count = sizeof(struct els_logo_payload); + els_iocb->tx_address[0] = + cpu_to_le32(LSD(elsio->u.els_logo.els_logo_pyld_dma)); + els_iocb->tx_address[1] = + cpu_to_le32(MSD(elsio->u.els_logo.els_logo_pyld_dma)); + els_iocb->tx_len = cpu_to_le32(sizeof(struct els_logo_payload)); - els_iocb->rx_byte_count = 0; - els_iocb->rx_address[0] = 0; - els_iocb->rx_address[1] = 0; - els_iocb->rx_len = 0; + els_iocb->rx_byte_count = 0; + els_iocb->rx_address[0] = 0; + els_iocb->rx_address[1] = 0; + els_iocb->rx_len = 0; + } sp->vha->qla_stats.control_requests++; } static void +qla2x00_els_dcmd2_sp_free(void *data) +{ + srb_t *sp = data; + struct srb_iocb *elsio = &sp->u.iocb_cmd; + + if (elsio->u.els_plogi.els_plogi_pyld) + dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE, + elsio->u.els_plogi.els_plogi_pyld, + elsio->u.els_plogi.els_plogi_pyld_dma); + + if (elsio->u.els_plogi.els_resp_pyld) + dma_free_coherent(&sp->vha->hw->pdev->dev, DMA_POOL_SIZE, + elsio->u.els_plogi.els_resp_pyld, + elsio->u.els_plogi.els_resp_pyld_dma); + + del_timer(&elsio->timer); + qla2x00_rel_sp(sp); +} + +static void +qla2x00_els_dcmd2_iocb_timeout(void *data) +{ + srb_t *sp = data; + fc_port_t *fcport = sp->fcport; + struct scsi_qla_host *vha = sp->vha; + struct qla_hw_data *ha = vha->hw; + struct srb_iocb *lio = &sp->u.iocb_cmd; + unsigned long flags = 0; + int res; + + ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069, + "%s %d ELS Timeout, %8phC hdl=%x, portid=%06x\n", + sp->name, sp->handle, fcport->port_name, fcport->d_id.b24); + + /* Abort the exchange */ + spin_lock_irqsave(&ha->hardware_lock, flags); + res = ha->isp_ops->abort_command(sp); + ql_dbg(ql_dbg_io, vha, 0x3070, + "mbx abort_command %s\n", + (res == QLA_SUCCESS) ? "successful" : "failed"); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + + complete(&lio->u.els_plogi.comp); +} + +static void +qla2x00_els_dcmd2_sp_done(void *ptr, int res) +{ + srb_t *sp = ptr; + fc_port_t *fcport = sp->fcport; + struct srb_iocb *lio = &sp->u.iocb_cmd; + struct scsi_qla_host *vha = sp->vha; + + ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3072, + "%s %s ELS hdl=%x, portid=%06x done %8pC\n", + sp->name, sp->handle, fcport->d_id.b24, fcport->port_name); + + complete(&lio->u.els_plogi.comp); +} + +int +qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, + fc_port_t *fcport, port_id_t remote_did) +{ + srb_t *sp; + struct srb_iocb *elsio = NULL; + struct qla_hw_data *ha = vha->hw; + int rval = QLA_SUCCESS; + void *ptr, *resp_ptr; + dma_addr_t ptr_dma; + + /* Alloc SRB structure */ + sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); + if (!sp) { + ql_log(ql_log_info, vha, 0x70e6, + "SRB allocation failed\n"); + return -ENOMEM; + } + + elsio = &sp->u.iocb_cmd; + fcport->d_id.b.domain = remote_did.b.domain; + fcport->d_id.b.area = remote_did.b.area; + fcport->d_id.b.al_pa = remote_did.b.al_pa; + + ql_dbg(ql_dbg_io, vha, 0x3073, + "Enter: PLOGI portid=%06x\n", fcport->d_id.b24); + + sp->type = SRB_ELS_DCMD; + sp->name = "ELS_DCMD"; + sp->fcport = fcport; + qla2x00_init_timer(sp, ELS_DCMD_TIMEOUT); + elsio->timeout = qla2x00_els_dcmd2_iocb_timeout; + sp->done = qla2x00_els_dcmd2_sp_done; + sp->free = qla2x00_els_dcmd2_sp_free; + + ptr = elsio->u.els_plogi.els_plogi_pyld = + dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE, + &elsio->u.els_plogi.els_plogi_pyld_dma, GFP_KERNEL); + ptr_dma = elsio->u.els_plogi.els_plogi_pyld_dma; + + if (!elsio->u.els_plogi.els_plogi_pyld) { + rval = QLA_FUNCTION_FAILED; + goto out; + } + + resp_ptr = elsio->u.els_plogi.els_resp_pyld = + dma_alloc_coherent(&ha->pdev->dev, DMA_POOL_SIZE, + &elsio->u.els_plogi.els_resp_pyld_dma, GFP_KERNEL); + + if (!elsio->u.els_plogi.els_resp_pyld) { + rval = QLA_FUNCTION_FAILED; + goto out; + } + + ql_dbg(ql_dbg_io, vha, 0x3073, "PLOGI %p %p\n", ptr, resp_ptr); + + memset(ptr, 0, sizeof(struct els_plogi_payload)); + memset(resp_ptr, 0, sizeof(struct els_plogi_payload)); + elsio->u.els_plogi.els_cmd = els_opcode; + elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode; + qla24xx_get_port_login_templ(vha, ptr_dma + 4, + &elsio->u.els_plogi.els_plogi_pyld->data[0], + sizeof(struct els_plogi_payload)); + + ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n"); + ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x0109, + (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70); + + init_completion(&elsio->u.els_plogi.comp); + rval = qla2x00_start_sp(sp); + if (rval != QLA_SUCCESS) { + rval = QLA_FUNCTION_FAILED; + goto out; + } + + ql_dbg(ql_dbg_io, vha, 0x3074, + "%s PLOGI sent, hdl=%x, loopid=%x, portid=%06x\n", + sp->name, sp->handle, fcport->loop_id, fcport->d_id.b24); + + wait_for_completion(&elsio->u.els_plogi.comp); + + if (elsio->u.els_plogi.comp_status != CS_COMPLETE) + rval = QLA_FUNCTION_FAILED; + +out: + sp->free(sp); + return rval; +} + +static void qla24xx_els_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) { struct bsg_job *bsg_job = sp->u.bsg_job; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ab97fb06c239..d06a1a809188 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1041,6 +1041,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) */ atomic_set(&vha->loop_down_timer, 0); if (atomic_read(&vha->loop_state) != LOOP_DOWN && + !ha->flags.n2n_ae && atomic_read(&vha->loop_state) != LOOP_DEAD) { ql_dbg(ql_dbg_async, vha, 0x5011, "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n", @@ -1545,6 +1546,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, uint32_t fw_status[3]; uint8_t* fw_sts_ptr; int res; + struct srb_iocb *els; sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); if (!sp) @@ -1561,10 +1563,14 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, break; case SRB_ELS_DCMD: type = "Driver ELS logo"; - ql_dbg(ql_dbg_user, vha, 0x5047, - "Completing %s: (%p) type=%d.\n", type, sp, sp->type); - sp->done(sp, 0); - return; + if (iocb_type != ELS_IOCB_TYPE) { + ql_dbg(ql_dbg_user, vha, 0x5047, + "Completing %s: (%p) type=%d.\n", + type, sp, sp->type); + sp->done(sp, 0); + return; + } + break; case SRB_CT_PTHRU_CMD: /* borrowing sts_entry_24xx.comp_status. same location as ct_entry_24xx.comp_status @@ -1584,6 +1590,33 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1); fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2); + if (iocb_type == ELS_IOCB_TYPE) { + els = &sp->u.iocb_cmd; + els->u.els_plogi.fw_status[0] = fw_status[0]; + els->u.els_plogi.fw_status[1] = fw_status[1]; + els->u.els_plogi.fw_status[2] = fw_status[2]; + els->u.els_plogi.comp_status = fw_status[0]; + if (comp_status == CS_COMPLETE) { + res = DID_OK << 16; + } else { + if (comp_status == CS_DATA_UNDERRUN) { + res = DID_OK << 16; + els->u.els_plogi.len = + le16_to_cpu(((struct els_sts_entry_24xx *) + pkt)->total_byte_count); + } else { + els->u.els_plogi.len = 0; + res = DID_ERROR << 16; + } + } + ql_log(ql_log_info, vha, 0x503f, + "ELS IOCB Done -%s error hdl=%x comp_status=0x%x error subcode 1=0x%x error subcode 2=0x%x total_byte=0x%x\n", + type, sp->handle, comp_status, fw_status[1], fw_status[2], + le16_to_cpu(((struct els_sts_entry_24xx *) + pkt)->total_byte_count)); + goto els_ct_done; + } + /* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT * fc payload to the caller */ @@ -1631,6 +1664,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, bsg_reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len; bsg_job->reply_len = 0; } +els_ct_done: sp->done(sp, res); } diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 71e56877e1eb..d44f65fe9434 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -1786,6 +1786,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) if (pd == NULL) { ql_log(ql_log_warn, vha, 0x1050, "Failed to allocate port database structure.\n"); + fcport->query = 0; return QLA_MEMORY_ALLOC_FAILED; } @@ -1926,6 +1927,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) gpd_error_out: dma_pool_free(ha->s_dma_pool, pd, pd_dma); + fcport->query = 0; if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_mbx, vha, 0x1052, @@ -3762,6 +3764,38 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, rptid_entry->vp_status, rptid_entry->port_id[2], rptid_entry->port_id[1], rptid_entry->port_id[0]); + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: Remote WWPN %8phC.\n", + rptid_entry->u.f1.port_name); + + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: WWPN %8phC.\n", + vha->port_name); + + /* N2N. direct connect */ + if (IS_QLA27XX(ha) && + ((rptid_entry->u.f1.flags>>1) & 0x7) == 2) { + /* if our portname is higher then initiate N2N login */ + if (wwn_to_u64(vha->port_name) > + wwn_to_u64(rptid_entry->u.f1.port_name)) { + // ??? qlt_update_host_map(vha, id); + vha->n2n_id = 0x1; + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: Setting n2n_update_needed for id %d\n", + vha->n2n_id); + } else { + ql_dbg(ql_dbg_async, vha, 0x5075, + "Format 1: Remote login - Waiting for WWPN %8phC.\n", + rptid_entry->u.f1.port_name); + } + + memcpy(vha->n2n_port_name, rptid_entry->u.f1.port_name, + WWN_SIZE); + set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); + set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); + set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); + return; + } /* buffer to buffer credit flag */ vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0; @@ -4599,6 +4633,48 @@ qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version) return rval; } +int +qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma, + void *buf, uint16_t bufsiz) +{ + int rval, i; + mbx_cmd_t mc; + mbx_cmd_t *mcp = &mc; + uint32_t *bp; + + if (!IS_FWI2_CAPABLE(vha->hw)) + return QLA_FUNCTION_FAILED; + + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159, + "Entered %s.\n", __func__); + + mcp->mb[0] = MBC_GET_RNID_PARAMS; + mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8; + mcp->mb[2] = MSW(buf_dma); + mcp->mb[3] = LSW(buf_dma); + mcp->mb[6] = MSW(MSD(buf_dma)); + mcp->mb[7] = LSW(MSD(buf_dma)); + mcp->mb[8] = bufsiz/4; + mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; + mcp->in_mb = MBX_1|MBX_0; + mcp->tov = MBX_TOV_SECONDS; + mcp->flags = 0; + rval = qla2x00_mailbox_command(vha, mcp); + + if (rval != QLA_SUCCESS) { + ql_dbg(ql_dbg_mbx, vha, 0x115a, + "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); + } else { + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b, + "Done %s.\n", __func__); + bp = (uint32_t *) buf; + for (i = 0; i < (bufsiz-4)/4; i++, bp++) + *bp = cpu_to_be32(*bp); + } + + return rval; +} + static int qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp) {