blob: 6028f42d20d489edac4458271872d22faa6c9064 [file] [log] [blame]
Artem Senichev7f598ef2020-02-19 12:20:50 +03001From b19111bb23044c9312d13e64dd1df2a9565f6b38 Mon Sep 17 00:00:00 2001
2From: Artem Senichev <a.senichev@yadro.com>
3Date: Wed, 12 Feb 2020 14:05:15 +0300
4Subject: [PATCH] Add NCSI channel selector
5
6NCSI channel number is selected depending on GPIO state of a pin
7described in the device tree (gpio/nsci_cfg node).
8Currently, this pin is controlled via MCU, and its state represents
9Nicole's physical position inside a fabric.
10
11Channel selector scheme:
12* GPIO pin value is 0: channel 0;
13* GPIO pin value is 1: channel 1;
14* invalid configuration or error: channel 0.
15
16After changing pin's state it is necessary to reboot the BMC to apply
17new channel number.
18
19Signed-off-by: Artem Senichev <a.senichev@yadro.com>
20---
21 net/ncsi/ncsi-rsp.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
22 1 file changed, 79 insertions(+), 1 deletion(-)
23
24diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
25index d876bd55f356..d211a7e64b14 100644
26--- a/net/ncsi/ncsi-rsp.c
27+++ b/net/ncsi/ncsi-rsp.c
28@@ -9,6 +9,9 @@
29 #include <linux/netdevice.h>
30 #include <linux/etherdevice.h>
31 #include <linux/skbuff.h>
32+#include <linux/of.h>
33+#include <linux/gpio.h>
34+#include <linux/gpio/consumer.h>
35
36 #include <net/ncsi.h>
37 #include <net/net_namespace.h>
38@@ -19,6 +22,81 @@
39 #include "ncsi-pkt.h"
40 #include "ncsi-netlink.h"
41
42+/* NSCI channel number, used as default in case of errors. */
43+#define NCSI_DEFAULT_CHANNEL 0
44+
45+/* Predicate for gpiochip_find() call. */
46+static int device_match(struct gpio_chip* chip, void* data)
47+{
48+ const struct device_node *node = data;
49+ return chip->of_node == node;
50+}
51+
52+/**
53+ * ncsi_select_channel() - Get channel number for NCSI.
54+ * @dev: Network device.
55+ *
56+ * NCSI channel number is selected depending on GPIO state of a pin
57+ * described in the device tree (gpio/nsci_cfg node).
58+ *
59+ * Return: channel number.
60+ */
61+static int ncsi_select_channel(const struct net_device* dev)
62+{
63+ static int channel_id = -1;
64+ struct device_node* node = NULL;
65+
66+ while (channel_id < 0) {
67+ struct gpio_chip* chip;
68+ const struct gpio_desc* desc;
69+ u32 pin;
70+ int rc;
71+
72+ /* Read NCSI configuration node from device tree */
73+ node = of_find_node_by_name(NULL, "ncsi_cfg");
74+ if (!node) {
75+ netdev_err(dev, "NCSI: Configuration node not found\n");
76+ break;
77+ }
78+
79+ /* Read GPIO pin configuration */
80+ rc = of_property_read_u32_index(node, "gpios", 0, &pin);
81+ if (rc) {
82+ netdev_err(dev, "NCSI: GPIO configuration not found\n");
83+ break;
84+ }
85+
86+ /* Find GPIO chip */
87+ chip = gpiochip_find(node->parent, device_match);
88+ if (!chip) {
89+ netdev_err(dev, "NCSI: GPIO chip not found\n");
90+ break;
91+ }
92+
93+ /* Read GPIO state */
94+ desc = gpio_to_desc(chip->base + pin);
95+ if (!desc) {
96+ netdev_err(dev, "NCSI: Cannot get GPIO descriptor\n");
97+ break;
98+ }
99+ channel_id = gpiod_get_value(desc);
100+ if (channel_id < 0) {
101+ netdev_err(dev, "NCSI: GPIO read error %d\n", channel_id);
102+ }
103+ break;
104+ }
105+
106+ if (node) {
107+ of_node_put(node);
108+ }
109+ if (channel_id < 0) {
110+ channel_id = NCSI_DEFAULT_CHANNEL;
111+ }
112+ netdev_info(dev, "NCSI: Set channel %d\n", channel_id);
113+
114+ return channel_id;
115+}
116+
117 static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
118 unsigned short payload)
119 {
120@@ -87,7 +165,7 @@ static int ncsi_rsp_handler_cis(struct ncsi_request *nr)
121 if (ndp->flags & NCSI_DEV_PROBED)
122 return -ENXIO;
123
124- id = NCSI_CHANNEL_INDEX(rsp->rsp.common.channel);
125+ id = ncsi_select_channel(ndp->ndev.dev);
126 nc = ncsi_add_channel(np, id);
127 }
128
129--
1302.25.0
131