1From 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 132