Skip to content

Commit e6f44ed

Browse files
Gavin Shandavem330
authored andcommitted
net/ncsi: Package and channel management
This manages NCSI packages and channels: * The available packages and channels are enumerated in the first time of calling ncsi_start_dev(). The channels' capabilities are probed in the meanwhile. The NCSI network topology won't change until the NCSI device is destroyed. * There in a queue in every NCSI device. The element in the queue, channel, is waiting for configuration (bringup) or suspending (teardown). The channel's state (inactive/active) indicates the futher action (configuration or suspending) will be applied on the channel. Another channel's state (invisible) means the requested action is being applied. * The hardware arbitration will be enabled if all available packages and channels support it. All available channels try to provide service when hardware arbitration is enabled. Otherwise, one channel is selected as the active one at once. * When channel is in active state, meaning it's providing service, a timer started to retrieve the channe's link status. If the channel's link status fails to be updated in the determined period, the channel is going to be reconfigured. It's the error handling implementation as defined in NCSI spec. Signed-off-by: Gavin Shan <[email protected]> Acked-by: Joel Stanley <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 138635c commit e6f44ed

File tree

4 files changed

+834
-0
lines changed

4 files changed

+834
-0
lines changed

include/net/ncsi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct ncsi_dev {
3030
#ifdef CONFIG_NET_NCSI
3131
struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
3232
void (*notifier)(struct ncsi_dev *nd));
33+
int ncsi_start_dev(struct ncsi_dev *nd);
3334
void ncsi_unregister_dev(struct ncsi_dev *nd);
3435
#else /* !CONFIG_NET_NCSI */
3536
static inline struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
@@ -38,6 +39,11 @@ static inline struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
3839
return NULL;
3940
}
4041

42+
static inline int ncsi_start_dev(struct ncsi_dev *nd)
43+
{
44+
return -ENOTTY;
45+
}
46+
4147
static inline void ncsi_unregister_dev(struct ncsi_dev *nd)
4248
{
4349
}

net/ncsi/internal.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,19 @@ struct ncsi_channel {
178178
int state;
179179
#define NCSI_CHANNEL_INACTIVE 1
180180
#define NCSI_CHANNEL_ACTIVE 2
181+
#define NCSI_CHANNEL_INVISIBLE 3
181182
spinlock_t lock; /* Protect filters etc */
182183
struct ncsi_package *package;
183184
struct ncsi_channel_version version;
184185
struct ncsi_channel_cap caps[NCSI_CAP_MAX];
185186
struct ncsi_channel_mode modes[NCSI_MODE_MAX];
186187
struct ncsi_channel_filter *filters[NCSI_FILTER_MAX];
187188
struct ncsi_channel_stats stats;
189+
struct timer_list timer; /* Link monitor timer */
190+
bool enabled; /* Timer is enabled */
191+
unsigned int timeout; /* Times of timeout */
188192
struct list_head node;
193+
struct list_head link;
189194
};
190195

191196
struct ncsi_package {
@@ -209,14 +214,56 @@ struct ncsi_request {
209214
bool enabled; /* Time has been enabled or not */
210215
};
211216

217+
enum {
218+
ncsi_dev_state_major = 0xff00,
219+
ncsi_dev_state_minor = 0x00ff,
220+
ncsi_dev_state_probe_deselect = 0x0201,
221+
ncsi_dev_state_probe_package,
222+
ncsi_dev_state_probe_channel,
223+
ncsi_dev_state_probe_cis,
224+
ncsi_dev_state_probe_gvi,
225+
ncsi_dev_state_probe_gc,
226+
ncsi_dev_state_probe_gls,
227+
ncsi_dev_state_probe_dp,
228+
ncsi_dev_state_config_sp = 0x0301,
229+
ncsi_dev_state_config_cis,
230+
ncsi_dev_state_config_sma,
231+
ncsi_dev_state_config_ebf,
232+
#if IS_ENABLED(CONFIG_IPV6)
233+
ncsi_dev_state_config_egmf,
234+
#endif
235+
ncsi_dev_state_config_ecnt,
236+
ncsi_dev_state_config_ec,
237+
ncsi_dev_state_config_ae,
238+
ncsi_dev_state_config_gls,
239+
ncsi_dev_state_config_done,
240+
ncsi_dev_state_suspend_select = 0x0401,
241+
ncsi_dev_state_suspend_dcnt,
242+
ncsi_dev_state_suspend_dc,
243+
ncsi_dev_state_suspend_deselect,
244+
ncsi_dev_state_suspend_done
245+
};
246+
212247
struct ncsi_dev_priv {
213248
struct ncsi_dev ndev; /* Associated NCSI device */
214249
unsigned int flags; /* NCSI device flags */
250+
#define NCSI_DEV_PROBED 1 /* Finalized NCSI topology */
251+
#define NCSI_DEV_HWA 2 /* Enabled HW arbitration */
252+
#define NCSI_DEV_RESHUFFLE 4
215253
spinlock_t lock; /* Protect the NCSI device */
254+
#if IS_ENABLED(CONFIG_IPV6)
255+
unsigned int inet6_addr_num; /* Number of IPv6 addresses */
256+
#endif
216257
unsigned int package_num; /* Number of packages */
217258
struct list_head packages; /* List of packages */
218259
struct ncsi_request requests[256]; /* Request table */
219260
unsigned int request_id; /* Last used request ID */
261+
unsigned int pending_req_num; /* Number of pending requests */
262+
struct ncsi_package *active_package; /* Currently handled package */
263+
struct ncsi_channel *active_channel; /* Currently handled channel */
264+
struct list_head channel_queue; /* Config queue of channels */
265+
struct work_struct work; /* For channel management */
266+
struct packet_type ptype; /* NCSI packet Rx handler */
220267
struct list_head node; /* Form NCSI device list */
221268
};
222269

@@ -251,6 +298,8 @@ extern spinlock_t ncsi_dev_lock;
251298
int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
252299
int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
253300
int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
301+
void ncsi_start_channel_monitor(struct ncsi_channel *nc);
302+
void ncsi_stop_channel_monitor(struct ncsi_channel *nc);
254303
struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
255304
unsigned char id);
256305
struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np,
@@ -267,6 +316,7 @@ void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
267316
struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp, bool driven);
268317
void ncsi_free_request(struct ncsi_request *nr);
269318
struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
319+
int ncsi_process_next_channel(struct ncsi_dev_priv *ndp);
270320

271321
/* Packet handlers */
272322
u32 ncsi_calculate_checksum(unsigned char *data, int len);

0 commit comments

Comments
 (0)