summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/designware.c2
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_portal.c66
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_portal.h22
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_private.h2
-rw-r--r--drivers/net/fsl-mc/dpni.c2
-rw-r--r--drivers/net/fsl-mc/mc.c121
-rw-r--r--drivers/net/keystone_net.c10
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.c162
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.h1
-rw-r--r--drivers/net/rtl8169.c236
-rw-r--r--drivers/net/sandbox-raw.c2
-rw-r--r--drivers/net/sandbox.c2
-rw-r--r--drivers/net/sunxi_emac.c2
-rw-r--r--drivers/net/zynq_gem.c26
14 files changed, 411 insertions, 245 deletions
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 645ca6427cf..bcae842389a 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -528,7 +528,7 @@ static int designware_eth_send(struct udevice *dev, void *packet, int length)
return _dw_eth_send(priv, packet, length);
}
-static int designware_eth_recv(struct udevice *dev, uchar **packetp)
+static int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct dw_eth_dev *priv = dev_get_priv(dev);
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c
index dd2a7deee5f..5fa8d953e5c 100644
--- a/drivers/net/fsl-mc/dpio/qbman_portal.c
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.c
@@ -64,7 +64,7 @@ enum qbman_sdqcr_fc {
struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
{
int ret;
- struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+ struct qbman_swp *p = malloc(sizeof(struct qbman_swp));
if (!p)
return NULL;
@@ -77,7 +77,7 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
- p->vdq.busy = 0; /* TODO: convert to atomic_t */
+ atomic_set(&p->vdq.busy, 1);
p->vdq.valid_bit = QB_VALID_BIT;
p->dqrr.next_idx = 0;
p->dqrr.valid_bit = QB_VALID_BIT;
@@ -165,7 +165,6 @@ static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
-static struct qb_attr_code code_eq_rsp_hi = QB_CODE(7, 0, 32);
enum qbman_eq_cmd_e {
/* No enqueue, primarily for plugging ORP gaps for dropped frames */
@@ -197,8 +196,7 @@ void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
{
uint32_t *cl = qb_cl(d);
- qb_attr_code_encode(&code_eq_rsp_lo, cl, lower32(storage_phys));
- qb_attr_code_encode(&code_eq_rsp_hi, cl, upper32(storage_phys));
+ qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
}
@@ -253,7 +251,6 @@ static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
-static struct qb_attr_code code_pull_rsp_hi = QB_CODE(3, 0, 32);
enum qb_pull_dt_e {
qb_pull_dt_channel,
@@ -282,8 +279,7 @@ void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
}
qb_attr_code_encode(&code_pull_rls, cl, 1);
qb_attr_code_encode(&code_pull_stash, cl, !!stash);
- qb_attr_code_encode(&code_pull_rsp_lo, cl, lower32(storage_phys));
- qb_attr_code_encode(&code_pull_rsp_hi, cl, upper32(storage_phys));
+ qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
}
void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
@@ -316,10 +312,10 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
uint32_t *p;
uint32_t *cl = qb_cl(d);
- /* TODO: convert to atomic_t */
- if (s->vdq.busy)
+ if (!atomic_dec_and_test(&s->vdq.busy)) {
+ atomic_inc(&s->vdq.busy);
return -EBUSY;
- s->vdq.busy = 1;
+ }
s->vdq.storage = *(void **)&cl[4];
s->vdq.token = qb_attr_code_decode(&code_pull_token, cl);
p = qbman_cena_write_start(&s->sys, QBMAN_CENA_SWP_VDQCR);
@@ -359,36 +355,44 @@ const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
{
uint32_t verb;
uint32_t response_verb;
- const struct ldpaa_dq *dq = qbman_cena_read(&s->sys,
- QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
- const uint32_t *p = qb_cl(dq);
+ uint32_t flags;
+ const struct ldpaa_dq *dq;
+ const uint32_t *p;
+ dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ p = qb_cl(dq);
verb = qb_attr_code_decode(&code_dqrr_verb, p);
- /* If the valid-bit isn't of the expected polarity, nothing there */
+
+ /* If the valid-bit isn't of the expected polarity, nothing there. Note,
+ * in the DQRR reset bug workaround, we shouldn't need to skip these
+ * check, because we've already determined that a new entry is available
+ * and we've invalidated the cacheline before reading it, so the
+ * valid-bit behaviour is repaired and should tell us what we already
+ * knew from reading PI.
+ */
if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
qbman_cena_invalidate_prefetch(&s->sys,
- QBMAN_CENA_SWP_DQRR(
- s->dqrr.next_idx));
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
return NULL;
}
/* There's something there. Move "next_idx" attention to the next ring
* entry (and prefetch it) before returning what we found. */
s->dqrr.next_idx++;
- s->dqrr.next_idx &= 3; /* Wrap around at 4 */
+ s->dqrr.next_idx &= QBMAN_DQRR_SIZE - 1; /* Wrap around at 4 */
/* TODO: it's possible to do all this without conditionals, optimise it
* later. */
if (!s->dqrr.next_idx)
s->dqrr.valid_bit ^= QB_VALID_BIT;
- /* VDQCR "no longer busy" hook - if VDQCR shows "busy" and this is a
- * VDQCR result, mark it as non-busy. */
- if (s->vdq.busy) {
- uint32_t flags = ldpaa_dq_flags(dq);
-
- response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
- if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) &&
- (flags & LDPAA_DQ_STAT_VOLATILE))
- s->vdq.busy = 0;
- }
+
+ /* If this is the final response to a volatile dequeue command
+ indicate that the vdq is no longer busy */
+ flags = ldpaa_dq_flags(dq);
+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
+ if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) &&
+ (flags & LDPAA_DQ_STAT_VOLATILE) &&
+ (flags & LDPAA_DQ_STAT_EXPIRED))
+ atomic_inc(&s->vdq.busy);
+
qbman_cena_invalidate_prefetch(&s->sys,
QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
return dq;
@@ -448,8 +452,10 @@ int qbman_dq_entry_has_newtoken(struct qbman_swp *s,
* reset "busy". We instead base the decision on whether the current
* result is sitting at the first 'storage' location of the busy
* command. */
- if (s->vdq.busy && (s->vdq.storage == dq))
- s->vdq.busy = 0;
+ if (s->vdq.storage == dq) {
+ s->vdq.storage = NULL;
+ atomic_inc(&s->vdq.busy);
+ }
return 1;
}
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.h b/drivers/net/fsl-mc/dpio/qbman_portal.h
index bb67c3bd066..86e2c3aac4c 100644
--- a/drivers/net/fsl-mc/dpio/qbman_portal.h
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.h
@@ -14,6 +14,10 @@
/* Management command result codes */
#define QBMAN_MC_RSLT_OK 0xf0
+/* TBD: as of QBMan 4.1, DQRR will be 8 rather than 4! */
+#define QBMAN_DQRR_SIZE 4
+
+
/* --------------------- */
/* portal data structure */
/* --------------------- */
@@ -48,14 +52,13 @@ struct qbman_swp {
* to whether or not a command can be submitted, not whether or
* not a previously-submitted command is still executing. In
* other words, once proof is seen that the previously-submitted
- * command is executing, "vdq" is no longer "busy". TODO:
- * convert this to "atomic_t" so that it is thread-safe (without
- * locking). */
- int busy;
+ * command is executing, "vdq" is no longer "busy".
+ */
+ atomic_t busy;
uint32_t valid_bit; /* 0x00 or 0x80 */
/* We need to determine when vdq is no longer busy. This depends
* on whether the "busy" (last-submitted) dequeue command is
- * targetting DQRR or main-memory, and detected is based on the
+ * targeting DQRR or main-memory, and detected is based on the
* presence of the dequeue command's "token" showing up in
* dequeue entries in DQRR or main-memory (respectively). Debug
* builds will, when submitting vdq commands, verify that the
@@ -127,6 +130,7 @@ static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
}
+
/* encode a field to a cacheline */
static inline void qb_attr_code_encode(const struct qb_attr_code *code,
uint32_t *cacheline, uint32_t val)
@@ -136,6 +140,12 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code,
| e32_uint32_t(code->lsoffset, code->width, val);
}
+static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
+ uint64_t *cacheline, uint64_t val)
+{
+ cacheline[code->word / 2] = val;
+}
+
/* ---------------------- */
/* Descriptors/cachelines */
/* ---------------------- */
@@ -144,7 +154,7 @@ static inline void qb_attr_code_encode(const struct qb_attr_code *code,
* a "descriptor" type that the caller can instantiate however they like.
* Ultimately though, it is just a cacheline of binary storage (or something
* smaller when it is known that the descriptor doesn't need all 64 bytes) for
- * holding pre-formatted pieces of harware commands. The performance-critical
+ * holding pre-formatted pieces of hardware commands. The performance-critical
* code can then copy these descriptors directly into hardware command
* registers more efficiently than trying to construct/format commands
* on-the-fly. The API user sees the descriptor as an array of 32-bit words in
diff --git a/drivers/net/fsl-mc/dpio/qbman_private.h b/drivers/net/fsl-mc/dpio/qbman_private.h
index 2d2556b7556..f1f16b828bf 100644
--- a/drivers/net/fsl-mc/dpio/qbman_private.h
+++ b/drivers/net/fsl-mc/dpio/qbman_private.h
@@ -9,7 +9,7 @@
#include <errno.h>
#include <asm/io.h>
#include <linux/types.h>
-#include <linux/compat.h>
+#include <asm/atomic.h>
#include <malloc.h>
#include <fsl-mc/fsl_qbman_base.h>
diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c
index b3844012955..7bc2504f8c3 100644
--- a/drivers/net/fsl-mc/dpni.c
+++ b/drivers/net/fsl-mc/dpni.c
@@ -313,7 +313,7 @@ int dpni_set_counter(struct fsl_mc_io *mc_io,
int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
uint16_t token,
- struct dpni_link_cfg *cfg)
+ const struct dpni_link_cfg *cfg)
{
struct mc_command cmd = { 0 };
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index c5c44bcab04..62a68c27441 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -3,13 +3,15 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <common.h>
#include <errno.h>
#include <asm/io.h>
+#include <libfdt.h>
+#include <fdt_support.h>
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_mc_private.h>
#include <fsl-mc/fsl_dpmng.h>
-#include <fsl_debug_server.h>
#include <fsl-mc/fsl_dprc.h>
#include <fsl-mc/fsl_dpio.h>
#include <fsl-mc/fsl_qbman_portal.h>
@@ -186,6 +188,36 @@ static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr,
return 0;
}
+static int mc_fixup_dpc(u64 dpc_addr)
+{
+ void *blob = (void *)dpc_addr;
+ int nodeoffset;
+
+ /* delete any existing ICID pools */
+ nodeoffset = fdt_path_offset(blob, "/resources/icid_pools");
+ if (fdt_del_node(blob, nodeoffset) < 0)
+ printf("\nfsl-mc: WARNING: could not delete ICID pool\n");
+
+ /* add a new pool */
+ nodeoffset = fdt_path_offset(blob, "/resources");
+ if (nodeoffset < 0) {
+ printf("\nfsl-mc: ERROR: DPC is missing /resources\n");
+ return -EINVAL;
+ }
+ nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools");
+ nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0");
+ do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
+ "base_icid", FSL_DPAA2_STREAM_ID_START, 1);
+ do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
+ "num",
+ FSL_DPAA2_STREAM_ID_END -
+ FSL_DPAA2_STREAM_ID_START + 1, 1);
+
+ flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob));
+
+ return 0;
+}
+
static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
{
u64 mc_dpc_offset;
@@ -225,13 +257,13 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
* Don't return with error here, since the MC firmware can
* still boot without a DPC
*/
- printf("fsl-mc: WARNING: No DPC image found\n");
+ printf("\nfsl-mc: WARNING: No DPC image found");
return 0;
}
dpc_size = fdt_totalsize(dpc_fdt_hdr);
if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) {
- printf("fsl-mc: ERROR: Bad DPC image (too large: %d)\n",
+ printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n",
dpc_size);
return -EINVAL;
}
@@ -240,6 +272,9 @@ static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
(u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
#endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
+ if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset))
+ return -EINVAL;
+
dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
return 0;
}
@@ -279,13 +314,13 @@ static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size)
error = fdt_check_header(dpl_fdt_hdr);
if (error != 0) {
- printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
+ printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n");
return error;
}
dpl_size = fdt_totalsize(dpl_fdt_hdr);
if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
- printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
+ printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n",
dpl_size);
return -EINVAL;
}
@@ -322,6 +357,23 @@ static unsigned long get_mc_boot_timeout_ms(void)
return timeout_ms;
}
+#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
+static int load_mc_aiop_img(u64 mc_ram_addr, size_t mc_ram_size)
+{
+ void *aiop_img;
+
+ /*
+ * Load the MC AIOP image in the MC private DRAM block:
+ */
+
+ aiop_img = (void *)CONFIG_SYS_LS_MC_AIOP_IMG_ADDR;
+ mc_copy_image("MC AIOP image",
+ (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH,
+ mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET);
+
+ return 0;
+}
+#endif
static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
{
u32 reg_gsr;
@@ -330,7 +382,6 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
dmb();
- debug("Polling mc_ccsr_regs->reg_gsr ...\n");
assert(timeout_ms > 0);
for (;;) {
udelay(1000); /* throttle polling */
@@ -345,10 +396,7 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
}
if (timeout_ms == 0) {
- if (booting_mc)
- printf("fsl-mc: timeout booting management complex firmware\n");
- else
- printf("fsl-mc: timeout deploying data path layout\n");
+ printf("ERROR: timeout\n");
/* TODO: Get an error status from an MC CCSR register */
return -ETIMEDOUT;
@@ -361,15 +409,13 @@ static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
* appropriate errno, so that the status property is set to
* failure in the fsl,dprc device tree node.
*/
- if (booting_mc) {
- printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
- reg_gsr);
- } else {
- printf("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n",
- reg_gsr);
- }
+ printf("WARNING: Firmware returned an error (GSR: %#x)\n",
+ reg_gsr);
+ } else {
+ printf("SUCCESS\n");
}
+
*final_reg_gsr = reg_gsr;
return 0;
}
@@ -403,13 +449,6 @@ int mc_init(void)
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
}
-#ifdef CONFIG_FSL_DEBUG_SERVER
- /*
- * FIXME: I don't think this is right. See get_dram_size_to_hide()
- */
- mc_ram_addr -= debug_server_get_dram_block_size();
-#endif
-
error = calculate_mc_private_ram_params(mc_ram_addr,
mc_ram_size,
&mc_ram_aligned_base_addr,
@@ -454,6 +493,12 @@ int mc_init(void)
if (error != 0)
goto out;
+#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
+ error = load_mc_aiop_img(mc_ram_addr, mc_ram_size);
+ if (error != 0)
+ goto out;
+#endif
+
debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
dump_mc_ccsr_regs(mc_ccsr_regs);
@@ -465,14 +510,14 @@ int mc_init(void)
out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
out_le32(&mc_ccsr_regs->reg_mcfbahr,
(u32)(mc_ram_aligned_base_addr >> 32));
- out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK);
+ out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ);
/*
* Tell the MC that we want delayed DPL deployment.
*/
out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
- printf("\nfsl-mc: Booting Management Complex ...\n");
+ printf("\nfsl-mc: Booting Management Complex ... ");
/*
* Deassert reset and release MC core 0 to run
@@ -509,9 +554,14 @@ int mc_init(void)
goto out;
}
- if (MC_VER_MAJOR != mc_ver_info.major)
+ if (MC_VER_MAJOR != mc_ver_info.major) {
printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
mc_ver_info.major, MC_VER_MAJOR);
+ printf("fsl-mc: Update the Management Complex firmware\n");
+
+ error = -ENODEV;
+ goto out;
+ }
if (MC_VER_MINOR != mc_ver_info.minor)
printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
@@ -525,13 +575,14 @@ int mc_init(void)
* Tell the MC to deploy the DPL:
*/
out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
- printf("\nfsl-mc: Deploying data path layout ...\n");
+ printf("fsl-mc: Deploying data path layout ... ");
error = wait_for_mc(false, &reg_gsr);
if (error != 0)
goto out;
+
out:
if (error != 0)
- mc_boot_status = -error;
+ mc_boot_status = error;
else
mc_boot_status = 0;
@@ -600,14 +651,16 @@ int dpio_init(struct dprc_obj_desc obj_desc)
printf("dpio_enable() failed %d\n", err);
goto err_get_enable;
}
- debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n",
- attr.qbman_portal_ce_paddr,
- attr.qbman_portal_ci_paddr,
+ debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n",
+ attr.qbman_portal_ce_offset,
+ attr.qbman_portal_ci_offset,
attr.qbman_portal_id,
attr.num_priorities);
- p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr;
- p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr;
+ p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
+ + attr.qbman_portal_ce_offset);
+ p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
+ + attr.qbman_portal_ci_offset);
dflt_dpio->sw_portal = qbman_swp_init(&p_des);
if (dflt_dpio->sw_portal == NULL) {
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index 0c5fdeefd75..67b570279ec 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -512,6 +512,13 @@ static int keystone2_eth_rcv_packet(struct eth_device *dev)
return pkt_size;
}
+#ifdef CONFIG_MCAST_TFTP
+static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set)
+{
+ return 0;
+}
+#endif
+
/*
* This function initializes the EMAC hardware.
*/
@@ -537,6 +544,9 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
dev->halt = keystone2_eth_close;
dev->send = keystone2_eth_send_packet;
dev->recv = keystone2_eth_rcv_packet;
+#ifdef CONFIG_MCAST_TFTP
+ dev->mcast = keystone2_eth_bcast_addr;
+#endif
eth_register(dev);
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index d4be1bada96..50ca6e45fb1 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -31,6 +31,8 @@ static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
uint32_t fd_length;
struct ldpaa_fas *fas;
uint32_t status, err;
+ u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
+ u32 time_start;
struct qbman_release_desc releasedesc;
struct qbman_swp *swp = dflt_dpio->sw_portal;
@@ -65,10 +67,15 @@ error:
flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
qbman_release_desc_clear(&releasedesc);
qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
+ time_start = get_timer(0);
do {
/* Release buffer into the QBMAN */
err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
- } while (err == -EBUSY);
+ } while (get_timer(time_start) < timeo && err == -EBUSY);
+
+ if (err == -EBUSY)
+ printf("Rx frame: QBMAN buffer release fails\n");
+
return;
}
@@ -77,7 +84,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
const struct ldpaa_dq *dq;
const struct dpaa_fd *fd;
- int i = 5, err = 0, status, loop = 20;
+ int i = 5, err = 0, status;
+ u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
+ u32 time_start;
static struct qbman_pull_desc pulldesc;
struct qbman_swp *swp = dflt_dpio->sw_portal;
@@ -92,13 +101,11 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
continue;
}
- do {
- loop--;
- dq = qbman_swp_dqrr_next(swp);
+ time_start = get_timer(0);
- if (!loop)
- break;
- } while (!dq);
+ do {
+ dq = qbman_swp_dqrr_next(swp);
+ } while (get_timer(time_start) < timeo && !dq);
if (dq) {
/* Check for valid frame. If not sent a consume
@@ -112,7 +119,7 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
debug("No frame delivered\n");
qbman_swp_dqrr_consume(swp, dq);
- break;
+ continue;
}
fd = ldpaa_dq_fd(dq);
@@ -121,92 +128,9 @@ static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
ldpaa_eth_rx(priv, fd);
qbman_swp_dqrr_consume(swp, dq);
break;
- }
- }
-
- return err;
-}
-
-static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv,
- const struct dpaa_fd *fd)
-{
- uint64_t fd_addr;
- struct ldpaa_fas *fas;
- uint32_t status, err;
- struct qbman_release_desc releasedesc;
- struct qbman_swp *swp = dflt_dpio->sw_portal;
-
- fd_addr = ldpaa_fd_get_addr(fd);
-
-
- debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr);
-
- /* Check the status from the Frame Annotation */
- if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
- fas = (struct ldpaa_fas *)
- ((uint8_t *)(fd_addr) +
- priv->buf_layout.private_data_size);
- status = le32_to_cpu(fas->status);
- if (status & LDPAA_ETH_TXCONF_ERR_MASK) {
- printf("TxConf frame error(s): 0x%08x\n",
- status & LDPAA_ETH_TXCONF_ERR_MASK);
- }
- }
-
- qbman_release_desc_clear(&releasedesc);
- qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
- do {
- /* Release buffer into the QBMAN */
- err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
- } while (err == -EBUSY);
-}
-
-static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)
-{
- const struct ldpaa_dq *dq;
- const struct dpaa_fd *fd;
- int err = 0;
- int i = 5, status, loop = 20;
- static struct qbman_pull_desc pulldesc;
- struct qbman_swp *swp = dflt_dpio->sw_portal;
-
- while (--i) {
- qbman_pull_desc_clear(&pulldesc);
- qbman_pull_desc_set_numframes(&pulldesc, 1);
- qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid);
-
- err = qbman_swp_pull(swp, &pulldesc);
- if (err < 0) {
- printf("Dequeue TX conf frames error:0x%08x\n", err);
- continue;
- }
-
- do {
- loop--;
- dq = qbman_swp_dqrr_next(swp);
-
- if (!loop)
- break;
- } while (!dq);
-
- if (dq) {
- /* Check for valid frame. If not sent a consume
- * confirmation to QBMAN otherwise give it to NADK
- * application and then send consume confirmation to
- * QBMAN.
- */
- status = (uint8_t)ldpaa_dq_flags(dq);
- if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
- debug("Dequeue TX conf frames:");
- debug("No frame is delivered\n");
-
- qbman_swp_dqrr_consume(swp, dq);
- break;
- }
- fd = ldpaa_dq_fd(dq);
-
- ldpaa_eth_tx_conf(priv, fd);
- qbman_swp_dqrr_consume(swp, dq);
+ } else {
+ err = -ENODATA;
+ debug("No DQRR entries\n");
break;
}
}
@@ -220,8 +144,11 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
struct dpaa_fd fd;
u64 buffer_start;
int data_offset, err;
+ u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
+ u32 time_start;
struct qbman_swp *swp = dflt_dpio->sw_portal;
struct qbman_eq_desc ed;
+ struct qbman_release_desc releasedesc;
/* Setup the FD fields */
memset(&fd, 0, sizeof(fd));
@@ -257,15 +184,34 @@ static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
qbman_eq_desc_clear(&ed);
qbman_eq_desc_set_no_orp(&ed, 0);
qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
- err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd));
- if (err < 0)
+
+ time_start = get_timer(0);
+
+ while (get_timer(time_start) < timeo) {
+ err = qbman_swp_enqueue(swp, &ed,
+ (const struct qbman_fd *)(&fd));
+ if (err != -EBUSY)
+ break;
+ }
+
+ if (err < 0) {
printf("error enqueueing Tx frame\n");
+ goto error;
+ }
+
+ return err;
- mdelay(1);
+error:
+ qbman_release_desc_clear(&releasedesc);
+ qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
+ time_start = get_timer(0);
+ do {
+ /* Release buffer into the QBMAN */
+ err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
+ } while (get_timer(time_start) < timeo && err == -EBUSY);
- err = ldpaa_eth_pull_dequeue_tx_conf(priv);
- if (err < 0)
- printf("error Tx Conf frame\n");
+ if (err == -EBUSY)
+ printf("TX data: QBMAN buffer release fails\n");
return err;
}
@@ -274,7 +220,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
{
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
struct dpni_queue_attr rx_queue_attr;
- struct dpni_tx_flow_attr tx_flow_attr;
uint8_t mac_addr[6];
int err;
@@ -345,21 +290,11 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
goto err_qdid;
}
- err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id,
- &tx_flow_attr);
- if (err) {
- printf("dpni_get_tx_flow() failed\n");
- goto err_tx_flow;
- }
-
- priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid;
-
if (!priv->phydev->link)
printf("%s: No link.\n", priv->phydev->dev->name);
return priv->phydev->link ? 0 : -1;
-err_tx_flow:
err_qdid:
err_rx_flow:
dpni_disable(dflt_mc_io, priv->dpni_handle);
@@ -626,6 +561,9 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
priv->tx_flow_id = DPNI_NEW_FLOW_ID;
memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
+ dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR;
+ dflt_tx_flow.conf_err_cfg.use_default_queue = 0;
+ dflt_tx_flow.conf_err_cfg.errors_only = 1;
err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle,
&priv->tx_flow_id, &dflt_tx_flow);
if (err) {
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h
index 3107ab6cff9..b4ef700cb05 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.h
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.h
@@ -128,7 +128,6 @@ struct ldpaa_eth_priv {
uint32_t rx_dflt_fqid;
uint16_t tx_qdid;
- uint32_t tx_conf_fqid;
uint16_t tx_flow_id;
enum ldpaa_eth_type type; /* 1G or 10G ethernet */
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index 958488c19a1..7b6e20f30fb 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -41,10 +41,13 @@
* Modified to use le32_to_cpu and cpu_to_le32 properly
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <net.h>
+#ifndef CONFIG_DM_ETH
#include <netdev.h>
+#endif
#include <asm/io.h>
#include <pci.h>
@@ -281,6 +284,8 @@ struct RxDesc {
u32 buf_Haddr;
};
+static unsigned char rxdata[RX_BUF_LEN];
+
#define RTL8169_DESC_SIZE 16
#if ARCH_DMA_MINALIGN > 256
@@ -299,7 +304,8 @@ struct RxDesc {
* the driver to allocate descriptors from a pool of non-cached memory.
*/
#if RTL8169_DESC_SIZE < ARCH_DMA_MINALIGN
-#if !defined(CONFIG_SYS_NONCACHED_MEMORY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#if !defined(CONFIG_SYS_NONCACHED_MEMORY) && \
+ !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_X86)
#warning cache-line size is larger than descriptor size
#endif
#endif
@@ -317,6 +323,7 @@ DEFINE_ALIGN_BUFFER(u8, txb, NUM_TX_DESC * RX_BUF_SIZE, RTL8169_ALIGN);
DEFINE_ALIGN_BUFFER(u8, rxb, NUM_RX_DESC * RX_BUF_SIZE, RTL8169_ALIGN);
struct rtl8169_private {
+ ulong iobase;
void *mmio_addr; /* memory map physical address */
int chipset;
unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
@@ -338,9 +345,9 @@ static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
static struct pci_device_id supported[] = {
- {PCI_VENDOR_ID_REALTEK, 0x8167},
- {PCI_VENDOR_ID_REALTEK, 0x8168},
- {PCI_VENDOR_ID_REALTEK, 0x8169},
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169) },
{}
};
@@ -380,7 +387,7 @@ int mdio_read(int RegAddr)
return value;
}
-static int rtl8169_init_board(struct eth_device *dev)
+static int rtl8169_init_board(unsigned long dev_iobase, const char *name)
{
int i;
u32 tmp;
@@ -388,7 +395,7 @@ static int rtl8169_init_board(struct eth_device *dev)
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
/* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset);
@@ -412,7 +419,8 @@ static int rtl8169_init_board(struct eth_device *dev)
}
/* if unknown chip, assume array element #0, original RTL-8169 in this case */
- printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name);
+ printf("PCI device %s: unknown chip version, assuming RTL-8169\n",
+ name);
printf("PCI device: TxConfig = 0x%lX\n", (unsigned long) RTL_R32(TxConfig));
tpc->chipset = 0;
@@ -504,7 +512,8 @@ static void rtl_flush_buffer(void *buf, size_t size)
/**************************************************************************
RECV - Receive a frame
***************************************************************************/
-static int rtl_recv(struct eth_device *dev)
+static int rtl_recv_common(pci_dev_t bdf, unsigned long dev_iobase,
+ uchar **packetp)
{
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
@@ -515,7 +524,7 @@ static int rtl_recv(struct eth_device *dev)
#ifdef DEBUG_RTL8169_RX
printf ("%s\n", __FUNCTION__);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
cur_rx = tpc->cur_rx;
@@ -523,7 +532,6 @@ static int rtl_recv(struct eth_device *dev)
if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) {
if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) {
- unsigned char rxdata[RX_BUF_LEN];
length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx].
status) & 0x00001FFF) - 4;
@@ -536,17 +544,22 @@ static int rtl_recv(struct eth_device *dev)
else
tpc->RxDescArray[cur_rx].status =
cpu_to_le32(OWNbit + RX_BUF_SIZE);
- tpc->RxDescArray[cur_rx].buf_addr =
- cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx]));
+ tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
+ pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)
+ tpc->RxBufferRing[cur_rx]));
rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
-
+#ifdef CONFIG_DM_ETH
+ *packetp = rxdata;
+#else
net_process_received_packet(rxdata, length);
+#endif
} else {
puts("Error Rx");
+ length = -EIO;
}
cur_rx = (cur_rx + 1) % NUM_RX_DESC;
tpc->cur_rx = cur_rx;
- return 1;
+ return length;
} else {
ushort sts = RTL_R8(IntrStatus);
@@ -557,11 +570,26 @@ static int rtl_recv(struct eth_device *dev)
return (0); /* initially as this is called to flush the input */
}
+#ifdef CONFIG_DM_ETH
+int rtl8169_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct rtl8169_private *priv = dev_get_priv(dev);
+
+ return rtl_recv_common(pci_get_bdf(dev), priv->iobase, packetp);
+}
+#else
+static int rtl_recv(struct eth_device *dev)
+{
+ return rtl_recv_common((pci_dev_t)dev->priv, dev->iobase, NULL);
+}
+#endif /* nCONFIG_DM_ETH */
+
#define HZ 1000
/**************************************************************************
SEND - Transmit a frame
***************************************************************************/
-static int rtl_send(struct eth_device *dev, void *packet, int length)
+static int rtl_send_common(pci_dev_t bdf, unsigned long dev_iobase,
+ void *packet, int length)
{
/* send the packet to destination */
@@ -577,7 +605,7 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)
printf("sending %d bytes\n", len);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
/* point to the current txb incase multiple tx_rings are used */
ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
@@ -588,7 +616,8 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)
ptxb[len++] = '\0';
tpc->TxDescArray[entry].buf_Haddr = 0;
- tpc->TxDescArray[entry].buf_addr = cpu_to_le32(bus_to_phys(ptxb));
+ tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
+ pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)ptxb));
if (entry != (NUM_TX_DESC - 1)) {
tpc->TxDescArray[entry].status =
cpu_to_le32((OWNbit | FSbit | LSbit) |
@@ -625,7 +654,23 @@ static int rtl_send(struct eth_device *dev, void *packet, int length)
return ret;
}
-static void rtl8169_set_rx_mode(struct eth_device *dev)
+#ifdef CONFIG_DM_ETH
+int rtl8169_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct rtl8169_private *priv = dev_get_priv(dev);
+
+ return rtl_send_common(pci_get_bdf(dev), priv->iobase, packet, length);
+}
+
+#else
+static int rtl_send(struct eth_device *dev, void *packet, int length)
+{
+ return rtl_send_common((pci_dev_t)dev->priv, dev->iobase, packet,
+ length);
+}
+#endif
+
+static void rtl8169_set_rx_mode(void)
{
u32 mc_filter[2]; /* Multicast hash filter */
int rx_mode;
@@ -648,7 +693,7 @@ static void rtl8169_set_rx_mode(struct eth_device *dev)
RTL_W32(MAR0 + 4, mc_filter[1]);
}
-static void rtl8169_hw_start(struct eth_device *dev)
+static void rtl8169_hw_start(pci_dev_t bdf)
{
u32 i;
@@ -693,9 +738,11 @@ static void rtl8169_hw_start(struct eth_device *dev)
tpc->cur_rx = 0;
- RTL_W32(TxDescStartAddrLow, bus_to_phys(tpc->TxDescArray));
+ RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(bdf,
+ (pci_addr_t)(unsigned long)tpc->TxDescArray));
RTL_W32(TxDescStartAddrHigh, (unsigned long)0);
- RTL_W32(RxDescStartAddrLow, bus_to_phys(tpc->RxDescArray));
+ RTL_W32(RxDescStartAddrLow, pci_mem_to_phys(
+ bdf, (pci_addr_t)(unsigned long)tpc->RxDescArray));
RTL_W32(RxDescStartAddrHigh, (unsigned long)0);
/* RTL-8169sc/8110sc or later version */
@@ -707,7 +754,7 @@ static void rtl8169_hw_start(struct eth_device *dev)
RTL_W32(RxMissed, 0);
- rtl8169_set_rx_mode(dev);
+ rtl8169_set_rx_mode();
/* no early-rx interrupts */
RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
@@ -717,7 +764,7 @@ static void rtl8169_hw_start(struct eth_device *dev)
#endif
}
-static void rtl8169_init_ring(struct eth_device *dev)
+static void rtl8169_init_ring(pci_dev_t bdf)
{
int i;
@@ -745,8 +792,8 @@ static void rtl8169_init_ring(struct eth_device *dev)
cpu_to_le32(OWNbit + RX_BUF_SIZE);
tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
- tpc->RxDescArray[i].buf_addr =
- cpu_to_le32(bus_to_phys(tpc->RxBufferRing[i]));
+ tpc->RxDescArray[i].buf_addr = cpu_to_le32(pci_mem_to_phys(
+ bdf, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
rtl_flush_rx_desc(&tpc->RxDescArray[i]);
}
@@ -755,10 +802,7 @@ static void rtl8169_init_ring(struct eth_device *dev)
#endif
}
-/**************************************************************************
-RESET - Finish setting up the ethernet interface
-***************************************************************************/
-static int rtl_reset(struct eth_device *dev, bd_t *bis)
+static void rtl8169_common_start(pci_dev_t bdf, unsigned char *enetaddr)
{
int i;
@@ -767,30 +811,47 @@ static int rtl_reset(struct eth_device *dev, bd_t *bis)
printf ("%s\n", __FUNCTION__);
#endif
- rtl8169_init_ring(dev);
- rtl8169_hw_start(dev);
+ rtl8169_init_ring(bdf);
+ rtl8169_hw_start(bdf);
/* Construct a perfect filter frame with the mac address as first match
* and broadcast for all others */
for (i = 0; i < 192; i++)
txb[i] = 0xFF;
- txb[0] = dev->enetaddr[0];
- txb[1] = dev->enetaddr[1];
- txb[2] = dev->enetaddr[2];
- txb[3] = dev->enetaddr[3];
- txb[4] = dev->enetaddr[4];
- txb[5] = dev->enetaddr[5];
+ txb[0] = enetaddr[0];
+ txb[1] = enetaddr[1];
+ txb[2] = enetaddr[2];
+ txb[3] = enetaddr[3];
+ txb[4] = enetaddr[4];
+ txb[5] = enetaddr[5];
#ifdef DEBUG_RTL8169
printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
#endif
- return 0;
}
+#ifdef CONFIG_DM_ETH
+static int rtl8169_eth_start(struct udevice *dev)
+{
+ struct eth_pdata *plat = dev_get_platdata(dev);
+
+ rtl8169_common_start(pci_get_bdf(dev), plat->enetaddr);
+
+ return 0;
+}
+#else
/**************************************************************************
-HALT - Turn off ethernet interface
+RESET - Finish setting up the ethernet interface
***************************************************************************/
-static void rtl_halt(struct eth_device *dev)
+static int rtl_reset(struct eth_device *dev, bd_t *bis)
+{
+ rtl8169_common_start((pci_dev_t)dev->priv, dev->enetaddr);
+
+ return 0;
+}
+#endif /* nCONFIG_DM_ETH */
+
+static void rtl_halt_common(unsigned long dev_iobase)
{
int i;
@@ -798,7 +859,7 @@ static void rtl_halt(struct eth_device *dev)
printf ("%s\n", __FUNCTION__);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
/* Stop the chip's Tx and Rx DMA processes. */
RTL_W8(ChipCmd, 0x00);
@@ -813,13 +874,31 @@ static void rtl_halt(struct eth_device *dev)
}
}
+#ifdef CONFIG_DM_ETH
+void rtl8169_eth_stop(struct udevice *dev)
+{
+ struct rtl8169_private *priv = dev_get_priv(dev);
+
+ rtl_halt_common(priv->iobase);
+}
+#else
+/**************************************************************************
+HALT - Turn off ethernet interface
+***************************************************************************/
+static void rtl_halt(struct eth_device *dev)
+{
+ rtl_halt_common(dev->iobase);
+}
+#endif
+
/**************************************************************************
INIT - Look for an adapter, this routine's visible to the outside
***************************************************************************/
#define board_found 1
#define valid_link 0
-static int rtl_init(struct eth_device *dev, bd_t *bis)
+static int rtl_init(unsigned long dev_ioaddr, const char *name,
+ unsigned char *enetaddr)
{
static int board_idx = -1;
int i, rc;
@@ -828,33 +907,32 @@ static int rtl_init(struct eth_device *dev, bd_t *bis)
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
-
- ioaddr = dev->iobase;
+ ioaddr = dev_ioaddr;
board_idx++;
/* point to private storage */
tpc = &tpx;
- rc = rtl8169_init_board(dev);
+ rc = rtl8169_init_board(ioaddr, name);
if (rc)
return rc;
/* Get MAC address. FIXME: read EEPROM */
for (i = 0; i < MAC_ADDR_LEN; i++)
- dev->enetaddr[i] = RTL_R8(MAC0 + i);
+ enetaddr[i] = RTL_R8(MAC0 + i);
#ifdef DEBUG_RTL8169
printf("chipset = %d\n", tpc->chipset);
printf("MAC Address");
for (i = 0; i < MAC_ADDR_LEN; i++)
- printf(":%02x", dev->enetaddr[i]);
+ printf(":%02x", enetaddr[i]);
putc('\n');
#endif
#ifdef DEBUG_RTL8169
/* Print out some hardware info */
- printf("%s: at ioaddr 0x%lx\n", dev->name, ioaddr);
+ printf("%s: at ioaddr 0x%lx\n", name, ioaddr);
#endif
/* if TBI is not endbled */
@@ -964,6 +1042,7 @@ static int rtl_init(struct eth_device *dev, bd_t *bis)
return 0;
}
+#ifndef CONFIG_DM_ETH
int rtl8169_initialize(bd_t *bis)
{
pci_dev_t devno;
@@ -1014,7 +1093,7 @@ int rtl8169_initialize(bd_t *bis)
dev->send = rtl_send;
dev->recv = rtl_recv;
- err = rtl_init(dev, bis);
+ err = rtl_init(dev->iobase, dev->name, dev->enetaddr);
if (err < 0) {
printf(pr_fmt("failed to initialize card: %d\n"), err);
free(dev);
@@ -1027,3 +1106,62 @@ int rtl8169_initialize(bd_t *bis)
}
return card_number;
}
+#endif
+
+#ifdef CONFIG_DM_ETH
+static int rtl8169_eth_probe(struct udevice *dev)
+{
+ struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
+ struct rtl8169_private *priv = dev_get_priv(dev);
+ struct eth_pdata *plat = dev_get_platdata(dev);
+ u32 iobase;
+ int region;
+ int ret;
+
+ debug("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
+ switch (pplat->device) {
+ case 0x8168:
+ region = 2;
+ break;
+ default:
+ region = 1;
+ break;
+ }
+ pci_read_config32(pci_get_bdf(dev), PCI_BASE_ADDRESS_0 + region * 4,
+ &iobase);
+ iobase &= ~0xf;
+ priv->iobase = (int)pci_mem_to_phys(pci_get_bdf(dev), iobase);
+
+ ret = rtl_init(priv->iobase, dev->name, plat->enetaddr);
+ if (ret < 0) {
+ printf(pr_fmt("failed to initialize card: %d\n"), ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct eth_ops rtl8169_eth_ops = {
+ .start = rtl8169_eth_start,
+ .send = rtl8169_eth_send,
+ .recv = rtl8169_eth_recv,
+ .stop = rtl8169_eth_stop,
+};
+
+static const struct udevice_id rtl8169_eth_ids[] = {
+ { .compatible = "realtek,rtl8169" },
+ { }
+};
+
+U_BOOT_DRIVER(eth_rtl8169) = {
+ .name = "eth_rtl8169",
+ .id = UCLASS_ETH,
+ .of_match = rtl8169_eth_ids,
+ .probe = rtl8169_eth_probe,
+ .ops = &rtl8169_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct rtl8169_private),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+
+U_BOOT_PCI_DEVICE(eth_rtl8169, supported);
+#endif
diff --git a/drivers/net/sandbox-raw.c b/drivers/net/sandbox-raw.c
index 45c3b18bdf3..591242797e2 100644
--- a/drivers/net/sandbox-raw.c
+++ b/drivers/net/sandbox-raw.c
@@ -65,7 +65,7 @@ static int sb_eth_raw_send(struct udevice *dev, void *packet, int length)
return sandbox_eth_raw_os_send(packet, length, priv);
}
-static int sb_eth_raw_recv(struct udevice *dev, uchar **packetp)
+static int sb_eth_raw_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
index 4e083d32ae6..6763a248f28 100644
--- a/drivers/net/sandbox.c
+++ b/drivers/net/sandbox.c
@@ -152,7 +152,7 @@ static int sb_eth_send(struct udevice *dev, void *packet, int length)
return 0;
}
-static int sb_eth_recv(struct udevice *dev, uchar **packetp)
+static int sb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct eth_sandbox_priv *priv = dev_get_priv(dev);
diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
index e939bf2108a..11cd0ea0688 100644
--- a/drivers/net/sunxi_emac.c
+++ b/drivers/net/sunxi_emac.c
@@ -527,7 +527,7 @@ static int sunxi_emac_eth_send(struct udevice *dev, void *packet, int length)
return _sunxi_emac_eth_send(priv, packet, length);
}
-static int sunxi_emac_eth_recv(struct udevice *dev, uchar **packetp)
+static int sunxi_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct emac_eth_dev *priv = dev_get_priv(dev);
int rx_len;
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index c723dbb0a69..b2006dfa077 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -20,6 +20,7 @@
#include <phy.h>
#include <miiphy.h>
#include <watchdog.h>
+#include <asm/system.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
@@ -58,7 +59,14 @@
#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */
#define ZYNQ_GEM_NWCFG_MDCCLKDIV2 0x0000c0000 /* Div pclk by 48, 120MHz */
-#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_FDEN | \
+#ifdef CONFIG_ARM64
+# define ZYNQ_GEM_DBUS_WIDTH (1 << 21) /* 64 bit bus */
+#else
+# define ZYNQ_GEM_DBUS_WIDTH (0 << 21) /* 32 bit bus */
+#endif
+
+#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_DBUS_WIDTH | \
+ ZYNQ_GEM_NWCFG_FDEN | \
ZYNQ_GEM_NWCFG_FSREM | \
ZYNQ_GEM_NWCFG_MDCCLKDIV)
@@ -130,7 +138,7 @@ struct emac_bd {
u32 status;
};
-#define RX_BUF 3
+#define RX_BUF 32
/* Page table entries are set to 1MB, or multiples of 1MB
* (not < 1MB). driver uses less bd's so use 1MB bdspace.
*/
@@ -155,7 +163,7 @@ struct zynq_gem_priv {
static inline int mdio_wait(struct eth_device *dev)
{
struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
- u32 timeout = 200;
+ u32 timeout = 20000;
/* Wait till MDIO interface is ready to accept a new transaction. */
while (--timeout) {
@@ -395,12 +403,18 @@ static int zynq_gem_send(struct eth_device *dev, void *ptr, int len)
priv->tx_bd->addr = (u32)ptr;
priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
- ZYNQ_GEM_TXBUF_LAST_MASK;
+ ZYNQ_GEM_TXBUF_LAST_MASK |
+ ZYNQ_GEM_TXBUF_WRAP_MASK;
addr = (u32) ptr;
addr &= ~(ARCH_DMA_MINALIGN - 1);
size = roundup(len, ARCH_DMA_MINALIGN);
flush_dcache_range(addr, addr + size);
+
+ addr = (u32)priv->rxbuffers;
+ addr &= ~(ARCH_DMA_MINALIGN - 1);
+ size = roundup((RX_BUF * PKTSIZE_ALIGN), ARCH_DMA_MINALIGN);
+ flush_dcache_range(addr, addr + size);
barrier();
/* Start transmit */
@@ -436,8 +450,6 @@ static int zynq_gem_recv(struct eth_device *dev)
if (frame_len) {
u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
addr &= ~(ARCH_DMA_MINALIGN - 1);
- u32 size = roundup(frame_len, ARCH_DMA_MINALIGN);
- invalidate_dcache_range(addr, addr + size);
net_process_received_packet((u8 *)addr, frame_len);
@@ -511,7 +523,7 @@ int zynq_gem_initialize(bd_t *bis, phys_addr_t base_addr,
priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN);
memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN);
- /* Align bd_space to 1MB */
+ /* Align bd_space to MMU_SECTION_SHIFT */
bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
mmu_set_region_dcache_behaviour((phys_addr_t)bd_space,
BD_SPACE, DCACHE_OFF);