xref: /linux/net/ncsi/internal.h (revision 138635cc27c9737f940c3aa80912ff7a61c825af)
12d283bddSGavin Shan /*
22d283bddSGavin Shan  * Copyright Gavin Shan, IBM Corporation 2016.
32d283bddSGavin Shan  *
42d283bddSGavin Shan  * This program is free software; you can redistribute it and/or modify
52d283bddSGavin Shan  * it under the terms of the GNU General Public License as published by
62d283bddSGavin Shan  * the Free Software Foundation; either version 2 of the License, or
72d283bddSGavin Shan  * (at your option) any later version.
82d283bddSGavin Shan  */
92d283bddSGavin Shan 
102d283bddSGavin Shan #ifndef __NCSI_INTERNAL_H__
112d283bddSGavin Shan #define __NCSI_INTERNAL_H__
122d283bddSGavin Shan 
132d283bddSGavin Shan enum {
142d283bddSGavin Shan 	NCSI_CAP_BASE		= 0,
152d283bddSGavin Shan 	NCSI_CAP_GENERIC	= 0,
162d283bddSGavin Shan 	NCSI_CAP_BC,
172d283bddSGavin Shan 	NCSI_CAP_MC,
182d283bddSGavin Shan 	NCSI_CAP_BUFFER,
192d283bddSGavin Shan 	NCSI_CAP_AEN,
202d283bddSGavin Shan 	NCSI_CAP_VLAN,
212d283bddSGavin Shan 	NCSI_CAP_MAX
222d283bddSGavin Shan };
232d283bddSGavin Shan 
242d283bddSGavin Shan enum {
252d283bddSGavin Shan 	NCSI_CAP_GENERIC_HWA             = 0x01, /* HW arbitration           */
262d283bddSGavin Shan 	NCSI_CAP_GENERIC_HDS             = 0x02, /* HNC driver status change */
272d283bddSGavin Shan 	NCSI_CAP_GENERIC_FC              = 0x04, /* HNC to MC flow control   */
282d283bddSGavin Shan 	NCSI_CAP_GENERIC_FC1             = 0x08, /* MC to HNC flow control   */
292d283bddSGavin Shan 	NCSI_CAP_GENERIC_MC              = 0x10, /* Global MC filtering      */
302d283bddSGavin Shan 	NCSI_CAP_GENERIC_HWA_UNKNOWN     = 0x00, /* Unknown HW arbitration   */
312d283bddSGavin Shan 	NCSI_CAP_GENERIC_HWA_SUPPORT     = 0x20, /* Supported HW arbitration */
322d283bddSGavin Shan 	NCSI_CAP_GENERIC_HWA_NOT_SUPPORT = 0x40, /* No HW arbitration        */
332d283bddSGavin Shan 	NCSI_CAP_GENERIC_HWA_RESERVED    = 0x60, /* Reserved HW arbitration  */
342d283bddSGavin Shan 	NCSI_CAP_GENERIC_HWA_MASK        = 0x60, /* Mask for HW arbitration  */
352d283bddSGavin Shan 	NCSI_CAP_GENERIC_MASK            = 0x7f,
362d283bddSGavin Shan 	NCSI_CAP_BC_ARP                  = 0x01, /* ARP packet filtering     */
372d283bddSGavin Shan 	NCSI_CAP_BC_DHCPC                = 0x02, /* DHCP client filtering    */
382d283bddSGavin Shan 	NCSI_CAP_BC_DHCPS                = 0x04, /* DHCP server filtering    */
392d283bddSGavin Shan 	NCSI_CAP_BC_NETBIOS              = 0x08, /* NetBIOS packet filtering */
402d283bddSGavin Shan 	NCSI_CAP_BC_MASK                 = 0x0f,
412d283bddSGavin Shan 	NCSI_CAP_MC_IPV6_NEIGHBOR        = 0x01, /* IPv6 neighbor filtering  */
422d283bddSGavin Shan 	NCSI_CAP_MC_IPV6_ROUTER          = 0x02, /* IPv6 router filering     */
432d283bddSGavin Shan 	NCSI_CAP_MC_DHCPV6_RELAY         = 0x04, /* DHCPv6 relay / server MC */
442d283bddSGavin Shan 	NCSI_CAP_MC_DHCPV6_WELL_KNOWN    = 0x08, /* DHCPv6 well-known MC     */
452d283bddSGavin Shan 	NCSI_CAP_MC_IPV6_MLD             = 0x10, /* IPv6 MLD filtering       */
462d283bddSGavin Shan 	NCSI_CAP_MC_IPV6_NEIGHBOR_S      = 0x20, /* IPv6 neighbour filtering */
472d283bddSGavin Shan 	NCSI_CAP_MC_MASK                 = 0x3f,
482d283bddSGavin Shan 	NCSI_CAP_AEN_LSC                 = 0x01, /* Link status change       */
492d283bddSGavin Shan 	NCSI_CAP_AEN_CR                  = 0x02, /* Configuration required   */
502d283bddSGavin Shan 	NCSI_CAP_AEN_HDS                 = 0x04, /* HNC driver status        */
512d283bddSGavin Shan 	NCSI_CAP_AEN_MASK                = 0x07,
522d283bddSGavin Shan 	NCSI_CAP_VLAN_ONLY               = 0x01, /* Filter VLAN packet only  */
532d283bddSGavin Shan 	NCSI_CAP_VLAN_NO                 = 0x02, /* Filter VLAN and non-VLAN */
542d283bddSGavin Shan 	NCSI_CAP_VLAN_ANY                = 0x04, /* Filter Any-and-non-VLAN  */
552d283bddSGavin Shan 	NCSI_CAP_VLAN_MASK               = 0x07
562d283bddSGavin Shan };
572d283bddSGavin Shan 
582d283bddSGavin Shan enum {
592d283bddSGavin Shan 	NCSI_MODE_BASE		= 0,
602d283bddSGavin Shan 	NCSI_MODE_ENABLE	= 0,
612d283bddSGavin Shan 	NCSI_MODE_TX_ENABLE,
622d283bddSGavin Shan 	NCSI_MODE_LINK,
632d283bddSGavin Shan 	NCSI_MODE_VLAN,
642d283bddSGavin Shan 	NCSI_MODE_BC,
652d283bddSGavin Shan 	NCSI_MODE_MC,
662d283bddSGavin Shan 	NCSI_MODE_AEN,
672d283bddSGavin Shan 	NCSI_MODE_FC,
682d283bddSGavin Shan 	NCSI_MODE_MAX
692d283bddSGavin Shan };
702d283bddSGavin Shan 
712d283bddSGavin Shan enum {
722d283bddSGavin Shan 	NCSI_FILTER_BASE	= 0,
732d283bddSGavin Shan 	NCSI_FILTER_VLAN	= 0,
742d283bddSGavin Shan 	NCSI_FILTER_UC,
752d283bddSGavin Shan 	NCSI_FILTER_MC,
762d283bddSGavin Shan 	NCSI_FILTER_MIXED,
772d283bddSGavin Shan 	NCSI_FILTER_MAX
782d283bddSGavin Shan };
792d283bddSGavin Shan 
802d283bddSGavin Shan struct ncsi_channel_version {
812d283bddSGavin Shan 	u32 version;		/* Supported BCD encoded NCSI version */
822d283bddSGavin Shan 	u32 alpha2;		/* Supported BCD encoded NCSI version */
832d283bddSGavin Shan 	u8  fw_name[12];	/* Firware name string                */
842d283bddSGavin Shan 	u32 fw_version;		/* Firmware version                   */
852d283bddSGavin Shan 	u16 pci_ids[4];		/* PCI identification                 */
862d283bddSGavin Shan 	u32 mf_id;		/* Manufacture ID                     */
872d283bddSGavin Shan };
882d283bddSGavin Shan 
892d283bddSGavin Shan struct ncsi_channel_cap {
902d283bddSGavin Shan 	u32 index;	/* Index of channel capabilities */
912d283bddSGavin Shan 	u32 cap;	/* NCSI channel capability       */
922d283bddSGavin Shan };
932d283bddSGavin Shan 
942d283bddSGavin Shan struct ncsi_channel_mode {
952d283bddSGavin Shan 	u32 index;	/* Index of channel modes      */
962d283bddSGavin Shan 	u32 enable;	/* Enabled or disabled         */
972d283bddSGavin Shan 	u32 size;	/* Valid entries in ncm_data[] */
982d283bddSGavin Shan 	u32 data[8];	/* Data entries                */
992d283bddSGavin Shan };
1002d283bddSGavin Shan 
1012d283bddSGavin Shan struct ncsi_channel_filter {
1022d283bddSGavin Shan 	u32 index;	/* Index of channel filters          */
1032d283bddSGavin Shan 	u32 total;	/* Total entries in the filter table */
1042d283bddSGavin Shan 	u64 bitmap;	/* Bitmap of valid entries           */
1052d283bddSGavin Shan 	u32 data[];	/* Data for the valid entries        */
1062d283bddSGavin Shan };
1072d283bddSGavin Shan 
1082d283bddSGavin Shan struct ncsi_channel_stats {
1092d283bddSGavin Shan 	u32 hnc_cnt_hi;		/* Counter cleared            */
1102d283bddSGavin Shan 	u32 hnc_cnt_lo;		/* Counter cleared            */
1112d283bddSGavin Shan 	u32 hnc_rx_bytes;	/* Rx bytes                   */
1122d283bddSGavin Shan 	u32 hnc_tx_bytes;	/* Tx bytes                   */
1132d283bddSGavin Shan 	u32 hnc_rx_uc_pkts;	/* Rx UC packets              */
1142d283bddSGavin Shan 	u32 hnc_rx_mc_pkts;     /* Rx MC packets              */
1152d283bddSGavin Shan 	u32 hnc_rx_bc_pkts;	/* Rx BC packets              */
1162d283bddSGavin Shan 	u32 hnc_tx_uc_pkts;	/* Tx UC packets              */
1172d283bddSGavin Shan 	u32 hnc_tx_mc_pkts;	/* Tx MC packets              */
1182d283bddSGavin Shan 	u32 hnc_tx_bc_pkts;	/* Tx BC packets              */
1192d283bddSGavin Shan 	u32 hnc_fcs_err;	/* FCS errors                 */
1202d283bddSGavin Shan 	u32 hnc_align_err;	/* Alignment errors           */
1212d283bddSGavin Shan 	u32 hnc_false_carrier;	/* False carrier detection    */
1222d283bddSGavin Shan 	u32 hnc_runt_pkts;	/* Rx runt packets            */
1232d283bddSGavin Shan 	u32 hnc_jabber_pkts;	/* Rx jabber packets          */
1242d283bddSGavin Shan 	u32 hnc_rx_pause_xon;	/* Rx pause XON frames        */
1252d283bddSGavin Shan 	u32 hnc_rx_pause_xoff;	/* Rx XOFF frames             */
1262d283bddSGavin Shan 	u32 hnc_tx_pause_xon;	/* Tx XON frames              */
1272d283bddSGavin Shan 	u32 hnc_tx_pause_xoff;	/* Tx XOFF frames             */
1282d283bddSGavin Shan 	u32 hnc_tx_s_collision;	/* Single collision frames    */
1292d283bddSGavin Shan 	u32 hnc_tx_m_collision;	/* Multiple collision frames  */
1302d283bddSGavin Shan 	u32 hnc_l_collision;	/* Late collision frames      */
1312d283bddSGavin Shan 	u32 hnc_e_collision;	/* Excessive collision frames */
1322d283bddSGavin Shan 	u32 hnc_rx_ctl_frames;	/* Rx control frames          */
1332d283bddSGavin Shan 	u32 hnc_rx_64_frames;	/* Rx 64-bytes frames         */
1342d283bddSGavin Shan 	u32 hnc_rx_127_frames;	/* Rx 65-127 bytes frames     */
1352d283bddSGavin Shan 	u32 hnc_rx_255_frames;	/* Rx 128-255 bytes frames    */
1362d283bddSGavin Shan 	u32 hnc_rx_511_frames;	/* Rx 256-511 bytes frames    */
1372d283bddSGavin Shan 	u32 hnc_rx_1023_frames;	/* Rx 512-1023 bytes frames   */
1382d283bddSGavin Shan 	u32 hnc_rx_1522_frames;	/* Rx 1024-1522 bytes frames  */
1392d283bddSGavin Shan 	u32 hnc_rx_9022_frames;	/* Rx 1523-9022 bytes frames  */
1402d283bddSGavin Shan 	u32 hnc_tx_64_frames;	/* Tx 64-bytes frames         */
1412d283bddSGavin Shan 	u32 hnc_tx_127_frames;	/* Tx 65-127 bytes frames     */
1422d283bddSGavin Shan 	u32 hnc_tx_255_frames;	/* Tx 128-255 bytes frames    */
1432d283bddSGavin Shan 	u32 hnc_tx_511_frames;	/* Tx 256-511 bytes frames    */
1442d283bddSGavin Shan 	u32 hnc_tx_1023_frames;	/* Tx 512-1023 bytes frames   */
1452d283bddSGavin Shan 	u32 hnc_tx_1522_frames;	/* Tx 1024-1522 bytes frames  */
1462d283bddSGavin Shan 	u32 hnc_tx_9022_frames;	/* Tx 1523-9022 bytes frames  */
1472d283bddSGavin Shan 	u32 hnc_rx_valid_bytes;	/* Rx valid bytes             */
1482d283bddSGavin Shan 	u32 hnc_rx_runt_pkts;	/* Rx error runt packets      */
1492d283bddSGavin Shan 	u32 hnc_rx_jabber_pkts;	/* Rx error jabber packets    */
1502d283bddSGavin Shan 	u32 ncsi_rx_cmds;	/* Rx NCSI commands           */
1512d283bddSGavin Shan 	u32 ncsi_dropped_cmds;	/* Dropped commands           */
1522d283bddSGavin Shan 	u32 ncsi_cmd_type_errs;	/* Command type errors        */
1532d283bddSGavin Shan 	u32 ncsi_cmd_csum_errs;	/* Command checksum errors    */
1542d283bddSGavin Shan 	u32 ncsi_rx_pkts;	/* Rx NCSI packets            */
1552d283bddSGavin Shan 	u32 ncsi_tx_pkts;	/* Tx NCSI packets            */
1562d283bddSGavin Shan 	u32 ncsi_tx_aen_pkts;	/* Tx AEN packets             */
1572d283bddSGavin Shan 	u32 pt_tx_pkts;		/* Tx packets                 */
1582d283bddSGavin Shan 	u32 pt_tx_dropped;	/* Tx dropped packets         */
1592d283bddSGavin Shan 	u32 pt_tx_channel_err;	/* Tx channel errors          */
1602d283bddSGavin Shan 	u32 pt_tx_us_err;	/* Tx undersize errors        */
1612d283bddSGavin Shan 	u32 pt_rx_pkts;		/* Rx packets                 */
1622d283bddSGavin Shan 	u32 pt_rx_dropped;	/* Rx dropped packets         */
1632d283bddSGavin Shan 	u32 pt_rx_channel_err;	/* Rx channel errors          */
1642d283bddSGavin Shan 	u32 pt_rx_us_err;	/* Rx undersize errors        */
1652d283bddSGavin Shan 	u32 pt_rx_os_err;	/* Rx oversize errors         */
1662d283bddSGavin Shan };
1672d283bddSGavin Shan 
1682d283bddSGavin Shan struct ncsi_dev_priv;
1692d283bddSGavin Shan struct ncsi_package;
1702d283bddSGavin Shan 
1712d283bddSGavin Shan #define NCSI_PACKAGE_SHIFT	5
1722d283bddSGavin Shan #define NCSI_PACKAGE_INDEX(c)	(((c) >> NCSI_PACKAGE_SHIFT) & 0x7)
1732d283bddSGavin Shan #define NCSI_CHANNEL_INDEX(c)	((c) & ((1 << NCSI_PACKAGE_SHIFT) - 1))
1742d283bddSGavin Shan #define NCSI_TO_CHANNEL(p, c)	(((p) << NCSI_PACKAGE_SHIFT) | (c))
1752d283bddSGavin Shan 
1762d283bddSGavin Shan struct ncsi_channel {
1772d283bddSGavin Shan 	unsigned char               id;
1782d283bddSGavin Shan 	int                         state;
1792d283bddSGavin Shan #define NCSI_CHANNEL_INACTIVE		1
1802d283bddSGavin Shan #define NCSI_CHANNEL_ACTIVE		2
1812d283bddSGavin Shan 	spinlock_t                  lock;	/* Protect filters etc */
1822d283bddSGavin Shan 	struct ncsi_package         *package;
1832d283bddSGavin Shan 	struct ncsi_channel_version version;
1842d283bddSGavin Shan 	struct ncsi_channel_cap	    caps[NCSI_CAP_MAX];
1852d283bddSGavin Shan 	struct ncsi_channel_mode    modes[NCSI_MODE_MAX];
1862d283bddSGavin Shan 	struct ncsi_channel_filter  *filters[NCSI_FILTER_MAX];
1872d283bddSGavin Shan 	struct ncsi_channel_stats   stats;
1882d283bddSGavin Shan 	struct list_head            node;
1892d283bddSGavin Shan };
1902d283bddSGavin Shan 
1912d283bddSGavin Shan struct ncsi_package {
1922d283bddSGavin Shan 	unsigned char        id;          /* NCSI 3-bits package ID */
1932d283bddSGavin Shan 	unsigned char        uuid[16];    /* UUID                   */
1942d283bddSGavin Shan 	struct ncsi_dev_priv *ndp;        /* NCSI device            */
1952d283bddSGavin Shan 	spinlock_t           lock;        /* Protect the package    */
1962d283bddSGavin Shan 	unsigned int         channel_num; /* Number of channels     */
1972d283bddSGavin Shan 	struct list_head     channels;    /* List of chanels        */
1982d283bddSGavin Shan 	struct list_head     node;        /* Form list of packages  */
1992d283bddSGavin Shan };
2002d283bddSGavin Shan 
2012d283bddSGavin Shan struct ncsi_request {
2022d283bddSGavin Shan 	unsigned char        id;      /* Request ID - 0 to 255           */
2032d283bddSGavin Shan 	bool                 used;    /* Request that has been assigned  */
2042d283bddSGavin Shan 	bool                 driven;  /* Drive state machine             */
2052d283bddSGavin Shan 	struct ncsi_dev_priv *ndp;    /* Associated NCSI device          */
2062d283bddSGavin Shan 	struct sk_buff       *cmd;    /* Associated NCSI command packet  */
2072d283bddSGavin Shan 	struct sk_buff       *rsp;    /* Associated NCSI response packet */
2082d283bddSGavin Shan 	struct timer_list    timer;   /* Timer on waiting for response   */
2092d283bddSGavin Shan 	bool                 enabled; /* Time has been enabled or not    */
2102d283bddSGavin Shan };
2112d283bddSGavin Shan 
2122d283bddSGavin Shan struct ncsi_dev_priv {
2132d283bddSGavin Shan 	struct ncsi_dev     ndev;            /* Associated NCSI device     */
2142d283bddSGavin Shan 	unsigned int        flags;           /* NCSI device flags          */
2152d283bddSGavin Shan 	spinlock_t          lock;            /* Protect the NCSI device    */
2162d283bddSGavin Shan 	unsigned int        package_num;     /* Number of packages         */
2172d283bddSGavin Shan 	struct list_head    packages;        /* List of packages           */
2182d283bddSGavin Shan 	struct ncsi_request requests[256];   /* Request table              */
2192d283bddSGavin Shan 	unsigned int        request_id;      /* Last used request ID       */
2202d283bddSGavin Shan 	struct list_head    node;            /* Form NCSI device list      */
2212d283bddSGavin Shan };
2222d283bddSGavin Shan 
2236389eaa7SGavin Shan struct ncsi_cmd_arg {
2246389eaa7SGavin Shan 	struct ncsi_dev_priv *ndp;        /* Associated NCSI device        */
2256389eaa7SGavin Shan 	unsigned char        type;        /* Command in the NCSI packet    */
2266389eaa7SGavin Shan 	unsigned char        id;          /* Request ID (sequence number)  */
2276389eaa7SGavin Shan 	unsigned char        package;     /* Destination package ID        */
2286389eaa7SGavin Shan 	unsigned char        channel;     /* Detination channel ID or 0x1f */
2296389eaa7SGavin Shan 	unsigned short       payload;     /* Command packet payload length */
2306389eaa7SGavin Shan 	bool                 driven;      /* Drive the state machine?      */
2316389eaa7SGavin Shan 	union {
2326389eaa7SGavin Shan 		unsigned char  bytes[16]; /* Command packet specific data  */
2336389eaa7SGavin Shan 		unsigned short words[8];
2346389eaa7SGavin Shan 		unsigned int   dwords[4];
2356389eaa7SGavin Shan 	};
2366389eaa7SGavin Shan };
2376389eaa7SGavin Shan 
2382d283bddSGavin Shan extern struct list_head ncsi_dev_list;
2392d283bddSGavin Shan extern spinlock_t ncsi_dev_lock;
2402d283bddSGavin Shan 
2412d283bddSGavin Shan #define TO_NCSI_DEV_PRIV(nd) \
2422d283bddSGavin Shan 	container_of(nd, struct ncsi_dev_priv, ndev)
2432d283bddSGavin Shan #define NCSI_FOR_EACH_DEV(ndp) \
2442d283bddSGavin Shan 	list_for_each_entry_rcu(ndp, &ncsi_dev_list, node)
2452d283bddSGavin Shan #define NCSI_FOR_EACH_PACKAGE(ndp, np) \
2462d283bddSGavin Shan 	list_for_each_entry_rcu(np, &ndp->packages, node)
2472d283bddSGavin Shan #define NCSI_FOR_EACH_CHANNEL(np, nc) \
2482d283bddSGavin Shan 	list_for_each_entry_rcu(nc, &np->channels, node)
2492d283bddSGavin Shan 
2502d283bddSGavin Shan /* Resources */
2512d283bddSGavin Shan int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data);
2522d283bddSGavin Shan int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data);
2532d283bddSGavin Shan int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index);
2542d283bddSGavin Shan struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
2552d283bddSGavin Shan 				       unsigned char id);
2562d283bddSGavin Shan struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np,
2572d283bddSGavin Shan 				      unsigned char id);
2582d283bddSGavin Shan struct ncsi_package *ncsi_find_package(struct ncsi_dev_priv *ndp,
2592d283bddSGavin Shan 				       unsigned char id);
2602d283bddSGavin Shan struct ncsi_package *ncsi_add_package(struct ncsi_dev_priv *ndp,
2612d283bddSGavin Shan 				      unsigned char id);
2622d283bddSGavin Shan void ncsi_remove_package(struct ncsi_package *np);
2632d283bddSGavin Shan void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
2642d283bddSGavin Shan 				   unsigned char id,
2652d283bddSGavin Shan 				   struct ncsi_package **np,
2662d283bddSGavin Shan 				   struct ncsi_channel **nc);
2672d283bddSGavin Shan struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp, bool driven);
2682d283bddSGavin Shan void ncsi_free_request(struct ncsi_request *nr);
2692d283bddSGavin Shan struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
2702d283bddSGavin Shan 
2716389eaa7SGavin Shan /* Packet handlers */
2726389eaa7SGavin Shan u32 ncsi_calculate_checksum(unsigned char *data, int len);
2736389eaa7SGavin Shan int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca);
274*138635ccSGavin Shan int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
275*138635ccSGavin Shan 		 struct packet_type *pt, struct net_device *orig_dev);
2766389eaa7SGavin Shan 
2772d283bddSGavin Shan #endif /* __NCSI_INTERNAL_H__ */
278