Skip to content

Commit f197a7a

Browse files
Rajesh Borundiadavem330
authored andcommitted
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 <[email protected]> Signed-off-by: Sucheta Chakraborty <[email protected]> Signed-off-by: Rajesh Borundia <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent da6c806 commit f197a7a

File tree

7 files changed

+1191
-8
lines changed

7 files changed

+1191
-8
lines changed

drivers/net/ethernet/qlogic/qlcnic/qlcnic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,7 @@ struct _cdrp_cmd {
13601360
struct qlcnic_cmd_args {
13611361
struct _cdrp_cmd req;
13621362
struct _cdrp_cmd rsp;
1363+
int op_type;
13631364
};
13641365

13651366
int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter);

drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#define QLCNIC_MAX_TX_QUEUES 1
1616
#define RSS_HASHTYPE_IP_TCP 0x3
17+
#define QLC_83XX_FW_MBX_CMD 0
1718

1819
/* status descriptor mailbox data
1920
* @phy_addr_{low|high}: physical address of buffer
@@ -211,6 +212,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
211212
{QLCNIC_CMD_GET_LED_CONFIG, 1, 5},
212213
{QLCNIC_CMD_ADD_RCV_RINGS, 130, 26},
213214
{QLCNIC_CMD_CONFIG_VPORT, 4, 4},
215+
{QLCNIC_CMD_BC_EVENT_SETUP, 2, 1},
214216
};
215217

216218
const u32 qlcnic_83xx_ext_reg_tbl[] = {
@@ -824,7 +826,7 @@ static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
824826
}
825827

826828
/* Mailbox response for mac rcode */
827-
static u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
829+
u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
828830
{
829831
u32 fw_data;
830832
u8 mac_cmd_rcode;
@@ -838,7 +840,7 @@ static u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
838840
return 1;
839841
}
840842

841-
static u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter)
843+
u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter)
842844
{
843845
u32 data;
844846
unsigned long wait_time = 0;
@@ -953,6 +955,7 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
953955
size = ARRAY_SIZE(qlcnic_83xx_mbx_tbl);
954956
for (i = 0; i < size; i++) {
955957
if (type == mbx_tbl[i].cmd) {
958+
mbx->op_type = QLC_83XX_FW_MBX_CMD;
956959
mbx->req.num = mbx_tbl[i].in_args;
957960
mbx->rsp.num = mbx_tbl[i].out_args;
958961
mbx->req.arg = kcalloc(mbx->req.num, sizeof(u32),
@@ -970,10 +973,10 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
970973
memset(mbx->rsp.arg, 0, sizeof(u32) * mbx->rsp.num);
971974
temp = adapter->ahw->fw_hal_version << 29;
972975
mbx->req.arg[0] = (type | (mbx->req.num << 16) | temp);
973-
break;
976+
return 0;
974977
}
975978
}
976-
return 0;
979+
return -EINVAL;
977980
}
978981

979982
void qlcnic_83xx_idc_aen_work(struct work_struct *work)
@@ -1029,6 +1032,9 @@ void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
10291032
break;
10301033
case QLCNIC_MBX_TIME_EXTEND_EVENT:
10311034
break;
1035+
case QLCNIC_MBX_BC_EVENT:
1036+
qlcnic_sriov_handle_bc_event(adapter, event[1]);
1037+
break;
10321038
case QLCNIC_MBX_SFP_INSERT_EVENT:
10331039
dev_info(&adapter->pdev->dev, "SFP+ Insert AEN:0x%x.\n",
10341040
QLCNIC_MBX_RSP(event[0]));

drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,4 +456,6 @@ int qlcnic_83xx_set_led(struct net_device *, enum ethtool_phys_id_state);
456456
int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
457457
int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
458458
int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
459+
u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *);
460+
u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *);
459461
#endif

drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum qlcnic_regs {
8383
#define QLCNIC_CMD_CONFIG_PORT 0x2e
8484
#define QLCNIC_CMD_TEMP_SIZE 0x2f
8585
#define QLCNIC_CMD_GET_TEMP_HDR 0x30
86+
#define QLCNIC_CMD_BC_EVENT_SETUP 0x31
8687
#define QLCNIC_CMD_CONFIG_VPORT 0x32
8788
#define QLCNIC_CMD_GET_MAC_STATS 0x37
8889
#define QLCNIC_CMD_SET_DRV_VER 0x38
@@ -115,6 +116,7 @@ enum qlcnic_regs {
115116
#define QLCNIC_SET_FAC_DEF_MAC 5
116117

117118
#define QLCNIC_MBX_LINK_EVENT 0x8001
119+
#define QLCNIC_MBX_BC_EVENT 0x8002
118120
#define QLCNIC_MBX_COMP_EVENT 0x8100
119121
#define QLCNIC_MBX_REQUEST_EVENT 0x8101
120122
#define QLCNIC_MBX_TIME_EXTEND_EVENT 0x8102

drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,84 @@
1515
extern const u32 qlcnic_83xx_reg_tbl[];
1616
extern const u32 qlcnic_83xx_ext_reg_tbl[];
1717

18+
struct qlcnic_bc_payload {
19+
u64 payload[126];
20+
};
21+
22+
struct qlcnic_bc_hdr {
23+
#if defined(__LITTLE_ENDIAN)
24+
u8 version;
25+
u8 msg_type:4;
26+
u8 rsvd1:3;
27+
u8 op_type:1;
28+
u8 num_cmds;
29+
u8 num_frags;
30+
u8 frag_num;
31+
u8 cmd_op;
32+
u16 seq_id;
33+
u64 rsvd3;
34+
#elif defined(__BIG_ENDIAN)
35+
u8 num_frags;
36+
u8 num_cmds;
37+
u8 op_type:1;
38+
u8 rsvd1:3;
39+
u8 msg_type:4;
40+
u8 version;
41+
u16 seq_id;
42+
u8 cmd_op;
43+
u8 frag_num;
44+
u64 rsvd3;
45+
#endif
46+
};
47+
48+
enum qlcnic_bc_commands {
49+
QLCNIC_BC_CMD_CHANNEL_INIT = 0x0,
50+
QLCNIC_BC_CMD_CHANNEL_TERM = 0x1,
51+
};
52+
53+
#define QLC_BC_CMD 1
54+
55+
struct qlcnic_trans_list {
56+
/* Lock for manipulating list */
57+
spinlock_t lock;
58+
struct list_head wait_list;
59+
int count;
60+
};
61+
62+
enum qlcnic_trans_state {
63+
QLC_INIT = 0,
64+
QLC_WAIT_FOR_CHANNEL_FREE,
65+
QLC_WAIT_FOR_RESP,
66+
QLC_ABORT,
67+
QLC_END,
68+
};
69+
70+
struct qlcnic_bc_trans {
71+
u8 func_id;
72+
u8 active;
73+
u8 curr_rsp_frag;
74+
u8 curr_req_frag;
75+
u16 cmd_id;
76+
u16 req_pay_size;
77+
u16 rsp_pay_size;
78+
u32 trans_id;
79+
enum qlcnic_trans_state trans_state;
80+
struct list_head list;
81+
struct qlcnic_bc_hdr *req_hdr;
82+
struct qlcnic_bc_hdr *rsp_hdr;
83+
struct qlcnic_bc_payload *req_pay;
84+
struct qlcnic_bc_payload *rsp_pay;
85+
struct completion resp_cmpl;
86+
struct qlcnic_vf_info *vf;
87+
};
88+
89+
enum qlcnic_vf_state {
90+
QLC_BC_VF_SEND = 0,
91+
QLC_BC_VF_RECV,
92+
QLC_BC_VF_CHANNEL,
93+
QLC_BC_VF_STATE,
94+
};
95+
1896
struct qlcnic_resources {
1997
u16 num_tx_mac_filters;
2098
u16 num_rx_ucast_mac_filters;
@@ -34,10 +112,36 @@ struct qlcnic_resources {
34112
u16 max_remote_ipv6_addrs;
35113
};
36114

115+
struct qlcnic_vport {
116+
u16 handle;
117+
u8 mac[6];
118+
};
119+
120+
struct qlcnic_vf_info {
121+
u8 pci_func;
122+
unsigned long state;
123+
struct completion ch_free_cmpl;
124+
struct work_struct trans_work;
125+
/* It synchronizes commands sent from VF */
126+
struct mutex send_cmd_lock;
127+
struct qlcnic_bc_trans *send_cmd;
128+
struct qlcnic_trans_list rcv_act;
129+
struct qlcnic_trans_list rcv_pend;
130+
struct qlcnic_adapter *adapter;
131+
struct qlcnic_vport *vp;
132+
};
133+
134+
struct qlcnic_back_channel {
135+
u16 trans_counter;
136+
struct workqueue_struct *bc_trans_wq;
137+
};
138+
37139
struct qlcnic_sriov {
38140
u16 vp_handle;
39141
u8 num_vfs;
40142
struct qlcnic_resources ff_max;
143+
struct qlcnic_back_channel bc;
144+
struct qlcnic_vf_info *vf_info;
41145
};
42146

43147
int qlcnic_sriov_init(struct qlcnic_adapter *, int);
@@ -46,13 +150,20 @@ void __qlcnic_sriov_cleanup(struct qlcnic_adapter *);
46150
void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *);
47151
int qlcnic_sriov_vf_init(struct qlcnic_adapter *, int);
48152
void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *);
153+
int qlcnic_sriov_func_to_index(struct qlcnic_adapter *, u8);
154+
int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *, u8);
155+
void qlcnic_sriov_handle_bc_event(struct qlcnic_adapter *, u32);
156+
int qlcnic_sriov_cfg_bc_intr(struct qlcnic_adapter *, u8);
49157

50158
static inline bool qlcnic_sriov_enable_check(struct qlcnic_adapter *adapter)
51159
{
52160
return test_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state) ? true : false;
53161
}
54162

55163
#ifdef CONFIG_QLCNIC_SRIOV
164+
void qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *,
165+
struct qlcnic_bc_trans *,
166+
struct qlcnic_cmd_args *);
56167
void qlcnic_sriov_pf_disable(struct qlcnic_adapter *);
57168
void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *);
58169
int qlcnic_pci_sriov_configure(struct pci_dev *, int);

0 commit comments

Comments
 (0)