sfc: Use proper macros to declare and access MCDI arrays
A few functions are using heap buffers; change them to use stack buffers as we really don't need to resort to the heap for a 252 byte buffer in process context. MC_CMD_MEMCPY is quite weird in that it can use inline data placed in the request buffer after the array of records. Thus there are two variable-length arrays and we can't use the normal accessors for the second. So we have to use _MCDI_PTR() in efx_sriov_memcpy(). Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
This commit is contained in:
@@ -294,8 +294,7 @@ struct efx_ptp_data {
|
||||
struct work_struct pps_work;
|
||||
struct workqueue_struct *pps_workwq;
|
||||
bool nic_ts_enabled;
|
||||
u8 txbuf[ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN(
|
||||
MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM), 4)];
|
||||
MCDI_DECLARE_BUF(txbuf, MC_CMD_PTP_IN_TRANSMIT_LENMAX);
|
||||
struct efx_ptp_timeset
|
||||
timeset[MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM];
|
||||
};
|
||||
@@ -396,7 +395,8 @@ static void efx_ptp_send_times(struct efx_nic *efx,
|
||||
}
|
||||
|
||||
/* Read a timeset from the MC's results and partial process. */
|
||||
static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset)
|
||||
static void efx_ptp_read_timeset(MCDI_DECLARE_STRUCT_PTR(data),
|
||||
struct efx_ptp_timeset *timeset)
|
||||
{
|
||||
unsigned start_ns, end_ns;
|
||||
|
||||
@@ -425,12 +425,14 @@ static void efx_ptp_read_timeset(u8 *data, struct efx_ptp_timeset *timeset)
|
||||
* busy. A number of readings are taken so that, hopefully, at least one good
|
||||
* synchronisation will be seen in the results.
|
||||
*/
|
||||
static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf,
|
||||
size_t response_length,
|
||||
const struct pps_event_time *last_time)
|
||||
static int
|
||||
efx_ptp_process_times(struct efx_nic *efx, MCDI_DECLARE_STRUCT_PTR(synch_buf),
|
||||
size_t response_length,
|
||||
const struct pps_event_time *last_time)
|
||||
{
|
||||
unsigned number_readings = (response_length /
|
||||
MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN);
|
||||
unsigned number_readings =
|
||||
MCDI_VAR_ARRAY_LEN(response_length,
|
||||
PTP_OUT_SYNCHRONIZE_TIMESET);
|
||||
unsigned i;
|
||||
unsigned total;
|
||||
unsigned ngood = 0;
|
||||
@@ -447,8 +449,10 @@ static int efx_ptp_process_times(struct efx_nic *efx, u8 *synch_buf,
|
||||
* appera to be erroneous.
|
||||
*/
|
||||
for (i = 0; i < number_readings; i++) {
|
||||
efx_ptp_read_timeset(synch_buf, &ptp->timeset[i]);
|
||||
synch_buf += MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN;
|
||||
efx_ptp_read_timeset(
|
||||
MCDI_ARRAY_STRUCT_PTR(synch_buf,
|
||||
PTP_OUT_SYNCHRONIZE_TIMESET, i),
|
||||
&ptp->timeset[i]);
|
||||
}
|
||||
|
||||
/* Find the last good host-MC synchronization result. The MC times
|
||||
@@ -564,15 +568,15 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings)
|
||||
/* Transmit a PTP packet, via the MCDI interface, to the wire. */
|
||||
static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb)
|
||||
{
|
||||
u8 *txbuf = efx->ptp_data->txbuf;
|
||||
struct efx_ptp_data *ptp_data = efx->ptp_data;
|
||||
struct skb_shared_hwtstamps timestamps;
|
||||
int rc = -EIO;
|
||||
/* MCDI driver requires word aligned lengths */
|
||||
size_t len = ALIGN(MC_CMD_PTP_IN_TRANSMIT_LEN(skb->len), 4);
|
||||
MCDI_DECLARE_BUF(txtime, MC_CMD_PTP_OUT_TRANSMIT_LEN);
|
||||
|
||||
MCDI_SET_DWORD(txbuf, PTP_IN_OP, MC_CMD_PTP_OP_TRANSMIT);
|
||||
MCDI_SET_DWORD(txbuf, PTP_IN_TRANSMIT_LENGTH, skb->len);
|
||||
MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_OP, MC_CMD_PTP_OP_TRANSMIT);
|
||||
MCDI_SET_DWORD(ptp_data->txbuf, PTP_IN_TRANSMIT_LENGTH, skb->len);
|
||||
if (skb_shinfo(skb)->nr_frags != 0) {
|
||||
rc = skb_linearize(skb);
|
||||
if (rc != 0)
|
||||
@@ -585,9 +589,10 @@ static int efx_ptp_xmit_skb(struct efx_nic *efx, struct sk_buff *skb)
|
||||
goto fail;
|
||||
}
|
||||
skb_copy_from_linear_data(skb,
|
||||
&txbuf[MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST],
|
||||
MCDI_PTR(ptp_data->txbuf,
|
||||
PTP_IN_TRANSMIT_PACKET),
|
||||
len);
|
||||
rc = efx_mcdi_rpc(efx, MC_CMD_PTP, txbuf, len, txtime,
|
||||
rc = efx_mcdi_rpc(efx, MC_CMD_PTP, ptp_data->txbuf, len, txtime,
|
||||
sizeof(txtime), &len);
|
||||
if (rc != 0)
|
||||
goto fail;
|
||||
|
Reference in New Issue
Block a user