diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/altera_tse.c | 265 | ||||
-rw-r--r-- | drivers/net/altera_tse.h | 314 | ||||
-rw-r--r-- | drivers/net/fm/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/fm/dtsec.c | 2 | ||||
-rw-r--r-- | drivers/net/fm/eth.c | 195 | ||||
-rw-r--r-- | drivers/net/fm/fm.c | 31 | ||||
-rw-r--r-- | drivers/net/fm/fm.h | 14 | ||||
-rw-r--r-- | drivers/net/fm/init.c | 10 | ||||
-rw-r--r-- | drivers/net/fm/ls1043.c | 119 | ||||
-rw-r--r-- | drivers/net/fm/tgec.c | 2 | ||||
-rw-r--r-- | drivers/net/fm/tgec_phy.c | 2 | ||||
-rw-r--r-- | drivers/net/ldpaa_eth/ldpaa_eth.c | 15 | ||||
-rw-r--r-- | drivers/net/ldpaa_eth/ls2085a.c | 2 | ||||
-rw-r--r-- | drivers/net/netconsole.c | 2 |
14 files changed, 652 insertions, 322 deletions
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c index 319983c482..5692fe9d4a 100644 --- a/drivers/net/altera_tse.c +++ b/drivers/net/altera_tse.c @@ -27,12 +27,12 @@ static inline void alt_sgdma_construct_descriptor( struct alt_sgdma_descriptor *next, void *read_addr, void *write_addr, - unsigned short length_or_eop, + u16 length_or_eop, int generate_eop, int read_fixed, int write_fixed_or_sop) { - unsigned char val; + u8 val; /* * Mark the "next" descriptor as "not" owned by hardware. This prevents @@ -100,7 +100,7 @@ static int alt_sgdma_wait_transfer(struct alt_sgdma_registers *regs) static int alt_sgdma_start_transfer(struct alt_sgdma_registers *regs, struct alt_sgdma_descriptor *desc) { - unsigned int val; + u32 val; /* Point the controller at the descriptor */ writel(virt_to_phys(desc), ®s->next_descriptor_pointer); @@ -121,7 +121,7 @@ static void tse_adjust_link(struct altera_tse_priv *priv, struct phy_device *phydev) { struct alt_tse_mac *mac_dev = priv->mac_dev; - unsigned int refvar; + u32 refvar; if (!phydev->link) { debug("%s: No link.\n", phydev->dev->name); @@ -152,13 +152,11 @@ static void tse_adjust_link(struct altera_tse_priv *priv, writel(refvar, &mac_dev->command_config); } -static int altera_tse_send(struct udevice *dev, void *packet, int length) +static int altera_tse_send_sgdma(struct udevice *dev, void *packet, int length) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_descriptor *tx_desc = priv->tx_desc; - unsigned long tx_buf = (unsigned long)packet; - flush_dcache_range(tx_buf, tx_buf + length); alt_sgdma_construct_descriptor( tx_desc, tx_desc + 1, @@ -178,7 +176,8 @@ static int altera_tse_send(struct udevice *dev, void *packet, int length) return tx_desc->actual_bytes_transferred; } -static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp) +static int altera_tse_recv_sgdma(struct udevice *dev, int flags, + uchar **packetp) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; @@ -186,6 +185,7 @@ static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp) if (rx_desc->descriptor_status & ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) { + alt_sgdma_wait_transfer(priv->sgdma_rx); packet_length = rx_desc->actual_bytes_transferred; debug("recv %d bytes\n", packet_length); *packetp = priv->rx_buf; @@ -196,15 +196,12 @@ static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp) return -EAGAIN; } -static int altera_tse_free_pkt(struct udevice *dev, uchar *packet, - int length) +static int altera_tse_free_pkt_sgdma(struct udevice *dev, uchar *packet, + int length) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; - unsigned long rx_buf = (unsigned long)priv->rx_buf; - alt_sgdma_wait_transfer(priv->sgdma_rx); - invalidate_dcache_range(rx_buf, rx_buf + PKTSIZE_ALIGN); alt_sgdma_construct_descriptor( rx_desc, rx_desc + 1, @@ -223,16 +220,33 @@ static int altera_tse_free_pkt(struct udevice *dev, uchar *packet, return 0; } -static void altera_tse_stop(struct udevice *dev) +static void altera_tse_stop_mac(struct altera_tse_priv *priv) { - struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_tse_mac *mac_dev = priv->mac_dev; + u32 status; + ulong ctime; + + /* reset the mac */ + writel(ALTERA_TSE_CMD_SW_RESET_MSK, &mac_dev->command_config); + ctime = get_timer(0); + while (1) { + status = readl(&mac_dev->command_config); + if (!(status & ALTERA_TSE_CMD_SW_RESET_MSK)) + break; + if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) { + debug("Reset mac timeout\n"); + break; + } + } +} + +static void altera_tse_stop_sgdma(struct udevice *dev) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx; struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx; struct alt_sgdma_descriptor *rx_desc = priv->rx_desc; - unsigned int status; int ret; - ulong ctime; /* clear rx desc & wait for sgdma to complete */ rx_desc->descriptor_control = 0; @@ -247,26 +261,128 @@ static void altera_tse_stop(struct udevice *dev) if (ret == -ETIMEDOUT) writel(ALT_SGDMA_CONTROL_SOFTWARERESET_MSK, &tx_sgdma->control); +} - /* reset the mac */ - writel(ALTERA_TSE_CMD_SW_RESET_MSK, &mac_dev->command_config); +static void msgdma_reset(struct msgdma_csr *csr) +{ + u32 status; + ulong ctime; + + /* Reset mSGDMA */ + writel(MSGDMA_CSR_STAT_MASK, &csr->status); + writel(MSGDMA_CSR_CTL_RESET, &csr->control); ctime = get_timer(0); while (1) { - status = readl(&mac_dev->command_config); - if (!(status & ALTERA_TSE_CMD_SW_RESET_MSK)) + status = readl(&csr->status); + if (!(status & MSGDMA_CSR_STAT_RESETTING)) break; if (get_timer(ctime) > ALT_TSE_SW_RESET_TIMEOUT) { - debug("Reset mac timeout\n"); + debug("Reset msgdma timeout\n"); + break; + } + } + /* Clear status */ + writel(MSGDMA_CSR_STAT_MASK, &csr->status); +} + +static u32 msgdma_wait(struct msgdma_csr *csr) +{ + u32 status; + ulong ctime; + + /* Wait for the descriptor to complete */ + ctime = get_timer(0); + while (1) { + status = readl(&csr->status); + if (!(status & MSGDMA_CSR_STAT_BUSY)) + break; + if (get_timer(ctime) > ALT_TSE_SGDMA_BUSY_TIMEOUT) { + debug("sgdma timeout\n"); break; } } + /* Clear status */ + writel(MSGDMA_CSR_STAT_MASK, &csr->status); + + return status; +} + +static int altera_tse_send_msgdma(struct udevice *dev, void *packet, + int length) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + struct msgdma_extended_desc *desc = priv->tx_desc; + u32 tx_buf = virt_to_phys(packet); + u32 status; + + writel(tx_buf, &desc->read_addr_lo); + writel(0, &desc->read_addr_hi); + writel(0, &desc->write_addr_lo); + writel(0, &desc->write_addr_hi); + writel(length, &desc->len); + writel(0, &desc->burst_seq_num); + writel(MSGDMA_DESC_TX_STRIDE, &desc->stride); + writel(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control); + status = msgdma_wait(priv->sgdma_tx); + debug("sent %d bytes, status %08x\n", length, status); + + return 0; +} + +static int altera_tse_recv_msgdma(struct udevice *dev, int flags, + uchar **packetp) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + struct msgdma_csr *csr = priv->sgdma_rx; + struct msgdma_response *resp = priv->rx_resp; + u32 level, length, status; + + level = readl(&csr->resp_fill_level); + if (level & 0xffff) { + length = readl(&resp->bytes_transferred); + status = readl(&resp->status); + debug("recv %d bytes, status %08x\n", length, status); + *packetp = priv->rx_buf; + + return length; + } + + return -EAGAIN; +} + +static int altera_tse_free_pkt_msgdma(struct udevice *dev, uchar *packet, + int length) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + struct msgdma_extended_desc *desc = priv->rx_desc; + u32 rx_buf = virt_to_phys(priv->rx_buf); + + writel(0, &desc->read_addr_lo); + writel(0, &desc->read_addr_hi); + writel(rx_buf, &desc->write_addr_lo); + writel(0, &desc->write_addr_hi); + writel(PKTSIZE_ALIGN, &desc->len); + writel(0, &desc->burst_seq_num); + writel(MSGDMA_DESC_RX_STRIDE, &desc->stride); + writel(MSGDMA_DESC_CTL_RX_SINGLE, &desc->control); + debug("recv setup\n"); + + return 0; +} + +static void altera_tse_stop_msgdma(struct udevice *dev) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + + msgdma_reset(priv->sgdma_rx); + msgdma_reset(priv->sgdma_tx); } static int tse_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) { struct altera_tse_priv *priv = bus->priv; struct alt_tse_mac *mac_dev = priv->mac_dev; - unsigned int value; + u32 value; /* set mdio address */ writel(addr, &mac_dev->mdio_phy1_addr); @@ -337,7 +453,7 @@ static int altera_tse_write_hwaddr(struct udevice *dev) struct alt_tse_mac *mac_dev = priv->mac_dev; struct eth_pdata *pdata = dev_get_platdata(dev); u8 *hwaddr = pdata->enetaddr; - unsigned int mac_lo, mac_hi; + u32 mac_lo, mac_hi; mac_lo = (hwaddr[3] << 24) | (hwaddr[2] << 16) | (hwaddr[1] << 8) | hwaddr[0]; @@ -358,11 +474,47 @@ static int altera_tse_write_hwaddr(struct udevice *dev) return 0; } +static int altera_tse_send(struct udevice *dev, void *packet, int length) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + unsigned long tx_buf = (unsigned long)packet; + + flush_dcache_range(tx_buf, tx_buf + length); + + return priv->ops->send(dev, packet, length); +} + +static int altera_tse_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + + return priv->ops->recv(dev, flags, packetp); +} + +static int altera_tse_free_pkt(struct udevice *dev, uchar *packet, + int length) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + unsigned long rx_buf = (unsigned long)priv->rx_buf; + + invalidate_dcache_range(rx_buf, rx_buf + PKTSIZE_ALIGN); + + return priv->ops->free_pkt(dev, packet, length); +} + +static void altera_tse_stop(struct udevice *dev) +{ + struct altera_tse_priv *priv = dev_get_priv(dev); + + priv->ops->stop(dev); + altera_tse_stop_mac(priv); +} + static int altera_tse_start(struct udevice *dev) { struct altera_tse_priv *priv = dev_get_priv(dev); struct alt_tse_mac *mac_dev = priv->mac_dev; - unsigned int val; + u32 val; int ret; /* need to create sgdma */ @@ -405,24 +557,45 @@ static int altera_tse_start(struct udevice *dev) return 0; } +static const struct tse_ops tse_sgdma_ops = { + .send = altera_tse_send_sgdma, + .recv = altera_tse_recv_sgdma, + .free_pkt = altera_tse_free_pkt_sgdma, + .stop = altera_tse_stop_sgdma, +}; + +static const struct tse_ops tse_msgdma_ops = { + .send = altera_tse_send_msgdma, + .recv = altera_tse_recv_msgdma, + .free_pkt = altera_tse_free_pkt_msgdma, + .stop = altera_tse_stop_msgdma, +}; + static int altera_tse_probe(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct altera_tse_priv *priv = dev_get_priv(dev); - const void *blob = gd->fdt_blob; + void *blob = (void *)gd->fdt_blob; int node = dev->of_offset; const char *list, *end; const fdt32_t *cell; void *base, *desc_mem = NULL; unsigned long addr, size; + int parent, addrc, sizec; int len, idx; int ret; + priv->dma_type = dev_get_driver_data(dev); + if (priv->dma_type == ALT_SGDMA) + priv->ops = &tse_sgdma_ops; + else + priv->ops = &tse_msgdma_ops; /* - * decode regs, assume address-cells and size-cells are both one. - * there are multiple reg tuples, and they need to match with - * reg-names. + * decode regs. there are multiple reg tuples, and they need to + * match with reg-names. */ + parent = fdt_parent_offset(blob, node); + of_bus_default_count_cells(blob, parent, &addrc, &sizec); list = fdt_getprop(blob, node, "reg-names", &len); if (!list) return -ENOENT; @@ -434,18 +607,24 @@ static int altera_tse_probe(struct udevice *dev) while (list < end) { addr = fdt_translate_address((void *)blob, node, cell + idx); - size = fdt_addr_to_cpu(cell[idx + 1]); + size = fdt_addr_to_cpu(cell[idx + addrc]); base = ioremap(addr, size); len = strlen(list); if (strcmp(list, "control_port") == 0) priv->mac_dev = base; else if (strcmp(list, "rx_csr") == 0) priv->sgdma_rx = base; + else if (strcmp(list, "rx_desc") == 0) + priv->rx_desc = base; + else if (strcmp(list, "rx_resp") == 0) + priv->rx_resp = base; else if (strcmp(list, "tx_csr") == 0) priv->sgdma_tx = base; + else if (strcmp(list, "tx_desc") == 0) + priv->tx_desc = base; else if (strcmp(list, "s1") == 0) desc_mem = base; - idx += 2; + idx += addrc + sizec; list += (len + 1); } /* decode fifo depth */ @@ -460,15 +639,18 @@ static int altera_tse_probe(struct udevice *dev) priv->phyaddr = fdtdec_get_int(blob, addr, "reg", 0); /* init desc */ - len = sizeof(struct alt_sgdma_descriptor) * 4; - if (!desc_mem) { - desc_mem = dma_alloc_coherent(len, &addr); - if (!desc_mem) - return -ENOMEM; + if (priv->dma_type == ALT_SGDMA) { + len = sizeof(struct alt_sgdma_descriptor) * 4; + if (!desc_mem) { + desc_mem = dma_alloc_coherent(len, &addr); + if (!desc_mem) + return -ENOMEM; + } + memset(desc_mem, 0, len); + priv->tx_desc = desc_mem; + priv->rx_desc = priv->tx_desc + + 2 * sizeof(struct alt_sgdma_descriptor); } - memset(desc_mem, 0, len); - priv->tx_desc = desc_mem; - priv->rx_desc = priv->tx_desc + 2; /* allocate recv packet buffer */ priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN); if (!priv->rx_buf) @@ -515,8 +697,9 @@ static const struct eth_ops altera_tse_ops = { }; static const struct udevice_id altera_tse_ids[] = { - { .compatible = "altr,tse-1.0", }, - { } + { .compatible = "altr,tse-msgdma-1.0", .data = ALT_MSGDMA }, + { .compatible = "altr,tse-1.0", .data = ALT_SGDMA }, + {} }; U_BOOT_DRIVER(altera_tse) = { diff --git a/drivers/net/altera_tse.h b/drivers/net/altera_tse.h index 08c4f660a0..2b1af81429 100644 --- a/drivers/net/altera_tse.h +++ b/drivers/net/altera_tse.h @@ -11,22 +11,18 @@ #ifndef _ALTERA_TSE_H_ #define _ALTERA_TSE_H_ -#define __packed_1_ __attribute__ ((packed, aligned(1))) +#define __packed_1_ __packed __aligned(1) -/* SGDMA Stuff */ -#define ALT_SGDMA_STATUS_ERROR_MSK (0x00000001) -#define ALT_SGDMA_STATUS_EOP_ENCOUNTERED_MSK (0x00000002) -#define ALT_SGDMA_STATUS_DESC_COMPLETED_MSK (0x00000004) -#define ALT_SGDMA_STATUS_CHAIN_COMPLETED_MSK (0x00000008) -#define ALT_SGDMA_STATUS_BUSY_MSK (0x00000010) +/* dma type */ +#define ALT_SGDMA 0 +#define ALT_MSGDMA 1 -#define ALT_SGDMA_CONTROL_RUN_MSK (0x00000020) -#define ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK (0x00000040) -#define ALT_SGDMA_CONTROL_SOFTWARERESET_MSK (0x00010000) +/* SGDMA Stuff */ +#define ALT_SGDMA_STATUS_BUSY_MSK BIT(4) -#define ALTERA_TSE_SGDMA_INTR_MASK (ALT_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK \ - | ALT_SGDMA_STATUS_DESC_COMPLETED_MSK \ - | ALT_SGDMA_CONTROL_IE_GLOBAL_MSK) +#define ALT_SGDMA_CONTROL_RUN_MSK BIT(5) +#define ALT_SGDMA_CONTROL_STOP_DMA_ER_MSK BIT(6) +#define ALT_SGDMA_CONTROL_SOFTWARERESET_MSK BIT(16) /* * Descriptor control bit masks & offsets @@ -35,11 +31,10 @@ * The following bit-offsets are expressed relative to the LSB of * the control register bitfield. */ -#define ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK (0x00000001) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK (0x00000002) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK (0x00000004) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_ATLANTIC_CHANNEL_MSK (0x00000008) -#define ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK (0x00000080) +#define ALT_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK BIT(0) +#define ALT_SGDMA_DESCRIPTOR_CONTROL_READ_FIXED_ADDRESS_MSK BIT(1) +#define ALT_SGDMA_DESCRIPTOR_CONTROL_WRITE_FIXED_ADDRESS_MSK BIT(2) +#define ALT_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK BIT(7) /* * Descriptor status bit masks & offsets @@ -48,15 +43,7 @@ * The following bit-offsets are expressed relative to the LSB of * the status register bitfield. */ -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK (0x00000001) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK (0x00000002) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK (0x00000004) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK (0x00000008) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK (0x00000010) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK (0x00000020) -#define ALT_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK (0x00000040) -#define ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK (0x00000080) -#define ALT_SGDMA_DESCRIPTOR_STATUS_ERROR_MSK (0x0000007F) +#define ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK BIT(7) /* * The SGDMA controller buffer descriptor allocates @@ -71,70 +58,101 @@ * */ struct alt_sgdma_descriptor { - unsigned int source; /* the address of data to be read. */ - unsigned int source_pad; + u32 source; /* the address of data to be read. */ + u32 source_pad; - unsigned int destination; /* the address to write data */ - unsigned int destination_pad; + u32 destination; /* the address to write data */ + u32 destination_pad; - unsigned int next; /* the next descriptor in the list. */ - unsigned int next_pad; + u32 next; /* the next descriptor in the list. */ + u32 next_pad; - unsigned short bytes_to_transfer; /* the number of bytes to transfer */ - unsigned char read_burst; - unsigned char write_burst; + u16 bytes_to_transfer; /* the number of bytes to transfer */ + u8 read_burst; + u8 write_burst; - unsigned short actual_bytes_transferred;/* bytes transferred by DMA */ - unsigned char descriptor_status; - unsigned char descriptor_control; + u16 actual_bytes_transferred;/* bytes transferred by DMA */ + u8 descriptor_status; + u8 descriptor_control; } __packed_1_; /* SG-DMA Control/Status Slave registers map */ struct alt_sgdma_registers { - unsigned int status; - unsigned int status_pad[3]; - unsigned int control; - unsigned int control_pad[3]; - unsigned int next_descriptor_pointer; - unsigned int descriptor_pad[3]; + u32 status; + u32 status_pad[3]; + u32 control; + u32 control_pad[3]; + u32 next_descriptor_pointer; + u32 descriptor_pad[3]; +}; + +/* mSGDMA Stuff */ + +/* mSGDMA extended descriptor format */ +struct msgdma_extended_desc { + u32 read_addr_lo; /* data buffer source address low bits */ + u32 write_addr_lo; /* data buffer destination address low bits */ + u32 len; + u32 burst_seq_num; + u32 stride; + u32 read_addr_hi; /* data buffer source address high bits */ + u32 write_addr_hi; /* data buffer destination address high bits */ + u32 control; /* characteristics of the transfer */ +}; + +/* mSGDMA descriptor control field bit definitions */ +#define MSGDMA_DESC_CTL_GEN_SOP BIT(8) +#define MSGDMA_DESC_CTL_GEN_EOP BIT(9) +#define MSGDMA_DESC_CTL_END_ON_EOP BIT(12) +#define MSGDMA_DESC_CTL_END_ON_LEN BIT(13) +#define MSGDMA_DESC_CTL_GO BIT(31) + +/* Tx buffer control flags */ +#define MSGDMA_DESC_CTL_TX_SINGLE (MSGDMA_DESC_CTL_GEN_SOP | \ + MSGDMA_DESC_CTL_GEN_EOP | \ + MSGDMA_DESC_CTL_GO) + +#define MSGDMA_DESC_CTL_RX_SINGLE (MSGDMA_DESC_CTL_END_ON_EOP | \ + MSGDMA_DESC_CTL_END_ON_LEN | \ + MSGDMA_DESC_CTL_GO) + +/* mSGDMA extended descriptor stride definitions */ +#define MSGDMA_DESC_TX_STRIDE 0x00010001 +#define MSGDMA_DESC_RX_STRIDE 0x00010001 + +/* mSGDMA dispatcher control and status register map */ +struct msgdma_csr { + u32 status; /* Read/Clear */ + u32 control; /* Read/Write */ + u32 rw_fill_level; + u32 resp_fill_level; /* bit 15:0 */ + u32 rw_seq_num; + u32 pad[3]; /* reserved */ +}; + +/* mSGDMA CSR status register bit definitions */ +#define MSGDMA_CSR_STAT_BUSY BIT(0) +#define MSGDMA_CSR_STAT_RESETTING BIT(6) +#define MSGDMA_CSR_STAT_MASK 0x3FF + +/* mSGDMA CSR control register bit definitions */ +#define MSGDMA_CSR_CTL_RESET BIT(1) + +/* mSGDMA response register map */ +struct msgdma_response { + u32 bytes_transferred; + u32 status; }; /* TSE Stuff */ -#define ALTERA_TSE_CMD_TX_ENA_MSK (0x00000001) -#define ALTERA_TSE_CMD_RX_ENA_MSK (0x00000002) -#define ALTERA_TSE_CMD_XON_GEN_MSK (0x00000004) -#define ALTERA_TSE_CMD_ETH_SPEED_MSK (0x00000008) -#define ALTERA_TSE_CMD_PROMIS_EN_MSK (0x00000010) -#define ALTERA_TSE_CMD_PAD_EN_MSK (0x00000020) -#define ALTERA_TSE_CMD_CRC_FWD_MSK (0x00000040) -#define ALTERA_TSE_CMD_PAUSE_FWD_MSK (0x00000080) -#define ALTERA_TSE_CMD_PAUSE_IGNORE_MSK (0x00000100) -#define ALTERA_TSE_CMD_TX_ADDR_INS_MSK (0x00000200) -#define ALTERA_TSE_CMD_HD_ENA_MSK (0x00000400) -#define ALTERA_TSE_CMD_EXCESS_COL_MSK (0x00000800) -#define ALTERA_TSE_CMD_LATE_COL_MSK (0x00001000) -#define ALTERA_TSE_CMD_SW_RESET_MSK (0x00002000) -#define ALTERA_TSE_CMD_MHASH_SEL_MSK (0x00004000) -#define ALTERA_TSE_CMD_LOOPBACK_MSK (0x00008000) -/* Bits (18:16) = address select */ -#define ALTERA_TSE_CMD_TX_ADDR_SEL_MSK (0x00070000) -#define ALTERA_TSE_CMD_MAGIC_ENA_MSK (0x00080000) -#define ALTERA_TSE_CMD_SLEEP_MSK (0x00100000) -#define ALTERA_TSE_CMD_WAKEUP_MSK (0x00200000) -#define ALTERA_TSE_CMD_XOFF_GEN_MSK (0x00400000) -#define ALTERA_TSE_CMD_CNTL_FRM_ENA_MSK (0x00800000) -#define ALTERA_TSE_CMD_NO_LENGTH_CHECK_MSK (0x01000000) -#define ALTERA_TSE_CMD_ENA_10_MSK (0x02000000) -#define ALTERA_TSE_CMD_RX_ERR_DISC_MSK (0x04000000) -/* Bits (30..27) reserved */ -#define ALTERA_TSE_CMD_CNT_RESET_MSK (0x80000000) - -#define ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 (0x00040000) -#define ALTERA_TSE_TX_CMD_STAT_OMIT_CRC (0x00020000) - -#define ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16 (0x02000000) +#define ALTERA_TSE_CMD_TX_ENA_MSK BIT(0) +#define ALTERA_TSE_CMD_RX_ENA_MSK BIT(1) +#define ALTERA_TSE_CMD_ETH_SPEED_MSK BIT(3) +#define ALTERA_TSE_CMD_HD_ENA_MSK BIT(10) +#define ALTERA_TSE_CMD_SW_RESET_MSK BIT(13) +#define ALTERA_TSE_CMD_ENA_10_MSK BIT(25) #define ALT_TSE_SW_RESET_TIMEOUT (3 * CONFIG_SYS_HZ) #define ALT_TSE_SGDMA_BUSY_TIMEOUT (3 * CONFIG_SYS_HZ) @@ -142,116 +160,72 @@ struct alt_sgdma_registers { /* MAC register Space */ struct alt_tse_mac { - unsigned int megacore_revision; - unsigned int scratch_pad; - unsigned int command_config; - unsigned int mac_addr_0; - unsigned int mac_addr_1; - unsigned int max_frame_length; - unsigned int pause_quanta; - unsigned int rx_sel_empty_threshold; - unsigned int rx_sel_full_threshold; - unsigned int tx_sel_empty_threshold; - unsigned int tx_sel_full_threshold; - unsigned int rx_almost_empty_threshold; - unsigned int rx_almost_full_threshold; - unsigned int tx_almost_empty_threshold; - unsigned int tx_almost_full_threshold; - unsigned int mdio_phy0_addr; - unsigned int mdio_phy1_addr; - - /* only if 100/1000 BaseX PCS, reserved otherwise */ - unsigned int reservedx44[5]; - - unsigned int reg_read_access_status; - unsigned int min_tx_ipg_length; - - /* IEEE 802.3 oEntity Managed Object Support */ - unsigned int aMACID_1; /*The MAC addresses */ - unsigned int aMACID_2; - unsigned int aFramesTransmittedOK; - unsigned int aFramesReceivedOK; - unsigned int aFramesCheckSequenceErrors; - unsigned int aAlignmentErrors; - unsigned int aOctetsTransmittedOK; - unsigned int aOctetsReceivedOK; - - /* IEEE 802.3 oPausedEntity Managed Object Support */ - unsigned int aTxPAUSEMACCtrlFrames; - unsigned int aRxPAUSEMACCtrlFrames; - - /* IETF MIB (MIB-II) Object Support */ - unsigned int ifInErrors; - unsigned int ifOutErrors; - unsigned int ifInUcastPkts; - unsigned int ifInMulticastPkts; - unsigned int ifInBroadcastPkts; - unsigned int ifOutDiscards; - unsigned int ifOutUcastPkts; - unsigned int ifOutMulticastPkts; - unsigned int ifOutBroadcastPkts; - - /* IETF RMON MIB Object Support */ - unsigned int etherStatsDropEvent; - unsigned int etherStatsOctets; - unsigned int etherStatsPkts; - unsigned int etherStatsUndersizePkts; - unsigned int etherStatsOversizePkts; - unsigned int etherStatsPkts64Octets; - unsigned int etherStatsPkts65to127Octets; - unsigned int etherStatsPkts128to255Octets; - unsigned int etherStatsPkts256to511Octets; - unsigned int etherStatsPkts512to1023Octets; - unsigned int etherStatsPkts1024to1518Octets; - - unsigned int etherStatsPkts1519toXOctets; - unsigned int etherStatsJabbers; - unsigned int etherStatsFragments; - - unsigned int reservedxE4; + u32 megacore_revision; + u32 scratch_pad; + u32 command_config; + u32 mac_addr_0; + u32 mac_addr_1; + u32 max_frame_length; + u32 pause_quanta; + u32 rx_sel_empty_threshold; + u32 rx_sel_full_threshold; + u32 tx_sel_empty_threshold; + u32 tx_sel_full_threshold; + u32 rx_almost_empty_threshold; + u32 rx_almost_full_threshold; + u32 tx_almost_empty_threshold; + u32 tx_almost_full_threshold; + u32 mdio_phy0_addr; + u32 mdio_phy1_addr; + + u32 reserved1[0x29]; /*FIFO control register. */ - unsigned int tx_cmd_stat; - unsigned int rx_cmd_stat; + u32 tx_cmd_stat; + u32 rx_cmd_stat; - unsigned int ipaccTxConf; - unsigned int ipaccRxConf; - unsigned int ipaccRxStat; - unsigned int ipaccRxStatSum; - - /*Multicast address resolution table */ - unsigned int hash_table[64]; + u32 reserved2[0x44]; /*Registers 0 to 31 within PHY device 0/1 */ - unsigned int mdio_phy0[0x20]; - unsigned int mdio_phy1[0x20]; + u32 mdio_phy0[0x20]; + u32 mdio_phy1[0x20]; /*4 Supplemental MAC Addresses */ - unsigned int supp_mac_addr_0_0; - unsigned int supp_mac_addr_0_1; - unsigned int supp_mac_addr_1_0; - unsigned int supp_mac_addr_1_1; - unsigned int supp_mac_addr_2_0; - unsigned int supp_mac_addr_2_1; - unsigned int supp_mac_addr_3_0; - unsigned int supp_mac_addr_3_1; - - unsigned int reservedx320[56]; + u32 supp_mac_addr_0_0; + u32 supp_mac_addr_0_1; + u32 supp_mac_addr_1_0; + u32 supp_mac_addr_1_1; + u32 supp_mac_addr_2_0; + u32 supp_mac_addr_2_1; + u32 supp_mac_addr_3_0; + u32 supp_mac_addr_3_1; + + u32 reserved3[0x38]; +}; + +struct tse_ops { + int (*send)(struct udevice *dev, void *packet, int length); + int (*recv)(struct udevice *dev, int flags, uchar **packetp); + int (*free_pkt)(struct udevice *dev, uchar *packet, int length); + void (*stop)(struct udevice *dev); }; struct altera_tse_priv { struct alt_tse_mac *mac_dev; - struct alt_sgdma_registers *sgdma_rx; - struct alt_sgdma_registers *sgdma_tx; + void *sgdma_rx; + void *sgdma_tx; unsigned int rx_fifo_depth; unsigned int tx_fifo_depth; - struct alt_sgdma_descriptor *rx_desc; - struct alt_sgdma_descriptor *tx_desc; + void *rx_desc; + void *tx_desc; + void *rx_resp; unsigned char *rx_buf; unsigned int phyaddr; unsigned int interface; struct phy_device *phydev; struct mii_dev *bus; + const struct tse_ops *ops; + int dma_type; }; #endif /* _ALTERA_TSE_H_ */ diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index d052fcb372..a3c9f99627 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -37,3 +37,4 @@ obj-$(CONFIG_PPC_T4160) += t4240.o obj-$(CONFIG_PPC_T4080) += t4240.o obj-$(CONFIG_PPC_B4420) += b4860.o obj-$(CONFIG_PPC_B4860) += b4860.o +obj-$(CONFIG_LS1043A) += ls1043.o diff --git a/drivers/net/fm/dtsec.c b/drivers/net/fm/dtsec.c index 8d3dc0e308..b339a84e59 100644 --- a/drivers/net/fm/dtsec.c +++ b/drivers/net/fm/dtsec.c @@ -7,7 +7,7 @@ #include <common.h> #include <asm/types.h> #include <asm/io.h> -#include <asm/fsl_dtsec.h> +#include <fsl_dtsec.h> #include <fsl_mdio.h> #include <phy.h> diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c index 6702f5a520..eb8e93618f 100644 --- a/drivers/net/fm/eth.c +++ b/drivers/net/fm/eth.c @@ -13,8 +13,8 @@ #include <fsl_mdio.h> #include <miiphy.h> #include <phy.h> -#include <asm/fsl_dtsec.h> -#include <asm/fsl_tgec.h> +#include <fsl_dtsec.h> +#include <fsl_tgec.h> #include <fsl_memac.h> #include "fm.h" @@ -41,28 +41,35 @@ static void dtsec_configure_serdes(struct fm_eth *priv) bus.priv = priv->mac->phyregs; bool sgmii_2500 = (priv->enet_if == PHY_INTERFACE_MODE_SGMII_2500) ? true : false; + int i = 0; +qsgmii_loop: /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */ value = PHY_SGMII_IF_MODE_SGMII; if (!sgmii_2500) value |= PHY_SGMII_IF_MODE_AN; - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value); + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x14, value); /* Dev ability according to SGMII specification */ value = PHY_SGMII_DEV_ABILITY_SGMII; - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value); + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x4, value); /* Adjust link timer for SGMII - 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 */ - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x3); - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xd40); + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x3); + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0xd40); /* Restart AN */ value = PHY_SGMII_CR_DEF_VAL; if (!sgmii_2500) value |= PHY_SGMII_CR_RESET_AN; - memac_mdio_write(&bus, 0, MDIO_DEVAD_NONE, 0, value); + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0, value); + + if ((priv->enet_if == PHY_INTERFACE_MODE_QSGMII) && (i < 3)) { + i++; + goto qsgmii_loop; + } #else struct dtsec *regs = priv->mac->base; struct tsec_mii_mng *phyregs = priv->mac->phyregs; @@ -91,10 +98,12 @@ static void dtsec_init_phy(struct eth_device *dev) #endif if (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII || + fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII || fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII_2500) dtsec_configure_serdes(fm_eth); } +#ifdef CONFIG_PHYLIB static int tgec_is_fibre(struct eth_device *dev) { struct fm_eth *fm = dev->priv; @@ -105,15 +114,16 @@ static int tgec_is_fibre(struct eth_device *dev) return hwconfig_arg_cmp(phyopt, "xfi"); } #endif +#endif static u16 muram_readw(u16 *addr) { - u32 base = (u32)addr & ~0x3; - u32 val32 = *(u32 *)base; + ulong base = (ulong)addr & ~0x3UL; + u32 val32 = in_be32((void *)base); int byte_pos; u16 ret; - byte_pos = (u32)addr & 0x3; + byte_pos = (ulong)addr & 0x3UL; if (byte_pos) ret = (u16)(val32 & 0x0000ffff); else @@ -124,18 +134,18 @@ static u16 muram_readw(u16 *addr) static void muram_writew(u16 *addr, u16 val) { - u32 base = (u32)addr & ~0x3; - u32 org32 = *(u32 *)base; + ulong base = (ulong)addr & ~0x3UL; + u32 org32 = in_be32((void *)base); u32 val32; int byte_pos; - byte_pos = (u32)addr & 0x3; + byte_pos = (ulong)addr & 0x3UL; if (byte_pos) val32 = (org32 & 0xffff0000) | val; else val32 = (org32 & 0x0000ffff) | ((u32)val << 16); - *(u32 *)base = val32; + out_be32((void *)base, val32); } static void bmi_rx_port_disable(struct fm_bmi_rx_port *rx_port) @@ -199,6 +209,8 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) u32 pram_page_offset; void *rx_bd_ring_base; void *rx_buf_pool; + u32 bd_ring_base_lo, bd_ring_base_hi; + u32 buf_lo, buf_hi; struct fm_port_bd *rxbd; struct fm_port_qd *rxqd; struct fm_bmi_rx_port *bmi_rx_port = fm_eth->rx_port; @@ -207,16 +219,21 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) /* alloc global parameter ram at MURAM */ pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, FM_PRAM_SIZE, FM_PRAM_ALIGN); + if (!pram) { + printf("%s: No muram for Rx global parameter\n", __func__); + return -ENOMEM; + } + fm_eth->rx_pram = pram; /* parameter page offset to MURAM */ - pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index); + pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index); /* enable global mode- snooping data buffers and BDs */ - pram->mode = PRAM_MODE_GLOBAL; + out_be32(&pram->mode, PRAM_MODE_GLOBAL); /* init the Rx queue descriptor pionter */ - pram->rxqd_ptr = pram_page_offset + 0x20; + out_be32(&pram->rxqd_ptr, pram_page_offset + 0x20); /* set the max receive buffer length, power of 2 */ muram_writew(&pram->mrblr, MAX_RXBUF_LOG2); @@ -225,15 +242,18 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) rx_bd_ring_base = malloc(sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); if (!rx_bd_ring_base) - return 0; + return -ENOMEM; + memset(rx_bd_ring_base, 0, sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); /* alloc Rx buffer from main memory */ rx_buf_pool = malloc(MAX_RXBUF_LEN * RX_BD_RING_SIZE); if (!rx_buf_pool) - return 0; + return -ENOMEM; + memset(rx_buf_pool, 0, MAX_RXBUF_LEN * RX_BD_RING_SIZE); + debug("%s: rx_buf_pool = %p\n", __func__, rx_buf_pool); /* save them to fm_eth */ fm_eth->rx_bd_ring = rx_bd_ring_base; @@ -243,18 +263,24 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) /* init Rx BDs ring */ rxbd = (struct fm_port_bd *)rx_bd_ring_base; for (i = 0; i < RX_BD_RING_SIZE; i++) { - rxbd->status = RxBD_EMPTY; - rxbd->len = 0; - rxbd->buf_ptr_hi = 0; - rxbd->buf_ptr_lo = (u32)rx_buf_pool + i * MAX_RXBUF_LEN; + muram_writew(&rxbd->status, RxBD_EMPTY); + muram_writew(&rxbd->len, 0); + buf_hi = upper_32_bits(virt_to_phys(rx_buf_pool + + i * MAX_RXBUF_LEN)); + buf_lo = lower_32_bits(virt_to_phys(rx_buf_pool + + i * MAX_RXBUF_LEN)); + muram_writew(&rxbd->buf_ptr_hi, (u16)buf_hi); + out_be32(&rxbd->buf_ptr_lo, buf_lo); rxbd++; } /* set the Rx queue descriptor */ rxqd = &pram->rxqd; muram_writew(&rxqd->gen, 0); - muram_writew(&rxqd->bd_ring_base_hi, 0); - rxqd->bd_ring_base_lo = (u32)rx_bd_ring_base; + bd_ring_base_hi = upper_32_bits(virt_to_phys(rx_bd_ring_base)); + bd_ring_base_lo = lower_32_bits(virt_to_phys(rx_bd_ring_base)); + muram_writew(&rxqd->bd_ring_base_hi, (u16)bd_ring_base_hi); + out_be32(&rxqd->bd_ring_base_lo, bd_ring_base_lo); muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd) * RX_BD_RING_SIZE); muram_writew(&rxqd->offset_in, 0); @@ -263,7 +289,7 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth) /* set IM parameter ram pointer to Rx Frame Queue ID */ out_be32(&bmi_rx_port->fmbm_rfqid, pram_page_offset); - return 1; + return 0; } static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) @@ -271,6 +297,7 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) struct fm_port_global_pram *pram; u32 pram_page_offset; void *tx_bd_ring_base; + u32 bd_ring_base_lo, bd_ring_base_hi; struct fm_port_bd *txbd; struct fm_port_qd *txqd; struct fm_bmi_tx_port *bmi_tx_port = fm_eth->tx_port; @@ -279,22 +306,27 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) /* alloc global parameter ram at MURAM */ pram = (struct fm_port_global_pram *)fm_muram_alloc(fm_eth->fm_index, FM_PRAM_SIZE, FM_PRAM_ALIGN); + if (!pram) { + printf("%s: No muram for Tx global parameter\n", __func__); + return -ENOMEM; + } fm_eth->tx_pram = pram; /* parameter page offset to MURAM */ - pram_page_offset = (u32)pram - fm_muram_base(fm_eth->fm_index); + pram_page_offset = (void *)pram - fm_muram_base(fm_eth->fm_index); /* enable global mode- snooping data buffers and BDs */ - pram->mode = PRAM_MODE_GLOBAL; + out_be32(&pram->mode, PRAM_MODE_GLOBAL); /* init the Tx queue descriptor pionter */ - pram->txqd_ptr = pram_page_offset + 0x40; + out_be32(&pram->txqd_ptr, pram_page_offset + 0x40); /* alloc Tx buffer descriptors from main memory */ tx_bd_ring_base = malloc(sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); if (!tx_bd_ring_base) - return 0; + return -ENOMEM; + memset(tx_bd_ring_base, 0, sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); /* save it to fm_eth */ @@ -304,16 +336,19 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) /* init Tx BDs ring */ txbd = (struct fm_port_bd *)tx_bd_ring_base; for (i = 0; i < TX_BD_RING_SIZE; i++) { - txbd->status = TxBD_LAST; - txbd->len = 0; - txbd->buf_ptr_hi = 0; - txbd->buf_ptr_lo = 0; + muram_writew(&txbd->status, TxBD_LAST); + muram_writew(&txbd->len, 0); + muram_writew(&txbd->buf_ptr_hi, 0); + out_be32(&txbd->buf_ptr_lo, 0); + txbd++; } /* set the Tx queue decriptor */ txqd = &pram->txqd; - muram_writew(&txqd->bd_ring_base_hi, 0); - txqd->bd_ring_base_lo = (u32)tx_bd_ring_base; + bd_ring_base_hi = upper_32_bits(virt_to_phys(tx_bd_ring_base)); + bd_ring_base_lo = lower_32_bits(virt_to_phys(tx_bd_ring_base)); + muram_writew(&txqd->bd_ring_base_hi, (u16)bd_ring_base_hi); + out_be32(&txqd->bd_ring_base_lo, bd_ring_base_lo); muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd) * TX_BD_RING_SIZE); muram_writew(&txqd->offset_in, 0); @@ -322,29 +357,35 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth) /* set IM parameter ram pointer to Tx Confirmation Frame Queue ID */ out_be32(&bmi_tx_port->fmbm_tcfqid, pram_page_offset); - return 1; + return 0; } static int fm_eth_init(struct fm_eth *fm_eth) { + int ret; - if (!fm_eth_rx_port_parameter_init(fm_eth)) - return 0; + ret = fm_eth_rx_port_parameter_init(fm_eth); + if (ret) + return ret; - if (!fm_eth_tx_port_parameter_init(fm_eth)) - return 0; + ret = fm_eth_tx_port_parameter_init(fm_eth); + if (ret) + return ret; - return 1; + return 0; } static int fm_eth_startup(struct fm_eth *fm_eth) { struct fsl_enet_mac *mac; + int ret; + mac = fm_eth->mac; /* Rx/TxBDs, Rx/TxQDs, Rx buff and parameter ram init */ - if (!fm_eth_init(fm_eth)) - return 0; + ret = fm_eth_init(fm_eth); + if (ret) + return ret; /* setup the MAC controller */ mac->init_mac(mac); @@ -359,7 +400,7 @@ static int fm_eth_startup(struct fm_eth *fm_eth) /* init bmi tx port, IM mode and disable */ bmi_tx_port_init(fm_eth->tx_port); - return 1; + return 0; } static void fmc_tx_port_graceful_stop_enable(struct fm_eth *fm_eth) @@ -368,7 +409,7 @@ static void fmc_tx_port_graceful_stop_enable(struct fm_eth *fm_eth) pram = fm_eth->tx_pram; /* graceful stop transmission of frames */ - pram->mode |= PRAM_MODE_GRACEFUL_STOP; + setbits_be32(&pram->mode, PRAM_MODE_GRACEFUL_STOP); sync(); } @@ -378,7 +419,7 @@ static void fmc_tx_port_graceful_stop_disable(struct fm_eth *fm_eth) pram = fm_eth->tx_pram; /* re-enable transmission of frames */ - pram->mode &= ~PRAM_MODE_GRACEFUL_STOP; + clrbits_be32(&pram->mode, PRAM_MODE_GRACEFUL_STOP); sync(); } @@ -452,8 +493,10 @@ static void fm_eth_halt(struct eth_device *dev) /* disable bmi Rx port */ bmi_rx_port_disable(fm_eth->rx_port); +#ifdef CONFIG_PHYLIB if (fm_eth->phydev) phy_shutdown(fm_eth->phydev); +#endif } static int fm_eth_send(struct eth_device *dev, void *buf, int len) @@ -469,19 +512,20 @@ static int fm_eth_send(struct eth_device *dev, void *buf, int len) txbd = fm_eth->cur_txbd; /* find one empty TxBD */ - for (i = 0; txbd->status & TxBD_READY; i++) { + for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) { udelay(100); if (i > 0x1000) { - printf("%s: Tx buffer not ready\n", dev->name); + printf("%s: Tx buffer not ready, txbd->status = 0x%x\n", + dev->name, muram_readw(&txbd->status)); return 0; } } /* setup TxBD */ - txbd->buf_ptr_hi = 0; - txbd->buf_ptr_lo = (u32)buf; - txbd->len = len; + muram_writew(&txbd->buf_ptr_hi, (u16)upper_32_bits(virt_to_phys(buf))); + out_be32(&txbd->buf_ptr_lo, lower_32_bits(virt_to_phys(buf))); + muram_writew(&txbd->len, len); sync(); - txbd->status = TxBD_READY | TxBD_LAST; + muram_writew(&txbd->status, TxBD_READY | TxBD_LAST); sync(); /* update TxQD, let RISC to send the packet */ @@ -493,10 +537,11 @@ static int fm_eth_send(struct eth_device *dev, void *buf, int len) sync(); /* wait for buffer to be transmitted */ - for (i = 0; txbd->status & TxBD_READY; i++) { + for (i = 0; muram_readw(&txbd->status) & TxBD_READY; i++) { udelay(100); if (i > 0x10000) { - printf("%s: Tx error\n", dev->name); + printf("%s: Tx error, txbd->status = 0x%x\n", + dev->name, muram_readw(&txbd->status)); return 0; } } @@ -518,6 +563,7 @@ static int fm_eth_recv(struct eth_device *dev) struct fm_port_global_pram *pram; struct fm_port_bd *rxbd, *rxbd_base; u16 status, len; + u32 buf_lo, buf_hi; u8 *data; u16 offset_out; int ret = 1; @@ -525,12 +571,14 @@ static int fm_eth_recv(struct eth_device *dev) fm_eth = (struct fm_eth *)dev->priv; pram = fm_eth->rx_pram; rxbd = fm_eth->cur_rxbd; - status = rxbd->status; + status = muram_readw(&rxbd->status); while (!(status & RxBD_EMPTY)) { if (!(status & RxBD_ERROR)) { - data = (u8 *)rxbd->buf_ptr_lo; - len = rxbd->len; + buf_hi = muram_readw(&rxbd->buf_ptr_hi); + buf_lo = in_be32(&rxbd->buf_ptr_lo); + data = (u8 *)((ulong)(buf_hi << 16) << 16 | buf_lo); + len = muram_readw(&rxbd->len); net_process_received_packet(data, len); } else { printf("%s: Rx error\n", dev->name); @@ -538,8 +586,8 @@ static int fm_eth_recv(struct eth_device *dev) } /* clear the RxBDs */ - rxbd->status = RxBD_EMPTY; - rxbd->len = 0; + muram_writew(&rxbd->status, RxBD_EMPTY); + muram_writew(&rxbd->len, 0); sync(); /* advance RxBD */ @@ -548,7 +596,7 @@ static int fm_eth_recv(struct eth_device *dev) if (rxbd >= (rxbd_base + RX_BD_RING_SIZE)) rxbd = rxbd_base; /* read next status */ - status = rxbd->status; + status = muram_readw(&rxbd->status); /* update RxQD */ offset_out = muram_readw(&pram->rxqd.offset_out); @@ -601,7 +649,7 @@ static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg) /* alloc mac controller */ mac = malloc(sizeof(struct fsl_enet_mac)); if (!mac) - return 0; + return -ENOMEM; memset(mac, 0, sizeof(struct fsl_enet_mac)); /* save the mac to fm_eth struct */ @@ -616,19 +664,21 @@ static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg) init_tgec(mac, base, phyregs, MAX_RXBUF_LEN); #endif - return 1; + return 0; } static int init_phy(struct eth_device *dev) { struct fm_eth *fm_eth = dev->priv; +#ifdef CONFIG_PHYLIB struct phy_device *phydev = NULL; u32 supported; +#endif -#ifdef CONFIG_PHYLIB if (fm_eth->type == FM_ETH_1G_E) dtsec_init_phy(dev); +#ifdef CONFIG_PHYLIB if (fm_eth->bus) { phydev = phy_connect(fm_eth->bus, fm_eth->phyaddr, dev, fm_eth->enet_if); @@ -669,17 +719,18 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info) struct eth_device *dev; struct fm_eth *fm_eth; int i, num = info->num; + int ret; /* alloc eth device */ dev = (struct eth_device *)malloc(sizeof(struct eth_device)); if (!dev) - return 0; + return -ENOMEM; memset(dev, 0, sizeof(struct eth_device)); /* alloc the FMan ethernet private struct */ fm_eth = (struct fm_eth *)malloc(sizeof(struct fm_eth)); if (!fm_eth) - return 0; + return -ENOMEM; memset(fm_eth, 0, sizeof(struct fm_eth)); /* save off some things we need from the info struct */ @@ -694,8 +745,9 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info) fm_eth->max_rx_len = MAX_RXBUF_LEN; /* init global mac structure */ - if (!fm_eth_init_mac(fm_eth, reg)) - return 0; + ret = fm_eth_init_mac(fm_eth, reg); + if (ret) + return ret; /* keep same as the manual, we call FMAN1, FMAN2, DTSEC1, DTSEC2, etc */ if (fm_eth->type == FM_ETH_1G_E) @@ -716,8 +768,9 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info) fm_eth->enet_if = info->enet_if; /* startup the FM im */ - if (!fm_eth_startup(fm_eth)) - return 0; + ret = fm_eth_startup(fm_eth); + if (ret) + return ret; init_phy(dev); @@ -726,5 +779,5 @@ int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info) dev->enetaddr[i] = 0; eth_register(dev); - return 1; + return 0; } diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index 400e9dd5e2..df5db723ba 100644 --- a/drivers/net/fm/fm.c +++ b/drivers/net/fm/fm.c @@ -22,21 +22,22 @@ struct fm_muram muram[CONFIG_SYS_NUM_FMAN]; -u32 fm_muram_base(int fm_idx) +void *fm_muram_base(int fm_idx) { return muram[fm_idx].base; } -u32 fm_muram_alloc(int fm_idx, u32 size, u32 align) +void *fm_muram_alloc(int fm_idx, size_t size, ulong align) { - u32 ret; - u32 align_mask, off; - u32 save; + void *ret; + ulong align_mask; + size_t off; + void *save; align_mask = align - 1; save = muram[fm_idx].alloc; - off = save & align_mask; + off = (ulong)save & align_mask; if (off != 0) muram[fm_idx].alloc += (align - off); off = size & align_mask; @@ -45,6 +46,7 @@ u32 fm_muram_alloc(int fm_idx, u32 size, u32 align) if ((muram[fm_idx].alloc + size) >= muram[fm_idx].top) { muram[fm_idx].alloc = save; printf("%s: run out of ram.\n", __func__); + return NULL; } ret = muram[fm_idx].alloc; @@ -56,7 +58,7 @@ u32 fm_muram_alloc(int fm_idx, u32 size, u32 align) static void fm_init_muram(int fm_idx, void *reg) { - u32 base = (u32)reg; + void *base = reg; muram[fm_idx].base = base; muram[fm_idx].size = CONFIG_SYS_FM_MURAM_SIZE; @@ -80,11 +82,11 @@ static void fm_upload_ucode(int fm_idx, struct fm_imem *imem, out_be32(&imem->iadd, IRAM_IADD_AIE); /* write microcode to IRAM */ for (i = 0; i < size / 4; i++) - out_be32(&imem->idata, ucode[i]); + out_be32(&imem->idata, (be32_to_cpu(ucode[i]))); /* verify if the writing is over */ out_be32(&imem->iadd, 0); - while ((in_be32(&imem->idata) != ucode[0]) && --timeout) + while ((in_be32(&imem->idata) != be32_to_cpu(ucode[0])) && --timeout) ; if (!timeout) printf("Fman%u: microcode upload timeout\n", fm_idx + 1); @@ -177,14 +179,15 @@ static int fman_upload_firmware(int fm_idx, const struct qe_microcode *ucode = &firmware->microcode[i]; /* Upload a microcode if it's present */ - if (ucode->code_offset) { + if (be32_to_cpu(ucode->code_offset)) { u32 ucode_size; u32 *code; printf("Fman%u: Uploading microcode version %u.%u.%u\n", fm_idx + 1, ucode->major, ucode->minor, ucode->revision); - code = (void *)firmware + ucode->code_offset; - ucode_size = sizeof(u32) * ucode->count; + code = (void *)firmware + + be32_to_cpu(ucode->code_offset); + ucode_size = sizeof(u32) * be32_to_cpu(ucode->count); fm_upload_ucode(fm_idx, fm_imem, code, ucode_size); } } @@ -255,7 +258,9 @@ static void fm_init_fpm(struct fm_fpm *fpm) static int fm_init_bmi(int fm_idx, struct fm_bmi_common *bmi) { int blk, i, port_id; - u32 val, offset, base; + u32 val; + size_t offset; + void *base; /* alloc free buffer pool in MURAM */ base = fm_muram_alloc(fm_idx, FM_FREE_POOL_SIZE, FM_FREE_POOL_ALIGN); diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index a9691c635a..fa9bc9f42d 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -10,7 +10,7 @@ #include <common.h> #include <phy.h> #include <fm_eth.h> -#include <asm/fsl_fman.h> +#include <fsl_fman.h> /* Port ID */ #define OH_PORT_ID_BASE 0x01 @@ -26,10 +26,10 @@ #define MIIM_TIMEOUT 0xFFFF struct fm_muram { - u32 base; - u32 top; - u32 size; - u32 alloc; + void *base; + void *top; + size_t size; + void *alloc; }; #define FM_MURAM_RES_SIZE 0x01000 @@ -95,8 +95,8 @@ struct fm_port_global_pram { #endif #define FM_FREE_POOL_ALIGN 256 -u32 fm_muram_alloc(int fm_idx, u32 size, u32 align); -u32 fm_muram_base(int fm_idx); +void *fm_muram_alloc(int fm_idx, size_t size, ulong align); +void *fm_muram_base(int fm_idx); int fm_init_common(int index, struct ccsr_fman *reg); int fm_eth_initialize(struct ccsr_fman *reg, struct fm_eth_info *info); phy_interface_t fman_port_enet_if(enum fm_port port); diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index b3ff4c50db..3a1de59fd8 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -1,13 +1,17 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2015 Freescale Semiconductor, Inc. * * SPDX-License-Identifier: GPL-2.0+ */ #include <errno.h> #include <common.h> #include <asm/io.h> -#include <asm/fsl_serdes.h> #include <fsl_mdio.h> +#ifdef CONFIG_FSL_LAYERSCAPE +#include <asm/arch/fsl_serdes.h> +#else +#include <asm/fsl_serdes.h> +#endif #include "fm.h" @@ -153,7 +157,9 @@ void fm_disable_port(enum fm_port port) return; fm_info[i].enabled = 0; +#ifndef CONFIG_SYS_FMAN_V3 fman_disable_port(port); +#endif } void fm_enable_port(enum fm_port port) diff --git a/drivers/net/fm/ls1043.c b/drivers/net/fm/ls1043.c new file mode 100644 index 0000000000..cf2cc95a3a --- /dev/null +++ b/drivers/net/fm/ls1043.c @@ -0,0 +1,119 @@ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <phy.h> +#include <fm_eth.h> +#include <asm/io.h> +#include <asm/arch/fsl_serdes.h> + +#define FSL_CHASSIS2_RCWSR13_EC1 0xe0000000 /* bits 416..418 */ +#define FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII 0x00000000 +#define FSL_CHASSIS2_RCWSR13_EC1_GPIO 0x20000000 +#define FSL_CHASSIS2_RCWSR13_EC1_FTM 0xa0000000 +#define FSL_CHASSIS2_RCWSR13_EC2 0x1c000000 /* bits 419..421 */ +#define FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII 0x00000000 +#define FSL_CHASSIS2_RCWSR13_EC2_GPIO 0x04000000 +#define FSL_CHASSIS2_RCWSR13_EC2_1588 0x08000000 +#define FSL_CHASSIS2_RCWSR13_EC2_FTM 0x14000000 + +u32 port_to_devdisr[] = { + [FM1_DTSEC1] = FSL_CHASSIS2_DEVDISR2_DTSEC1_1, + [FM1_DTSEC2] = FSL_CHASSIS2_DEVDISR2_DTSEC1_2, + [FM1_DTSEC3] = FSL_CHASSIS2_DEVDISR2_DTSEC1_3, + [FM1_DTSEC4] = FSL_CHASSIS2_DEVDISR2_DTSEC1_4, + [FM1_DTSEC5] = FSL_CHASSIS2_DEVDISR2_DTSEC1_5, + [FM1_DTSEC6] = FSL_CHASSIS2_DEVDISR2_DTSEC1_6, + [FM1_DTSEC9] = FSL_CHASSIS2_DEVDISR2_DTSEC1_9, + [FM1_DTSEC10] = FSL_CHASSIS2_DEVDISR2_DTSEC1_10, + [FM1_10GEC1] = FSL_CHASSIS2_DEVDISR2_10GEC1_1, + [FM1_10GEC2] = FSL_CHASSIS2_DEVDISR2_10GEC1_2, + [FM1_10GEC3] = FSL_CHASSIS2_DEVDISR2_10GEC1_3, + [FM1_10GEC4] = FSL_CHASSIS2_DEVDISR2_10GEC1_4, +}; + +static int is_device_disabled(enum fm_port port) +{ + struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 devdisr2 = in_be32(&gur->devdisr2); + + return port_to_devdisr[port] & devdisr2; +} + +void fman_disable_port(enum fm_port port) +{ + struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + + setbits_be32(&gur->devdisr2, port_to_devdisr[port]); +} + +phy_interface_t fman_port_enet_if(enum fm_port port) +{ + struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 rcwsr13 = in_be32(&gur->rcwsr[13]); + + if (is_device_disabled(port)) { + printf("%s:%d: port(%d) is disabled\n", __func__, + __LINE__, port); + return PHY_INTERFACE_MODE_NONE; + } + + if ((port == FM1_10GEC1) && (is_serdes_configured(XFI_FM1_MAC9))) + return PHY_INTERFACE_MODE_XGMII; + + if ((port == FM1_DTSEC9) && (is_serdes_configured(XFI_FM1_MAC9))) + return PHY_INTERFACE_MODE_NONE; + + if (port == FM1_DTSEC3) + if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC1) == + FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII) { + printf("%s:%d: port(FM1_DTSEC3) is OK\n", + __func__, __LINE__); + return PHY_INTERFACE_MODE_RGMII; + } + if (port == FM1_DTSEC4) + if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC2) == + FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII) { + printf("%s:%d: port(FM1_DTSEC4) is OK\n", + __func__, __LINE__); + return PHY_INTERFACE_MODE_RGMII; + } + + /* handle SGMII */ + switch (port) { + case FM1_DTSEC1: + case FM1_DTSEC2: + if ((port == FM1_DTSEC2) && + is_serdes_configured(SGMII_2500_FM1_DTSEC2)) + return PHY_INTERFACE_MODE_SGMII_2500; + case FM1_DTSEC5: + case FM1_DTSEC6: + case FM1_DTSEC9: + if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) + return PHY_INTERFACE_MODE_SGMII; + else if ((port == FM1_DTSEC9) && + is_serdes_configured(SGMII_2500_FM1_DTSEC9)) + return PHY_INTERFACE_MODE_SGMII_2500; + break; + default: + break; + } + + /* handle QSGMII */ + switch (port) { + case FM1_DTSEC1: + case FM1_DTSEC2: + case FM1_DTSEC5: + case FM1_DTSEC6: + /* only MAC 1,2,5,6 available for QSGMII */ + if (is_serdes_configured(QSGMII_FM1_A)) + return PHY_INTERFACE_MODE_QSGMII; + break; + default: + break; + } + + return PHY_INTERFACE_MODE_NONE; +} diff --git a/drivers/net/fm/tgec.c b/drivers/net/fm/tgec.c index 50171230ea..8d4622ff38 100644 --- a/drivers/net/fm/tgec.c +++ b/drivers/net/fm/tgec.c @@ -12,7 +12,7 @@ #include <phy.h> #include <asm/types.h> #include <asm/io.h> -#include <asm/fsl_tgec.h> +#include <fsl_tgec.h> #include "fm.h" diff --git a/drivers/net/fm/tgec_phy.c b/drivers/net/fm/tgec_phy.c index 095f00cf97..24cb17b6ed 100644 --- a/drivers/net/fm/tgec_phy.c +++ b/drivers/net/fm/tgec_phy.c @@ -9,7 +9,7 @@ #include <miiphy.h> #include <phy.h> #include <asm/io.h> -#include <asm/fsl_tgec.h> +#include <fsl_tgec.h> #include <fm_eth.h> /* diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c index 4de7586408..99acb7a0c9 100644 --- a/drivers/net/ldpaa_eth/ldpaa_eth.c +++ b/drivers/net/ldpaa_eth/ldpaa_eth.c @@ -220,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; - uint8_t mac_addr[6]; int err; if (net_dev->state == ETH_STATE_ACTIVE) @@ -240,21 +239,13 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd) if (err) goto err_bind; - err = dpni_get_primary_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, - priv->dpni_handle, mac_addr); + err = dpni_add_mac_addr(dflt_mc_io, MC_CMD_NO_FLAGS, + priv->dpni_handle, net_dev->enetaddr); if (err) { - printf("dpni_get_primary_mac_addr() failed\n"); + printf("dpni_add_mac_addr() failed\n"); return err; } - memcpy(net_dev->enetaddr, mac_addr, 0x6); - - /* setup the MAC address */ - if (net_dev->enetaddr[0] & 0x01) { - printf("%s: MacAddress is multcast address\n", __func__); - return 1; - } - #ifdef CONFIG_PHYLIB /* TODO Check this path */ err = phy_startup(priv->phydev); diff --git a/drivers/net/ldpaa_eth/ls2085a.c b/drivers/net/ldpaa_eth/ls2085a.c index 6b7960a000..93ed4f18fe 100644 --- a/drivers/net/ldpaa_eth/ls2085a.c +++ b/drivers/net/ldpaa_eth/ls2085a.c @@ -7,9 +7,7 @@ #include <phy.h> #include <fsl-mc/ldpaa_wriop.h> #include <asm/io.h> -#include <asm/arch-fsl-lsch3/immap_lsch3.h> #include <asm/arch/fsl_serdes.h> -#include <fsl-mc/ldpaa_wriop.h> u32 dpmac_to_devdisr[] = { [WRIOP1_DPMAC1] = FSL_CHASSIS3_DEVDISR2_DPMAC1, diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index bf972dc39b..3500047577 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -330,7 +330,7 @@ int drv_nc_init(void) memset(&dev, 0, sizeof(dev)); strcpy(dev.name, "nc"); - dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; + dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.start = nc_stdio_start; dev.putc = nc_stdio_putc; dev.puts = nc_stdio_puts; |