Skip to content

Commit

Permalink
Merge branch 'dpaa-coalesce'
Browse files Browse the repository at this point in the history
Madalin Bucur says:

====================
dpaa_eth: add ethtool coalesce control

Add control of the DPAA portal interrupt coalescing settings from
ethtool.

changes from v2: read ithresh from HW, set previous values on failure
changes from v1: added range checking for the QMan APIs
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 23, 2018
2 parents 2882b06 + 10f70e9 commit d72ff4b
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 10 deletions.
71 changes: 71 additions & 0 deletions drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,75 @@ static int dpaa_get_ts_info(struct net_device *net_dev,
return 0;
}

static int dpaa_get_coalesce(struct net_device *dev,
struct ethtool_coalesce *c)
{
struct qman_portal *portal;
u32 period;
u8 thresh;

portal = qman_get_affine_portal(smp_processor_id());
qman_portal_get_iperiod(portal, &period);
qman_dqrr_get_ithresh(portal, &thresh);

c->rx_coalesce_usecs = period;
c->rx_max_coalesced_frames = thresh;
c->use_adaptive_rx_coalesce = false;

return 0;
}

static int dpaa_set_coalesce(struct net_device *dev,
struct ethtool_coalesce *c)
{
const cpumask_t *cpus = qman_affine_cpus();
bool needs_revert[NR_CPUS] = {false};
struct qman_portal *portal;
u32 period, prev_period;
u8 thresh, prev_thresh;
int cpu, res;

if (c->use_adaptive_rx_coalesce)
return -EINVAL;

period = c->rx_coalesce_usecs;
thresh = c->rx_max_coalesced_frames;

/* save previous values */
portal = qman_get_affine_portal(smp_processor_id());
qman_portal_get_iperiod(portal, &prev_period);
qman_dqrr_get_ithresh(portal, &prev_thresh);

/* set new values */
for_each_cpu(cpu, cpus) {
portal = qman_get_affine_portal(cpu);
res = qman_portal_set_iperiod(portal, period);
if (res)
goto revert_values;
res = qman_dqrr_set_ithresh(portal, thresh);
if (res) {
qman_portal_set_iperiod(portal, prev_period);
goto revert_values;
}
needs_revert[cpu] = true;
}

return 0;

revert_values:
/* restore previous values */
for_each_cpu(cpu, cpus) {
if (!needs_revert[cpu])
continue;
portal = qman_get_affine_portal(cpu);
/* previous values will not fail, ignore return value */
qman_portal_set_iperiod(portal, prev_period);
qman_dqrr_set_ithresh(portal, prev_thresh);
}

return res;
}

const struct ethtool_ops dpaa_ethtool_ops = {
.get_drvinfo = dpaa_get_drvinfo,
.get_msglevel = dpaa_get_msglevel,
Expand All @@ -545,4 +614,6 @@ const struct ethtool_ops dpaa_ethtool_ops = {
.get_rxnfc = dpaa_get_rxnfc,
.set_rxnfc = dpaa_set_rxnfc,
.get_ts_info = dpaa_get_ts_info,
.get_coalesce = dpaa_get_coalesce,
.set_coalesce = dpaa_set_coalesce,
};
35 changes: 27 additions & 8 deletions drivers/soc/fsl/qbman/qman.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
#define QMAN_POLL_LIMIT 32
#define QMAN_PIRQ_DQRR_ITHRESH 12
#define QMAN_DQRR_IT_MAX 15
#define QMAN_ITP_MAX 0xFFF
#define QMAN_PIRQ_MR_ITHRESH 4
#define QMAN_PIRQ_IPERIOD 100

Expand Down Expand Up @@ -727,9 +729,15 @@ static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
qm_out(portal, QM_REG_DQRR_VDQCR, vdqcr);
}

static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
static inline int qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
{

if (ithresh > QMAN_DQRR_IT_MAX)
return -EINVAL;

qm_out(portal, QM_REG_DQRR_ITR, ithresh);

return 0;
}

/* --- MR API --- */
Expand Down Expand Up @@ -1012,20 +1020,27 @@ static inline void put_affine_portal(void)

static struct workqueue_struct *qm_portal_wq;

void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
{
int res;

if (!portal)
return;
return -EINVAL;

res = qm_dqrr_set_ithresh(&portal->p, ithresh);
if (res)
return res;

qm_dqrr_set_ithresh(&portal->p, ithresh);
portal->p.dqrr.ithresh = ithresh;

return 0;
}
EXPORT_SYMBOL(qman_dqrr_set_ithresh);

void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh)
{
if (portal && ithresh)
*ithresh = portal->p.dqrr.ithresh;
*ithresh = qm_in(&portal->p, QM_REG_DQRR_ITR);
}
EXPORT_SYMBOL(qman_dqrr_get_ithresh);

Expand All @@ -1036,10 +1051,14 @@ void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod)
}
EXPORT_SYMBOL(qman_portal_get_iperiod);

void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod)
{
if (portal)
qm_out(&portal->p, QM_REG_ITPR, iperiod);
if (!portal || iperiod > QMAN_ITP_MAX)
return -EINVAL;

qm_out(&portal->p, QM_REG_ITPR, iperiod);

return 0;
}
EXPORT_SYMBOL(qman_portal_set_iperiod);

Expand Down
8 changes: 6 additions & 2 deletions include/soc/fsl/qman.h
Original file line number Diff line number Diff line change
Expand Up @@ -1205,8 +1205,10 @@ void qman_dqrr_get_ithresh(struct qman_portal *portal, u8 *ithresh);
* qman_dqrr_set_ithresh - Set coalesce interrupt threshold
* @portal: portal to set the new value on
* @ithresh: new threshold value
*
* Returns 0 on success, or a negative error code.
*/
void qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);
int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh);

/**
* qman_dqrr_get_iperiod - Get coalesce interrupt period
Expand All @@ -1219,7 +1221,9 @@ void qman_portal_get_iperiod(struct qman_portal *portal, u32 *iperiod);
* qman_dqrr_set_iperiod - Set coalesce interrupt period
* @portal: portal to set the new value on
* @ithresh: new period value
*
* Returns 0 on success, or a negative error code.
*/
void qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);
int qman_portal_set_iperiod(struct qman_portal *portal, u32 iperiod);

#endif /* __FSL_QMAN_H */

0 comments on commit d72ff4b

Please sign in to comment.