Skip to content

Commit

Permalink
net/ncsi: Package and channel management
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Gavin Shan authored and davem330 committed Jul 20, 2016
1 parent 138635c commit e6f44ed
Show file tree
Hide file tree
Showing 4 changed files with 834 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/net/ncsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct ncsi_dev {
#ifdef CONFIG_NET_NCSI
struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
void (*notifier)(struct ncsi_dev *nd));
int ncsi_start_dev(struct ncsi_dev *nd);
void ncsi_unregister_dev(struct ncsi_dev *nd);
#else /* !CONFIG_NET_NCSI */
static inline struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
Expand All @@ -38,6 +39,11 @@ static inline struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
return NULL;
}

static inline int ncsi_start_dev(struct ncsi_dev *nd)
{
return -ENOTTY;
}

static inline void ncsi_unregister_dev(struct ncsi_dev *nd)
{
}
Expand Down
50 changes: 50 additions & 0 deletions net/ncsi/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,19 @@ struct ncsi_channel {
int state;
#define NCSI_CHANNEL_INACTIVE 1
#define NCSI_CHANNEL_ACTIVE 2
#define NCSI_CHANNEL_INVISIBLE 3
spinlock_t lock; /* Protect filters etc */
struct ncsi_package *package;
struct ncsi_channel_version version;
struct ncsi_channel_cap caps[NCSI_CAP_MAX];
struct ncsi_channel_mode modes[NCSI_MODE_MAX];
struct ncsi_channel_filter *filters[NCSI_FILTER_MAX];
struct ncsi_channel_stats stats;
struct timer_list timer; /* Link monitor timer */
bool enabled; /* Timer is enabled */
unsigned int timeout; /* Times of timeout */
struct list_head node;
struct list_head link;
};

struct ncsi_package {
Expand All @@ -209,14 +214,56 @@ struct ncsi_request {
bool enabled; /* Time has been enabled or not */
};

enum {
ncsi_dev_state_major = 0xff00,
ncsi_dev_state_minor = 0x00ff,
ncsi_dev_state_probe_deselect = 0x0201,
ncsi_dev_state_probe_package,
ncsi_dev_state_probe_channel,
ncsi_dev_state_probe_cis,
ncsi_dev_state_probe_gvi,
ncsi_dev_state_probe_gc,
ncsi_dev_state_probe_gls,
ncsi_dev_state_probe_dp,
ncsi_dev_state_config_sp = 0x0301,
ncsi_dev_state_config_cis,
ncsi_dev_state_config_sma,
ncsi_dev_state_config_ebf,
#if IS_ENABLED(CONFIG_IPV6)
ncsi_dev_state_config_egmf,
#endif
ncsi_dev_state_config_ecnt,
ncsi_dev_state_config_ec,
ncsi_dev_state_config_ae,
ncsi_dev_state_config_gls,
ncsi_dev_state_config_done,
ncsi_dev_state_suspend_select = 0x0401,
ncsi_dev_state_suspend_dcnt,
ncsi_dev_state_suspend_dc,
ncsi_dev_state_suspend_deselect,
ncsi_dev_state_suspend_done
};

struct ncsi_dev_priv {
struct ncsi_dev ndev; /* Associated NCSI device */
unsigned int flags; /* NCSI device flags */
#define NCSI_DEV_PROBED 1 /* Finalized NCSI topology */
#define NCSI_DEV_HWA 2 /* Enabled HW arbitration */
#define NCSI_DEV_RESHUFFLE 4
spinlock_t lock; /* Protect the NCSI device */
#if IS_ENABLED(CONFIG_IPV6)
unsigned int inet6_addr_num; /* Number of IPv6 addresses */
#endif
unsigned int package_num; /* Number of packages */
struct list_head packages; /* List of packages */
struct ncsi_request requests[256]; /* Request table */
unsigned int request_id; /* Last used request ID */
unsigned int pending_req_num; /* Number of pending requests */
struct ncsi_package *active_package; /* Currently handled package */
struct ncsi_channel *active_channel; /* Currently handled channel */
struct list_head channel_queue; /* Config queue of channels */
struct work_struct work; /* For channel management */
struct packet_type ptype; /* NCSI packet Rx handler */
struct list_head node; /* Form NCSI device list */
};

Expand Down Expand Up @@ -251,6 +298,8 @@ extern spinlock_t ncsi_dev_lock;
int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
void ncsi_start_channel_monitor(struct ncsi_channel *nc);
void ncsi_stop_channel_monitor(struct ncsi_channel *nc);
struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
unsigned char id);
struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np,
Expand All @@ -267,6 +316,7 @@ void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp, bool driven);
void ncsi_free_request(struct ncsi_request *nr);
struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
int ncsi_process_next_channel(struct ncsi_dev_priv *ndp);

/* Packet handlers */
u32 ncsi_calculate_checksum(unsigned char *data, int len);
Expand Down
Loading

0 comments on commit e6f44ed

Please sign in to comment.