Skip to content

Commit

Permalink
Merge branch 'net-stmmac-Stop-using-hard-coded-callbacks'
Browse files Browse the repository at this point in the history
Jose Abreu says:

====================
net: stmmac: Stop using hard-coded callbacks

This a starting point for a cleanup and re-organization of stmmac.

In this series we stop using hard-coded callbacks along the code and use
instead helpers which are defined in a single place ("hwif.h").

This brings several advantages:
	1) Less typing :)
	2) Guaranteed function pointer check
	3) More flexibility

By 2) we stop using the repeated pattern of:
	if (priv->hw->mac->some_func)
		priv->hw->mac->some_func(...)

I didn't check but I expect the final .ko will be bigger with this series
because *all* of function pointers are checked.

Anyway, I hope this can make the code more readable and more flexible now.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 16, 2018
2 parents 309c446 + 2c520b1 commit 5da8baa
Show file tree
Hide file tree
Showing 13 changed files with 726 additions and 577 deletions.
34 changes: 16 additions & 18 deletions drivers/net/ethernet/stmicro/stmmac/chain_mode.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

#include "stmmac.h"

static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
static int jumbo_frm(void *p, struct sk_buff *skb, int csum)
{
struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)p;
unsigned int nopaged_len = skb_headlen(skb);
Expand All @@ -51,8 +51,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
tx_q->tx_skbuff_dma[entry].buf = des2;
tx_q->tx_skbuff_dma[entry].len = bmax;
/* do not close the descriptor and do not set own bit */
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
0, false, skb->len);
stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
0, false, skb->len);

while (len != 0) {
tx_q->tx_skbuff[entry] = NULL;
Expand All @@ -68,9 +68,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
return -1;
tx_q->tx_skbuff_dma[entry].buf = des2;
tx_q->tx_skbuff_dma[entry].len = bmax;
priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
STMMAC_CHAIN_MODE, 1,
false, skb->len);
stmmac_prepare_tx_desc(priv, desc, 0, bmax, csum,
STMMAC_CHAIN_MODE, 1, false, skb->len);
len -= bmax;
i++;
} else {
Expand All @@ -83,9 +82,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
tx_q->tx_skbuff_dma[entry].buf = des2;
tx_q->tx_skbuff_dma[entry].len = len;
/* last descriptor can be set now */
priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
STMMAC_CHAIN_MODE, 1,
true, skb->len);
stmmac_prepare_tx_desc(priv, desc, 0, len, csum,
STMMAC_CHAIN_MODE, 1, true, skb->len);
len = 0;
}
}
Expand All @@ -95,7 +93,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
return entry;
}

static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
static unsigned int is_jumbo_frm(int len, int enh_desc)
{
unsigned int ret = 0;

Expand All @@ -107,7 +105,7 @@ static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
return ret;
}

static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
static void init_dma_chain(void *des, dma_addr_t phy_addr,
unsigned int size, unsigned int extend_desc)
{
/*
Expand Down Expand Up @@ -137,7 +135,7 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
}
}

static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
static void refill_desc3(void *priv_ptr, struct dma_desc *p)
{
struct stmmac_rx_queue *rx_q = (struct stmmac_rx_queue *)priv_ptr;
struct stmmac_priv *priv = rx_q->priv_data;
Expand All @@ -153,7 +151,7 @@ static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
sizeof(struct dma_desc)));
}

static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
static void clean_desc3(void *priv_ptr, struct dma_desc *p)
{
struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)priv_ptr;
struct stmmac_priv *priv = tx_q->priv_data;
Expand All @@ -171,9 +169,9 @@ static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
}

const struct stmmac_mode_ops chain_mode_ops = {
.init = stmmac_init_dma_chain,
.is_jumbo_frm = stmmac_is_jumbo_frm,
.jumbo_frm = stmmac_jumbo_frm,
.refill_desc3 = stmmac_refill_desc3,
.clean_desc3 = stmmac_clean_desc3,
.init = init_dma_chain,
.is_jumbo_frm = is_jumbo_frm,
.jumbo_frm = jumbo_frm,
.refill_desc3 = refill_desc3,
.clean_desc3 = clean_desc3,
};
199 changes: 1 addition & 198 deletions drivers/net/ethernet/stmicro/stmmac/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#endif

#include "descs.h"
#include "hwif.h"
#include "mmc.h"

/* Synopsys Core versions */
Expand Down Expand Up @@ -377,197 +378,11 @@ struct dma_features {

#define JUMBO_LEN 9000

/* Descriptors helpers */
struct stmmac_desc_ops {
/* DMA RX descriptor ring initialization */
void (*init_rx_desc) (struct dma_desc *p, int disable_rx_ic, int mode,
int end);
/* DMA TX descriptor ring initialization */
void (*init_tx_desc) (struct dma_desc *p, int mode, int end);

/* Invoked by the xmit function to prepare the tx descriptor */
void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
bool csum_flag, int mode, bool tx_own,
bool ls, unsigned int tot_pkt_len);
void (*prepare_tso_tx_desc)(struct dma_desc *p, int is_fs, int len1,
int len2, bool tx_own, bool ls,
unsigned int tcphdrlen,
unsigned int tcppayloadlen);
/* Set/get the owner of the descriptor */
void (*set_tx_owner) (struct dma_desc *p);
int (*get_tx_owner) (struct dma_desc *p);
/* Clean the tx descriptor as soon as the tx irq is received */
void (*release_tx_desc) (struct dma_desc *p, int mode);
/* Clear interrupt on tx frame completion. When this bit is
* set an interrupt happens as soon as the frame is transmitted */
void (*set_tx_ic)(struct dma_desc *p);
/* Last tx segment reports the transmit status */
int (*get_tx_ls) (struct dma_desc *p);
/* Return the transmit status looking at the TDES1 */
int (*tx_status) (void *data, struct stmmac_extra_stats *x,
struct dma_desc *p, void __iomem *ioaddr);
/* Get the buffer size from the descriptor */
int (*get_tx_len) (struct dma_desc *p);
/* Handle extra events on specific interrupts hw dependent */
void (*set_rx_owner) (struct dma_desc *p);
/* Get the receive frame size */
int (*get_rx_frame_len) (struct dma_desc *p, int rx_coe_type);
/* Return the reception status looking at the RDES1 */
int (*rx_status) (void *data, struct stmmac_extra_stats *x,
struct dma_desc *p);
void (*rx_extended_status) (void *data, struct stmmac_extra_stats *x,
struct dma_extended_desc *p);
/* Set tx timestamp enable bit */
void (*enable_tx_timestamp) (struct dma_desc *p);
/* get tx timestamp status */
int (*get_tx_timestamp_status) (struct dma_desc *p);
/* get timestamp value */
u64(*get_timestamp) (void *desc, u32 ats);
/* get rx timestamp status */
int (*get_rx_timestamp_status)(void *desc, void *next_desc, u32 ats);
/* Display ring */
void (*display_ring)(void *head, unsigned int size, bool rx);
/* set MSS via context descriptor */
void (*set_mss)(struct dma_desc *p, unsigned int mss);
};

extern const struct stmmac_desc_ops enh_desc_ops;
extern const struct stmmac_desc_ops ndesc_ops;

/* Specific DMA helpers */
struct stmmac_dma_ops {
/* DMA core initialization */
int (*reset)(void __iomem *ioaddr);
void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
u32 dma_tx, u32 dma_rx, int atds);
void (*init_chan)(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan);
void (*init_rx_chan)(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
u32 dma_rx_phy, u32 chan);
void (*init_tx_chan)(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
u32 dma_tx_phy, u32 chan);
/* Configure the AXI Bus Mode Register */
void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi);
/* Dump DMA registers */
void (*dump_regs)(void __iomem *ioaddr, u32 *reg_space);
/* Set tx/rx threshold in the csr6 register
* An invalid value enables the store-and-forward mode */
void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
int rxfifosz);
void (*dma_rx_mode)(void __iomem *ioaddr, int mode, u32 channel,
int fifosz, u8 qmode);
void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel,
int fifosz, u8 qmode);
/* To track extra statistic (if supported) */
void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
void __iomem *ioaddr);
void (*enable_dma_transmission) (void __iomem *ioaddr);
void (*enable_dma_irq)(void __iomem *ioaddr, u32 chan);
void (*disable_dma_irq)(void __iomem *ioaddr, u32 chan);
void (*start_tx)(void __iomem *ioaddr, u32 chan);
void (*stop_tx)(void __iomem *ioaddr, u32 chan);
void (*start_rx)(void __iomem *ioaddr, u32 chan);
void (*stop_rx)(void __iomem *ioaddr, u32 chan);
int (*dma_interrupt) (void __iomem *ioaddr,
struct stmmac_extra_stats *x, u32 chan);
/* If supported then get the optional core features */
void (*get_hw_feature)(void __iomem *ioaddr,
struct dma_features *dma_cap);
/* Program the HW RX Watchdog */
void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 number_chan);
void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
};

struct mac_device_info;

/* Helpers to program the MAC core */
struct stmmac_ops {
/* MAC core initialization */
void (*core_init)(struct mac_device_info *hw, struct net_device *dev);
/* Enable the MAC RX/TX */
void (*set_mac)(void __iomem *ioaddr, bool enable);
/* Enable and verify that the IPC module is supported */
int (*rx_ipc)(struct mac_device_info *hw);
/* Enable RX Queues */
void (*rx_queue_enable)(struct mac_device_info *hw, u8 mode, u32 queue);
/* RX Queues Priority */
void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
/* TX Queues Priority */
void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue);
/* RX Queues Routing */
void (*rx_queue_routing)(struct mac_device_info *hw, u8 packet,
u32 queue);
/* Program RX Algorithms */
void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
/* Program TX Algorithms */
void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg);
/* Set MTL TX queues weight */
void (*set_mtl_tx_queue_weight)(struct mac_device_info *hw,
u32 weight, u32 queue);
/* RX MTL queue to RX dma mapping */
void (*map_mtl_to_dma)(struct mac_device_info *hw, u32 queue, u32 chan);
/* Configure AV Algorithm */
void (*config_cbs)(struct mac_device_info *hw, u32 send_slope,
u32 idle_slope, u32 high_credit, u32 low_credit,
u32 queue);
/* Dump MAC registers */
void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space);
/* Handle extra events on specific interrupts hw dependent */
int (*host_irq_status)(struct mac_device_info *hw,
struct stmmac_extra_stats *x);
/* Handle MTL interrupts */
int (*host_mtl_irq_status)(struct mac_device_info *hw, u32 chan);
/* Multicast filter setting */
void (*set_filter)(struct mac_device_info *hw, struct net_device *dev);
/* Flow control setting */
void (*flow_ctrl)(struct mac_device_info *hw, unsigned int duplex,
unsigned int fc, unsigned int pause_time, u32 tx_cnt);
/* Set power management mode (e.g. magic frame) */
void (*pmt)(struct mac_device_info *hw, unsigned long mode);
/* Set/Get Unicast MAC addresses */
void (*set_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
unsigned int reg_n);
void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr,
unsigned int reg_n);
void (*set_eee_mode)(struct mac_device_info *hw,
bool en_tx_lpi_clockgating);
void (*reset_eee_mode)(struct mac_device_info *hw);
void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);
void (*set_eee_pls)(struct mac_device_info *hw, int link);
void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x,
u32 rx_queues, u32 tx_queues);
/* PCS calls */
void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral,
bool loopback);
void (*pcs_rane)(void __iomem *ioaddr, bool restart);
void (*pcs_get_adv_lp)(void __iomem *ioaddr, struct rgmii_adv *adv);
/* Safety Features */
int (*safety_feat_config)(void __iomem *ioaddr, unsigned int asp);
bool (*safety_feat_irq_status)(struct net_device *ndev,
void __iomem *ioaddr, unsigned int asp,
struct stmmac_safety_stats *stats);
const char *(*safety_feat_dump)(struct stmmac_safety_stats *stats,
int index, unsigned long *count);
};

/* PTP and HW Timer helpers */
struct stmmac_hwtimestamp {
void (*config_hw_tstamping) (void __iomem *ioaddr, u32 data);
u32 (*config_sub_second_increment)(void __iomem *ioaddr, u32 ptp_clock,
int gmac4);
int (*init_systime) (void __iomem *ioaddr, u32 sec, u32 nsec);
int (*config_addend) (void __iomem *ioaddr, u32 addend);
int (*adjust_systime) (void __iomem *ioaddr, u32 sec, u32 nsec,
int add_sub, int gmac4);
u64(*get_systime) (void __iomem *ioaddr);
};

extern const struct stmmac_hwtimestamp stmmac_ptp;
extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;

Expand All @@ -590,18 +405,6 @@ struct mii_regs {
unsigned int clk_csr_mask;
};

/* Helpers to manage the descriptors for chain and ring modes */
struct stmmac_mode_ops {
void (*init) (void *des, dma_addr_t phy_addr, unsigned int size,
unsigned int extend_desc);
unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
int (*jumbo_frm)(void *priv, struct sk_buff *skb, int csum);
int (*set_16kib_bfsize)(int mtu);
void (*init_desc3)(struct dma_desc *p);
void (*refill_desc3) (void *priv, struct dma_desc *p);
void (*clean_desc3) (void *priv, struct dma_desc *p);
};

struct mac_device_info {
const struct stmmac_ops *mac;
const struct stmmac_desc_ops *desc;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ static int dwmac4_wrback_get_tx_timestamp_status(struct dma_desc *p)
return 0;
}

static inline u64 dwmac4_get_timestamp(void *desc, u32 ats)
static inline void dwmac4_get_timestamp(void *desc, u32 ats, u64 *ts)
{
struct dma_desc *p = (struct dma_desc *)desc;
u64 ns;
Expand All @@ -232,7 +232,7 @@ static inline u64 dwmac4_get_timestamp(void *desc, u32 ats)
/* convert high/sec time stamp value to nanosecond */
ns += le32_to_cpu(p->des1) * 1000000000ULL;

return ns;
*ts = ns;
}

static int dwmac4_rx_check_timestamp(void *desc)
Expand Down
19 changes: 11 additions & 8 deletions drivers/net/ethernet/stmicro/stmmac/dwmac5.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,16 @@ int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp)
return 0;
}

bool dwmac5_safety_feat_irq_status(struct net_device *ndev,
int dwmac5_safety_feat_irq_status(struct net_device *ndev,
void __iomem *ioaddr, unsigned int asp,
struct stmmac_safety_stats *stats)
{
bool ret = false, err, corr;
bool err, corr;
u32 mtl, dma;
int ret = 0;

if (!asp)
return false;
return -EINVAL;

mtl = readl(ioaddr + MTL_SAFETY_INT_STATUS);
dma = readl(ioaddr + DMA_SAFETY_INT_STATUS);
Expand Down Expand Up @@ -282,17 +283,19 @@ static const struct dwmac5_error {
{ dwmac5_dma_errors },
};

const char *dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
int index, unsigned long *count)
int dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
int index, unsigned long *count, const char **desc)
{
int module = index / 32, offset = index % 32;
unsigned long *ptr = (unsigned long *)stats;

if (module >= ARRAY_SIZE(dwmac5_all_errors))
return NULL;
return -EINVAL;
if (!dwmac5_all_errors[module].desc[offset].valid)
return NULL;
return -EINVAL;
if (count)
*count = *(ptr + index);
return dwmac5_all_errors[module].desc[offset].desc;
if (desc)
*desc = dwmac5_all_errors[module].desc[offset].desc;
return 0;
}
6 changes: 3 additions & 3 deletions drivers/net/ethernet/stmicro/stmmac/dwmac5.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
#define DMA_ECC_INT_STATUS 0x00001088

int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp);
bool dwmac5_safety_feat_irq_status(struct net_device *ndev,
int dwmac5_safety_feat_irq_status(struct net_device *ndev,
void __iomem *ioaddr, unsigned int asp,
struct stmmac_safety_stats *stats);
const char *dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
int index, unsigned long *count);
int dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
int index, unsigned long *count, const char **desc);

#endif /* __DWMAC5_H__ */
Loading

0 comments on commit 5da8baa

Please sign in to comment.