Skip to content
Snippets Groups Projects
qlcnic.h 41.6 KiB
Newer Older
	u16 max_tx_ques;
	u16 max_rx_ques;
	u16 max_mtu;
	u16 pvid;
	u32 capabilities;
	u32 irq;
	u32 temp;

	u32 int_vec_bit;
	u8 reset_ack_timeo;
	u8 dev_init_timeo;
	u16 msg_enable;
	u64 dev_rst_time;
	unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)];
	struct qlcnic_npar_info *npars;
	struct qlcnic_eswitch *eswitch;
	struct qlcnic_nic_template *nic_ops;

	struct qlcnic_adapter_stats stats;
	struct list_head mac_list;

	void __iomem	*tgt_mask_reg;
	void __iomem	*tgt_status_reg;
	void __iomem	*crb_int_state_reg;
	void __iomem	*isr_int_vec;

	struct msix_entry *msix_entries;
	struct qlcnic_filter_hash fhash;

	spinlock_t tx_clean_lock;
	spinlock_t mac_learn_lock;
	__le32 file_prd_off;	/*File fw product offset*/
	u32 fw_version;
	const struct firmware *fw;
};

struct qlcnic_info {
	__le16	pci_func;
	__le16	op_mode; /* 1 = Priv, 2 = NP, 3 = NP passthru */
	__le16	phys_port;
	__le16	switch_mode; /* 0 = disabled, 1 = int, 2 = ext */

	__le32	capabilities;
	u8	max_mac_filters;
	u8	reserved1;
	__le16	max_mtu;

	__le16	max_tx_ques;
	__le16	max_rx_ques;
	__le16	min_tx_bw;
	__le16	max_tx_bw;
	u8	reserved2[104];
} __packed;

struct qlcnic_pci_info {
	__le16	id; /* pci function id */
	__le16	active; /* 1 = Enabled */
	__le16	type; /* 1 = NIC, 2 = FCoE, 3 = iSCSI */
	__le16	default_port; /* default port number */

	__le16	tx_min_bw; /* Multiple of 100mbpc */
	__le16	tx_max_bw;
	__le16	reserved1[2];

	u8	mac[ETH_ALEN];
	u8	reserved2[106];
} __packed;
struct qlcnic_npar_info {
	u8	phy_port;
	u8	type;
	u8	active;
	u8	enable_pm;
	u8	dest_npar;
	u8	discard_tagged;
	u8	mac_override;
	u8	mac_anti_spoof;
	u8	promisc_mode;
	u8	offload_flags;
struct qlcnic_eswitch {
	u8	port;
	u8	active_vports;
	u8	active_vlans;
	u8	active_ucast_filters;
	u8	max_ucast_filters;
	u8	max_active_vlans;

	u32	flags;
#define QLCNIC_SWITCH_ENABLE		BIT_1
#define QLCNIC_SWITCH_VLAN_FILTERING	BIT_2
#define QLCNIC_SWITCH_PROMISC_MODE	BIT_3
#define QLCNIC_SWITCH_PORT_MIRRORING	BIT_4
};


/* Return codes for Error handling */
#define QL_STATUS_INVALID_PARAM	-1

#define MAX_BW			100	/* % of link speed */
#define MAX_VLAN_ID		4095
#define MIN_VLAN_ID		2
#define DEFAULT_MAC_LEARN	1

#define IS_VALID_VLAN(vlan)	(vlan >= MIN_VLAN_ID && vlan < MAX_VLAN_ID)
#define IS_VALID_BW(bw)		(bw <= MAX_BW)

struct qlcnic_pci_func_cfg {
	u16	func_type;
	u16	min_bw;
	u16	max_bw;
	u16	port_num;
	u8	pci_func;
	u8	func_state;
	u8	def_mac_addr[6];
};

struct qlcnic_npar_func_cfg {
	u32	fw_capab;
	u16	port_num;
	u16	min_bw;
	u16	max_bw;
	u16	max_tx_queues;
	u16	max_rx_queues;
	u8	pci_func;
	u8	op_mode;
};

struct qlcnic_pm_func_cfg {
	u8	pci_func;
	u8	action;
	u8	dest_npar;
	u8	reserved[5];
};

struct qlcnic_esw_func_cfg {
	u16	vlan_id;
	u8	op_mode;
	u8	op_type;
	u8	pci_func;
	u8	host_vlan_tag;
	u8	promisc_mode;
	u8	discard_tagged;
	u8	mac_override;
	u8	mac_anti_spoof;
	u8	offload_flags;
	u8	reserved[5];
#define QLCNIC_STATS_VERSION		1
#define QLCNIC_STATS_PORT		1
#define QLCNIC_STATS_ESWITCH		2
#define QLCNIC_QUERY_RX_COUNTER		0
#define QLCNIC_QUERY_TX_COUNTER		1
#define QLCNIC_ESW_STATS_NOT_AVAIL	0xffffffffffffffffULL

#define QLCNIC_ADD_ESW_STATS(VAL1, VAL2)\
do {	\
	if (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) && \
	    ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \
		(VAL1) = (VAL2); \
	else if (((VAL1) != QLCNIC_ESW_STATS_NOT_AVAIL) && \
		 ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \
			(VAL1) += (VAL2); \
} while (0)

struct __qlcnic_esw_statistics {
	__le16 context_id;
	__le16 version;
	__le16 size;
	__le16 unused;
	__le64 unicast_frames;
	__le64 multicast_frames;
	__le64 broadcast_frames;
	__le64 dropped_frames;
	__le64 errors;
	__le64 local_frames;
	__le64 numbytes;
	__le64 rsvd[3];
} __packed;

struct qlcnic_esw_statistics {
	struct __qlcnic_esw_statistics rx;
	struct __qlcnic_esw_statistics tx;
};

struct qlcnic_common_entry_hdr {
	__le32	type;
	__le32	offset;
	__le32	cap_size;
	u8	mask;
	u8	rsvd[2];
	u8	flags;
} __packed;

struct __crb {
	__le32	addr;
	u8	stride;
	u8	rsvd1[3];
	__le32	data_size;
	__le32	no_ops;
	__le32	rsvd2[4];
} __packed;

struct __ctrl {
	__le32	addr;
	u8	stride;
	u8	index_a;
	__le16	timeout;
	__le32	data_size;
	__le32	no_ops;
	u8	opcode;
	u8	index_v;
	u8	shl_val;
	u8	shr_val;
	__le32	val1;
	__le32	val2;
	__le32	val3;
} __packed;

struct __cache {
	__le32	addr;
	__le16	stride;
	__le16	init_tag_val;
	__le32	size;
	__le32	no_ops;
	__le32	ctrl_addr;
	__le32	ctrl_val;
	__le32	read_addr;
	u8	read_addr_stride;
	u8	read_addr_num;
	u8	rsvd1[2];
} __packed;

struct __ocm {
	u8	rsvd[8];
	__le32	size;
	__le32	no_ops;
	u8	rsvd1[8];
	__le32	read_addr;
	__le32	read_addr_stride;
} __packed;

struct __mem {
	u8	rsvd[24];
	__le32	addr;
	__le32	size;
} __packed;

struct __mux {
	__le32	addr;
	u8	rsvd[4];
	__le32	size;
	__le32	no_ops;
	__le32	val;
	__le32	val_stride;
	__le32	read_addr;
	u8	rsvd2[4];
} __packed;

struct __queue {
	__le32	sel_addr;
	__le16	stride;
	u8	rsvd[2];
	__le32	size;
	__le32	no_ops;
	u8	rsvd2[8];
	__le32	read_addr;
	u8	read_addr_stride;
	u8	read_addr_cnt;
	u8	rsvd3[2];
} __packed;

struct qlcnic_dump_entry {
	struct qlcnic_common_entry_hdr hdr;
	union {
		struct __crb	crb;
		struct __cache	cache;
		struct __ocm	ocm;
		struct __mem	mem;
		struct __mux	mux;
		struct __queue	que;
		struct __ctrl	ctrl;
	} region;
} __packed;

enum op_codes {
	QLCNIC_DUMP_NOP		= 0,
	QLCNIC_DUMP_READ_CRB	= 1,
	QLCNIC_DUMP_READ_MUX	= 2,
	QLCNIC_DUMP_QUEUE	= 3,
	QLCNIC_DUMP_BRD_CONFIG	= 4,
	QLCNIC_DUMP_READ_OCM	= 6,
	QLCNIC_DUMP_PEG_REG	= 7,
	QLCNIC_DUMP_L1_DTAG	= 8,
	QLCNIC_DUMP_L1_ITAG	= 9,
	QLCNIC_DUMP_L1_DATA	= 11,
	QLCNIC_DUMP_L1_INST	= 12,
	QLCNIC_DUMP_L2_DTAG	= 21,
	QLCNIC_DUMP_L2_ITAG	= 22,
	QLCNIC_DUMP_L2_DATA	= 23,
	QLCNIC_DUMP_L2_INST	= 24,
	QLCNIC_DUMP_READ_ROM	= 71,
	QLCNIC_DUMP_READ_MEM	= 72,
	QLCNIC_DUMP_READ_CTRL	= 98,
	QLCNIC_DUMP_TLHDR	= 99,
	QLCNIC_DUMP_RDEND	= 255
};

#define QLCNIC_DUMP_WCRB	BIT_0
#define QLCNIC_DUMP_RWCRB	BIT_1
#define QLCNIC_DUMP_ANDCRB	BIT_2
#define QLCNIC_DUMP_ORCRB	BIT_3
#define QLCNIC_DUMP_POLLCRB	BIT_4
#define QLCNIC_DUMP_RD_SAVE	BIT_5
#define QLCNIC_DUMP_WRT_SAVED	BIT_6
#define QLCNIC_DUMP_MOD_SAVE_ST	BIT_7
#define QLCNIC_DUMP_SKIP	BIT_7

#define QLCNIC_DUMP_MASK_MIN		3
#define QLCNIC_DUMP_MASK_DEF		0x7f
#define QLCNIC_DUMP_MASK_MAX		0xff
#define QLCNIC_FORCE_FW_DUMP_KEY	0xdeadfeed
#define QLCNIC_ENABLE_FW_DUMP		0xaddfeed
#define QLCNIC_DISABLE_FW_DUMP		0xbadfeed

struct qlcnic_dump_operations {
	enum op_codes opcode;
	u32 (*handler)(struct qlcnic_adapter *,
			struct qlcnic_dump_entry *, u32 *);
};

int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter);
int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config);

u32 qlcnic_hw_read_wx_2M(struct qlcnic_adapter *adapter, ulong off);
int qlcnic_hw_write_wx_2M(struct qlcnic_adapter *, ulong off, u32 data);
int qlcnic_pci_mem_write_2M(struct qlcnic_adapter *, u64 off, u64 data);
int qlcnic_pci_mem_read_2M(struct qlcnic_adapter *, u64 off, u64 *data);
void qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *, u64, u64 *);
void qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *, u64, u64);

#define ADDR_IN_RANGE(addr, low, high)	\
	(((addr) < (high)) && ((addr) >= (low)))

#define QLCRD32(adapter, off) \
	(qlcnic_hw_read_wx_2M(adapter, off))
#define QLCWR32(adapter, off, val) \
	(qlcnic_hw_write_wx_2M(adapter, off, val))

int qlcnic_pcie_sem_lock(struct qlcnic_adapter *, int, u32);
void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int);

#define qlcnic_rom_lock(a)	\
	qlcnic_pcie_sem_lock((a), 2, QLCNIC_ROM_LOCK_ID)
#define qlcnic_rom_unlock(a)	\
	qlcnic_pcie_sem_unlock((a), 2)
#define qlcnic_phy_lock(a)	\
	qlcnic_pcie_sem_lock((a), 3, QLCNIC_PHY_LOCK_ID)
#define qlcnic_phy_unlock(a)	\
	qlcnic_pcie_sem_unlock((a), 3)
#define qlcnic_api_lock(a)	\
	qlcnic_pcie_sem_lock((a), 5, 0)
#define qlcnic_api_unlock(a)	\
	qlcnic_pcie_sem_unlock((a), 5)
#define qlcnic_sw_lock(a)	\
	qlcnic_pcie_sem_lock((a), 6, 0)
#define qlcnic_sw_unlock(a)	\
	qlcnic_pcie_sem_unlock((a), 6)
#define crb_win_lock(a)	\
	qlcnic_pcie_sem_lock((a), 7, QLCNIC_CRB_WIN_LOCK_ID)
#define crb_win_unlock(a)	\
	qlcnic_pcie_sem_unlock((a), 7)

int qlcnic_get_board_info(struct qlcnic_adapter *adapter);
int qlcnic_wol_supported(struct qlcnic_adapter *adapter);
int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter);
void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter);
int qlcnic_dump_fw(struct qlcnic_adapter *);

/* Functions from qlcnic_init.c */
int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
int qlcnic_need_fw_reset(struct qlcnic_adapter *adapter);
void qlcnic_request_firmware(struct qlcnic_adapter *adapter);
void qlcnic_release_firmware(struct qlcnic_adapter *adapter);
int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter);
int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter);
int qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter);
int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, u32 addr, u32 *valp);
int qlcnic_rom_fast_read_words(struct qlcnic_adapter *adapter, int addr,
				u8 *bytes, size_t size);
int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter);
void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter);

void __iomem *qlcnic_get_ioaddr(struct qlcnic_adapter *, u32);

int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter);
void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter);

int qlcnic_fw_create_ctx(struct qlcnic_adapter *adapter);
void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter);

void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter);
void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);

int qlcnic_check_fw_status(struct qlcnic_adapter *adapter);
void qlcnic_watchdog_task(struct work_struct *work);
void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
		struct qlcnic_host_rds_ring *rds_ring);
int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max);
void qlcnic_set_multi(struct net_device *netdev);
void qlcnic_free_mac_list(struct qlcnic_adapter *adapter);
int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32);
int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter);
int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable);
int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd);
int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable);
void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup);

int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
int qlcnic_change_mtu(struct net_device *netdev, int new_mtu);
u32 qlcnic_fix_features(struct net_device *netdev, u32 features);
int qlcnic_set_features(struct net_device *netdev, u32 features);
int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable);
int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
		struct qlcnic_host_tx_ring *tx_ring);
void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *);
void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring);
void qlcnic_clear_lb_mode(struct qlcnic_adapter *adapter);
int qlcnic_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode);

/* Functions from qlcnic_ethtool.c */
int qlcnic_check_loopback_buff(unsigned char *data, u8 mac[]);

/* Functions from qlcnic_main.c */
int qlcnic_reset_context(struct qlcnic_adapter *);
u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
	u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd);
void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val);
int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data);
void qlcnic_dev_request_reset(struct qlcnic_adapter *);
void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
/* Management functions */
int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8);
int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *);
int qlcnic_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*);
int qlcnic_config_switch_port(struct qlcnic_adapter *,
				struct qlcnic_esw_func_cfg *);
int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *,
				struct qlcnic_esw_func_cfg *);
int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8);
int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8,
					struct __qlcnic_esw_statistics *);
int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8,
					struct __qlcnic_esw_statistics *);
int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8);
#define QLCNIC_MAX_BOARD_NAME_LEN 100
struct qlcnic_brdinfo {
	unsigned short  vendor;
	unsigned short  device;
	unsigned short  sub_vendor;
	unsigned short  sub_device;
	char short_name[QLCNIC_MAX_BOARD_NAME_LEN];
};

static const struct qlcnic_brdinfo qlcnic_boards[] = {
	{0x1077, 0x8020, 0x1077, 0x203,
		"8200 Series Single Port 10GbE Converged Network Adapter "
		"(TCP/IP Networking)"},
	{0x1077, 0x8020, 0x1077, 0x207,
		"8200 Series Dual Port 10GbE Converged Network Adapter "
		"(TCP/IP Networking)"},
	{0x1077, 0x8020, 0x1077, 0x20b,
		"3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"},
	{0x1077, 0x8020, 0x1077, 0x20c,
		"3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"},
	{0x1077, 0x8020, 0x1077, 0x20f,
		"3200 Series Single Port 10Gb Intelligent Ethernet Adapter"},
Sritej Velaga's avatar
Sritej Velaga committed
	{0x1077, 0x8020, 0x103c, 0x3733,
		"NC523SFP 10Gb 2-port Server Adapter"},
	{0x1077, 0x8020, 0x103c, 0x3346,
		"CN1000Q Dual Port Converged Network Adapter"},
	{0x1077, 0x8020, 0x1077, 0x210,
		"QME8242-k 10GbE Dual Port Mezzanine Card"},
	{0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"},
};

#define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards)

static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
{
	if (likely(tx_ring->producer < tx_ring->sw_consumer))
		return tx_ring->sw_consumer - tx_ring->producer;
	else
		return tx_ring->sw_consumer + tx_ring->num_desc -
				tx_ring->producer;
}

extern const struct ethtool_ops qlcnic_ethtool_ops;

struct qlcnic_nic_template {
	int (*config_bridged_mode) (struct qlcnic_adapter *, u32);
	int (*config_led) (struct qlcnic_adapter *, u32, u32);
	int (*start_firmware) (struct qlcnic_adapter *);
#define QLCDB(adapter, lvl, _fmt, _args...) do {	\
	if (NETIF_MSG_##lvl & adapter->msg_enable)	\
		printk(KERN_INFO "%s: %s: " _fmt,	\
			 dev_name(&adapter->pdev->dev),	\
			__func__, ##_args);		\
	} while (0)

#endif				/* __QLCNIC_H_ */