<commit_before>/*
 * Copyright 2014, NICTA
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(NICTA_GPL)
 */

#include "../../descriptors.h"
#include <ethdrivers/lwip_iface.h>
#include "imx6EthernetDriver.h"
#include "../../dma_buffers.h"
#include "unimplemented.h"
#include "uboot/common.h"
#include "uboot/fec_mxc.h"
#include "io.h"
#include "../../raw_iface.h"
#include <netif/etharp.h>
#include <lwip/stats.h>
#include "uboot/miiphy.h"
#include "uboot/micrel.h"
#include "debug.h"
#include "ocotp_ctrl.h"
#include <assert.h>
#include <string.h>
#include "enet.h"
#include <utils/util.h>

#define DEFAULT_MAC "\x00\x19\xb8\x00\xf0\xa3"

/* Receive descriptor status */ 
#define RXD_EMPTY     BIT(15) /* Buffer has no data. Waiting for reception. */
#define RXD_OWN0      BIT(14) /* Receive software ownership. R/W by user */
#define RXD_WRAP      BIT(13) /* Next buffer is found in ENET_RDSR */
#define RXD_OWN1      BIT(12) /* Receive software ownership. R/W by user */
#define RXD_LAST      BIT(11) /* Last buffer in frame. Written by the uDMA. */
#define RXD_MISS      BIT( 8) /* Frame does not match MAC (promiscuous mode) */
#define RXD_BROADCAST BIT( 7) /* frame is a broadcast frame */
#define RXD_MULTICAST BIT( 6) /* frame is a multicast frame */
#define RXD_BADLEN    BIT( 5) /* Incoming frame was larger than RCR[MAX_FL] */
#define RXD_BADALIGN  BIT( 4) /* Frame length does not align to a byte */
#define RXD_CRCERR    BIT( 2) /* The frame has a CRC error */
#define RXD_OVERRUN   BIT( 1) /* FIFO overrun */
#define RXD_TRUNC     BIT( 0) /* Receive frame > TRUNC_FL */

#define RXD_ERROR    (RXD_BADLEN  | RXD_BADALIGN | RXD_CRCERR |\
                      RXD_OVERRUN | RXD_TRUNC)

/* Transmit descriptor status */ 
#define TXD_READY     BIT(15) /* buffer in use waiting to be transmitted */
#define TXD_OWN0      BIT(14) /* Receive software ownership. R/W by user */
#define TXD_WRAP      BIT(13) /* Next buffer is found in ENET_TDSR */
#define TXD_OWN1      BIT(12) /* Receive software ownership. R/W by user */
#define TXD_LAST      BIT(11) /* Last buffer in frame. Written by the uDMA. */
#define TXD_ADDCRC    BIT(10) /* Append a CRC to the end of the frame */
#define TXD_ADDBADCRC BIT( 9) /* Append a bad CRC to the end of the frame */

/* We chose the total number of spare DMA buffers to be 2 * RX ring size + TX ring size
 * This means we can be processing a full set of received packets, transmitting as
 * many packets as possible, and still have buffers to receive more packets. In reality
 * I made this constant up so it's probably bad */
#define NUM_DMA_BUFS (CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT * 2 + \
                        CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT)
int setup_iomux_enet(ps_io_ops_t *io_ops);

#define INTERRUPT_ENET 150
#define INTERRUPT_ENET_TIMER 151
static const int net_irqs[] = {
        INTERRUPT_ENET,
        INTERRUPT_ENET_TIMER,
        0
};

struct imx6_eth_data {
    struct enet * enet;
    ps_io_ops_t io_ops;
    int irq_enabled;
};

struct descriptor {
    /* NOTE: little endian packing: len before stat */
#if BYTE_ORDER == LITTLE_ENDIAN
    uint16_t len;
    uint16_t stat;
#elif BYTE_ORDER == BIG_ENDIAN
    uint16_t stat;
    uint16_t len;
#else
#error Could not determine endianess
#endif
    uint32_t phys;
};

// Driver specific implementations of function in raw_iface.h and raw_descriptors.h
struct raw_iface_funcs* setup_raw_iface_funcs();
struct raw_desc_funcs* setup_raw_desc_funcs();
void  imx6_low_level_init(struct netif *netif);
void imx6_start_tx_logic(struct netif *netif);
void imx6_start_rx_logic(struct netif *netif);
void imx6_raw_handleIRQ(struct netif *netif, int irq);
const int* imx6_raw_enableIRQ(struct eth_driver *driver, int *nirqs);
dma_addr_t imx6_create_tx_descs(ps_dma_man_t *dma_man, int count);
dma_addr_t imx6_create_rx_descs(ps_dma_man_t *dman_man, int count);
void imx6_reset_tx_descs(struct eth_driver *driver);
void imx6_reset_rx_descs(struct eth_driver *driver);
int imx6_is_tx_desc_ready(int buf_num, struct desc *desc);
int imx6_is_rx_desc_empty(int buf_num, struct desc *desc);
void imx6_set_tx_desc_buf(int buf_num, dma_addr_t buf, int len, struct desc *desc);
void imx6_ready_tx_desc(int buf_num, int tx_desc_wrap, int tx_last_section, struct eth_driver *driver);
void imx6_set_rx_desc_buf(int buf_num, dma_addr_t buf, int len, struct desc *desc);
void imx6_ready_rx_desc(int buf_num, int rx_desc_wrap, struct eth_driver *driver);
int imx6_get_rx_buf_len(int buf_num, struct desc *desc);
int imx6_get_rx_desc_error(int buf_num, struct desc *desc);

struct imx6_eth_data*
eth_driver_get_eth_data(struct eth_driver *eth_driver) {
    return (struct imx6_eth_data*)eth_driver->eth_data;
}

struct eth_driver*
netif_get_eth_driver(struct netif *netif) {
    return (struct eth_driver*)netif->state;
}

struct imx6_eth_data*
netif_get_eth_data(struct netif *netif) {
    return eth_driver_get_eth_data(netif_get_eth_driver(netif));
}

struct eth_driver*
ethif_imx6_init(int dev_id, ps_io_ops_t interface)
{
    struct eth_driver *driver = NULL;
    struct desc* desc = NULL;
    
    struct ocotp *ocotp = NULL;
    int err;
    struct enet * enet;
    struct imx6_eth_data *eth_data = NULL;
    uint8_t mac[6];
    (void)dev_id;

    driver = (struct eth_driver*)malloc(sizeof(struct eth_driver));
    if (driver == NULL) {
        LOG_ERROR("Failed to allocate eth driver struct");
        goto error;
    }
    driver->r_fn = setup_raw_iface_funcs();
    if (!driver->r_fn) {
        goto error;
    }
    driver->d_fn = setup_raw_desc_funcs(); 
    if (!driver->d_fn) {
        goto error;
    }

    eth_data = (struct imx6_eth_data*)malloc(sizeof(struct imx6_eth_data));
    if (eth_data == NULL) {
        LOG_ERROR("Failed to allocate eth data struct");
        goto error;
    }

    desc = desc_init(&interface.dma_manager, CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT, 
                    CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT, NUM_DMA_BUFS, MAX_PKT_SIZE, driver);
    if (!desc) {
        LOG_ERROR("Failed to initialize / allocate DMA descriptors");
        goto error;
    }

    /* initialise the eFuse controller so we can get a MAC address */
    ocotp = ocotp_init(&interface.io_mapper);
    if (!ocotp) {
        LOG_ERROR("Failed to initialize ocotp");
        goto error;
    }
    /* Initialise ethernet pins */
    //gpio_init();
    err = setup_iomux_enet(&interface);
    if (err) {
        LOG_ERROR("Failed to setup iomux enet");
        goto error;
    }
    /* Initialise the phy library */
    miiphy_init();
    /* Initialise the phy */
    phy_micrel_init();
    /* Initialise the RGMII interface */ 
    enet = enet_init(desc, &interface);
    assert(enet);

    /* Fetch and set the MAC address */
    if (ocotp == NULL || ocotp_get_mac(ocotp, mac)) {<commit_msg>Rely on uboot setting when OCOTP and GPIO memory are not mapped.<commit_after>/*
 * Copyright 2014, NICTA
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(NICTA_GPL)
 */

#include "../../descriptors.h"
#include <ethdrivers/lwip_iface.h>
#include "imx6EthernetDriver.h"
#include "../../dma_buffers.h"
#include "unimplemented.h"
#include "uboot/common.h"
#include "uboot/fec_mxc.h"
#include "io.h"
#include "../../raw_iface.h"
#include <netif/etharp.h>
#include <lwip/stats.h>
#include "uboot/miiphy.h"
#include "uboot/micrel.h"
#include "debug.h"
#include "ocotp_ctrl.h"
#include <assert.h>
#include <string.h>
#include "enet.h"
#include <utils/util.h>

#define DEFAULT_MAC "\x00\x19\xb8\x00\xf0\xa3"

/* Receive descriptor status */ 
#define RXD_EMPTY     BIT(15) /* Buffer has no data. Waiting for reception. */
#define RXD_OWN0      BIT(14) /* Receive software ownership. R/W by user */
#define RXD_WRAP      BIT(13) /* Next buffer is found in ENET_RDSR */
#define RXD_OWN1      BIT(12) /* Receive software ownership. R/W by user */
#define RXD_LAST      BIT(11) /* Last buffer in frame. Written by the uDMA. */
#define RXD_MISS      BIT( 8) /* Frame does not match MAC (promiscuous mode) */
#define RXD_BROADCAST BIT( 7) /* frame is a broadcast frame */
#define RXD_MULTICAST BIT( 6) /* frame is a multicast frame */
#define RXD_BADLEN    BIT( 5) /* Incoming frame was larger than RCR[MAX_FL] */
#define RXD_BADALIGN  BIT( 4) /* Frame length does not align to a byte */
#define RXD_CRCERR    BIT( 2) /* The frame has a CRC error */
#define RXD_OVERRUN   BIT( 1) /* FIFO overrun */
#define RXD_TRUNC     BIT( 0) /* Receive frame > TRUNC_FL */

#define RXD_ERROR    (RXD_BADLEN  | RXD_BADALIGN | RXD_CRCERR |\
                      RXD_OVERRUN | RXD_TRUNC)

/* Transmit descriptor status */ 
#define TXD_READY     BIT(15) /* buffer in use waiting to be transmitted */
#define TXD_OWN0      BIT(14) /* Receive software ownership. R/W by user */
#define TXD_WRAP      BIT(13) /* Next buffer is found in ENET_TDSR */
#define TXD_OWN1      BIT(12) /* Receive software ownership. R/W by user */
#define TXD_LAST      BIT(11) /* Last buffer in frame. Written by the uDMA. */
#define TXD_ADDCRC    BIT(10) /* Append a CRC to the end of the frame */
#define TXD_ADDBADCRC BIT( 9) /* Append a bad CRC to the end of the frame */

/* We chose the total number of spare DMA buffers to be 2 * RX ring size + TX ring size
 * This means we can be processing a full set of received packets, transmitting as
 * many packets as possible, and still have buffers to receive more packets. In reality
 * I made this constant up so it's probably bad */
#define NUM_DMA_BUFS (CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT * 2 + \
                        CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT)
int setup_iomux_enet(ps_io_ops_t *io_ops);

#define INTERRUPT_ENET 150
#define INTERRUPT_ENET_TIMER 151
static const int net_irqs[] = {
        INTERRUPT_ENET,
        INTERRUPT_ENET_TIMER,
        0
};

struct imx6_eth_data {
    struct enet * enet;
    ps_io_ops_t io_ops;
    int irq_enabled;
};

struct descriptor {
    /* NOTE: little endian packing: len before stat */
#if BYTE_ORDER == LITTLE_ENDIAN
    uint16_t len;
    uint16_t stat;
#elif BYTE_ORDER == BIG_ENDIAN
    uint16_t stat;
    uint16_t len;
#else
#error Could not determine endianess
#endif
    uint32_t phys;
};

// Driver specific implementations of function in raw_iface.h and raw_descriptors.h
struct raw_iface_funcs* setup_raw_iface_funcs();
struct raw_desc_funcs* setup_raw_desc_funcs();
void  imx6_low_level_init(struct netif *netif);
void imx6_start_tx_logic(struct netif *netif);
void imx6_start_rx_logic(struct netif *netif);
void imx6_raw_handleIRQ(struct netif *netif, int irq);
const int* imx6_raw_enableIRQ(struct eth_driver *driver, int *nirqs);
dma_addr_t imx6_create_tx_descs(ps_dma_man_t *dma_man, int count);
dma_addr_t imx6_create_rx_descs(ps_dma_man_t *dman_man, int count);
void imx6_reset_tx_descs(struct eth_driver *driver);
void imx6_reset_rx_descs(struct eth_driver *driver);
int imx6_is_tx_desc_ready(int buf_num, struct desc *desc);
int imx6_is_rx_desc_empty(int buf_num, struct desc *desc);
void imx6_set_tx_desc_buf(int buf_num, dma_addr_t buf, int len, struct desc *desc);
void imx6_ready_tx_desc(int buf_num, int tx_desc_wrap, int tx_last_section, struct eth_driver *driver);
void imx6_set_rx_desc_buf(int buf_num, dma_addr_t buf, int len, struct desc *desc);
void imx6_ready_rx_desc(int buf_num, int rx_desc_wrap, struct eth_driver *driver);
int imx6_get_rx_buf_len(int buf_num, struct desc *desc);
int imx6_get_rx_desc_error(int buf_num, struct desc *desc);

struct imx6_eth_data*
eth_driver_get_eth_data(struct eth_driver *eth_driver) {
    return (struct imx6_eth_data*)eth_driver->eth_data;
}

struct eth_driver*
netif_get_eth_driver(struct netif *netif) {
    return (struct eth_driver*)netif->state;
}

struct imx6_eth_data*
netif_get_eth_data(struct netif *netif) {
    return eth_driver_get_eth_data(netif_get_eth_driver(netif));
}

struct eth_driver*
ethif_imx6_init(int dev_id, ps_io_ops_t interface)
{
    struct eth_driver *driver = NULL;
    struct desc* desc = NULL;
    
    struct ocotp *ocotp = NULL;
    int err;
    struct enet * enet;
    struct imx6_eth_data *eth_data = NULL;
    uint8_t mac[6];
    (void)dev_id;

    driver = (struct eth_driver*)malloc(sizeof(struct eth_driver));
    if (driver == NULL) {
        LOG_ERROR("Failed to allocate eth driver struct");
        goto error;
    }
    driver->r_fn = setup_raw_iface_funcs();
    if (!driver->r_fn) {
        goto error;
    }
    driver->d_fn = setup_raw_desc_funcs(); 
    if (!driver->d_fn) {
        goto error;
    }

    eth_data = (struct imx6_eth_data*)malloc(sizeof(struct imx6_eth_data));
    if (eth_data == NULL) {
        LOG_ERROR("Failed to allocate eth data struct");
        goto error;
    }

    desc = desc_init(&interface.dma_manager, CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT, 
                    CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT, NUM_DMA_BUFS, MAX_PKT_SIZE, driver);
    if (!desc) {
        LOG_ERROR("Failed to initialize / allocate DMA descriptors");
        goto error;
    }

    /* initialise the eFuse controller so we can get a MAC address */
    ocotp = ocotp_init(&interface.io_mapper);
    if (!ocotp) {
        LOG_INFO("Failed to initialize ocotp");
    }
    /* Initialise ethernet pins */
    //gpio_init();
    err = setup_iomux_enet(&interface);
    if (err) {
        LOG_INFO("Failed to setup iomux enet");
    }
    /* Initialise the phy library */
    miiphy_init();
    /* Initialise the phy */
    phy_micrel_init();
    /* Initialise the RGMII interface */ 
    enet = enet_init(desc, &interface);
    assert(enet);

    /* Fetch and set the MAC address */
    if (ocotp == NULL || ocotp_get_mac(ocotp, mac)) {
{'fraction_non_alphanumeric': 0.10262495505213952, 'fraction_numerical': 0.013951815893563466, 'mean_word_length': 3.6805789296533153, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7467794', 'n_tokens_mistral': 5176, 'n_tokens_neox': 4975, 'n_words': 1401}