Skip to content

Commit 79e4998

Browse files
liupoerdavem330
authored andcommitted
net: enetc: add hw tc hw offload features for PSPF capability
This patch is to let ethtool enable/disable the tc flower offload features. Hardware ENETC has the feature of PSFP which is for per-stream policing. When enable the tc hw offloading feature, driver would enable the IEEE 802.1Qci feature. It is only set the register enable bit for this feature not enable for any entry of per stream filtering and stream gate or stream identify but get how much capabilities for each feature. Signed-off-by: Po Liu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d29bdd6 commit 79e4998

File tree

4 files changed

+96
-0
lines changed

4 files changed

+96
-0
lines changed

drivers/net/ethernet/freescale/enetc/enetc.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,9 @@ void enetc_get_si_caps(struct enetc_si *si)
756756

757757
if (val & ENETC_SIPCAPR0_QBV)
758758
si->hw_features |= ENETC_SI_F_QBV;
759+
760+
if (val & ENETC_SIPCAPR0_PSFP)
761+
si->hw_features |= ENETC_SI_F_PSFP;
759762
}
760763

761764
static int enetc_dma_alloc_bdr(struct enetc_bdr *r, size_t bd_size)
@@ -1567,6 +1570,23 @@ static int enetc_set_rss(struct net_device *ndev, int en)
15671570
return 0;
15681571
}
15691572

1573+
static int enetc_set_psfp(struct net_device *ndev, int en)
1574+
{
1575+
struct enetc_ndev_priv *priv = netdev_priv(ndev);
1576+
1577+
if (en) {
1578+
priv->active_offloads |= ENETC_F_QCI;
1579+
enetc_get_max_cap(priv);
1580+
enetc_psfp_enable(&priv->si->hw);
1581+
} else {
1582+
priv->active_offloads &= ~ENETC_F_QCI;
1583+
memset(&priv->psfp_cap, 0, sizeof(struct psfp_cap));
1584+
enetc_psfp_disable(&priv->si->hw);
1585+
}
1586+
1587+
return 0;
1588+
}
1589+
15701590
int enetc_set_features(struct net_device *ndev,
15711591
netdev_features_t features)
15721592
{
@@ -1575,6 +1595,9 @@ int enetc_set_features(struct net_device *ndev,
15751595
if (changed & NETIF_F_RXHASH)
15761596
enetc_set_rss(ndev, !!(features & NETIF_F_RXHASH));
15771597

1598+
if (changed & NETIF_F_HW_TC)
1599+
enetc_set_psfp(ndev, !!(features & NETIF_F_HW_TC));
1600+
15781601
return 0;
15791602
}
15801603

drivers/net/ethernet/freescale/enetc/enetc.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ enum enetc_errata {
151151
};
152152

153153
#define ENETC_SI_F_QBV BIT(0)
154+
#define ENETC_SI_F_PSFP BIT(1)
154155

155156
/* PCI IEP device data */
156157
struct enetc_si {
@@ -203,12 +204,20 @@ struct enetc_cls_rule {
203204
};
204205

205206
#define ENETC_MAX_BDR_INT 2 /* fixed to max # of available cpus */
207+
struct psfp_cap {
208+
u32 max_streamid;
209+
u32 max_psfp_filter;
210+
u32 max_psfp_gate;
211+
u32 max_psfp_gatelist;
212+
u32 max_psfp_meter;
213+
};
206214

207215
/* TODO: more hardware offloads */
208216
enum enetc_active_offloads {
209217
ENETC_F_RX_TSTAMP = BIT(0),
210218
ENETC_F_TX_TSTAMP = BIT(1),
211219
ENETC_F_QBV = BIT(2),
220+
ENETC_F_QCI = BIT(3),
212221
};
213222

214223
struct enetc_ndev_priv {
@@ -231,6 +240,8 @@ struct enetc_ndev_priv {
231240

232241
struct enetc_cls_rule *cls_rules;
233242

243+
struct psfp_cap psfp_cap;
244+
234245
struct device_node *phy_node;
235246
phy_interface_t if_mode;
236247
};
@@ -289,9 +300,46 @@ int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
289300
void enetc_sched_speed_set(struct net_device *ndev);
290301
int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
291302
int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data);
303+
304+
static inline void enetc_get_max_cap(struct enetc_ndev_priv *priv)
305+
{
306+
u32 reg;
307+
308+
reg = enetc_port_rd(&priv->si->hw, ENETC_PSIDCAPR);
309+
priv->psfp_cap.max_streamid = reg & ENETC_PSIDCAPR_MSK;
310+
/* Port stream filter capability */
311+
reg = enetc_port_rd(&priv->si->hw, ENETC_PSFCAPR);
312+
priv->psfp_cap.max_psfp_filter = reg & ENETC_PSFCAPR_MSK;
313+
/* Port stream gate capability */
314+
reg = enetc_port_rd(&priv->si->hw, ENETC_PSGCAPR);
315+
priv->psfp_cap.max_psfp_gate = (reg & ENETC_PSGCAPR_SGIT_MSK);
316+
priv->psfp_cap.max_psfp_gatelist = (reg & ENETC_PSGCAPR_GCL_MSK) >> 16;
317+
/* Port flow meter capability */
318+
reg = enetc_port_rd(&priv->si->hw, ENETC_PFMCAPR);
319+
priv->psfp_cap.max_psfp_meter = reg & ENETC_PFMCAPR_MSK;
320+
}
321+
322+
static inline void enetc_psfp_enable(struct enetc_hw *hw)
323+
{
324+
enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) |
325+
ENETC_PPSFPMR_PSFPEN | ENETC_PPSFPMR_VS |
326+
ENETC_PPSFPMR_PVC | ENETC_PPSFPMR_PVZC);
327+
}
328+
329+
static inline void enetc_psfp_disable(struct enetc_hw *hw)
330+
{
331+
enetc_wr(hw, ENETC_PPSFPMR, enetc_rd(hw, ENETC_PPSFPMR) &
332+
~ENETC_PPSFPMR_PSFPEN & ~ENETC_PPSFPMR_VS &
333+
~ENETC_PPSFPMR_PVC & ~ENETC_PPSFPMR_PVZC);
334+
}
292335
#else
293336
#define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
294337
#define enetc_sched_speed_set(ndev) (void)0
295338
#define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
296339
#define enetc_setup_tc_txtime(ndev, type_data) -EOPNOTSUPP
340+
#define enetc_get_max_cap(p) \
341+
memset(&((p)->psfp_cap), 0, sizeof(struct psfp_cap))
342+
343+
#define enetc_psfp_enable(hw) (void)0
344+
#define enetc_psfp_disable(hw) (void)0
297345
#endif

drivers/net/ethernet/freescale/enetc/enetc_hw.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define ENETC_SICTR1 0x1c
2020
#define ENETC_SIPCAPR0 0x20
2121
#define ENETC_SIPCAPR0_QBV BIT(4)
22+
#define ENETC_SIPCAPR0_PSFP BIT(9)
2223
#define ENETC_SIPCAPR0_RSS BIT(8)
2324
#define ENETC_SIPCAPR1 0x24
2425
#define ENETC_SITGTGR 0x30
@@ -228,6 +229,15 @@ enum enetc_bdr_type {TX, RX};
228229
#define ENETC_PM0_IFM_RLP (BIT(5) | BIT(11))
229230
#define ENETC_PM0_IFM_RGAUTO (BIT(15) | ENETC_PMO_IFM_RG | BIT(1))
230231
#define ENETC_PM0_IFM_XGMII BIT(12)
232+
#define ENETC_PSIDCAPR 0x1b08
233+
#define ENETC_PSIDCAPR_MSK GENMASK(15, 0)
234+
#define ENETC_PSFCAPR 0x1b18
235+
#define ENETC_PSFCAPR_MSK GENMASK(15, 0)
236+
#define ENETC_PSGCAPR 0x1b28
237+
#define ENETC_PSGCAPR_GCL_MSK GENMASK(18, 16)
238+
#define ENETC_PSGCAPR_SGIT_MSK GENMASK(15, 0)
239+
#define ENETC_PFMCAPR 0x1b38
240+
#define ENETC_PFMCAPR_MSK GENMASK(15, 0)
231241

232242
/* MAC counters */
233243
#define ENETC_PM0_REOCT 0x8100
@@ -621,3 +631,10 @@ struct enetc_cbd {
621631
/* Port time specific departure */
622632
#define ENETC_PTCTSDR(n) (0x1210 + 4 * (n))
623633
#define ENETC_TSDE BIT(31)
634+
635+
/* PSFP setting */
636+
#define ENETC_PPSFPMR 0x11b00
637+
#define ENETC_PPSFPMR_PSFPEN BIT(0)
638+
#define ENETC_PPSFPMR_VS BIT(1)
639+
#define ENETC_PPSFPMR_PVC BIT(2)
640+
#define ENETC_PPSFPMR_PVZC BIT(3)

drivers/net/ethernet/freescale/enetc/enetc_pf.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,14 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
727727
if (si->hw_features & ENETC_SI_F_QBV)
728728
priv->active_offloads |= ENETC_F_QBV;
729729

730+
if (si->hw_features & ENETC_SI_F_PSFP) {
731+
priv->active_offloads |= ENETC_F_QCI;
732+
ndev->features |= NETIF_F_HW_TC;
733+
ndev->hw_features |= NETIF_F_HW_TC;
734+
enetc_get_max_cap(priv);
735+
enetc_psfp_enable(&si->hw);
736+
}
737+
730738
/* pick up primary MAC address from SI */
731739
enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr);
732740
}

0 commit comments

Comments
 (0)