summaryrefslogtreecommitdiff
path: root/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed/0001-Add-NCSI-channel-selector.patch
blob: 6028f42d20d489edac4458271872d22faa6c9064 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
From b19111bb23044c9312d13e64dd1df2a9565f6b38 Mon Sep 17 00:00:00 2001
From: Artem Senichev <a.senichev@yadro.com>
Date: Wed, 12 Feb 2020 14:05:15 +0300
Subject: [PATCH] Add NCSI channel selector

NCSI channel number is selected depending on GPIO state of a pin
described in the device tree (gpio/nsci_cfg node).
Currently, this pin is controlled via MCU, and its state represents
Nicole's physical position inside a fabric.

Channel selector scheme:
* GPIO pin value is 0: channel 0;
* GPIO pin value is 1: channel 1;
* invalid configuration or error: channel 0.

After changing pin's state it is necessary to reboot the BMC to apply
new channel number.

Signed-off-by: Artem Senichev <a.senichev@yadro.com>
---
 net/ncsi/ncsi-rsp.c | 80 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 1 deletion(-)

diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index d876bd55f356..d211a7e64b14 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -9,6 +9,9 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/of.h>
+#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <net/ncsi.h>
 #include <net/net_namespace.h>
@@ -19,6 +22,81 @@
 #include "ncsi-pkt.h"
 #include "ncsi-netlink.h"
 
+/* NSCI channel number, used as default in case of errors. */
+#define NCSI_DEFAULT_CHANNEL 0
+
+/* Predicate for gpiochip_find() call. */
+static int device_match(struct gpio_chip* chip, void* data)
+{
+	const struct device_node *node = data;
+	return chip->of_node == node;
+}
+
+/**
+ * ncsi_select_channel() - Get channel number for NCSI.
+ * @dev: Network device.
+ *
+ * NCSI channel number is selected depending on GPIO state of a pin
+ * described in the device tree (gpio/nsci_cfg node).
+ *
+ * Return: channel number.
+ */
+static int ncsi_select_channel(const struct net_device* dev)
+{
+	static int channel_id = -1;
+	struct device_node* node = NULL;
+
+	while (channel_id < 0) {
+		struct gpio_chip* chip;
+		const struct gpio_desc* desc;
+		u32 pin;
+		int rc;
+
+		/* Read NCSI configuration node from device tree */
+		node = of_find_node_by_name(NULL, "ncsi_cfg");
+		if (!node) {
+			netdev_err(dev, "NCSI: Configuration node not found\n");
+			break;
+		}
+
+		/* Read GPIO pin configuration */
+		rc = of_property_read_u32_index(node, "gpios", 0, &pin);
+		if (rc) {
+			netdev_err(dev, "NCSI: GPIO configuration not found\n");
+			break;
+		}
+
+		/* Find GPIO chip */
+		chip = gpiochip_find(node->parent, device_match);
+		if (!chip) {
+			netdev_err(dev, "NCSI: GPIO chip not found\n");
+			break;
+		}
+
+		/* Read GPIO state */
+		desc = gpio_to_desc(chip->base + pin);
+		if (!desc) {
+			netdev_err(dev, "NCSI: Cannot get GPIO descriptor\n");
+			break;
+		}
+		channel_id = gpiod_get_value(desc);
+		if (channel_id < 0) {
+			netdev_err(dev, "NCSI: GPIO read error %d\n", channel_id);
+		}
+		break;
+	}
+
+	if (node) {
+		of_node_put(node);
+	}
+	if (channel_id < 0) {
+		channel_id = NCSI_DEFAULT_CHANNEL;
+	}
+	netdev_info(dev, "NCSI: Set channel %d\n", channel_id);
+
+	return channel_id;
+}
+
 static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
 				 unsigned short payload)
 {
@@ -87,7 +165,7 @@ static int ncsi_rsp_handler_cis(struct ncsi_request *nr)
 		if (ndp->flags & NCSI_DEV_PROBED)
 			return -ENXIO;
 
-		id = NCSI_CHANNEL_INDEX(rsp->rsp.common.channel);
+		id = ncsi_select_channel(ndp->ndev.dev);
 		nc = ncsi_add_channel(np, id);
 	}
 
-- 
2.25.0