linux/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
Rajesh Borundia f197a7aa62 qlcnic: VF-PF communication channel implementation
o Adapter provides communication channel between VF and PF.
  Any control commands from the VF driver are sent to the PF driver
  through this communication channel. PF driver validates the
  commands before sending them to the adapter. Similarly PF driver
  forwards any control command responses  to the VF driver
  through this communication channel.  Adapter sends message pending
  event to VF or PF when there is an outstanding response or a command
  for VF or PF respectively. When a command or a response is sent over
  a channel VF or PF cannot send another command or a response
  until adapter sends a channel free event. Adapter allocates 1K area to
  VF and  PF each for this communication.
o Commands and  responses are encapsulated in a header. Header determines
  sequence id, number of fragments, fragment number etc.

Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2013-03-29 15:51:05 -04:00

176 lines
3.9 KiB
C

/*
* QLogic qlcnic NIC Driver
* Copyright (c) 2009-2013 QLogic Corporation
*
* See LICENSE.qlcnic for copyright and licensing details.
*/
#ifndef _QLCNIC_83XX_SRIOV_H_
#define _QLCNIC_83XX_SRIOV_H_
#include "qlcnic.h"
#include <linux/types.h>
#include <linux/pci.h>
extern const u32 qlcnic_83xx_reg_tbl[];
extern const u32 qlcnic_83xx_ext_reg_tbl[];
struct qlcnic_bc_payload {
u64 payload[126];
};
struct qlcnic_bc_hdr {
#if defined(__LITTLE_ENDIAN)
u8 version;
u8 msg_type:4;
u8 rsvd1:3;
u8 op_type:1;
u8 num_cmds;
u8 num_frags;
u8 frag_num;
u8 cmd_op;
u16 seq_id;
u64 rsvd3;
#elif defined(__BIG_ENDIAN)
u8 num_frags;
u8 num_cmds;
u8 op_type:1;
u8 rsvd1:3;
u8 msg_type:4;
u8 version;
u16 seq_id;
u8 cmd_op;
u8 frag_num;
u64 rsvd3;
#endif
};
enum qlcnic_bc_commands {
QLCNIC_BC_CMD_CHANNEL_INIT = 0x0,
QLCNIC_BC_CMD_CHANNEL_TERM = 0x1,
};
#define QLC_BC_CMD 1
struct qlcnic_trans_list {
/* Lock for manipulating list */
spinlock_t lock;
struct list_head wait_list;
int count;
};
enum qlcnic_trans_state {
QLC_INIT = 0,
QLC_WAIT_FOR_CHANNEL_FREE,
QLC_WAIT_FOR_RESP,
QLC_ABORT,
QLC_END,
};
struct qlcnic_bc_trans {
u8 func_id;
u8 active;
u8 curr_rsp_frag;
u8 curr_req_frag;
u16 cmd_id;
u16 req_pay_size;
u16 rsp_pay_size;
u32 trans_id;
enum qlcnic_trans_state trans_state;
struct list_head list;
struct qlcnic_bc_hdr *req_hdr;
struct qlcnic_bc_hdr *rsp_hdr;
struct qlcnic_bc_payload *req_pay;
struct qlcnic_bc_payload *rsp_pay;
struct completion resp_cmpl;
struct qlcnic_vf_info *vf;
};
enum qlcnic_vf_state {
QLC_BC_VF_SEND = 0,
QLC_BC_VF_RECV,
QLC_BC_VF_CHANNEL,
QLC_BC_VF_STATE,
};
struct qlcnic_resources {
u16 num_tx_mac_filters;
u16 num_rx_ucast_mac_filters;
u16 num_rx_mcast_mac_filters;
u16 num_txvlan_keys;
u16 num_rx_queues;
u16 num_tx_queues;
u16 num_rx_buf_rings;
u16 num_rx_status_rings;
u16 num_destip;
u32 num_lro_flows_supported;
u16 max_local_ipv6_addrs;
u16 max_remote_ipv6_addrs;
};
struct qlcnic_vport {
u16 handle;
u8 mac[6];
};
struct qlcnic_vf_info {
u8 pci_func;
unsigned long state;
struct completion ch_free_cmpl;
struct work_struct trans_work;
/* It synchronizes commands sent from VF */
struct mutex send_cmd_lock;
struct qlcnic_bc_trans *send_cmd;
struct qlcnic_trans_list rcv_act;
struct qlcnic_trans_list rcv_pend;
struct qlcnic_adapter *adapter;
struct qlcnic_vport *vp;
};
struct qlcnic_back_channel {
u16 trans_counter;
struct workqueue_struct *bc_trans_wq;
};
struct qlcnic_sriov {
u16 vp_handle;
u8 num_vfs;
struct qlcnic_resources ff_max;
struct qlcnic_back_channel bc;
struct qlcnic_vf_info *vf_info;
};
int qlcnic_sriov_init(struct qlcnic_adapter *, int);
void qlcnic_sriov_cleanup(struct qlcnic_adapter *);
void __qlcnic_sriov_cleanup(struct qlcnic_adapter *);
void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *);
int qlcnic_sriov_vf_init(struct qlcnic_adapter *, int);
void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *);
int qlcnic_sriov_func_to_index(struct qlcnic_adapter *, u8);
int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *, u8);
void qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *, u32);
int qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *, u8);
static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
{
return test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state) ? true : false;
}
#ifdef CONFIG_QLCNIC_SRIOV
void qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *,
struct qlcnic_bc_trans *,
struct qlcnic_cmd_args *);
void qlcnic_sriov_pf_disable(struct qlcnic_adapter *);
void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *);
int qlcnic_pci_sriov_configure(struct pci_dev *, int);
#else
static inline void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter) {}
static inline void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter) {}
#endif
#endif