Skip to content

Commit 2d283bd

Browse files
Gavin Shandavem330
authored andcommitted
net/ncsi: Resource management
NCSI spec (DSP0222) defines several objects: package, channel, mode, filter, version and statistics etc. This introduces the data structs to represent those objects and implement functions to manage them. Also, this introduces CONFIG_NET_NCSI for the newly implemented NCSI stack. * The user (e.g. netdev driver) dereference NCSI device by "struct ncsi_dev", which is embedded to "struct ncsi_dev_priv". The later one is used by NCSI stack internally. * Every NCSI device can have multiple packages simultaneously, up to 8 packages. It's represented by "struct ncsi_package" and identified by 3-bits ID. * Every NCSI package can have multiple channels, up to 32. It's represented by "struct ncsi_channel" and identified by 5-bits ID. * Every NCSI channel has version, statistics, various modes and filters. They are represented by "struct ncsi_channel_version", "struct ncsi_channel_stats", "struct ncsi_channel_mode" and "struct ncsi_channel_filter" separately. * Apart from AEN (Asynchronous Event Notification), the NCSI stack works in terms of command and response. This introduces "struct ncsi_req" to represent a complete NCSI transaction made of NCSI request and response. link: https://www.dmtf.org/sites/default/files/standards/documents/DSP0222_1.1.0.pdf Signed-off-by: Gavin Shan <[email protected]> Acked-by: Joel Stanley <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5e31c70 commit 2d283bd

File tree

7 files changed

+756
-0
lines changed

7 files changed

+756
-0
lines changed

include/net/ncsi.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#ifndef __NET_NCSI_H
2+
#define __NET_NCSI_H
3+
4+
/*
5+
* The NCSI device states seen from external. More NCSI device states are
6+
* only visible internally (in net/ncsi/internal.h). When the NCSI device
7+
* is registered, it's in ncsi_dev_state_registered state. The state
8+
* ncsi_dev_state_start is used to drive to choose active package and
9+
* channel. After that, its state is changed to ncsi_dev_state_functional.
10+
*
11+
* The state ncsi_dev_state_stop helps to shut down the currently active
12+
* package and channel while ncsi_dev_state_config helps to reconfigure
13+
* them.
14+
*/
15+
enum {
16+
ncsi_dev_state_registered = 0x0000,
17+
ncsi_dev_state_functional = 0x0100,
18+
ncsi_dev_state_probe = 0x0200,
19+
ncsi_dev_state_config = 0x0300,
20+
ncsi_dev_state_suspend = 0x0400,
21+
};
22+
23+
struct ncsi_dev {
24+
int state;
25+
int link_up;
26+
struct net_device *dev;
27+
void (*handler)(struct ncsi_dev *ndev);
28+
};
29+
30+
#ifdef CONFIG_NET_NCSI
31+
struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
32+
void (*notifier)(struct ncsi_dev *nd));
33+
void ncsi_unregister_dev(struct ncsi_dev *nd);
34+
#else /* !CONFIG_NET_NCSI */
35+
static inline struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
36+
void (*notifier)(struct ncsi_dev *nd))
37+
{
38+
return NULL;
39+
}
40+
41+
static inline void ncsi_unregister_dev(struct ncsi_dev *nd)
42+
{
43+
}
44+
#endif /* CONFIG_NET_NCSI */
45+
46+
#endif /* __NET_NCSI_H */

net/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ source "net/hsr/Kconfig"
237237
source "net/switchdev/Kconfig"
238238
source "net/l3mdev/Kconfig"
239239
source "net/qrtr/Kconfig"
240+
source "net/ncsi/Kconfig"
240241

241242
config RPS
242243
bool

net/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@ ifneq ($(CONFIG_NET_L3_MASTER_DEV),)
7979
obj-y += l3mdev/
8080
endif
8181
obj-$(CONFIG_QRTR) += qrtr/
82+
obj-$(CONFIG_NET_NCSI) += ncsi/

net/ncsi/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
# Configuration for NCSI support
3+
#
4+
5+
config NET_NCSI
6+
bool "NCSI interface support"
7+
depends on INET
8+
---help---
9+
This module provides NCSI (Network Controller Sideband Interface)
10+
support. Enable this only if your system connects to a network
11+
device via NCSI and the ethernet driver you're using supports
12+
the protocol explicitly.

net/ncsi/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#
2+
# Makefile for NCSI API
3+
#
4+
obj-$(CONFIG_NET_NCSI) += ncsi-manage.o

net/ncsi/internal.h

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
/*
2+
* Copyright Gavin Shan, IBM Corporation 2016.
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*/
9+
10+
#ifndef __NCSI_INTERNAL_H__
11+
#define __NCSI_INTERNAL_H__
12+
13+
enum {
14+
NCSI_CAP_BASE = 0,
15+
NCSI_CAP_GENERIC = 0,
16+
NCSI_CAP_BC,
17+
NCSI_CAP_MC,
18+
NCSI_CAP_BUFFER,
19+
NCSI_CAP_AEN,
20+
NCSI_CAP_VLAN,
21+
NCSI_CAP_MAX
22+
};
23+
24+
enum {
25+
NCSI_CAP_GENERIC_HWA = 0x01, /* HW arbitration */
26+
NCSI_CAP_GENERIC_HDS = 0x02, /* HNC driver status change */
27+
NCSI_CAP_GENERIC_FC = 0x04, /* HNC to MC flow control */
28+
NCSI_CAP_GENERIC_FC1 = 0x08, /* MC to HNC flow control */
29+
NCSI_CAP_GENERIC_MC = 0x10, /* Global MC filtering */
30+
NCSI_CAP_GENERIC_HWA_UNKNOWN = 0x00, /* Unknown HW arbitration */
31+
NCSI_CAP_GENERIC_HWA_SUPPORT = 0x20, /* Supported HW arbitration */
32+
NCSI_CAP_GENERIC_HWA_NOT_SUPPORT = 0x40, /* No HW arbitration */
33+
NCSI_CAP_GENERIC_HWA_RESERVED = 0x60, /* Reserved HW arbitration */
34+
NCSI_CAP_GENERIC_HWA_MASK = 0x60, /* Mask for HW arbitration */
35+
NCSI_CAP_GENERIC_MASK = 0x7f,
36+
NCSI_CAP_BC_ARP = 0x01, /* ARP packet filtering */
37+
NCSI_CAP_BC_DHCPC = 0x02, /* DHCP client filtering */
38+
NCSI_CAP_BC_DHCPS = 0x04, /* DHCP server filtering */
39+
NCSI_CAP_BC_NETBIOS = 0x08, /* NetBIOS packet filtering */
40+
NCSI_CAP_BC_MASK = 0x0f,
41+
NCSI_CAP_MC_IPV6_NEIGHBOR = 0x01, /* IPv6 neighbor filtering */
42+
NCSI_CAP_MC_IPV6_ROUTER = 0x02, /* IPv6 router filering */
43+
NCSI_CAP_MC_DHCPV6_RELAY = 0x04, /* DHCPv6 relay / server MC */
44+
NCSI_CAP_MC_DHCPV6_WELL_KNOWN = 0x08, /* DHCPv6 well-known MC */
45+
NCSI_CAP_MC_IPV6_MLD = 0x10, /* IPv6 MLD filtering */
46+
NCSI_CAP_MC_IPV6_NEIGHBOR_S = 0x20, /* IPv6 neighbour filtering */
47+
NCSI_CAP_MC_MASK = 0x3f,
48+
NCSI_CAP_AEN_LSC = 0x01, /* Link status change */
49+
NCSI_CAP_AEN_CR = 0x02, /* Configuration required */
50+
NCSI_CAP_AEN_HDS = 0x04, /* HNC driver status */
51+
NCSI_CAP_AEN_MASK = 0x07,
52+
NCSI_CAP_VLAN_ONLY = 0x01, /* Filter VLAN packet only */
53+
NCSI_CAP_VLAN_NO = 0x02, /* Filter VLAN and non-VLAN */
54+
NCSI_CAP_VLAN_ANY = 0x04, /* Filter Any-and-non-VLAN */
55+
NCSI_CAP_VLAN_MASK = 0x07
56+
};
57+
58+
enum {
59+
NCSI_MODE_BASE = 0,
60+
NCSI_MODE_ENABLE = 0,
61+
NCSI_MODE_TX_ENABLE,
62+
NCSI_MODE_LINK,
63+
NCSI_MODE_VLAN,
64+
NCSI_MODE_BC,
65+
NCSI_MODE_MC,
66+
NCSI_MODE_AEN,
67+
NCSI_MODE_FC,
68+
NCSI_MODE_MAX
69+
};
70+
71+
enum {
72+
NCSI_FILTER_BASE = 0,
73+
NCSI_FILTER_VLAN = 0,
74+
NCSI_FILTER_UC,
75+
NCSI_FILTER_MC,
76+
NCSI_FILTER_MIXED,
77+
NCSI_FILTER_MAX
78+
};
79+
80+
struct ncsi_channel_version {
81+
u32 version; /* Supported BCD encoded NCSI version */
82+
u32 alpha2; /* Supported BCD encoded NCSI version */
83+
u8 fw_name[12]; /* Firware name string */
84+
u32 fw_version; /* Firmware version */
85+
u16 pci_ids[4]; /* PCI identification */
86+
u32 mf_id; /* Manufacture ID */
87+
};
88+
89+
struct ncsi_channel_cap {
90+
u32 index; /* Index of channel capabilities */
91+
u32 cap; /* NCSI channel capability */
92+
};
93+
94+
struct ncsi_channel_mode {
95+
u32 index; /* Index of channel modes */
96+
u32 enable; /* Enabled or disabled */
97+
u32 size; /* Valid entries in ncm_data[] */
98+
u32 data[8]; /* Data entries */
99+
};
100+
101+
struct ncsi_channel_filter {
102+
u32 index; /* Index of channel filters */
103+
u32 total; /* Total entries in the filter table */
104+
u64 bitmap; /* Bitmap of valid entries */
105+
u32 data[]; /* Data for the valid entries */
106+
};
107+
108+
struct ncsi_channel_stats {
109+
u32 hnc_cnt_hi; /* Counter cleared */
110+
u32 hnc_cnt_lo; /* Counter cleared */
111+
u32 hnc_rx_bytes; /* Rx bytes */
112+
u32 hnc_tx_bytes; /* Tx bytes */
113+
u32 hnc_rx_uc_pkts; /* Rx UC packets */
114+
u32 hnc_rx_mc_pkts; /* Rx MC packets */
115+
u32 hnc_rx_bc_pkts; /* Rx BC packets */
116+
u32 hnc_tx_uc_pkts; /* Tx UC packets */
117+
u32 hnc_tx_mc_pkts; /* Tx MC packets */
118+
u32 hnc_tx_bc_pkts; /* Tx BC packets */
119+
u32 hnc_fcs_err; /* FCS errors */
120+
u32 hnc_align_err; /* Alignment errors */
121+
u32 hnc_false_carrier; /* False carrier detection */
122+
u32 hnc_runt_pkts; /* Rx runt packets */
123+
u32 hnc_jabber_pkts; /* Rx jabber packets */
124+
u32 hnc_rx_pause_xon; /* Rx pause XON frames */
125+
u32 hnc_rx_pause_xoff; /* Rx XOFF frames */
126+
u32 hnc_tx_pause_xon; /* Tx XON frames */
127+
u32 hnc_tx_pause_xoff; /* Tx XOFF frames */
128+
u32 hnc_tx_s_collision; /* Single collision frames */
129+
u32 hnc_tx_m_collision; /* Multiple collision frames */
130+
u32 hnc_l_collision; /* Late collision frames */
131+
u32 hnc_e_collision; /* Excessive collision frames */
132+
u32 hnc_rx_ctl_frames; /* Rx control frames */
133+
u32 hnc_rx_64_frames; /* Rx 64-bytes frames */
134+
u32 hnc_rx_127_frames; /* Rx 65-127 bytes frames */
135+
u32 hnc_rx_255_frames; /* Rx 128-255 bytes frames */
136+
u32 hnc_rx_511_frames; /* Rx 256-511 bytes frames */
137+
u32 hnc_rx_1023_frames; /* Rx 512-1023 bytes frames */
138+
u32 hnc_rx_1522_frames; /* Rx 1024-1522 bytes frames */
139+
u32 hnc_rx_9022_frames; /* Rx 1523-9022 bytes frames */
140+
u32 hnc_tx_64_frames; /* Tx 64-bytes frames */
141+
u32 hnc_tx_127_frames; /* Tx 65-127 bytes frames */
142+
u32 hnc_tx_255_frames; /* Tx 128-255 bytes frames */
143+
u32 hnc_tx_511_frames; /* Tx 256-511 bytes frames */
144+
u32 hnc_tx_1023_frames; /* Tx 512-1023 bytes frames */
145+
u32 hnc_tx_1522_frames; /* Tx 1024-1522 bytes frames */
146+
u32 hnc_tx_9022_frames; /* Tx 1523-9022 bytes frames */
147+
u32 hnc_rx_valid_bytes; /* Rx valid bytes */
148+
u32 hnc_rx_runt_pkts; /* Rx error runt packets */
149+
u32 hnc_rx_jabber_pkts; /* Rx error jabber packets */
150+
u32 ncsi_rx_cmds; /* Rx NCSI commands */
151+
u32 ncsi_dropped_cmds; /* Dropped commands */
152+
u32 ncsi_cmd_type_errs; /* Command type errors */
153+
u32 ncsi_cmd_csum_errs; /* Command checksum errors */
154+
u32 ncsi_rx_pkts; /* Rx NCSI packets */
155+
u32 ncsi_tx_pkts; /* Tx NCSI packets */
156+
u32 ncsi_tx_aen_pkts; /* Tx AEN packets */
157+
u32 pt_tx_pkts; /* Tx packets */
158+
u32 pt_tx_dropped; /* Tx dropped packets */
159+
u32 pt_tx_channel_err; /* Tx channel errors */
160+
u32 pt_tx_us_err; /* Tx undersize errors */
161+
u32 pt_rx_pkts; /* Rx packets */
162+
u32 pt_rx_dropped; /* Rx dropped packets */
163+
u32 pt_rx_channel_err; /* Rx channel errors */
164+
u32 pt_rx_us_err; /* Rx undersize errors */
165+
u32 pt_rx_os_err; /* Rx oversize errors */
166+
};
167+
168+
struct ncsi_dev_priv;
169+
struct ncsi_package;
170+
171+
#define NCSI_PACKAGE_SHIFT 5
172+
#define NCSI_PACKAGE_INDEX(c) (((c) >> NCSI_PACKAGE_SHIFT) & 0x7)
173+
#define NCSI_CHANNEL_INDEX(c) ((c) & ((1 << NCSI_PACKAGE_SHIFT) - 1))
174+
#define NCSI_TO_CHANNEL(p, c) (((p) << NCSI_PACKAGE_SHIFT) | (c))
175+
176+
struct ncsi_channel {
177+
unsigned char id;
178+
int state;
179+
#define NCSI_CHANNEL_INACTIVE 1
180+
#define NCSI_CHANNEL_ACTIVE 2
181+
spinlock_t lock; /* Protect filters etc */
182+
struct ncsi_package *package;
183+
struct ncsi_channel_version version;
184+
struct ncsi_channel_cap caps[NCSI_CAP_MAX];
185+
struct ncsi_channel_mode modes[NCSI_MODE_MAX];
186+
struct ncsi_channel_filter *filters[NCSI_FILTER_MAX];
187+
struct ncsi_channel_stats stats;
188+
struct list_head node;
189+
};
190+
191+
struct ncsi_package {
192+
unsigned char id; /* NCSI 3-bits package ID */
193+
unsigned char uuid[16]; /* UUID */
194+
struct ncsi_dev_priv *ndp; /* NCSI device */
195+
spinlock_t lock; /* Protect the package */
196+
unsigned int channel_num; /* Number of channels */
197+
struct list_head channels; /* List of chanels */
198+
struct list_head node; /* Form list of packages */
199+
};
200+
201+
struct ncsi_request {
202+
unsigned char id; /* Request ID - 0 to 255 */
203+
bool used; /* Request that has been assigned */
204+
bool driven; /* Drive state machine */
205+
struct ncsi_dev_priv *ndp; /* Associated NCSI device */
206+
struct sk_buff *cmd; /* Associated NCSI command packet */
207+
struct sk_buff *rsp; /* Associated NCSI response packet */
208+
struct timer_list timer; /* Timer on waiting for response */
209+
bool enabled; /* Time has been enabled or not */
210+
};
211+
212+
struct ncsi_dev_priv {
213+
struct ncsi_dev ndev; /* Associated NCSI device */
214+
unsigned int flags; /* NCSI device flags */
215+
spinlock_t lock; /* Protect the NCSI device */
216+
unsigned int package_num; /* Number of packages */
217+
struct list_head packages; /* List of packages */
218+
struct ncsi_request requests[256]; /* Request table */
219+
unsigned int request_id; /* Last used request ID */
220+
struct list_head node; /* Form NCSI device list */
221+
};
222+
223+
extern struct list_head ncsi_dev_list;
224+
extern spinlock_t ncsi_dev_lock;
225+
226+
#define TO_NCSI_DEV_PRIV(nd) \
227+
container_of(nd, struct ncsi_dev_priv, ndev)
228+
#define NCSI_FOR_EACH_DEV(ndp) \
229+
list_for_each_entry_rcu(ndp, &ncsi_dev_list, node)
230+
#define NCSI_FOR_EACH_PACKAGE(ndp, np) \
231+
list_for_each_entry_rcu(np, &ndp->packages, node)
232+
#define NCSI_FOR_EACH_CHANNEL(np, nc) \
233+
list_for_each_entry_rcu(nc, &np->channels, node)
234+
235+
/* Resources */
236+
int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
237+
int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
238+
int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
239+
struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
240+
unsigned char id);
241+
struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np,
242+
unsigned char id);
243+
struct ncsi_package *ncsi_find_package(struct ncsi_dev_priv *ndp,
244+
unsigned char id);
245+
struct ncsi_package *ncsi_add_package(struct ncsi_dev_priv *ndp,
246+
unsigned char id);
247+
void ncsi_remove_package(struct ncsi_package *np);
248+
void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
249+
unsigned char id,
250+
struct ncsi_package **np,
251+
struct ncsi_channel **nc);
252+
struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp, bool driven);
253+
void ncsi_free_request(struct ncsi_request *nr);
254+
struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
255+
256+
#endif /* __NCSI_INTERNAL_H__ */

0 commit comments

Comments
 (0)