From patchwork Sat Mar 31 17:54:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Chan X-Patchwork-Id: 893852 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=broadcom.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=broadcom.com header.i=@broadcom.com header.b="Dc+OcnSg"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40D5kk4J8Pz9s1S for ; Sun, 1 Apr 2018 03:55:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753335AbeCaRzs (ORCPT ); Sat, 31 Mar 2018 13:55:48 -0400 Received: from mail-pf0-f193.google.com ([209.85.192.193]:38578 "EHLO mail-pf0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753222AbeCaRzI (ORCPT ); Sat, 31 Mar 2018 13:55:08 -0400 Received: by mail-pf0-f193.google.com with SMTP id y69so7373870pfb.5 for ; Sat, 31 Mar 2018 10:55:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=roJfpKxKxUOkjJyjvP1EZd8kWw1R8WXw3V8y/ZGzVCM=; b=Dc+OcnSgTPKfLxzV6bZPdEPVP5zvXzXaOSHuR1r770BrT0DAtZS7XFV8tzu0XwrXpi ZDbrOlZww8/p7gBiTbVvF1/6V7NjUW63icPDJrBjDxxPFni6j61Q8NK4/Q5YTsCIMEAm nwOBaM3p26GCIF58KJUkqh/kZy/sC3R8QXNXI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=roJfpKxKxUOkjJyjvP1EZd8kWw1R8WXw3V8y/ZGzVCM=; b=MERW5AhiYni3xtoN48oYrs4VfGH16kYaXhsRSoRPAF7ryrfr5LG8Lty1240nkqbEbJ FoH3xh9SU6gabYHnEnBslhKVBuZD2HBFkIwgAVRCuyezSLRSpFrQJV74H8cwa2khbo4H ir/Ex3p/Cc7ktWvHdmKpv7a5TRXpUWS/al90CmnbzjapsSGoXMlmPek9PPO6Et5hiYBa FuezcU82dOatC33NIPZpFu0BUZDjgn6kkW8UxZpGP87i/3MNYWMQ14h24OuWd/nv9dP9 bXbu/7qlz2LkD7VKsusR/m7ldO6lyHU/4AOFfHHMDP0hVBNLxBLBI2L0qE20bgiR1w33 3CIg== X-Gm-Message-State: AElRT7HmOK5DIaPwEVhViirfDgWkEFp/8A9TQ1t+TaTFfzhE7PyxYuFe klobsKj9oD4E19oHedJL8gWydeYoofA= X-Google-Smtp-Source: AIpwx4/mIoc9x7dlfSNZ91roVybY1K8Ma/3XW33Yz54caQkIwatItNdkDoieLXZ98RC9mtIoj6WJHA== X-Received: by 2002:a17:902:8:: with SMTP id 8-v6mr3673885pla.291.1522518908281; Sat, 31 Mar 2018 10:55:08 -0700 (PDT) Received: from localhost.dhcp.broadcom.net ([192.19.223.250]) by smtp.gmail.com with ESMTPSA id l80sm25512831pfk.73.2018.03.31.10.55.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 31 Mar 2018 10:55:07 -0700 (PDT) From: Michael Chan To: davem@davemloft.net Cc: netdev@vger.kernel.org Subject: [PATCH net-next 10/16] bnxt_en: Improve valid bit checking in firmware response message. Date: Sat, 31 Mar 2018 13:54:15 -0400 Message-Id: <1522518861-9845-11-git-send-email-michael.chan@broadcom.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1522518861-9845-1-git-send-email-michael.chan@broadcom.com> References: <1522518861-9845-1-git-send-email-michael.chan@broadcom.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When firmware sends a DMA response to the driver, the last byte of the message will be set to 1 to indicate that the whole response is valid. The driver waits for the message to be valid before reading the message. The firmware spec allows these response messages to increase in length by adding new fields to the end of these messages. The older spec's valid location may become a new field in a newer spec. To guarantee compatibility, the driver should zero the valid byte before interpreting the entire message so that any new fields not implemented by the older spec will be read as zero. For messages that are forwarded to VFs, we need to set the length and re-instate the valid bit so the VF will see the valid response. Signed-off-by: Michael Chan --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 21 ++++++++++++++++----- drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 2 ++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 62b7d69c..6fcf4dc 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3422,7 +3422,8 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len, int i, intr_process, rc, tmo_count; struct input *req = msg; u32 *data = msg; - __le32 *resp_len, *valid; + __le32 *resp_len; + u8 *valid; u16 cp_ring_id, len = 0; struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr; u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN; @@ -3474,6 +3475,7 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len, i = 0; tmo_count = timeout * 40; + resp_len = bp->hwrm_cmd_resp_addr + HWRM_RESP_LEN_OFFSET; if (intr_process) { /* Wait until hwrm response cmpl interrupt is processed */ while (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID && @@ -3486,9 +3488,11 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len, le16_to_cpu(req->req_type)); return -1; } + len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >> + HWRM_RESP_LEN_SFT; + valid = bp->hwrm_cmd_resp_addr + len - 1; } else { /* Check if response len is updated */ - resp_len = bp->hwrm_cmd_resp_addr + HWRM_RESP_LEN_OFFSET; for (i = 0; i < tmo_count; i++) { len = (le32_to_cpu(*resp_len) & HWRM_RESP_LEN_MASK) >> HWRM_RESP_LEN_SFT; @@ -3504,10 +3508,12 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len, return -1; } - /* Last word of resp contains valid bit */ - valid = bp->hwrm_cmd_resp_addr + len - 4; + /* Last byte of resp contains valid bit */ + valid = bp->hwrm_cmd_resp_addr + len - 1; for (i = 0; i < 5; i++) { - if (le32_to_cpu(*valid) & HWRM_RESP_VALID_MASK) + /* make sure we read from updated DMA memory */ + dma_rmb(); + if (*valid) break; udelay(1); } @@ -3520,6 +3526,11 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len, } } + /* Zero valid bit for compatibility. Valid bit in an older spec + * may become a new field in a newer spec. We must make sure that + * a new field not implemented by old spec will read zero. + */ + *valid = 0; rc = le16_to_cpu(resp->error_code); if (rc && !silent) netdev_err(bp->dev, "hwrm req_type 0x%x seq id 0x%x error 0x%x\n", diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index 4fa4761..f952963 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -974,7 +974,9 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf) memcpy(&phy_qcfg_resp, &bp->link_info.phy_qcfg_resp, sizeof(phy_qcfg_resp)); mutex_unlock(&bp->hwrm_cmd_lock); + phy_qcfg_resp.resp_len = cpu_to_le16(sizeof(phy_qcfg_resp)); phy_qcfg_resp.seq_id = phy_qcfg_req->seq_id; + phy_qcfg_resp.valid = 1; if (vf->flags & BNXT_VF_LINK_UP) { /* if physical link is down, force link up on VF */