*
* We must do this before dma_map_single(DMA_TO_DEVICE), because we may
* need to write into the skb.
-@@ -2036,12 +2091,129 @@ static inline int dpaa_xmit(struct dpaa_
+@@ -2036,6 +2091,121 @@ static inline int dpaa_xmit(struct dpaa_
return 0;
}
+ * the buffers
+ */
+
-+#define DPAA_A010022_HEADROOM 256
++#define DPAA_A010022_HEADROOM 256
+#define CROSS_4K_BOUND(start, size) \
-+ (((start) + (size)) > (((start) + 0x1000) & ~0xFFF))
++ (((start) + (size)) > (((start) + 0x1000) & ~0xFFF))
+
+static bool dpaa_errata_a010022_has_dma_issue(struct sk_buff *skb,
+ struct dpaa_priv *priv)
+{
+ int nr_frags, i = 0;
-+ skb_frag_t *frag;
++ skb_frag_t *frag;
+
+ /* Transfers that do not start at 16B aligned addresses will be split;
+ * Transfers that cross a 4K page boundary will also be split
+ goto err;
+ }
+ copy_skb_header(nskb, skb);
-+
+ /* We move the headroom when we align it so we have to reset the
+ * network and transport header offsets relative to the new data
+ * pointer. The checksum offload relies on these offsets.
+}
+#endif
+
- static int dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
+ static netdev_tx_t
+ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
{
- const int queue_mapping = skb_get_queue_mapping(skb);
+@@ -2043,6 +2213,7 @@ dpaa_start_xmit(struct sk_buff *skb, str
bool nonlinear = skb_is_nonlinear(skb);
struct rtnl_link_stats64 *percpu_stats;
struct dpaa_percpu_priv *percpu_priv;
struct dpaa_priv *priv;
struct qm_fd fd;
int offset = 0;
-@@ -2069,24 +2241,47 @@ static int dpaa_start_xmit(struct sk_buf
+@@ -2070,24 +2241,47 @@ dpaa_start_xmit(struct sk_buff *skb, str
/* MAX_SKB_FRAGS is equal or larger than our dpaa_SGT_MAX_ENTRIES;
* make sure we don't feed FMan with more fragments than it supports.
*/
if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0))
return NETDEV_TX_OK;
-@@ -2218,14 +2413,8 @@ static enum qman_cb_dqrr_result rx_error
+@@ -2219,14 +2413,8 @@ static enum qman_cb_dqrr_result rx_error
if (dpaa_eth_napi_schedule(percpu_priv, portal))
return qman_cb_dqrr_stop;
return qman_cb_dqrr_consume;
}
-@@ -2234,6 +2423,7 @@ static enum qman_cb_dqrr_result rx_defau
+@@ -2235,6 +2423,7 @@ static enum qman_cb_dqrr_result rx_defau
struct qman_fq *fq,
const struct qm_dqrr_entry *dq)
{
struct rtnl_link_stats64 *percpu_stats;
struct dpaa_percpu_priv *percpu_priv;
const struct qm_fd *fd = &dq->fd;
-@@ -2247,6 +2437,7 @@ static enum qman_cb_dqrr_result rx_defau
+@@ -2248,6 +2437,7 @@ static enum qman_cb_dqrr_result rx_defau
struct sk_buff *skb;
int *count_ptr;
void *vaddr;
fd_status = be32_to_cpu(fd->status);
fd_format = qm_fd_get_format(fd);
-@@ -2289,12 +2480,12 @@ static enum qman_cb_dqrr_result rx_defau
+@@ -2290,12 +2480,12 @@ static enum qman_cb_dqrr_result rx_defau
if (!dpaa_bp)
return qman_cb_dqrr_consume;
/* The only FD types that we may receive are contig and S/G */
WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg));
-@@ -2305,12 +2496,22 @@ static enum qman_cb_dqrr_result rx_defau
+@@ -2306,12 +2496,22 @@ static enum qman_cb_dqrr_result rx_defau
(*count_ptr)--;
if (likely(fd_format == qm_fd_contig))
skb->protocol = eth_type_trans(skb, net_dev);
if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
-@@ -2439,6 +2640,44 @@ static void dpaa_eth_napi_disable(struct
+@@ -2440,6 +2640,44 @@ static void dpaa_eth_napi_disable(struct
}
}
static int dpaa_open(struct net_device *net_dev)
{
struct mac_device *mac_dev;
-@@ -2449,12 +2688,9 @@ static int dpaa_open(struct net_device *
+@@ -2450,12 +2688,9 @@ static int dpaa_open(struct net_device *
mac_dev = priv->mac_dev;
dpaa_eth_napi_enable(priv);
for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
err = fman_port_enable(mac_dev->port[i]);
-@@ -2495,11 +2731,58 @@ static int dpaa_eth_stop(struct net_devi
+@@ -2496,11 +2731,58 @@ static int dpaa_eth_stop(struct net_devi
return err;
}
}
static const struct net_device_ops dpaa_ops = {
-@@ -2653,7 +2936,6 @@ static inline u16 dpaa_get_headroom(stru
+@@ -2652,7 +2934,6 @@ static inline u16 dpaa_get_headroom(stru
static int dpaa_eth_probe(struct platform_device *pdev)
{
struct dpaa_bp *dpaa_bps[DPAA_BPS_NUM] = {NULL};
struct net_device *net_dev = NULL;
struct dpaa_fq *dpaa_fq, *tmp;
struct dpaa_priv *priv = NULL;
-@@ -2662,7 +2944,51 @@ static int dpaa_eth_probe(struct platfor
+@@ -2661,7 +2942,51 @@ static int dpaa_eth_probe(struct platfor
int err = 0, i, channel;
struct device *dev;
/* Allocate this early, so we can store relevant information in
* the private area
-@@ -2670,7 +2996,7 @@ static int dpaa_eth_probe(struct platfor
+@@ -2669,7 +2994,7 @@ static int dpaa_eth_probe(struct platfor
net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TXQ_NUM);
if (!net_dev) {
dev_err(dev, "alloc_etherdev_mq() failed\n");
}
/* Do this here, so we can be verbose early */
-@@ -2682,13 +3008,6 @@ static int dpaa_eth_probe(struct platfor
+@@ -2681,13 +3006,6 @@ static int dpaa_eth_probe(struct platfor
priv->msg_enable = netif_msg_init(debug, DPAA_MSG_DEFAULT);
/* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
* we choose conservatively and let the user explicitly set a higher
* MTU via ifconfig. Otherwise, the user may end up with different MTUs
-@@ -2704,21 +3023,13 @@ static int dpaa_eth_probe(struct platfor
+@@ -2703,21 +3021,13 @@ static int dpaa_eth_probe(struct platfor
priv->buf_layout[RX].priv_data_size = DPAA_RX_PRIV_DATA_SIZE; /* Rx */
priv->buf_layout[TX].priv_data_size = DPAA_TX_PRIV_DATA_SIZE; /* Tx */
/* the raw size of the buffers used for reception */
dpaa_bps[i]->raw_size = bpool_buffer_raw_size(i, DPAA_BPS_NUM);
/* avoid runtime computations by keeping the usable size here */
-@@ -2726,11 +3037,8 @@ static int dpaa_eth_probe(struct platfor
+@@ -2725,11 +3035,8 @@ static int dpaa_eth_probe(struct platfor
dpaa_bps[i]->dev = dev;
err = dpaa_bp_alloc_pool(dpaa_bps[i]);
priv->dpaa_bps[i] = dpaa_bps[i];
}
-@@ -2741,7 +3049,7 @@ static int dpaa_eth_probe(struct platfor
+@@ -2740,7 +3047,7 @@ static int dpaa_eth_probe(struct platfor
err = dpaa_alloc_all_fqs(dev, &priv->dpaa_fq_list, &port_fqs);
if (err < 0) {
dev_err(dev, "dpaa_alloc_all_fqs() failed\n");
}
priv->mac_dev = mac_dev;
-@@ -2750,12 +3058,12 @@ static int dpaa_eth_probe(struct platfor
+@@ -2749,12 +3056,12 @@ static int dpaa_eth_probe(struct platfor
if (channel < 0) {
dev_err(dev, "dpaa_get_channel() failed\n");
err = channel;
* and add this pool channel to each's dequeue mask.
*/
dpaa_eth_add_channel(priv->channel);
-@@ -2770,20 +3078,20 @@ static int dpaa_eth_probe(struct platfor
+@@ -2769,20 +3076,20 @@ static int dpaa_eth_probe(struct platfor
err = dpaa_eth_cgr_init(priv);
if (err < 0) {
dev_err(dev, "Error initializing CGR\n");
}
priv->tx_headroom = dpaa_get_headroom(&priv->buf_layout[TX]);
-@@ -2793,7 +3101,7 @@ static int dpaa_eth_probe(struct platfor
+@@ -2792,7 +3099,7 @@ static int dpaa_eth_probe(struct platfor
err = dpaa_eth_init_ports(mac_dev, dpaa_bps, DPAA_BPS_NUM, &port_fqs,
&priv->buf_layout[0], dev);
if (err)
/* Rx traffic distribution based on keygen hashing defaults to on */
priv->keygen_in_use = true;
-@@ -2802,11 +3110,7 @@ static int dpaa_eth_probe(struct platfor
+@@ -2801,11 +3108,7 @@ static int dpaa_eth_probe(struct platfor
if (!priv->percpu_priv) {
dev_err(dev, "devm_alloc_percpu() failed\n");
err = -ENOMEM;
}
priv->num_tc = 1;
-@@ -2815,11 +3119,11 @@ static int dpaa_eth_probe(struct platfor
+@@ -2814,11 +3117,11 @@ static int dpaa_eth_probe(struct platfor
/* Initialize NAPI */
err = dpaa_napi_add(net_dev);
if (err < 0)
dpaa_eth_sysfs_init(&net_dev->dev);
-@@ -2828,32 +3132,21 @@ static int dpaa_eth_probe(struct platfor
+@@ -2827,32 +3130,21 @@ static int dpaa_eth_probe(struct platfor
return 0;
return err;
}
-@@ -2890,6 +3183,23 @@ static int dpaa_remove(struct platform_d
+@@ -2889,6 +3181,23 @@ static int dpaa_remove(struct platform_d
return err;
}
static const struct platform_device_id dpaa_devtype[] = {
{
.name = "dpaa-ethernet",
-@@ -2914,6 +3224,10 @@ static int __init dpaa_load(void)
+@@ -2913,6 +3222,10 @@ static int __init dpaa_load(void)
pr_debug("FSL DPAA Ethernet driver\n");
+fsl_dpaa_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
-@@ -629,6 +629,7 @@ static void set_port_order_restoration(s
+@@ -634,6 +634,7 @@ static void set_port_order_restoration(s
iowrite32be(tmp, &fpm_rg->fmfp_prc);
}
static void set_port_liodn(struct fman *fman, u8 port_id,
u32 liodn_base, u32 liodn_ofst)
{
-@@ -646,6 +647,27 @@ static void set_port_liodn(struct fman *
+@@ -651,6 +652,27 @@ static void set_port_liodn(struct fman *
iowrite32be(tmp, &fman->dma_regs->fmdmplr[port_id / 2]);
iowrite32be(liodn_ofst, &fman->bmi_regs->fmbm_spliodn[port_id - 1]);
}
static void enable_rams_ecc(struct fman_fpm_regs __iomem *fpm_rg)
{
-@@ -1914,7 +1936,10 @@ _return:
+@@ -1919,7 +1941,10 @@ _return:
static int fman_init(struct fman *fman)
{
struct fman_cfg *cfg = NULL;
if (is_init_done(fman->cfg))
return -EINVAL;
-@@ -1934,6 +1959,7 @@ static int fman_init(struct fman *fman)
+@@ -1939,6 +1964,7 @@ static int fman_init(struct fman *fman)
memset_io((void __iomem *)(fman->base_addr + CGP_OFFSET), 0,
fman->state->fm_port_num_of_cg);
/* Save LIODN info before FMan reset
* Skipping non-existent port 0 (i = 1)
*/
-@@ -1953,6 +1979,9 @@ static int fman_init(struct fman *fman)
+@@ -1958,6 +1984,9 @@ static int fman_init(struct fman *fman)
}
fman->liodn_base[i] = liodn_base;
}
err = fman_reset(fman);
if (err)
-@@ -2181,8 +2210,12 @@ int fman_set_port_params(struct fman *fm
+@@ -2186,8 +2215,12 @@ int fman_set_port_params(struct fman *fm
if (err)
goto return_err;
if (fman->state->rev_info.major < 6)
set_port_order_restoration(fman->fpm_regs, port_id);
-@@ -2800,7 +2833,8 @@ static struct fman *read_dts_node(struct
+@@ -2813,7 +2846,8 @@ static struct fman *read_dts_node(struct
of_node_put(muram_node);
__func__, irq, err);
--- a/drivers/net/ethernet/freescale/fman/fman.h
+++ b/drivers/net/ethernet/freescale/fman/fman.h
-@@ -41,6 +41,7 @@
+@@ -42,6 +42,7 @@
/* Frame queue Context Override */
#define FM_FD_CMD_FCO 0x80000000
#define FM_FD_CMD_RPD 0x40000000 /* Read Prepended Data */
#define FM_FD_CMD_DTC 0x10000000 /* Do L4 Checksum */
/* TX-Port: Unsupported Format */
-@@ -345,8 +346,12 @@ struct fman {
+@@ -346,8 +347,12 @@ struct fman {
unsigned long fifo_offset;
size_t fifo_size;