From patchwork Fri Dec 8 21:16:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Salil Mehta X-Patchwork-Id: 121239 Delivered-To: patch@linaro.org Received: by 10.140.42.230 with SMTP id c93csp25553qga; Fri, 8 Dec 2017 13:17:57 -0800 (PST) X-Google-Smtp-Source: AGs4zMZZG9CPeFb+u8N+uiE0KN3dlpAkh1NHBGrZXSKjYY7KEvbiDDIzhQ1C7o1irgG9IbNjHawx X-Received: by 10.84.235.11 with SMTP id o11mr10449887plk.5.1512767877306; Fri, 08 Dec 2017 13:17:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512767877; cv=none; d=google.com; s=arc-20160816; b=G54FilbAqv9zlzeWHLy0GtIQxK7X/eVnT88qEQ5qfLlYE7LsyfKw13zPAbrx76yrR3 f8UU84EeQ6PfIURYlnIGvjkeZSEXTBk735KGxvlgY7uxu3vjjQq8VBBltziIocjNQpoG isJWAiTXWlZ9sNO+pKFcwgruwiVsvJ0pNzN9Khc3VAeAZWn2dtl+NrVjhWigyS3bMzLs uu9PEMUfAYkJk84lTQnzbTYMSTNeQUUCgYk9Y0urCJTujy2/2rdsuxfz9L1V7sLeOTuV bYG0BIl1KHVdNJFn/hMhkcmUlqI0AD8xabWTz/8Hw6E/W9yUp9aRjC2CnL00JejG5+Bk nw4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=BONv+KEFzwsbLth+x2dsmPmNrUKKyIFjdTeO/WAbVQw=; b=N+/ttWUAnp4gjm0dnNyfSFkwHUp/aiHqgOPvZwHNwbgSFMAEcPixmeEwMYxmubndEO M6N5Y2EBvWByLRngw1n3o94S+XqRD8JkcfFJSPXLz6U1fljl6ioqpV9QIWB+g16jipak YSRZoAj/Qx3Ic2vSNBQSMUZjpKMdhg/oFejjCQJ8R0rLC7wGDPLyrHA0dw32ewKTwJZO tAblpLGBXE7XpYKbeoUCiBjS8yS4/QprGclJtxYpvndW8PD6z4VB8pm2LaDjCVdBJR1x VX7j+SdXen8/XiB6hCpDyi9p5Udt//A9MHlFpFbuKv1lkP/HjXsch4jISsKisuQ9foL7 azSg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j5si6814902pfk.24.2017.12.08.13.17.57; Fri, 08 Dec 2017 13:17:57 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753525AbdLHVRy (ORCPT + 19 others); Fri, 8 Dec 2017 16:17:54 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:11921 "EHLO szxga04-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752527AbdLHVRt (ORCPT ); Fri, 8 Dec 2017 16:17:49 -0500 Received: from 172.30.72.60 (EHLO DGGEMS401-HUB.china.huawei.com) ([172.30.72.60]) by dggrg04-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id DLW14166; Sat, 09 Dec 2017 05:17:46 +0800 (CST) Received: from S00293818-DELL1.china.huawei.com (10.202.226.117) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.361.1; Sat, 9 Dec 2017 05:17:38 +0800 From: Salil Mehta To: CC: , , , , , , , Subject: [PATCH V2 net-next 2/8] net: hns3: Add mailbox support to VF driver Date: Fri, 8 Dec 2017 21:16:56 +0000 Message-ID: <20171208211702.20104-3-salil.mehta@huawei.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20171208211702.20104-1-salil.mehta@huawei.com> References: <20171208211702.20104-1-salil.mehta@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.226.117] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A0B0206.5A2B017A.00A9, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: a25330ef19f15ee9ca94b9875732c55f Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds the support of the mailbox to the VF driver. The mailbox shall be used as an interface to communicate with the PF driver for various purposes like {set|get} MAC related operations, reset, link status etc. The mailbox supports both synchronous and asynchronous command send to PF driver. Signed-off-by: Salil Mehta Signed-off-by: lipeng --- Patch V2: Addressed some internal commnets Patch V1: Initial Submit --- drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h | 94 +++++++++++ .../ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 188 +++++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c -- 2.7.4 diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h new file mode 100644 index 0000000..5a6ebfca --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016-2017 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __HCLGE_MBX_H +#define __HCLGE_MBX_H +#include +#include +#include + +#define HCLGE_MBX_VF_MSG_DATA_NUM 16 + +enum HCLGE_MBX_OPCODE { + HCLGE_MBX_RESET = 0x01, /* (VF -> PF) assert reset */ + HCLGE_MBX_SET_UNICAST, /* (VF -> PF) set UC addr */ + HCLGE_MBX_SET_MULTICAST, /* (VF -> PF) set MC addr */ + HCLGE_MBX_SET_VLAN, /* (VF -> PF) set VLAN */ + HCLGE_MBX_MAP_RING_TO_VECTOR, /* (VF -> PF) map ring-to-vector */ + HCLGE_MBX_UNMAP_RING_TO_VECTOR, /* (VF -> PF) unamp ring-to-vector */ + HCLGE_MBX_SET_PROMISC_MODE, /* (VF -> PF) set promiscuous mode */ + HCLGE_MBX_SET_MACVLAN, /* (VF -> PF) set unicast filter */ + HCLGE_MBX_API_NEGOTIATE, /* (VF -> PF) negotiate API version */ + HCLGE_MBX_GET_QINFO, /* (VF -> PF) get queue config */ + HCLGE_MBX_GET_TCINFO, /* (VF -> PF) get TC config */ + HCLGE_MBX_GET_RETA, /* (VF -> PF) get RETA */ + HCLGE_MBX_GET_RSS_KEY, /* (VF -> PF) get RSS key */ + HCLGE_MBX_GET_MAC_ADDR, /* (VF -> PF) get MAC addr */ + HCLGE_MBX_PF_VF_RESP, /* (PF -> VF) generate respone to VF */ + HCLGE_MBX_GET_BDNUM, /* (VF -> PF) get BD num */ + HCLGE_MBX_GET_BUFSIZE, /* (VF -> PF) get buffer size */ + HCLGE_MBX_GET_STREAMID, /* (VF -> PF) get stream id */ + HCLGE_MBX_SET_AESTART, /* (VF -> PF) start ae */ + HCLGE_MBX_SET_TSOSTATS, /* (VF -> PF) get tso stats */ + HCLGE_MBX_LINK_STAT_CHANGE, /* (PF -> VF) link status has changed */ + HCLGE_MBX_GET_BASE_CONFIG, /* (VF -> PF) get config */ + HCLGE_MBX_BIND_FUNC_QUEUE, /* (VF -> PF) bind function and queue */ + HCLGE_MBX_GET_LINK_STATUS, /* (VF -> PF) get link status */ + HCLGE_MBX_QUEUE_RESET, /* (VF -> PF) reset queue */ +}; + +/* below are per-VF mac-vlan subcodes */ +enum hclge_mbx_mac_vlan_subcode { + HCLGE_MBX_MAC_VLAN_UC_MODIFY = 0, /* modify UC mac addr */ + HCLGE_MBX_MAC_VLAN_UC_ADD, /* add a new UC mac addr */ + HCLGE_MBX_MAC_VLAN_UC_REMOVE, /* remove a new UC mac addr */ + HCLGE_MBX_MAC_VLAN_MC_MODIFY, /* modify MC mac addr */ + HCLGE_MBX_MAC_VLAN_MC_ADD, /* add new MC mac addr */ + HCLGE_MBX_MAC_VLAN_MC_REMOVE, /* remove MC mac addr */ + HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE, /* config func MTA enable */ +}; + +/* below are per-VF vlan cfg subcodes */ +enum hclge_mbx_vlan_cfg_subcode { + HCLGE_MBX_VLAN_FILTER = 0, /* set vlan filter */ + HCLGE_MBX_VLAN_TX_OFF_CFG, /* set tx side vlan offload */ + HCLGE_MBX_VLAN_RX_OFF_CFG, /* set rx side vlan offload */ +}; + +#define HCLGE_MBX_MAX_MSG_SIZE 16 +#define HCLGE_MBX_MAX_RESP_DATA_SIZE 8 + +struct hclgevf_mbx_resp_status { + struct mutex mbx_mutex; /* protects against contending sync cmd resp */ + u32 origin_mbx_msg; + bool received_resp; + int resp_status; + u8 additional_info[HCLGE_MBX_MAX_RESP_DATA_SIZE]; +}; + +struct hclge_mbx_vf_to_pf_cmd { + u8 rsv; + u8 mbx_src_vfid; /* Auto filled by IMP */ + u8 rsv1[2]; + u8 msg_len; + u8 rsv2[3]; + u8 msg[HCLGE_MBX_MAX_MSG_SIZE]; +}; + +struct hclge_mbx_pf_to_vf_cmd { + u8 dest_vfid; + u8 rsv[3]; + u8 msg_len; + u8 rsv1[3]; + u16 msg[8]; +}; + +#define hclge_mbx_ring_ptr_move_crq(crq) \ + (crq->next_to_use = (crq->next_to_use + 1) % crq->desc_num) +#endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c new file mode 100644 index 0000000..fb3380b --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2016-2017 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "hclge_mbx.h" +#include "hclgevf_main.h" +#include "hnae3.h" + +static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev *hdev) +{ + /* this function should be called with mbx_resp.mbx_mutex held + * to prtect the received_response from race condition + */ + hdev->mbx_resp.received_resp = false; + hdev->mbx_resp.origin_mbx_msg = 0; + hdev->mbx_resp.resp_status = 0; + memset(hdev->mbx_resp.additional_info, 0, HCLGE_MBX_MAX_RESP_DATA_SIZE); +} + +/* hclgevf_get_mbx_resp: used to get a response from PF after VF sends a mailbox + * message to PF. + * @hdev: pointer to struct hclgevf_dev + * @resp_msg: pointer to store the original message type and response status + * @len: the resp_msg data array length. + */ +static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1, + u8 *resp_data, u16 resp_len) +{ +#define HCLGEVF_MAX_TRY_TIMES 500 +#define HCLGEVF_SLEEP_USCOEND 1000 + struct hclgevf_mbx_resp_status *mbx_resp; + u16 r_code0, r_code1; + int i = 0; + + if (resp_len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { + dev_err(&hdev->pdev->dev, + "VF mbx response len(=%d) exceeds maximum(=%d)\n", + resp_len, + HCLGE_MBX_MAX_RESP_DATA_SIZE); + return -EINVAL; + } + + while ((!hdev->mbx_resp.received_resp) && (i < HCLGEVF_MAX_TRY_TIMES)) { + udelay(HCLGEVF_SLEEP_USCOEND); + i++; + } + + if (i >= HCLGEVF_MAX_TRY_TIMES) { + dev_err(&hdev->pdev->dev, + "VF could not get mbx resp(=%d) from PF in %d tries\n", + hdev->mbx_resp.received_resp, i); + return -EIO; + } + + mbx_resp = &hdev->mbx_resp; + r_code0 = (u16)(mbx_resp->origin_mbx_msg >> 16); + r_code1 = (u16)(mbx_resp->origin_mbx_msg & 0xff); + if (resp_data) + memcpy(resp_data, &mbx_resp->additional_info[0], resp_len); + + hclgevf_reset_mbx_resp_status(hdev); + + if (!(r_code0 == code0 && r_code1 == code1 && !mbx_resp->resp_status)) { + dev_err(&hdev->pdev->dev, + "VF could not match resp code(code0=%d,code1=%d), %d", + code0, code1, mbx_resp->resp_status); + return -EIO; + } + + return 0; +} + +int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode, + const u8 *msg_data, u8 msg_len, bool need_resp, + u8 *resp_data, u16 resp_len) +{ + struct hclge_mbx_vf_to_pf_cmd *req; + struct hclgevf_desc desc; + int status; + + req = (struct hclge_mbx_vf_to_pf_cmd *)desc.data; + + /* first two bytes are reserved for code & subcode */ + if (msg_len > (HCLGE_MBX_MAX_MSG_SIZE - 2)) { + dev_err(&hdev->pdev->dev, + "VF send mbx msg fail, msg len %d exceeds max len %d\n", + msg_len, HCLGE_MBX_MAX_MSG_SIZE); + return -EINVAL; + } + + hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false); + req->msg[0] = code; + req->msg[1] = subcode; + memcpy(&req->msg[2], msg_data, msg_len); + + /* synchronous send */ + if (need_resp) { + mutex_lock(&hdev->mbx_resp.mbx_mutex); + hclgevf_reset_mbx_resp_status(hdev); + status = hclgevf_cmd_send(&hdev->hw, &desc, 1); + if (status) { + dev_err(&hdev->pdev->dev, + "VF failed(=%d) to send mbx message to PF\n", + status); + mutex_unlock(&hdev->mbx_resp.mbx_mutex); + return status; + } + + status = hclgevf_get_mbx_resp(hdev, code, subcode, resp_data, + resp_len); + mutex_unlock(&hdev->mbx_resp.mbx_mutex); + } else { + /* asynchronous send */ + status = hclgevf_cmd_send(&hdev->hw, &desc, 1); + if (status) { + dev_err(&hdev->pdev->dev, + "VF failed(=%d) to send mbx message to PF\n", + status); + return status; + } + } + + return status; +} + +void hclgevf_mbx_handler(struct hclgevf_dev *hdev) +{ + struct hclgevf_mbx_resp_status *resp; + struct hclge_mbx_pf_to_vf_cmd *req; + struct hclgevf_cmq_ring *crq; + struct hclgevf_desc *desc; + u16 link_status, flag; + u8 *temp; + int i; + + resp = &hdev->mbx_resp; + crq = &hdev->hw.cmq.crq; + + flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); + while (hnae_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B)) { + desc = &crq->desc[crq->next_to_use]; + req = (struct hclge_mbx_pf_to_vf_cmd *)desc->data; + + switch (req->msg[0]) { + case HCLGE_MBX_PF_VF_RESP: + if (resp->received_resp) + dev_warn(&hdev->pdev->dev, + "VF mbx resp flag not clear(%d)\n", + req->msg[1]); + + resp->origin_mbx_msg = (req->msg[1] << 16); + resp->origin_mbx_msg |= req->msg[2]; + resp->received_resp = true; + + resp->resp_status = req->msg[3]; + + temp = (u8 *)&req->msg[4]; + for (i = 0; i < HCLGE_MBX_MAX_RESP_DATA_SIZE; i++) { + resp->additional_info[i] = *temp; + temp++; + } + break; + case HCLGE_MBX_LINK_STAT_CHANGE: + link_status = le16_to_cpu(req->msg[1]); + + /* update upper layer with new link link status */ + hclgevf_update_link_status(hdev, link_status); + + break; + default: + dev_err(&hdev->pdev->dev, + "VF received unsupported(%d) mbx msg from PF\n", + req->msg[0]); + break; + } + hclge_mbx_ring_ptr_move_crq(crq); + flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); + } + + /* Write back CMDQ_RQ header pointer, M7 need this pointer */ + hclgevf_write_dev(&hdev->hw, HCLGEVF_NIC_CRQ_HEAD_REG, + crq->next_to_use); +} From patchwork Fri Dec 8 21:16:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Salil Mehta X-Patchwork-Id: 121245 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp111qgn; Fri, 8 Dec 2017 13:19:24 -0800 (PST) X-Google-Smtp-Source: AGs4zMbpJhGhDciUmzXtp3NRcb5o68KT7YaWGSuVnpo62Ob4MIu0aMWZKlQ+eoT9LfC7fGYFmv99 X-Received: by 10.84.252.143 with SMTP id y15mr32333807pll.138.1512767963825; Fri, 08 Dec 2017 13:19:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512767963; cv=none; d=google.com; s=arc-20160816; b=kE7qPaEPbQdEFgnfhhS9yAWF4irt/mpsnyN2D50dsQNjuIwr572cXwa+ZbgyRelUjc lgXn6xJAavMZoTE6Om429wRvuqne10pu0xcTvlS0+kCc3pPHZ+EVZGdkrGq098kMLTIu xxvVTLUlMzRzlFHq73ohnk5+GR7XeRd8pj8x8LFH2Y7spCq+16CyZC863rtX+AWqcNNB e6bepbJ5cTTTs/JIgYJbbyOeM6Ue3T4EgftNGxpEYDIMRGm25rEgZQ8qi2Q656UOE5nU gIC2VjYRjzhZdShk7+My3HVY0cUy52yYSp4JlvkQoTEnX7ta5NgiImOFaKVBK1EPV4su GkEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=va21OskEOzsUNGr2HQVpgKe+KACvMFbahs9t4n3LI0g=; b=z6s+y9xt1NKMvNHahvsB8jrDQs34DCi0ZNf87hNhiDS1i6gBCN/9S5YOOaIf8z6oLn bAqy0R3qS8yxTAeTNanyCC5JICvTCWv4zIyPjnKh0kxuy376CtpdqafBKqpM+z90jolO e6Z+B4ttVXI7wbZYz1BSKKAvmKZGXRE6eAb83CiJQfXxsMV4lxYM+V/qWArPE573vnQG 804Y38I6l6Y3Oa4HDYIRp1o0vfA4Jom7Sd0D7yoeFjesVNDSf/KAlFnngM/42iTKGKNR cXRSRXeitKvKr/6NLNWkR2FN1tPpjflx+u3dPj6xvkfuP0uVPtPZlSO4ft8aw+kQf0vo 6XzA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a4si6763908pfj.350.2017.12.08.13.19.23; Fri, 08 Dec 2017 13:19:23 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753875AbdLHVTV (ORCPT + 19 others); Fri, 8 Dec 2017 16:19:21 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:2669 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753022AbdLHVSH (ORCPT ); Fri, 8 Dec 2017 16:18:07 -0500 Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 076F14071CE5F; Sat, 9 Dec 2017 05:17:54 +0800 (CST) Received: from S00293818-DELL1.china.huawei.com (10.202.226.117) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.361.1; Sat, 9 Dec 2017 05:17:47 +0800 From: Salil Mehta To: CC: , , , , , , , Subject: [PATCH V2 net-next 5/8] net: hns3: Unified HNS3 {VF|PF} Ethernet Driver for hip08 SoC Date: Fri, 8 Dec 2017 21:16:59 +0000 Message-ID: <20171208211702.20104-6-salil.mehta@huawei.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20171208211702.20104-1-salil.mehta@huawei.com> References: <20171208211702.20104-1-salil.mehta@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.226.117] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Most of the NAPI handling interface, skb buffer management, management of the RX/TX descriptors, ethool interface etc. has quite a bit of code which is common to VF and PF driver. This patch makes the exisitng PF's HNS3 ENET driver as the common ENET driver for both Virtual & Physical Function. This will help in reduction of redundancy and better management of code. Signed-off-by: Salil Mehta Signed-off-by: lipeng --- drivers/net/ethernet/hisilicon/hns3/Makefile | 6 +++++- drivers/net/ethernet/hisilicon/hns3/hnae3.c | 14 ++++++++++++-- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 7 ++++--- .../hisilicon/hns3/{hns3pf => }/hns3_dcbnl.c | 2 +- .../hisilicon/hns3/{hns3pf => }/hns3_enet.c | 2 ++ .../hisilicon/hns3/{hns3pf => }/hns3_enet.h | 0 .../hisilicon/hns3/{hns3pf => }/hns3_ethtool.c | 22 +++++++++++++++++++++- .../net/ethernet/hisilicon/hns3/hns3pf/Makefile | 5 ----- .../ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 1 + 9 files changed, 46 insertions(+), 13 deletions(-) rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_dcbnl.c (97%) rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_enet.c (99%) rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_enet.h (100%) rename drivers/net/ethernet/hisilicon/hns3/{hns3pf => }/hns3_ethtool.c (97%) -- 2.7.4 diff --git a/drivers/net/ethernet/hisilicon/hns3/Makefile b/drivers/net/ethernet/hisilicon/hns3/Makefile index 244664b..48af9b1 100644 --- a/drivers/net/ethernet/hisilicon/hns3/Makefile +++ b/drivers/net/ethernet/hisilicon/hns3/Makefile @@ -1,8 +1,12 @@ # # Makefile for the HISILICON network device drivers. # - obj-$(CONFIG_HNS3) += hns3pf/ obj-$(CONFIG_HNS3) += hns3vf/ obj-$(CONFIG_HNS3) += hnae3.o + +obj-$(CONFIG_HNS3_ENET) += hns3.o +hns3-objs = hns3_enet.o hns3_ethtool.o + +hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.c b/drivers/net/ethernet/hisilicon/hns3/hnae3.c index 5bcb223..02145f2 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.c +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.c @@ -196,9 +196,18 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) const struct pci_device_id *id; struct hnae3_ae_algo *ae_algo; struct hnae3_client *client; - int ret = 0; + int ret = 0, lock_acquired; + + /* we can get deadlocked if SRIOV is being enabled in context to probe + * and probe gets called again in same context. This can happen when + * pci_enable_sriov() is called to create VFs from PF probes context. + * Therefore, for simplicity uniformly defering further probing in all + * cases where we detect contention. + */ + lock_acquired = mutex_trylock(&hnae3_common_lock); + if (!lock_acquired) + return -EPROBE_DEFER; - mutex_lock(&hnae3_common_lock); list_add_tail(&ae_dev->node, &hnae3_ae_dev_list); /* Check if there are matched ae_algo */ @@ -211,6 +220,7 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev) if (!ae_dev->ops) { dev_err(&ae_dev->pdev->dev, "ae_dev ops are null\n"); + ret = -EOPNOTSUPP; goto out_err; } diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 67c59e1..a9e2b32 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -452,9 +452,10 @@ struct hnae3_unic_private_info { struct hnae3_queue **tqp; /* array base of all TQPs of this instance */ }; -#define HNAE3_SUPPORT_MAC_LOOPBACK 1 -#define HNAE3_SUPPORT_PHY_LOOPBACK 2 -#define HNAE3_SUPPORT_SERDES_LOOPBACK 4 +#define HNAE3_SUPPORT_MAC_LOOPBACK BIT(0) +#define HNAE3_SUPPORT_PHY_LOOPBACK BIT(1) +#define HNAE3_SUPPORT_SERDES_LOOPBACK BIT(2) +#define HNAE3_SUPPORT_VF BIT(3) struct hnae3_handle { struct hnae3_client *client; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c b/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c similarity index 97% rename from drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c rename to drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c index 925619a..eb82700 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_dcbnl.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c @@ -93,7 +93,7 @@ void hns3_dcbnl_setup(struct hnae3_handle *handle) { struct net_device *dev = handle->kinfo.netdev; - if (!handle->kinfo.dcb_ops) + if ((!handle->kinfo.dcb_ops) || (handle->flags & HNAE3_SUPPORT_VF)) return; dev->dcbnl_ops = &hns3_dcbnl_ops; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c similarity index 99% rename from drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c rename to drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 5941509..c2c1323 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -52,6 +52,8 @@ static const struct pci_device_id hns3_pci_tbl[] = { HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_MACSEC), HNAE3_DEV_SUPPORT_ROCE_DCB_BITS}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_VF), 0}, + {PCI_VDEVICE(HUAWEI, HNAE3_DEV_ID_100G_RDMA_DCB_PFC_VF), 0}, /* required last entry */ {0, } }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h similarity index 100% rename from drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_enet.h rename to drivers/net/ethernet/hisilicon/hns3/hns3_enet.h diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c similarity index 97% rename from drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c rename to drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index a21470c..65a69b4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -849,6 +849,21 @@ static int hns3_nway_reset(struct net_device *netdev) return genphy_restart_aneg(phy); } +static const struct ethtool_ops hns3vf_ethtool_ops = { + .get_drvinfo = hns3_get_drvinfo, + .get_ringparam = hns3_get_ringparam, + .set_ringparam = hns3_set_ringparam, + .get_strings = hns3_get_strings, + .get_ethtool_stats = hns3_get_stats, + .get_sset_count = hns3_get_sset_count, + .get_rxnfc = hns3_get_rxnfc, + .get_rxfh_key_size = hns3_get_rss_key_size, + .get_rxfh_indir_size = hns3_get_rss_indir_size, + .get_rxfh = hns3_get_rss, + .set_rxfh = hns3_set_rss, + .get_link_ksettings = hns3_get_link_ksettings, +}; + static const struct ethtool_ops hns3_ethtool_ops = { .self_test = hns3_self_test, .get_drvinfo = hns3_get_drvinfo, @@ -872,5 +887,10 @@ static const struct ethtool_ops hns3_ethtool_ops = { void hns3_ethtool_set_ops(struct net_device *netdev) { - netdev->ethtool_ops = &hns3_ethtool_ops; + struct hnae3_handle *h = hns3_get_handle(netdev); + + if (h->flags & HNAE3_SUPPORT_VF) + netdev->ethtool_ops = &hns3vf_ethtool_ops; + else + netdev->ethtool_ops = &hns3_ethtool_ops; } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile index d2b20d0..d077fa0 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile @@ -8,8 +8,3 @@ obj-$(CONFIG_HNS3_HCLGE) += hclge.o hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o - -obj-$(CONFIG_HNS3_ENET) += hns3.o -hns3-objs = hns3_enet.o hns3_ethtool.o - -hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index a878c63..fdfc8a7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -316,6 +316,7 @@ static int hclgevf_set_handle_info(struct hclgevf_dev *hdev) nic->ae_algo = &ae_algovf; nic->pdev = hdev->pdev; nic->numa_node_mask = hdev->numa_node_mask; + nic->flags |= HNAE3_SUPPORT_VF; if (hdev->ae_dev->dev_type != HNAE3_DEV_KNIC) { dev_err(&hdev->pdev->dev, "unsupported device type %d\n", From patchwork Fri Dec 8 21:17:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Salil Mehta X-Patchwork-Id: 121244 Delivered-To: patch@linaro.org Received: by 10.140.42.230 with SMTP id c93csp26079qga; Fri, 8 Dec 2017 13:18:33 -0800 (PST) X-Google-Smtp-Source: AGs4zMYzNX3ime8EC52ec/sW7cAzmYYcwQQnapxiCKEnaPgik9rk4yW8ftm2g/ctYNg7uV4OsGXV X-Received: by 10.99.127.88 with SMTP id p24mr30949641pgn.98.1512767913639; Fri, 08 Dec 2017 13:18:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512767913; cv=none; d=google.com; s=arc-20160816; b=Xql2g3NMZftlz/FlEEWa1Yq/rkJzGck0ZU0fSBfIjgHJF7QrNfsSIj3pA+citHI1Y9 VqukPCLsnKeTCv/+rPAlmLxo+WWt72jYnbzcOnUbCopDXkyv6K5QynrRVpF4QyGdgyLG LxGl/37zGczYKdmdKMUgHHXUSKz9Bwv8DLEPUuhXlPOC/mzoNStPWpk1o6rhzxEkBL33 /w8Avje1Fv4GgiFTiNC55pWwpXMNC/318LrUcXTMbL4gAL4aKHDfACOb437lYe8wvKVu rEYgU/ZrI0U3pP8XULMvKGFlRCUHT6zYiWzQ7DIJI5frZzNeBZKXff5U1dn9g048/Hnj /5tQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=a90zfwvCVQ+t56I2hKOwC1J7hiDggYxJRUee1qx78ts=; b=bX2PDMeDbeH2B8PyEAWxRb7GBfvQlb4lzKeBwrp6UdI4VP0NBMdkTS9MCzVnyYkxYb zIQk3cSpW/UZ56I0Lb93hsfpkLpilvsvFVi8RLVGAmJQLviA4WPink4XiyWv+hq/BO7C +59MEgaYELOozsPHKdFDeHCfQsZLwZNLKNHiitwmpv8aWeenmvB/B4Id8PjK3c0nkU8o pBieJ2+h52JfpLarYEWnK+MUZYA0xxXv7Vtbvax8vH7qpfvjtvrSz2APiAbQG4RLnKXc az2jbX5uc+mQX6XyMYkluvdQKKkh0e3hEFCjCWSQ1oOFiVe85Nsz9SY18sb/8z2tHPbO ApMg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 73si6827733pfr.73.2017.12.08.13.18.33; Fri, 08 Dec 2017 13:18:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753840AbdLHVSc (ORCPT + 19 others); Fri, 8 Dec 2017 16:18:32 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2274 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753611AbdLHVSN (ORCPT ); Fri, 8 Dec 2017 16:18:13 -0500 Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 2FBFEA45FD124; Sat, 9 Dec 2017 05:17:59 +0800 (CST) Received: from S00293818-DELL1.china.huawei.com (10.202.226.117) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.361.1; Sat, 9 Dec 2017 05:17:49 +0800 From: Salil Mehta To: CC: , , , , , , , Subject: [PATCH V2 net-next 6/8] net: hns3: Add mailbox support to PF driver Date: Fri, 8 Dec 2017 21:17:00 +0000 Message-ID: <20171208211702.20104-7-salil.mehta@huawei.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20171208211702.20104-1-salil.mehta@huawei.com> References: <20171208211702.20104-1-salil.mehta@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.226.117] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Command queue provides the provision of Mailbox command which can be used for communication between PF and VF. PF handles messages from various VFs for fetching various information like, queue, vlan, link status related etc. It also handles the request from various VFs to perform certain privileged operations. This patch adds the support of a message handler for handling such various command requests from VF. Signed-off-by: Salil Mehta Signed-off-by: lipeng --- .../net/ethernet/hisilicon/hns3/hns3pf/Makefile | 2 +- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 1 + .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 2 + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 310 +++++++++++++++++++++ 4 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c -- 2.7.4 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile index d077fa0..393a1b3 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/Makefile @@ -5,6 +5,6 @@ ccflags-y := -Idrivers/net/ethernet/hisilicon/hns3 obj-$(CONFIG_HNS3_HCLGE) += hclge.o -hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o +hclge-objs = hclge_main.o hclge_cmd.o hclge_mdio.o hclge_tm.o hclge_mbx.o hclge-$(CONFIG_HNS3_DCB) += hclge_dcb.o diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index d07c700..980fcdf 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -21,6 +21,7 @@ #include "hclge_cmd.h" #include "hclge_dcb.h" #include "hclge_main.h" +#include "hclge_mbx.h" #include "hclge_mdio.h" #include "hclge_tm.h" #include "hnae3.h" diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index aacec43..028817c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -554,4 +554,6 @@ int hclge_set_vf_vlan_common(struct hclge_dev *vport, int vfid, int hclge_buffer_alloc(struct hclge_dev *hdev); int hclge_rss_init_hw(struct hclge_dev *hdev); + +void hclge_mbx_handler(struct hclge_dev *hdev); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c new file mode 100644 index 0000000..a993735 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2016-2017 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "hclge_main.h" +#include "hclge_mbx.h" +#include "hnae3.h" + +/* hclge_gen_resp_to_vf: used to generate a synchronous response to VF when PF + * receives a mailbox message from VF. + * @vport: pointer to struct hclge_vport + * @vf_to_pf_req: pointer to hclge_mbx_vf_to_pf_cmd of the original mailbox + * message + * @resp_status: indicate to VF whether its request success(0) or failed. + */ +static int hclge_gen_resp_to_vf(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *vf_to_pf_req, + int resp_status, + u8 *resp_data, u16 resp_data_len) +{ + struct hclge_mbx_pf_to_vf_cmd *resp_pf_to_vf; + struct hclge_dev *hdev = vport->back; + enum hclge_cmd_status status; + struct hclge_desc desc; + + resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; + + if (resp_data_len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { + dev_err(&hdev->pdev->dev, + "PF fail to gen resp to VF len %d exceeds max len %d\n", + resp_data_len, + HCLGE_MBX_MAX_RESP_DATA_SIZE); + } + + hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); + + resp_pf_to_vf->dest_vfid = vf_to_pf_req->mbx_src_vfid; + resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len; + + resp_pf_to_vf->msg[0] = HCLGE_MBX_PF_VF_RESP; + resp_pf_to_vf->msg[1] = vf_to_pf_req->msg[0]; + resp_pf_to_vf->msg[2] = vf_to_pf_req->msg[1]; + resp_pf_to_vf->msg[3] = (resp_status == 0) ? 0 : 1; + + if (resp_data && resp_data_len > 0) + memcpy(&resp_pf_to_vf->msg[4], resp_data, resp_data_len); + + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) + dev_err(&hdev->pdev->dev, + "PF failed(=%d) to send response to VF\n", status); + + return status; +} + +static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, + u16 mbx_opcode, u8 dest_vfid) +{ + struct hclge_mbx_pf_to_vf_cmd *resp_pf_to_vf; + struct hclge_dev *hdev = vport->back; + enum hclge_cmd_status status; + struct hclge_desc desc; + + resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; + + hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); + + resp_pf_to_vf->dest_vfid = dest_vfid; + resp_pf_to_vf->msg_len = msg_len; + resp_pf_to_vf->msg[0] = mbx_opcode; + + memcpy(&resp_pf_to_vf->msg[1], msg, msg_len); + + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) + dev_err(&hdev->pdev->dev, + "PF failed(=%d) to send mailbox message to VF\n", + status); + + return status; +} + +static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *req) +{ + bool en = req->msg[1] ? true : false; + struct hclge_promisc_param param; + + /* always enable broadcast promisc bit */ + hclge_promisc_param_init(¶m, en, en, true, vport->vport_id); + return hclge_cmd_set_promisc_mode(vport->back, ¶m); +} + +static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + bool gen_resp) +{ + const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); + struct hclge_dev *hdev = vport->back; + int status; + + if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_MODIFY) { + const u8 *old_addr = (const u8 *)(&mbx_req->msg[8]); + + hclge_rm_uc_addr_common(vport, old_addr); + status = hclge_add_uc_addr_common(vport, mac_addr); + } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) { + status = hclge_add_uc_addr_common(vport, mac_addr); + } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { + status = hclge_rm_uc_addr_common(vport, mac_addr); + } else { + dev_err(&hdev->pdev->dev, + "failed to set unicast mac addr, unknown subcode %d\n", + mbx_req->msg[1]); + return -EIO; + } + + if (gen_resp) + hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); + + return 0; +} + +static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + bool gen_resp) +{ + const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); + struct hclge_dev *hdev = vport->back; + int status; + + if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_ADD) { + status = hclge_add_mc_addr_common(vport, mac_addr); + } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_REMOVE) { + status = hclge_rm_mc_addr_common(vport, mac_addr); + } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE) { + u8 func_id = vport->vport_id; + bool enable = mbx_req->msg[2]; + + status = hclge_cfg_func_mta_filter(hdev, func_id, enable); + } else { + dev_err(&hdev->pdev->dev, + "failed to set mcast mac addr, unknown subcode %d\n", + mbx_req->msg[1]); + return -EIO; + } + + if (gen_resp) + hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); + + return 0; +} + +static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + bool gen_resp) +{ + struct hclge_dev *hdev = vport->back; + int status = 0; + + if (mbx_req->msg[1] == HCLGE_MBX_VLAN_FILTER) { + u16 vlan, proto; + bool is_kill; + + is_kill = !!mbx_req->msg[2]; + memcpy(&vlan, &mbx_req->msg[3], sizeof(vlan)); + memcpy(&proto, &mbx_req->msg[5], sizeof(proto)); + status = hclge_set_vf_vlan_common(hdev, vport->vport_id, + is_kill, vlan, 0, + cpu_to_be16(proto)); + } + + if (gen_resp) + status = hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); + + return status; +} + +static int hclge_get_vf_tcinfo(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + bool gen_resp) +{ + struct hclge_dev *hdev = vport->back; + int ret; + + ret = hclge_gen_resp_to_vf(vport, mbx_req, 0, &hdev->hw_tc_map, + sizeof(u8)); + + return ret; +} + +static int hclge_get_vf_queue_info(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req, + bool gen_resp) +{ +#define HCLGE_TQPS_RSS_INFO_LEN 8 + u8 resp_data[HCLGE_TQPS_RSS_INFO_LEN]; + struct hclge_dev *hdev = vport->back; + + /* get the queue related info */ + memcpy(&resp_data[0], &vport->alloc_tqps, sizeof(u16)); + memcpy(&resp_data[2], &hdev->rss_size_max, sizeof(u16)); + memcpy(&resp_data[4], &hdev->num_desc, sizeof(u16)); + memcpy(&resp_data[6], &hdev->rx_buf_len, sizeof(u16)); + + return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, + HCLGE_TQPS_RSS_INFO_LEN); +} + +static int hclge_get_link_info(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req) +{ + struct hclge_dev *hdev = vport->back; + u16 link_status; + u8 msg_data[2]; + u8 dest_vfid; + + /* mac.link can only be 0 or 1 */ + link_status = (u16)hdev->hw.mac.link; + memcpy(&msg_data[0], &link_status, sizeof(u16)); + dest_vfid = mbx_req->mbx_src_vfid; + + /* send this requested info to VF */ + return hclge_send_mbx_msg(vport, msg_data, sizeof(u8), + HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid); +} + +void hclge_mbx_handler(struct hclge_dev *hdev) +{ + struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq; + struct hclge_mbx_vf_to_pf_cmd *req; + struct hclge_vport *vport; + struct hclge_desc *desc; + int ret; + + /* handle all the mailbox requests in the queue */ + while (hnae_get_bit(crq->desc[crq->next_to_use].flag, + HCLGE_CMDQ_RX_OUTVLD_B)) { + desc = &crq->desc[crq->next_to_use]; + req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data; + + vport = &hdev->vport[req->mbx_src_vfid]; + + switch (req->msg[0]) { + case HCLGE_MBX_SET_PROMISC_MODE: + ret = hclge_set_vf_promisc_mode(vport, req); + if (ret) + dev_err(&hdev->pdev->dev, + "PF fail(%d) to set VF promisc mode\n", + ret); + break; + case HCLGE_MBX_SET_UNICAST: + ret = hclge_set_vf_uc_mac_addr(vport, req, false); + if (ret) + dev_err(&hdev->pdev->dev, + "PF fail(%d) to set VF UC MAC Addr\n", + ret); + break; + case HCLGE_MBX_SET_MULTICAST: + ret = hclge_set_vf_mc_mac_addr(vport, req, false); + if (ret) + dev_err(&hdev->pdev->dev, + "PF fail(%d) to set VF MC MAC Addr\n", + ret); + break; + case HCLGE_MBX_SET_VLAN: + ret = hclge_set_vf_vlan_cfg(vport, req, false); + if (ret) + dev_err(&hdev->pdev->dev, + "PF failed(%d) to config VF's VLAN\n", + ret); + break; + case HCLGE_MBX_GET_QINFO: + ret = hclge_get_vf_queue_info(vport, req, true); + if (ret) + dev_err(&hdev->pdev->dev, + "PF failed(%d) to get Q info for VF\n", + ret); + break; + case HCLGE_MBX_GET_TCINFO: + ret = hclge_get_vf_tcinfo(vport, req, true); + if (ret) + dev_err(&hdev->pdev->dev, + "PF failed(%d) to get TC info for VF\n", + ret); + break; + case HCLGE_MBX_GET_LINK_STATUS: + ret = hclge_get_link_info(vport, req); + if (ret) + dev_err(&hdev->pdev->dev, + "PF fail(%d) to get link stat for VF\n", + ret); + break; + default: + dev_err(&hdev->pdev->dev, + "un-supported mailbox message, code = %d\n", + req->msg[0]); + break; + } + hclge_mbx_ring_ptr_move_crq(crq); + } + + /* Write back CMDQ_RQ header pointer, M7 need this pointer */ + hclge_write_dev(&hdev->hw, HCLGE_NIC_CRQ_HEAD_REG, crq->next_to_use); +} From patchwork Fri Dec 8 21:17:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Salil Mehta X-Patchwork-Id: 121243 Delivered-To: patch@linaro.org Received: by 10.140.42.230 with SMTP id c93csp26053qga; Fri, 8 Dec 2017 13:18:30 -0800 (PST) X-Google-Smtp-Source: AGs4zMYSx0oN61FFQOOacUcpAqAgNXuUwu4Vj+Q+9QC0gC7ExkhcUhe1ae7i6x52uWFfA0AYajaN X-Received: by 10.101.92.74 with SMTP id v10mr30935051pgr.193.1512767910865; Fri, 08 Dec 2017 13:18:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512767910; cv=none; d=google.com; s=arc-20160816; b=mrkTkhFONx+PO66jpZXBCf3JDcnseiyzYr9Naic1CzDQbgOBJCfn4+wjFung982S9r XJpBpnoN0ANshlBKi6gmd86FH3cjf7zW4Vz7dbSDKYD6Q9zsQrhuSOdooGaBvv3a435d KBMRkoxQxsY0WbztrOHBurIGCsZDFUc3Srjaprds80Wc6a1y8VNs4OBQTX4UDjml/83l Nj5CwiRQPfrezmmPGH53EhrJ3j04/XOt//ELo3gHa2GyWFheLXdmlEF5BCW56qpokx+j QvGnIwvCrvkOWnUmxiTQ33+LeEPdc+p67Bi/n2ZMyKCzs3B44wtrmJhF+MaXCgek0+e4 U9cg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=MlgNcO4Ch+3V6XQ2SqqMFxjoHgAJpCizuxUTszrJekg=; b=eXz0QbSLMcJLnwwKLLspA57RNLlIRhPeFjtwrPyyv8wcG90D6Ja+Bw5sCRYsJHhhMY Didjz6K9zxy5ikGVMsDBmF8gBsTejs4mAeQcwLQReGXgq/ivVIzbL1LQBuBG41NJiBvr E4sXF7+KoYCoABftjqr8ExnR3mNCGBHP8qM5SdH7sJhxEkFALeADkxMCULzehSUWs0Wi HIRywu07hxDrJeuw3xiHrveWrznGGcaUmO29T/K8qpoyHyPj2wULRTW9Jpz58F8kGnK0 Vz7K2EdoRgjLKuQAP4DHdsOly4/U432j14WSbBpNKt09o4YCBzoeQhtDicaouBIB9L+r Osjw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 73si6827733pfr.73.2017.12.08.13.18.30; Fri, 08 Dec 2017 13:18:30 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753803AbdLHVS3 (ORCPT + 19 others); Fri, 8 Dec 2017 16:18:29 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2273 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753198AbdLHVSN (ORCPT ); Fri, 8 Dec 2017 16:18:13 -0500 Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 4016788999DE; Sat, 9 Dec 2017 05:17:59 +0800 (CST) Received: from S00293818-DELL1.china.huawei.com (10.202.226.117) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.361.1; Sat, 9 Dec 2017 05:17:52 +0800 From: Salil Mehta To: CC: , , , , , , , Subject: [PATCH V2 net-next 7/8] net: hns3: Change PF to add ring-vect binding & resetQ to mailbox Date: Fri, 8 Dec 2017 21:17:01 +0000 Message-ID: <20171208211702.20104-8-salil.mehta@huawei.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20171208211702.20104-1-salil.mehta@huawei.com> References: <20171208211702.20104-1-salil.mehta@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.226.117] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch is required to support ring-vector binding and reset of TQPs requested by the VF driver to the PF driver. Mailbox handler is added with corresponding VF commands/messages to handle the request. Signed-off-by: Salil Mehta Signed-off-by: lipeng --- Patch V2: Addressed some internal comments Patch V1: Initial Submit --- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 138 +++++++-------------- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 7 +- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c | 106 ++++++++++++++++ 3 files changed, 159 insertions(+), 92 deletions(-) -- 2.7.4 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 980fcdf..3b1fc49 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -3256,49 +3256,48 @@ int hclge_rss_init_hw(struct hclge_dev *hdev) return ret; } -int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector_id, - struct hnae3_ring_chain_node *ring_chain) +int hclge_bind_ring_with_vector(struct hclge_vport *vport, + int vector_id, bool en, + struct hnae3_ring_chain_node *ring_chain) { struct hclge_dev *hdev = vport->back; - struct hclge_ctrl_vector_chain_cmd *req; struct hnae3_ring_chain_node *node; struct hclge_desc desc; - int ret; + struct hclge_ctrl_vector_chain_cmd *req + = (struct hclge_ctrl_vector_chain_cmd *)desc.data; + enum hclge_cmd_status status; + enum hclge_opcode_type op; + u16 tqp_type_and_id; int i; - hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ADD_RING_TO_VECTOR, false); - - req = (struct hclge_ctrl_vector_chain_cmd *)desc.data; + op = en ? HCLGE_OPC_ADD_RING_TO_VECTOR : HCLGE_OPC_DEL_RING_TO_VECTOR; + hclge_cmd_setup_basic_desc(&desc, op, false); req->int_vector_id = vector_id; i = 0; for (node = ring_chain; node; node = node->next) { - u16 type_and_id = 0; - - hnae_set_field(type_and_id, HCLGE_INT_TYPE_M, HCLGE_INT_TYPE_S, + tqp_type_and_id = le16_to_cpu(req->tqp_type_and_id[i]); + hnae_set_field(tqp_type_and_id, HCLGE_INT_TYPE_M, + HCLGE_INT_TYPE_S, hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); - hnae_set_field(type_and_id, HCLGE_TQP_ID_M, HCLGE_TQP_ID_S, - node->tqp_index); - hnae_set_field(type_and_id, HCLGE_INT_GL_IDX_M, - HCLGE_INT_GL_IDX_S, - hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); - req->tqp_type_and_id[i] = cpu_to_le16(type_and_id); - req->vfid = vport->vport_id; - + hnae_set_field(tqp_type_and_id, HCLGE_TQP_ID_M, + HCLGE_TQP_ID_S, node->tqp_index); + req->tqp_type_and_id[i] = cpu_to_le16(tqp_type_and_id); if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) { req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD; + req->vfid = vport->vport_id; - ret = hclge_cmd_send(&hdev->hw, &desc, 1); - if (ret) { + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) { dev_err(&hdev->pdev->dev, "Map TQP fail, status is %d.\n", - ret); - return ret; + status); + return -EIO; } i = 0; hclge_cmd_setup_basic_desc(&desc, - HCLGE_OPC_ADD_RING_TO_VECTOR, + op, false); req->int_vector_id = vector_id; } @@ -3306,21 +3305,21 @@ int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector_id, if (i > 0) { req->int_cause_num = i; - - ret = hclge_cmd_send(&hdev->hw, &desc, 1); - if (ret) { + req->vfid = vport->vport_id; + status = hclge_cmd_send(&hdev->hw, &desc, 1); + if (status) { dev_err(&hdev->pdev->dev, - "Map TQP fail, status is %d.\n", ret); - return ret; + "Map TQP fail, status is %d.\n", status); + return -EIO; } } return 0; } -static int hclge_map_handle_ring_to_vector( - struct hnae3_handle *handle, int vector, - struct hnae3_ring_chain_node *ring_chain) +static int hclge_map_ring_to_vector(struct hnae3_handle *handle, + int vector, + struct hnae3_ring_chain_node *ring_chain) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -3329,24 +3328,20 @@ static int hclge_map_handle_ring_to_vector( vector_id = hclge_get_vector_index(hdev, vector); if (vector_id < 0) { dev_err(&hdev->pdev->dev, - "Get vector index fail. ret =%d\n", vector_id); + "Get vector index fail. vector_id =%d\n", vector_id); return vector_id; } - return hclge_map_vport_ring_to_vector(vport, vector_id, ring_chain); + return hclge_bind_ring_with_vector(vport, vector_id, true, ring_chain); } -static int hclge_unmap_ring_from_vector( - struct hnae3_handle *handle, int vector, - struct hnae3_ring_chain_node *ring_chain) +static int hclge_unmap_ring_frm_vector(struct hnae3_handle *handle, + int vector, + struct hnae3_ring_chain_node *ring_chain) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; - struct hclge_ctrl_vector_chain_cmd *req; - struct hnae3_ring_chain_node *node; - struct hclge_desc desc; - int i, vector_id; - int ret; + int vector_id, ret; vector_id = hclge_get_vector_index(hdev, vector); if (vector_id < 0) { @@ -3355,54 +3350,17 @@ static int hclge_unmap_ring_from_vector( return vector_id; } - hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_DEL_RING_TO_VECTOR, false); - - req = (struct hclge_ctrl_vector_chain_cmd *)desc.data; - req->int_vector_id = vector_id; - - i = 0; - for (node = ring_chain; node; node = node->next) { - u16 type_and_id = 0; - - hnae_set_field(type_and_id, HCLGE_INT_TYPE_M, HCLGE_INT_TYPE_S, - hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); - hnae_set_field(type_and_id, HCLGE_TQP_ID_M, HCLGE_TQP_ID_S, - node->tqp_index); - hnae_set_field(type_and_id, HCLGE_INT_GL_IDX_M, - HCLGE_INT_GL_IDX_S, - hnae_get_bit(node->flag, HNAE3_RING_TYPE_B)); - - req->tqp_type_and_id[i] = cpu_to_le16(type_and_id); - req->vfid = vport->vport_id; - - if (++i >= HCLGE_VECTOR_ELEMENTS_PER_CMD) { - req->int_cause_num = HCLGE_VECTOR_ELEMENTS_PER_CMD; - - ret = hclge_cmd_send(&hdev->hw, &desc, 1); - if (ret) { - dev_err(&hdev->pdev->dev, - "Unmap TQP fail, status is %d.\n", - ret); - return ret; - } - i = 0; - hclge_cmd_setup_basic_desc(&desc, - HCLGE_OPC_DEL_RING_TO_VECTOR, - false); - req->int_vector_id = vector_id; - } + ret = hclge_bind_ring_with_vector(vport, vector_id, false, ring_chain); + if (ret) { + dev_err(&handle->pdev->dev, + "Unmap ring from vector fail. vectorid=%d, ret =%d\n", + vector_id, + ret); + return ret; } - if (i > 0) { - req->int_cause_num = i; - - ret = hclge_cmd_send(&hdev->hw, &desc, 1); - if (ret) { - dev_err(&hdev->pdev->dev, - "Unmap TQP fail, status is %d.\n", ret); - return ret; - } - } + /* Free this MSIX or MSI vector */ + hclge_free_vector(hdev, vector_id); return 0; } @@ -4423,7 +4381,7 @@ static int hclge_get_reset_status(struct hclge_dev *hdev, u16 queue_id) return hnae_get_bit(req->ready_to_reset, HCLGE_TQP_RESET_B); } -static void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id) +void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id) { struct hclge_vport *vport = hclge_get_vport(handle); struct hclge_dev *hdev = vport->back; @@ -4995,8 +4953,8 @@ static const struct hnae3_ae_ops hclge_ops = { .uninit_ae_dev = hclge_uninit_ae_dev, .init_client_instance = hclge_init_client_instance, .uninit_client_instance = hclge_uninit_client_instance, - .map_ring_to_vector = hclge_map_handle_ring_to_vector, - .unmap_ring_from_vector = hclge_unmap_ring_from_vector, + .map_ring_to_vector = hclge_map_ring_to_vector, + .unmap_ring_from_vector = hclge_unmap_ring_frm_vector, .get_vector = hclge_get_vector, .set_promisc_mode = hclge_set_promisc_mode, .set_loopback = hclge_set_loopback, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 028817c..c7c9a28 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -539,8 +539,10 @@ int hclge_cfg_func_mta_filter(struct hclge_dev *hdev, u8 func_id, bool enable); struct hclge_vport *hclge_get_vport(struct hnae3_handle *handle); -int hclge_map_vport_ring_to_vector(struct hclge_vport *vport, int vector, - struct hnae3_ring_chain_node *ring_chain); +int hclge_bind_ring_with_vector(struct hclge_vport *vport, + int vector_id, bool en, + struct hnae3_ring_chain_node *ring_chain); + static inline int hclge_get_queue_id(struct hnae3_queue *queue) { struct hclge_tqp *tqp = container_of(queue, struct hclge_tqp, q); @@ -556,4 +558,5 @@ int hclge_buffer_alloc(struct hclge_dev *hdev); int hclge_rss_init_hw(struct hclge_dev *hdev); void hclge_mbx_handler(struct hclge_dev *hdev); +void hclge_reset_tqp(struct hnae3_handle *handle, u16 queue_id); #endif diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index a993735..7a82444 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -85,6 +85,91 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, return status; } +static void hclge_free_vector_ring_chain(struct hnae3_ring_chain_node *head) +{ + struct hnae3_ring_chain_node *chain_tmp, *chain; + + chain = head->next; + + while (chain) { + chain_tmp = chain->next; + kzfree(chain); + chain = chain_tmp; + } +} + +/* hclge_get_ring_chain_from_mbx: get ring type & tqpid from mailbox message + * msg[0]: opcode + * msg[1]: + * msg[2]: ring_num + * msg[3]: first ring type (TX|RX) + * msg[4]: first tqp id + * msg[5] ~ msg[14]: other ring type and tqp id + */ +static int hclge_get_ring_chain_from_mbx( + struct hclge_mbx_vf_to_pf_cmd *req, + struct hnae3_ring_chain_node *ring_chain, + struct hclge_vport *vport) +{ +#define HCLGE_RING_NODE_VARIABLE_NUM 3 +#define HCLGE_RING_MAP_MBX_BASIC_MSG_NUM 3 + struct hnae3_ring_chain_node *cur_chain, *new_chain; + int ring_num; + int i; + + ring_num = req->msg[2]; + + hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]); + ring_chain->tqp_index = + hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]); + + cur_chain = ring_chain; + + for (i = 1; i < ring_num; i++) { + new_chain = kzalloc(sizeof(*new_chain), GFP_KERNEL); + if (!new_chain) + goto err; + + hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B, + req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + + HCLGE_RING_MAP_MBX_BASIC_MSG_NUM]); + + new_chain->tqp_index = + hclge_get_queue_id(vport->nic.kinfo.tqp + [req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i + + HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 1]]); + + cur_chain->next = new_chain; + cur_chain = new_chain; + } + + return 0; +err: + hclge_free_vector_ring_chain(ring_chain); + return -ENOMEM; +} + +static int hclge_map_unmap_ring_to_vf_vector(struct hclge_vport *vport, bool en, + struct hclge_mbx_vf_to_pf_cmd *req) +{ + struct hnae3_ring_chain_node ring_chain; + int vector_id = req->msg[1]; + int ret; + + memset(&ring_chain, 0, sizeof(ring_chain)); + ret = hclge_get_ring_chain_from_mbx(req, &ring_chain, vport); + if (ret) + return ret; + + ret = hclge_bind_ring_with_vector(vport, vector_id, en, &ring_chain); + if (ret) + return ret; + + hclge_free_vector_ring_chain(&ring_chain); + + return 0; +} + static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, struct hclge_mbx_vf_to_pf_cmd *req) { @@ -230,6 +315,16 @@ static int hclge_get_link_info(struct hclge_vport *vport, HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid); } +static void hclge_reset_vf_queue(struct hclge_vport *vport, + struct hclge_mbx_vf_to_pf_cmd *mbx_req) +{ + u16 queue_id; + + memcpy(&queue_id, &mbx_req->msg[0], sizeof(queue_id)); + + hclge_reset_tqp(&vport->nic, queue_id); +} + void hclge_mbx_handler(struct hclge_dev *hdev) { struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq; @@ -247,6 +342,14 @@ void hclge_mbx_handler(struct hclge_dev *hdev) vport = &hdev->vport[req->mbx_src_vfid]; switch (req->msg[0]) { + case HCLGE_MBX_MAP_RING_TO_VECTOR: + ret = hclge_map_unmap_ring_to_vf_vector(vport, true, + req); + break; + case HCLGE_MBX_UNMAP_RING_TO_VECTOR: + ret = hclge_map_unmap_ring_to_vf_vector(vport, false, + req); + break; case HCLGE_MBX_SET_PROMISC_MODE: ret = hclge_set_vf_promisc_mode(vport, req); if (ret) @@ -296,6 +399,9 @@ void hclge_mbx_handler(struct hclge_dev *hdev) "PF fail(%d) to get link stat for VF\n", ret); break; + case HCLGE_MBX_QUEUE_RESET: + hclge_reset_vf_queue(vport, req); + break; default: dev_err(&hdev->pdev->dev, "un-supported mailbox message, code = %d\n", From patchwork Fri Dec 8 21:17:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Salil Mehta X-Patchwork-Id: 121242 Delivered-To: patch@linaro.org Received: by 10.140.42.230 with SMTP id c93csp25822qga; Fri, 8 Dec 2017 13:18:16 -0800 (PST) X-Google-Smtp-Source: AGs4zMb11Dz7VdFUAzA/+a1RH2XjEKtoL7tjxR3So0cDmsPqpqmsrLThZLgMwua8T/rQPS0x8fqm X-Received: by 10.101.101.131 with SMTP id u3mr30740970pgv.76.1512767896823; Fri, 08 Dec 2017 13:18:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512767896; cv=none; d=google.com; s=arc-20160816; b=kIkJVVUnYl8AFvfXDcq9rACPcF39iunhBXG41xmIxAWLPJjYfFWyxJzwSxgs/toANC onKT2oALXTyco3nt2WCx768vkebyy7sXpLetfDVD7jgFgBmLs3EdpGLHci4rlkq2uMn3 FMbiJFQ+GalgErVuRwTv2O/SDwPK5Oe4Q2yhXpYwHYcK8nDSDzPfud7bwkf4Ivs3QOgq o25OBnD4VE8FwEqAQCaZACdVM6iVdVgVD4dVKZ89kmzAku9NQlcLUg6uXpHWMC0N+M2k lucRoPNERpegmQQXXrXir1iVRI+zp7gQsE4LJXdsHfnh7yPol6wV7OHjeVjOYw+gO0MK cgYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=M6BEdfAURU8edRTijOxrDpsbN5dCcMQy9TO8oXr0Ap0=; b=e1mHokGA2gkGP04CPglf75j0Vusx9ltszGPINNHmouNxTHqKcyA7BVs/8g58D8C/mg knC6Bj7nuJJfjpn8xL7h1BOm6XOQ1ddE5az5ZLins+4sCJMnhSTvd2KYrEcknRazqUyg Uy4QYUW+FMcL1LwmozEapOYP+VfktgJKWJ2aI4OkK4Gzug5mAgfHEv08A76puE2XJHdn rPNzwLdCm0N79S1na4f7XFH5L8hDwJCl9S2umACNRQgI+4HD0nezBMuq13/VxXj5qEnI W+cfM/qlUL9WbzGHxGuEpTigmbBRexWBPkEETK3yqYlqEffN5Prz2wrESY+yN1XE1St6 aq7g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j5si6815997pfk.24.2017.12.08.13.18.16; Fri, 08 Dec 2017 13:18:16 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753708AbdLHVSP (ORCPT + 19 others); Fri, 8 Dec 2017 16:18:15 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:11923 "EHLO szxga04-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753591AbdLHVSI (ORCPT ); Fri, 8 Dec 2017 16:18:08 -0500 Received: from 172.30.72.58 (EHLO DGGEMS401-HUB.china.huawei.com) ([172.30.72.58]) by dggrg04-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id DLW14193; Sat, 09 Dec 2017 05:18:06 +0800 (CST) Received: from S00293818-DELL1.china.huawei.com (10.202.226.117) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.361.1; Sat, 9 Dec 2017 05:17:55 +0800 From: Salil Mehta To: CC: , , , , , , , Subject: [PATCH V2 net-next 8/8] net: hns3: Add mailbox interrupt handling to PF driver Date: Fri, 8 Dec 2017 21:17:02 +0000 Message-ID: <20171208211702.20104-9-salil.mehta@huawei.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20171208211702.20104-1-salil.mehta@huawei.com> References: <20171208211702.20104-1-salil.mehta@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.202.226.117] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090206.5A2B018E.0096, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 5c053c3e6ae9a994e2116d3f0cfa30dc Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org All PF mailbox events are conveyed through a common interrupt (vector 0). This interrupt vector is shared by reset and mailbox. This patch adds the handling of mailbox interrupt event and its deferred processing in context to a separate mailbox task. Signed-off-by: Salil Mehta Signed-off-by: lipeng --- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 68 +++++++++++++++++++--- .../ethernet/hisilicon/hns3/hns3pf/hclge_main.h | 8 ++- 2 files changed, 68 insertions(+), 8 deletions(-) -- 2.7.4 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 3b1fc49..e97fd66 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -2227,6 +2227,12 @@ static int hclge_mac_init(struct hclge_dev *hdev) return hclge_cfg_func_mta_filter(hdev, 0, hdev->accept_mta_mc); } +static void hclge_mbx_task_schedule(struct hclge_dev *hdev) +{ + if (!test_and_set_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state)) + schedule_work(&hdev->mbx_service_task); +} + static void hclge_reset_task_schedule(struct hclge_dev *hdev) { if (!test_and_set_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state)) @@ -2372,9 +2378,18 @@ static void hclge_service_complete(struct hclge_dev *hdev) static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) { u32 rst_src_reg; + u32 cmdq_src_reg; /* fetch the events from their corresponding regs */ rst_src_reg = hclge_read_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG); + cmdq_src_reg = hclge_read_dev(&hdev->hw, HCLGE_VECTOR0_CMDQ_SRC_REG); + + /* Assumption: If by any chance reset and mailbox events are reported + * together then we will only process reset event in this go and will + * defer the processing of the mailbox events. Since, we would have not + * cleared RX CMDQ event this time we would receive again another + * interrupt from H/W just for the mailbox. + */ /* check for vector0 reset event sources */ if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & rst_src_reg) { @@ -2395,7 +2410,12 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) return HCLGE_VECTOR0_EVENT_RST; } - /* mailbox event sharing vector 0 interrupt would be placed here */ + /* check for vector0 mailbox(=CMDQ RX) event source */ + if (BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B) & cmdq_src_reg) { + cmdq_src_reg &= ~BIT(HCLGE_VECTOR0_RX_CMDQ_INT_B); + *clearval = cmdq_src_reg; + return HCLGE_VECTOR0_EVENT_MBX; + } return HCLGE_VECTOR0_EVENT_OTHER; } @@ -2403,10 +2423,14 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, u32 regclr) { - if (event_type == HCLGE_VECTOR0_EVENT_RST) + switch (event_type) { + case HCLGE_VECTOR0_EVENT_RST: hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); - - /* mailbox event sharing vector 0 interrupt would be placed here */ + break; + case HCLGE_VECTOR0_EVENT_MBX: + hclge_write_dev(&hdev->hw, HCLGE_VECTOR0_CMDQ_SRC_REG, regclr); + break; + } } static void hclge_enable_vector(struct hclge_misc_vector *vector, bool enable) @@ -2423,13 +2447,23 @@ static irqreturn_t hclge_misc_irq_handle(int irq, void *data) hclge_enable_vector(&hdev->misc_vector, false); event_cause = hclge_check_event_cause(hdev, &clearval); - /* vector 0 interrupt is shared with reset and mailbox source events. - * For now, we are not handling mailbox events. - */ + /* vector 0 interrupt is shared with reset and mailbox source events.*/ switch (event_cause) { case HCLGE_VECTOR0_EVENT_RST: hclge_reset_task_schedule(hdev); break; + case HCLGE_VECTOR0_EVENT_MBX: + /* If we are here then, + * 1. Either we are not handling any mbx task and we are not + * scheduled as well + * OR + * 2. We could be handling a mbx task but nothing more is + * scheduled. + * In both cases, we should schedule mbx task as there are more + * mbx messages reported by this interrupt. + */ + hclge_mbx_task_schedule(hdev); + default: dev_dbg(&hdev->pdev->dev, "received unknown or unhandled event of vector0\n"); @@ -2708,6 +2742,21 @@ static void hclge_reset_service_task(struct work_struct *work) clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); } +static void hclge_mailbox_service_task(struct work_struct *work) +{ + struct hclge_dev *hdev = + container_of(work, struct hclge_dev, mbx_service_task); + + if (test_and_set_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state)) + return; + + clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state); + + hclge_mbx_handler(hdev); + + clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state); +} + static void hclge_service_task(struct work_struct *work) { struct hclge_dev *hdev = @@ -4815,6 +4864,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) timer_setup(&hdev->service_timer, hclge_service_timer, 0); INIT_WORK(&hdev->service_task, hclge_service_task); INIT_WORK(&hdev->rst_service_task, hclge_reset_service_task); + INIT_WORK(&hdev->mbx_service_task, hclge_mailbox_service_task); /* Enable MISC vector(vector0) */ hclge_enable_vector(&hdev->misc_vector, true); @@ -4823,6 +4873,8 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) set_bit(HCLGE_STATE_DOWN, &hdev->state); clear_bit(HCLGE_STATE_RST_SERVICE_SCHED, &hdev->state); clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state); + clear_bit(HCLGE_STATE_MBX_SERVICE_SCHED, &hdev->state); + clear_bit(HCLGE_STATE_MBX_HANDLING, &hdev->state); pr_info("%s driver initialization finished.\n", HCLGE_DRIVER_NAME); return 0; @@ -4936,6 +4988,8 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) cancel_work_sync(&hdev->service_task); if (hdev->rst_service_task.func) cancel_work_sync(&hdev->rst_service_task); + if (hdev->mbx_service_task.func) + cancel_work_sync(&hdev->mbx_service_task); if (mac->phydev) mdiobus_unregister(mac->mdio_bus); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index c7c9a28..fb043b5 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -92,6 +92,11 @@ #define HCLGE_VECTOR0_CORERESET_INT_B 6 #define HCLGE_VECTOR0_IMPRESET_INT_B 7 +/* Vector0 interrupt CMDQ event source register(RW) */ +#define HCLGE_VECTOR0_CMDQ_SRC_REG 0x27100 +/* CMDQ register bits for RX event(=MBX event) */ +#define HCLGE_VECTOR0_RX_CMDQ_INT_B 1 + enum HCLGE_DEV_STATE { HCLGE_STATE_REINITING, HCLGE_STATE_DOWN, @@ -101,8 +106,8 @@ enum HCLGE_DEV_STATE { HCLGE_STATE_SERVICE_SCHED, HCLGE_STATE_RST_SERVICE_SCHED, HCLGE_STATE_RST_HANDLING, + HCLGE_STATE_MBX_SERVICE_SCHED, HCLGE_STATE_MBX_HANDLING, - HCLGE_STATE_MBX_IRQ, HCLGE_STATE_MAX }; @@ -479,6 +484,7 @@ struct hclge_dev { struct timer_list service_timer; struct work_struct service_task; struct work_struct rst_service_task; + struct work_struct mbx_service_task; bool cur_promisc; int num_alloc_vfs; /* Actual number of VFs allocated */