net/ncsi: Rework the channel monitoring
[cascardo/linux.git] / net / ncsi / internal.h
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_RESERVED_CHANNEL   0x1f
174 #define NCSI_CHANNEL_INDEX(c)   ((c) & ((1 << NCSI_PACKAGE_SHIFT) - 1))
175 #define NCSI_TO_CHANNEL(p, c)   (((p) << NCSI_PACKAGE_SHIFT) | (c))
176
177 struct ncsi_channel {
178         unsigned char               id;
179         int                         state;
180 #define NCSI_CHANNEL_INACTIVE           1
181 #define NCSI_CHANNEL_ACTIVE             2
182 #define NCSI_CHANNEL_INVISIBLE          3
183         spinlock_t                  lock;       /* Protect filters etc */
184         struct ncsi_package         *package;
185         struct ncsi_channel_version version;
186         struct ncsi_channel_cap     caps[NCSI_CAP_MAX];
187         struct ncsi_channel_mode    modes[NCSI_MODE_MAX];
188         struct ncsi_channel_filter  *filters[NCSI_FILTER_MAX];
189         struct ncsi_channel_stats   stats;
190         struct {
191                 struct timer_list   timer;
192                 bool                enabled;
193                 unsigned int        state;
194 #define NCSI_CHANNEL_MONITOR_START      0
195 #define NCSI_CHANNEL_MONITOR_RETRY      1
196 #define NCSI_CHANNEL_MONITOR_WAIT       2
197 #define NCSI_CHANNEL_MONITOR_WAIT_MAX   5
198         } monitor;
199         struct list_head            node;
200         struct list_head            link;
201 };
202
203 struct ncsi_package {
204         unsigned char        id;          /* NCSI 3-bits package ID */
205         unsigned char        uuid[16];    /* UUID                   */
206         struct ncsi_dev_priv *ndp;        /* NCSI device            */
207         spinlock_t           lock;        /* Protect the package    */
208         unsigned int         channel_num; /* Number of channels     */
209         struct list_head     channels;    /* List of chanels        */
210         struct list_head     node;        /* Form list of packages  */
211 };
212
213 struct ncsi_request {
214         unsigned char        id;      /* Request ID - 0 to 255           */
215         bool                 used;    /* Request that has been assigned  */
216         unsigned int         flags;   /* NCSI request property           */
217 #define NCSI_REQ_FLAG_EVENT_DRIVEN      1
218         struct ncsi_dev_priv *ndp;    /* Associated NCSI device          */
219         struct sk_buff       *cmd;    /* Associated NCSI command packet  */
220         struct sk_buff       *rsp;    /* Associated NCSI response packet */
221         struct timer_list    timer;   /* Timer on waiting for response   */
222         bool                 enabled; /* Time has been enabled or not    */
223 };
224
225 enum {
226         ncsi_dev_state_major            = 0xff00,
227         ncsi_dev_state_minor            = 0x00ff,
228         ncsi_dev_state_probe_deselect   = 0x0201,
229         ncsi_dev_state_probe_package,
230         ncsi_dev_state_probe_channel,
231         ncsi_dev_state_probe_cis,
232         ncsi_dev_state_probe_gvi,
233         ncsi_dev_state_probe_gc,
234         ncsi_dev_state_probe_gls,
235         ncsi_dev_state_probe_dp,
236         ncsi_dev_state_config_sp        = 0x0301,
237         ncsi_dev_state_config_cis,
238         ncsi_dev_state_config_sma,
239         ncsi_dev_state_config_ebf,
240 #if IS_ENABLED(CONFIG_IPV6)
241         ncsi_dev_state_config_egmf,
242 #endif
243         ncsi_dev_state_config_ecnt,
244         ncsi_dev_state_config_ec,
245         ncsi_dev_state_config_ae,
246         ncsi_dev_state_config_gls,
247         ncsi_dev_state_config_done,
248         ncsi_dev_state_suspend_select   = 0x0401,
249         ncsi_dev_state_suspend_dcnt,
250         ncsi_dev_state_suspend_dc,
251         ncsi_dev_state_suspend_deselect,
252         ncsi_dev_state_suspend_done
253 };
254
255 struct ncsi_dev_priv {
256         struct ncsi_dev     ndev;            /* Associated NCSI device     */
257         unsigned int        flags;           /* NCSI device flags          */
258 #define NCSI_DEV_PROBED         1            /* Finalized NCSI topology    */
259 #define NCSI_DEV_HWA            2            /* Enabled HW arbitration     */
260 #define NCSI_DEV_RESHUFFLE      4
261         spinlock_t          lock;            /* Protect the NCSI device    */
262 #if IS_ENABLED(CONFIG_IPV6)
263         unsigned int        inet6_addr_num;  /* Number of IPv6 addresses   */
264 #endif
265         unsigned int        package_num;     /* Number of packages         */
266         struct list_head    packages;        /* List of packages           */
267         struct ncsi_request requests[256];   /* Request table              */
268         unsigned int        request_id;      /* Last used request ID       */
269 #define NCSI_REQ_START_IDX      1
270         unsigned int        pending_req_num; /* Number of pending requests */
271         struct ncsi_package *active_package; /* Currently handled package  */
272         struct ncsi_channel *active_channel; /* Currently handled channel  */
273         struct list_head    channel_queue;   /* Config queue of channels   */
274         struct work_struct  work;            /* For channel management     */
275         struct packet_type  ptype;           /* NCSI packet Rx handler     */
276         struct list_head    node;            /* Form NCSI device list      */
277 };
278
279 struct ncsi_cmd_arg {
280         struct ncsi_dev_priv *ndp;        /* Associated NCSI device        */
281         unsigned char        type;        /* Command in the NCSI packet    */
282         unsigned char        id;          /* Request ID (sequence number)  */
283         unsigned char        package;     /* Destination package ID        */
284         unsigned char        channel;     /* Detination channel ID or 0x1f */
285         unsigned short       payload;     /* Command packet payload length */
286         unsigned int         req_flags;   /* NCSI request properties       */
287         union {
288                 unsigned char  bytes[16]; /* Command packet specific data  */
289                 unsigned short words[8];
290                 unsigned int   dwords[4];
291         };
292 };
293
294 extern struct list_head ncsi_dev_list;
295 extern spinlock_t ncsi_dev_lock;
296
297 #define TO_NCSI_DEV_PRIV(nd) \
298         container_of(nd, struct ncsi_dev_priv, ndev)
299 #define NCSI_FOR_EACH_DEV(ndp) \
300         list_for_each_entry_rcu(ndp, &ncsi_dev_list, node)
301 #define NCSI_FOR_EACH_PACKAGE(ndp, np) \
302         list_for_each_entry_rcu(np, &ndp->packages, node)
303 #define NCSI_FOR_EACH_CHANNEL(np, nc) \
304         list_for_each_entry_rcu(nc, &np->channels, node)
305
306 /* Resources */
307 int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
308 int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
309 int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
310 void ncsi_start_channel_monitor(struct ncsi_channel *nc);
311 void ncsi_stop_channel_monitor(struct ncsi_channel *nc);
312 struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
313                                        unsigned char id);
314 struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np,
315                                       unsigned char id);
316 struct ncsi_package *ncsi_find_package(struct ncsi_dev_priv *ndp,
317                                        unsigned char id);
318 struct ncsi_package *ncsi_add_package(struct ncsi_dev_priv *ndp,
319                                       unsigned char id);
320 void ncsi_remove_package(struct ncsi_package *np);
321 void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
322                                    unsigned char id,
323                                    struct ncsi_package **np,
324                                    struct ncsi_channel **nc);
325 struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp,
326                                         unsigned int req_flags);
327 void ncsi_free_request(struct ncsi_request *nr);
328 struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
329 int ncsi_process_next_channel(struct ncsi_dev_priv *ndp);
330
331 /* Packet handlers */
332 u32 ncsi_calculate_checksum(unsigned char *data, int len);
333 int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca);
334 int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
335                  struct packet_type *pt, struct net_device *orig_dev);
336 int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb);
337
338 #endif /* __NCSI_INTERNAL_H__ */