Skip to content

Commit 378e5cc

Browse files
sanmanp2111993kuba-moo
authored andcommitted
eth: fbnic: hwmon: Add completion infrastructure for firmware requests
Add infrastructure to support firmware request/response handling with completions. Add a completion structure to track message state including message type for matching, completion for waiting for response, and result for error propagation. Use existing spinlock to protect the writes. The data from the various response types will be added to the "union u" by subsequent commits. Signed-off-by: Sanman Pradhan <[email protected]> Reviewed-by: Michal Swiatkowski <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 586b298 commit 378e5cc

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

drivers/net/ethernet/meta/fbnic/fbnic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct fbnic_dev {
4141

4242
struct fbnic_fw_mbx mbx[FBNIC_IPC_MBX_INDICES];
4343
struct fbnic_fw_cap fw_cap;
44+
struct fbnic_fw_completion *cmpl_data;
4445
/* Lock protecting Tx Mailbox queue to prevent possible races */
4546
spinlock_t fw_tx_lock;
4647

drivers/net/ethernet/meta/fbnic/fbnic_fw.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,63 @@ static void fbnic_mbx_process_tx_msgs(struct fbnic_dev *fbd)
228228
tx_mbx->head = head;
229229
}
230230

231+
static __maybe_unused int fbnic_mbx_map_req_w_cmpl(struct fbnic_dev *fbd,
232+
struct fbnic_tlv_msg *msg,
233+
struct fbnic_fw_completion *cmpl_data)
234+
{
235+
unsigned long flags;
236+
int err;
237+
238+
spin_lock_irqsave(&fbd->fw_tx_lock, flags);
239+
240+
/* If we are already waiting on a completion then abort */
241+
if (cmpl_data && fbd->cmpl_data) {
242+
err = -EBUSY;
243+
goto unlock_mbx;
244+
}
245+
246+
/* Record completion location and submit request */
247+
if (cmpl_data)
248+
fbd->cmpl_data = cmpl_data;
249+
250+
err = fbnic_mbx_map_msg(fbd, FBNIC_IPC_MBX_TX_IDX, msg,
251+
le16_to_cpu(msg->hdr.len) * sizeof(u32), 1);
252+
253+
/* If msg failed then clear completion data for next caller */
254+
if (err && cmpl_data)
255+
fbd->cmpl_data = NULL;
256+
257+
unlock_mbx:
258+
spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
259+
260+
return err;
261+
}
262+
263+
static void fbnic_fw_release_cmpl_data(struct kref *kref)
264+
{
265+
struct fbnic_fw_completion *cmpl_data;
266+
267+
cmpl_data = container_of(kref, struct fbnic_fw_completion,
268+
ref_count);
269+
kfree(cmpl_data);
270+
}
271+
272+
static __maybe_unused struct fbnic_fw_completion *
273+
fbnic_fw_get_cmpl_by_type(struct fbnic_dev *fbd, u32 msg_type)
274+
{
275+
struct fbnic_fw_completion *cmpl_data = NULL;
276+
unsigned long flags;
277+
278+
spin_lock_irqsave(&fbd->fw_tx_lock, flags);
279+
if (fbd->cmpl_data && fbd->cmpl_data->msg_type == msg_type) {
280+
cmpl_data = fbd->cmpl_data;
281+
kref_get(&fbd->cmpl_data->ref_count);
282+
}
283+
spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
284+
285+
return cmpl_data;
286+
}
287+
231288
/**
232289
* fbnic_fw_xmit_simple_msg - Transmit a simple single TLV message w/o data
233290
* @fbd: FBNIC device structure
@@ -802,3 +859,25 @@ void fbnic_get_fw_ver_commit_str(struct fbnic_dev *fbd, char *fw_version,
802859
fbnic_mk_full_fw_ver_str(mgmt->version, delim, mgmt->commit,
803860
fw_version, str_sz);
804861
}
862+
863+
void fbnic_fw_init_cmpl(struct fbnic_fw_completion *fw_cmpl,
864+
u32 msg_type)
865+
{
866+
fw_cmpl->msg_type = msg_type;
867+
init_completion(&fw_cmpl->done);
868+
kref_init(&fw_cmpl->ref_count);
869+
}
870+
871+
void fbnic_fw_clear_compl(struct fbnic_dev *fbd)
872+
{
873+
unsigned long flags;
874+
875+
spin_lock_irqsave(&fbd->fw_tx_lock, flags);
876+
fbd->cmpl_data = NULL;
877+
spin_unlock_irqrestore(&fbd->fw_tx_lock, flags);
878+
}
879+
880+
void fbnic_fw_put_cmpl(struct fbnic_fw_completion *fw_cmpl)
881+
{
882+
kref_put(&fw_cmpl->ref_count, fbnic_fw_release_cmpl_data);
883+
}

drivers/net/ethernet/meta/fbnic/fbnic_fw.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ struct fbnic_fw_cap {
4444
u8 link_fec;
4545
};
4646

47+
struct fbnic_fw_completion {
48+
u32 msg_type;
49+
struct completion done;
50+
struct kref ref_count;
51+
int result;
52+
union {
53+
} u;
54+
};
55+
4756
void fbnic_mbx_init(struct fbnic_dev *fbd);
4857
void fbnic_mbx_clean(struct fbnic_dev *fbd);
4958
void fbnic_mbx_poll(struct fbnic_dev *fbd);
@@ -52,6 +61,10 @@ void fbnic_mbx_flush_tx(struct fbnic_dev *fbd);
5261
int fbnic_fw_xmit_ownership_msg(struct fbnic_dev *fbd, bool take_ownership);
5362
int fbnic_fw_init_heartbeat(struct fbnic_dev *fbd, bool poll);
5463
void fbnic_fw_check_heartbeat(struct fbnic_dev *fbd);
64+
void fbnic_fw_init_cmpl(struct fbnic_fw_completion *cmpl_data,
65+
u32 msg_type);
66+
void fbnic_fw_clear_compl(struct fbnic_dev *fbd);
67+
void fbnic_fw_put_cmpl(struct fbnic_fw_completion *cmpl_data);
5568

5669
#define fbnic_mk_full_fw_ver_str(_rev_id, _delim, _commit, _str, _str_sz) \
5770
do { \

0 commit comments

Comments
 (0)