1 /* QLogic qed NIC Driver
2 * Copyright (c) 2015 QLogic Corporation
4 * This software is available under the terms of the GNU General Public License
5 * (GPL) Version 2, available from the file COPYING in the main directory of
9 #include <linux/types.h>
10 #include <asm/byteorder.h>
11 #include <linux/bitops.h>
12 #include <linux/errno.h>
13 #include <linux/kernel.h>
14 #include <linux/string.h>
16 #include <linux/qed/qed_chain.h>
21 #include "qed_reg_addr.h"
24 int qed_sp_init_request(struct qed_hwfn
*p_hwfn
,
25 struct qed_spq_entry
**pp_ent
,
28 struct qed_sp_init_data
*p_data
)
30 u32 opaque_cid
= p_data
->opaque_fid
<< 16 | p_data
->cid
;
31 struct qed_spq_entry
*p_ent
= NULL
;
37 rc
= qed_spq_get_entry(p_hwfn
, pp_ent
);
44 p_ent
->elem
.hdr
.cid
= cpu_to_le32(opaque_cid
);
45 p_ent
->elem
.hdr
.cmd_id
= cmd
;
46 p_ent
->elem
.hdr
.protocol_id
= protocol
;
48 p_ent
->priority
= QED_SPQ_PRIORITY_NORMAL
;
49 p_ent
->comp_mode
= p_data
->comp_mode
;
50 p_ent
->comp_done
.done
= 0;
52 switch (p_ent
->comp_mode
) {
53 case QED_SPQ_MODE_EBLOCK
:
54 p_ent
->comp_cb
.cookie
= &p_ent
->comp_done
;
57 case QED_SPQ_MODE_BLOCK
:
58 if (!p_data
->p_comp_data
)
61 p_ent
->comp_cb
.cookie
= p_data
->p_comp_data
->cookie
;
65 if (!p_data
->p_comp_data
)
66 p_ent
->comp_cb
.function
= NULL
;
68 p_ent
->comp_cb
= *p_data
->p_comp_data
;
72 DP_NOTICE(p_hwfn
, "Unknown SPQE completion mode %d\n",
77 DP_VERBOSE(p_hwfn
, QED_MSG_SPQ
,
78 "Initialized: CID %08x cmd %02x protocol %02x data_addr %lu comp_mode [%s]\n",
79 opaque_cid
, cmd
, protocol
,
80 (unsigned long)&p_ent
->ramrod
,
81 D_TRINE(p_ent
->comp_mode
, QED_SPQ_MODE_EBLOCK
,
82 QED_SPQ_MODE_BLOCK
, "MODE_EBLOCK", "MODE_BLOCK",
85 memset(&p_ent
->ramrod
, 0, sizeof(p_ent
->ramrod
));
90 int qed_sp_pf_start(struct qed_hwfn
*p_hwfn
,
91 enum qed_mf_mode mode
)
93 struct pf_start_ramrod_data
*p_ramrod
= NULL
;
94 u16 sb
= qed_int_get_sp_sb_id(p_hwfn
);
95 u8 sb_index
= p_hwfn
->p_eq
->eq_sb_index
;
96 struct qed_spq_entry
*p_ent
= NULL
;
97 struct qed_sp_init_data init_data
;
100 /* update initial eq producer */
101 qed_eq_prod_update(p_hwfn
,
102 qed_chain_get_prod_idx(&p_hwfn
->p_eq
->chain
));
104 memset(&init_data
, 0, sizeof(init_data
));
105 init_data
.cid
= qed_spq_get_cid(p_hwfn
);
106 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
107 init_data
.comp_mode
= QED_SPQ_MODE_EBLOCK
;
109 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
110 COMMON_RAMROD_PF_START
,
116 p_ramrod
= &p_ent
->ramrod
.pf_start
;
118 p_ramrod
->event_ring_sb_id
= cpu_to_le16(sb
);
119 p_ramrod
->event_ring_sb_index
= sb_index
;
120 p_ramrod
->path_id
= QED_PATH_ID(p_hwfn
);
121 p_ramrod
->dont_log_ramrods
= 0;
122 p_ramrod
->log_type_mask
= cpu_to_le16(0xf);
123 p_ramrod
->mf_mode
= mode
;
127 p_ramrod
->mf_mode
= MF_NPAR
;
130 p_ramrod
->mf_mode
= MF_OVLAN
;
133 DP_NOTICE(p_hwfn
, "Unsupported MF mode, init as DEFAULT\n");
134 p_ramrod
->mf_mode
= MF_NPAR
;
136 p_ramrod
->outer_tag
= p_hwfn
->hw_info
.ovlan
;
138 /* Place EQ address in RAMROD */
139 DMA_REGPAIR_LE(p_ramrod
->event_ring_pbl_addr
,
140 p_hwfn
->p_eq
->chain
.pbl
.p_phys_table
);
141 p_ramrod
->event_ring_num_pages
= (u8
)p_hwfn
->p_eq
->chain
.page_cnt
;
143 DMA_REGPAIR_LE(p_ramrod
->consolid_q_pbl_addr
,
144 p_hwfn
->p_consq
->chain
.pbl
.p_phys_table
);
146 p_hwfn
->hw_info
.personality
= PERSONALITY_ETH
;
148 DP_VERBOSE(p_hwfn
, QED_MSG_SPQ
,
149 "Setting event_ring_sb [id %04x index %02x], outer_tag [%d]\n",
151 p_ramrod
->outer_tag
);
153 return qed_spq_post(p_hwfn
, p_ent
, NULL
);
156 int qed_sp_pf_stop(struct qed_hwfn
*p_hwfn
)
158 struct qed_spq_entry
*p_ent
= NULL
;
159 struct qed_sp_init_data init_data
;
163 memset(&init_data
, 0, sizeof(init_data
));
164 init_data
.cid
= qed_spq_get_cid(p_hwfn
);
165 init_data
.opaque_fid
= p_hwfn
->hw_info
.opaque_fid
;
166 init_data
.comp_mode
= QED_SPQ_MODE_EBLOCK
;
168 rc
= qed_sp_init_request(p_hwfn
, &p_ent
,
169 COMMON_RAMROD_PF_STOP
, PROTOCOLID_COMMON
,
174 return qed_spq_post(p_hwfn
, p_ent
, NULL
);