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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
|
#ifndef __NCSI_INTERNAL_H__
#define __NCSI_INTERNAL_H__
struct ncsi_dev_priv;
struct ncsi_package;
#define NCSI_PACKAGE_INDEX(c) (((c) >> 5) & 0x7)
#define NCSI_CHANNEL_INDEX(c) ((c) & 0x1ffff)
#define NCSI_TO_CHANNEL(p, c) ((((p) & 0x7) << 5) | ((c) & 0x1ffff))
/* Channel state */
enum {
ncsi_channel_state_deselected_initial,
ncsi_channel_state_selected_initial,
ncsi_channel_state_deselected_ready,
ncsi_channel_state_selected_ready,
};
struct ncsi_channel {
unsigned char nc_id;
int nc_state;
struct ncsi_package *nc_package;
struct ncsi_channel_version nc_version;
struct ncsi_channel_cap nc_caps[NCSI_CAP_MAX];
struct ncsi_channel_mode nc_modes[NCSI_MODE_MAX];
struct ncsi_channel_filter *nc_filters[NCSI_FILTER_MAX];
struct ncsi_channel_stats nc_stats;
struct list_head nc_node;
};
struct ncsi_package {
unsigned char np_id;
struct ncsi_dev_priv *np_ndp;
atomic_t np_channel_num;
spinlock_t np_channel_lock;
struct list_head np_channels;
struct list_head np_node;
};
struct ncsi_skb_parms {
unsigned int nsp_valid;
unsigned int nsp_portid;
struct nlmsghdr nsp_nlh;
};
#define NCSI_CB(skb) (*(struct ncsi_skb_parms*)&((skb)->cb))
struct ncsi_req {
unsigned char nr_id;
bool nr_used;
struct ncsi_dev_priv *nr_ndp;
struct sk_buff *nr_cmd;
struct sk_buff *nr_rsp;
struct timer_list nr_timer;
bool nr_timer_enabled;
};
enum {
ncsi_dev_state_major = 0xff00,
ncsi_dev_state_minor = 0x00ff,
ncsi_dev_state_start_deselect = 0x0201,
ncsi_dev_state_start_package,
ncsi_dev_state_start_channel,
ncsi_dev_state_start_sp,
ncsi_dev_state_start_cis,
ncsi_dev_state_start_gvi,
ncsi_dev_state_start_gc,
ncsi_dev_state_start_dp,
ncsi_dev_state_start_active,
ncsi_dev_state_config_sp = 0x0301,
ncsi_dev_state_config_cis,
ncsi_dev_state_config_sma,
ncsi_dev_state_config_ebf,
ncsi_dev_state_config_ecnt,
ncsi_dev_state_config_ec,
ncsi_dev_state_config_gls,
ncsi_dev_state_config_done,
ncsi_dev_state_stop_select = 0x0401,
ncsi_dev_state_stop_dcnt,
ncsi_dev_state_stop_dc,
ncsi_dev_state_stop_deselect,
ncsi_dev_state_stop_done
};
struct ncsi_dev_priv {
struct ncsi_dev ndp_ndev;
int ndp_flags;
#define NCSI_DEV_PRIV_FLAG_CHANGE_ACTIVE 0x1
struct ncsi_package *ndp_active_package;
struct ncsi_channel *ndp_active_channel;
atomic_t ndp_package_num;
spinlock_t ndp_package_lock;
struct list_head ndp_packages;
atomic_t ndp_pending_reqs;
atomic_t ndp_last_req_idx;
spinlock_t ndp_req_lock;
struct ncsi_req ndp_reqs[256];
struct work_struct ndp_work;
struct packet_type ndp_ptype;
struct list_head ndp_node;
};
struct ncsi_cmd_arg {
struct ncsi_dev_priv *nca_ndp;
unsigned char nca_type;
unsigned char nca_id;
unsigned char nca_package;
unsigned char nca_channel;
unsigned short nca_payload;
struct nlmsghdr *nca_nlh;
unsigned int nca_portid;
union {
unsigned char nca_bytes[16];
unsigned short nca_words[8];
unsigned int nca_dwords[4];
};
};
extern struct net *ncsi_net;
extern struct list_head ncsi_dev_list;
extern spinlock_t ncsi_dev_lock;
#define TO_NCSI_DEV_PRIV(nd) \
container_of(nd, struct ncsi_dev_priv, ndp_ndev)
#define NCSI_FOR_EACH_DEV(ndp) \
list_for_each_entry_rcu(ndp, &ncsi_dev_list, ndp_node)
#define NCSI_FOR_EACH_PACKAGE(ndp, np) \
list_for_each_entry_rcu(np, &ndp->ndp_packages, np_node)
#define NCSI_FOR_EACH_CHANNEL(np, nc) \
list_for_each_entry_rcu(nc, &np->np_channels, nc_node)
/* Resources */
int ncsi_find_channel_filter(struct ncsi_channel *nc, int table, void *data);
int ncsi_add_channel_filter(struct ncsi_channel *nc, int table, void *data);
int ncsi_del_channel_filter(struct ncsi_channel *nc, int table, int index);
struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np,
unsigned char id);
struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
unsigned char id);
struct ncsi_package *ncsi_add_package(struct ncsi_dev_priv *ndp,
unsigned char id);
struct ncsi_package *ncsi_find_package(struct ncsi_dev_priv *ndp,
unsigned char id);
void ncsi_release_package(struct ncsi_package *np);
void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
unsigned char id,
struct ncsi_package **np,
struct ncsi_channel **nc);
struct ncsi_req *ncsi_alloc_req(struct ncsi_dev_priv *ndp);
void ncsi_free_req(struct ncsi_req *nr, bool check, bool timeout);
struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
int ncsi_config_dev(struct ncsi_dev *nd);
/* Packet handlers */
int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca);
int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev);
int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb);
/* Netlink */
int __net_init ncsi_netlink_init(struct net *net);
void __net_exit ncsi_netlink_exit(struct net *net);
void ncsi_netlink_reply(struct nlmsghdr *h,
unsigned int portid, bool timeout);
#endif /* __NCSI_INTERNAL_H__ */
|