Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp6945835imm; Tue, 28 Aug 2018 04:00:03 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYt41O0k4e+BJwUkH6OjoDOAON4aMtVvar+JZ6KjFCdnwZg50z9WFPzeFmj9zBoGeHbg365 X-Received: by 2002:a17:902:2:: with SMTP id 2-v6mr1034830pla.181.1535454003304; Tue, 28 Aug 2018 04:00:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535454003; cv=none; d=google.com; s=arc-20160816; b=QPtI+DDxc8+b7mVvQW6+zKO/4nLiwOiYyFq7oPHqYb1irY0YsERmacqx9LQnxNadDn cv7M6Pdpn6j4xs9AcJMcRZFqDGuhmvQ8yo/xmaeZUKwH8ttOFvaUpv8Ly/xInp4ilvYk 8wfgptkan6MY2xMZXptjB8D6Gxgv2DMQ2rsgtRG8mSUFDY5kpjquH9CRi8RHTKbcRrXG XFeeSEmbka3pGEXNjwGCiuCUxQBDRQEFG4DmcBn30CebFTJx8Wbyx5jI6igHP9ilyzB2 pZDd+zsIpJOiIGwH+IK0E1RSOyDPF70BbEqFbDf9IJ+Dw0xmISx85zw0yFa3hDu2ZfCT 0DnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=LwVCS0V1bXJgMnJPB4C1NFGpQd7OlOXk7pUk2uc8gO8=; b=uu7dDWAWrLkayC/qJmdNJrCyIuLGvu57gj3qcPMYW6l3EbPCH9n5rycAjoyqz7kDCI YDVE01VKZORi/KY3DNyWbJnCFFIhOlA0gxuiVyOQTQRFSRmCvESSn9qwuPsUeIePKxJ8 Q8v9VH0jUxi0TGXyfNAReT3CNKq9DqD6yUHUWrXOTbZxAsFLJkqJJcAIcdPKC0BjNHp6 isWJcW1fqmO1tkAsG9N3k9AIrO7AyuUeNRe1Bm3XYBgOEKQWoIRsEfrqrjnpQ3ez1oc9 6FFRcfBAOh7U/D0aumcNUup3ARLT4xPZfhTnCwdx/M6ZNYu6zoVBYAadK/pqEWILFSdP 19gA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Un+bK0k4; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p32-v6si841670pgb.198.2018.08.28.03.59.48; Tue, 28 Aug 2018 04:00:03 -0700 (PDT) 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; dkim=pass header.i=@gmail.com header.s=20161025 header.b=Un+bK0k4; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728061AbeH1Otb (ORCPT + 99 others); Tue, 28 Aug 2018 10:49:31 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:33432 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727192AbeH1Ota (ORCPT ); Tue, 28 Aug 2018 10:49:30 -0400 Received: by mail-pf1-f196.google.com with SMTP id d4-v6so558943pfn.0; Tue, 28 Aug 2018 03:58:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=LwVCS0V1bXJgMnJPB4C1NFGpQd7OlOXk7pUk2uc8gO8=; b=Un+bK0k4aTvGpXmYMJe1q9HaIA6c8nn9RNyeE7TrHWmY7MWpFerdp13jVXyRuaMpUr VY2jQleoULMROvvg2xJMEUA/Gs0rFT9XFful+aaizgOEgcSkdYZ1Lg9OvHFeUbBzTM8r vKsu/VFZVhz348He9CZc9/7ypPXEkSLzlmCpt017FWgz66SibbLSlB7cSCqCfjR3Ypsp cTXZrBwlxre1OF+FbKRn0zHyLyH4XNWp1OgX+b0ZjSkXSGyogtIRtcS+OTirC+pNyvpa WPhBp+K7ZwqV4EA11A7aA0zgRnwd4AoRY1c5FFjxFgUd4xl6XoO+YdFain8GaRZOUHx9 F2UA== 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=LwVCS0V1bXJgMnJPB4C1NFGpQd7OlOXk7pUk2uc8gO8=; b=X5V5a35N91BKwMcR7P60sdDUIGa/hSPeT+qWLTzy8Qd1VzzJlw10a7qNGZwnsGqvBv +ie3C5OkMVtSYaga8lITsZmpNbFVrHjirvfZ4Ee7VmRvdywg9YfynBf4NWYp35EjuH3X Z6isaJ7bRRvJSkYUMw9cdam5idqCinpF3i1CJK3i2fIjs7pV5CBDl0pVF7aj7KH0jx0t BvHGVCCdBWw76SjUbcETnP/MmOm+wxgJMUxSe55rpJX2eBWgon5faS27oo+dt6UR2RBG 2M3W0XwTkCCS3M6a4zW9QPraoSxYd/CHqI+DIo5vRHDrap/ffS2Sr1SuXJRBVV0DGvxl 4S0A== X-Gm-Message-State: APzg51BWnAxyEJvg2G/tWayHVkZlssH+1R/RlrHR11ZJAera9QIeBNqQ ec6pOrh6Y2wNifZLPPKWe5zt/2rE X-Received: by 2002:a63:dc53:: with SMTP id f19-v6mr1026815pgj.56.1535453903977; Tue, 28 Aug 2018 03:58:23 -0700 (PDT) Received: from machine421.caveonetworks.com ([115.113.156.2]) by smtp.googlemail.com with ESMTPSA id n22-v6sm2946798pfj.68.2018.08.28.03.58.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Aug 2018 03:58:23 -0700 (PDT) From: sunil.kovvuri@gmail.com To: linux-kernel@vger.kernel.org, arnd@arndb.de, olof@lixom.net Cc: linux-arm-kernel@lists.infradead.org, linux-soc@vger.kernel.org, Linu Cherian Subject: [PATCH 14/15] soc: octeontx2: Register for CGX lmac events Date: Tue, 28 Aug 2018 16:27:17 +0530 Message-Id: <1535453838-12154-15-git-send-email-sunil.kovvuri@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1535453838-12154-1-git-send-email-sunil.kovvuri@gmail.com> References: <1535453838-12154-1-git-send-email-sunil.kovvuri@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Linu Cherian Added support in RVU AF driver to register for CGX LMAC link status change events from firmware and managing them. Processing part will be added in followup patches. - Introduced eventqueue for posting events from cgx lmac. Queueing mechanism will ensure that events can be posted and firmware can be acked immediately and hence event reception and processing are decoupled. - Events gets added to the queue by notification callback. Notification callback is expected to be atomic, since it is called from interrupt context. - Events are dequeued and processed in a worker thread. Signed-off-by: Linu Cherian --- drivers/soc/marvell/octeontx2/rvu.c | 6 +- drivers/soc/marvell/octeontx2/rvu.h | 5 ++ drivers/soc/marvell/octeontx2/rvu_cgx.c | 101 +++++++++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 4 deletions(-) diff --git a/drivers/soc/marvell/octeontx2/rvu.c b/drivers/soc/marvell/octeontx2/rvu.c index d7b19e0..3809517 100644 --- a/drivers/soc/marvell/octeontx2/rvu.c +++ b/drivers/soc/marvell/octeontx2/rvu.c @@ -1563,10 +1563,11 @@ static int rvu_probe(struct pci_dev *pdev, const struct pci_device_id *id) err = rvu_register_interrupts(rvu); if (err) - goto err_mbox; + goto err_cgx; return 0; - +err_cgx: + rvu_cgx_wq_destroy(rvu); err_mbox: rvu_mbox_destroy(rvu); err_hwsetup: @@ -1588,6 +1589,7 @@ static void rvu_remove(struct pci_dev *pdev) struct rvu *rvu = pci_get_drvdata(pdev); rvu_unregister_interrupts(rvu); + rvu_cgx_wq_destroy(rvu); rvu_mbox_destroy(rvu); rvu_reset_all_blocks(rvu); rvu_free_hw_resources(rvu); diff --git a/drivers/soc/marvell/octeontx2/rvu.h b/drivers/soc/marvell/octeontx2/rvu.h index 385f597..d169fa9 100644 --- a/drivers/soc/marvell/octeontx2/rvu.h +++ b/drivers/soc/marvell/octeontx2/rvu.h @@ -110,6 +110,10 @@ struct rvu { * every cgx lmac port */ void **cgx_idmap; /* cgx id to cgx data map table */ + struct work_struct cgx_evh_work; + struct workqueue_struct *cgx_evh_wq; + spinlock_t cgx_evq_lock; /* cgx event queue lock */ + struct list_head cgx_evq_head; /* cgx event queue head */ }; static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) @@ -150,4 +154,5 @@ int rvu_poll_reg(struct rvu *rvu, u64 block, u64 offset, u64 mask, bool zero); /* CGX APIs */ int rvu_cgx_probe(struct rvu *rvu); +void rvu_cgx_wq_destroy(struct rvu *rvu); #endif /* RVU_H */ diff --git a/drivers/soc/marvell/octeontx2/rvu_cgx.c b/drivers/soc/marvell/octeontx2/rvu_cgx.c index bf81507..2359806e 100644 --- a/drivers/soc/marvell/octeontx2/rvu_cgx.c +++ b/drivers/soc/marvell/octeontx2/rvu_cgx.c @@ -15,6 +15,11 @@ #include "rvu.h" #include "cgx.h" +struct cgx_evq_entry { + struct list_head evq_node; + struct cgx_link_event link_event; +}; + static inline u8 cgxlmac_id_to_bmap(u8 cgx_id, u8 lmac_id) { return ((cgx_id & 0xF) << 4) | (lmac_id & 0xF); @@ -72,9 +77,95 @@ static int rvu_map_cgx_lmac_pf(struct rvu *rvu) return 0; } +/* This is called from interrupt context and is expected to be atomic */ +static int cgx_lmac_postevent(struct cgx_link_event *event, void *data) +{ + struct rvu *rvu = data; + struct cgx_evq_entry *qentry; + + /* post event to the event queue */ + qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); + if (!qentry) + return -ENOMEM; + qentry->link_event = *event; + spin_lock(&rvu->cgx_evq_lock); + list_add_tail(&qentry->evq_node, &rvu->cgx_evq_head); + spin_unlock(&rvu->cgx_evq_lock); + + /* start worker to process the events */ + queue_work(rvu->cgx_evh_wq, &rvu->cgx_evh_work); + + return 0; +} + +static void cgx_evhandler_task(struct work_struct *work) +{ + struct rvu *rvu = container_of(work, struct rvu, cgx_evh_work); + struct cgx_evq_entry *qentry; + struct cgx_link_event *event; + unsigned long flags; + + do { + /* Dequeue an event */ + spin_lock_irqsave(&rvu->cgx_evq_lock, flags); + qentry = list_first_entry_or_null(&rvu->cgx_evq_head, + struct cgx_evq_entry, + evq_node); + if (qentry) + list_del(&qentry->evq_node); + spin_unlock_irqrestore(&rvu->cgx_evq_lock, flags); + if (!qentry) + break; /* nothing more to process */ + + event = &qentry->link_event; + + /* Do nothing for now */ + kfree(qentry); + } while (1); +} + +static void cgx_lmac_event_handler_init(struct rvu *rvu) +{ + struct cgx_event_cb cb; + int cgx, lmac, err; + void *cgxd; + + spin_lock_init(&rvu->cgx_evq_lock); + INIT_LIST_HEAD(&rvu->cgx_evq_head); + INIT_WORK(&rvu->cgx_evh_work, cgx_evhandler_task); + rvu->cgx_evh_wq = alloc_workqueue("rvu_evh_wq", 0, 0); + if (!rvu->cgx_evh_wq) { + dev_err(rvu->dev, "alloc workqueue failed"); + return; + } + + cb.notify_link_chg = cgx_lmac_postevent; /* link change call back */ + cb.data = rvu; + + for (cgx = 0; cgx < rvu->cgx_cnt; cgx++) { + cgxd = rvu_cgx_pdata(cgx, rvu); + for (lmac = 0; lmac < cgx_get_lmac_cnt(cgxd); lmac++) { + err = cgx_lmac_evh_register(&cb, cgxd, lmac); + if (err) + dev_err(rvu->dev, + "%d:%d handler register failed\n", + cgx, lmac); + } + } +} + +void rvu_cgx_wq_destroy(struct rvu *rvu) +{ + if (rvu->cgx_evh_wq) { + flush_workqueue(rvu->cgx_evh_wq); + destroy_workqueue(rvu->cgx_evh_wq); + rvu->cgx_evh_wq = NULL; + } +} + int rvu_cgx_probe(struct rvu *rvu) { - int i; + int i, err; /* find available cgx ports */ rvu->cgx_cnt = cgx_get_cgx_cnt(); @@ -93,5 +184,11 @@ int rvu_cgx_probe(struct rvu *rvu) rvu->cgx_idmap[i] = cgx_get_pdata(i); /* Map CGX LMAC interfaces to RVU PFs */ - return rvu_map_cgx_lmac_pf(rvu); + err = rvu_map_cgx_lmac_pf(rvu); + if (err) + return err; + + /* Register for CGX events */ + cgx_lmac_event_handler_init(rvu); + return 0; } -- 2.7.4