/*
- * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved.
*
* Author: Shlomi Gridish <gridish@freescale.com>
* Li Yang <leoli@freescale.com>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/fsl_devices.h>
-#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/workqueue.h>
#undef DEBUG
-#define DRV_DESC "QE UCC Gigabit Ethernet Controller version:Sept 11, 2006"
+#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
#define DRV_NAME "ucc_geth"
+#define DRV_VERSION "1.1"
#define ugeth_printk(level, format, arg...) \
printk(level format "\n", ## arg)
else {
init_enet_offset =
qe_muram_alloc(thread_size, thread_alignment);
- if (IS_MURAM_ERR(init_enet_offset)) {
+ if (IS_ERR_VALUE(init_enet_offset)) {
ugeth_err
("fill_init_enet_entries: Can not allocate DPRAM memory.");
qe_put_snum((u8) snum);
}
-#ifdef CONFIG_UGETH_TX_ON_DEMOND
-static int ugeth_transmit_on_demand(struct ucc_geth_private *ugeth)
-{
- struct ucc_fastransmit_on_demand(ugeth->uccf);
-
- return 0;
-}
-#endif
static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
{
}
for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
bd = ugeth->p_tx_bd_ring[i];
+ if (!bd)
+ continue;
for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
if (ugeth->tx_skbuff[i][j]) {
dma_unmap_single(NULL,
ug_info = ugeth->ug_info;
uf_info = &ug_info->uf_info;
+ /* Create CQs for hash tables */
+ INIT_LIST_HEAD(&ugeth->group_hash_q);
+ INIT_LIST_HEAD(&ugeth->ind_hash_q);
+
if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
(uf_info->bd_mem_part == MEM_PART_MURAM))) {
ugeth_err("%s: Bad memory partition value.", __FUNCTION__);
ugeth->tx_bd_ring_offset[j] =
qe_muram_alloc(length,
UCC_GETH_TX_BD_RING_ALIGNMENT);
- if (!IS_MURAM_ERR(ugeth->tx_bd_ring_offset[j]))
+ if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j]))
ugeth->p_tx_bd_ring[j] =
(u8 *) qe_muram_addr(ugeth->
tx_bd_ring_offset[j]);
ugeth->rx_bd_ring_offset[j] =
qe_muram_alloc(length,
UCC_GETH_RX_BD_RING_ALIGNMENT);
- if (!IS_MURAM_ERR(ugeth->rx_bd_ring_offset[j]))
+ if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j]))
ugeth->p_rx_bd_ring[j] =
(u8 *) qe_muram_addr(ugeth->
rx_bd_ring_offset[j]);
ugeth->tx_glbl_pram_offset =
qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram),
UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) {
+ if (IS_ERR_VALUE(ugeth->tx_glbl_pram_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
__FUNCTION__);
sizeof(struct ucc_geth_thread_data_tx) +
32 * (numThreadsTxNumerical == 1),
UCC_GETH_THREAD_DATA_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) {
+ if (IS_ERR_VALUE(ugeth->thread_dat_tx_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
__FUNCTION__);
qe_muram_alloc(ug_info->numQueuesTx *
sizeof(struct ucc_geth_send_queue_qd),
UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) {
+ if (IS_ERR_VALUE(ugeth->send_q_mem_reg_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
__FUNCTION__);
ugeth->scheduler_offset =
qe_muram_alloc(sizeof(struct ucc_geth_scheduler),
UCC_GETH_SCHEDULER_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->scheduler_offset)) {
+ if (IS_ERR_VALUE(ugeth->scheduler_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_scheduler.",
__FUNCTION__);
qe_muram_alloc(sizeof
(struct ucc_geth_tx_firmware_statistics_pram),
UCC_GETH_TX_STATISTICS_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) {
+ if (IS_ERR_VALUE(ugeth->tx_fw_statistics_pram_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for"
" p_tx_fw_statistics_pram.", __FUNCTION__);
ugeth->rx_glbl_pram_offset =
qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram),
UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) {
+ if (IS_ERR_VALUE(ugeth->rx_glbl_pram_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
__FUNCTION__);
qe_muram_alloc(numThreadsRxNumerical *
sizeof(struct ucc_geth_thread_data_rx),
UCC_GETH_THREAD_DATA_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) {
+ if (IS_ERR_VALUE(ugeth->thread_dat_rx_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
__FUNCTION__);
qe_muram_alloc(sizeof
(struct ucc_geth_rx_firmware_statistics_pram),
UCC_GETH_RX_STATISTICS_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) {
+ if (IS_ERR_VALUE(ugeth->rx_fw_statistics_pram_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for"
" p_rx_fw_statistics_pram.", __FUNCTION__);
/* Size varies with number of Rx queues */
ugeth->rx_irq_coalescing_tbl_offset =
qe_muram_alloc(ug_info->numQueuesRx *
- sizeof(struct ucc_geth_rx_interrupt_coalescing_entry),
- UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) {
+ sizeof(struct ucc_geth_rx_interrupt_coalescing_entry)
+ + 4, UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
+ if (IS_ERR_VALUE(ugeth->rx_irq_coalescing_tbl_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for"
" p_rx_irq_coalescing_tbl.", __FUNCTION__);
(sizeof(struct ucc_geth_rx_bd_queues_entry) +
sizeof(struct ucc_geth_rx_prefetched_bds)),
UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) {
+ if (IS_ERR_VALUE(ugeth->rx_bd_qs_tbl_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
__FUNCTION__);
ugeth->exf_glbl_param_offset =
qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram),
UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT);
- if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) {
+ if (IS_ERR_VALUE(ugeth->exf_glbl_param_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for"
" p_exf_glbl_param.", __FUNCTION__);
for (j = 0; j < NUM_OF_PADDRS; j++)
ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j);
- /* Create CQs for hash tables */
- if (ug_info->maxGroupAddrInHash > 0) {
- INIT_LIST_HEAD(&ugeth->group_hash_q);
- }
- if (ug_info->maxIndAddrInHash > 0) {
- INIT_LIST_HEAD(&ugeth->ind_hash_q);
- }
p_82xx_addr_filt =
(struct ucc_geth_82xx_address_filtering_pram *) ugeth->
p_rx_glbl_pram->addressfiltering;
/* Allocate InitEnet command parameter structure */
init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4);
- if (IS_MURAM_ERR(init_enet_pram_offset)) {
+ if (IS_ERR_VALUE(init_enet_pram_offset)) {
ugeth_err
("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
__FUNCTION__);
static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ucc_geth_private *ugeth = netdev_priv(dev);
+#ifdef CONFIG_UGETH_TX_ON_DEMAND
+ struct ucc_fast_private *uccf;
+#endif
u8 *bd; /* BD pointer */
u32 bd_status;
u8 txQ = 0;
out_be16(ugeth->p_cpucount[txQ], ugeth->cpucount[txQ]);
}
+#ifdef CONFIG_UGETH_TX_ON_DEMAND
+ uccf = ugeth->uccf;
+ out_be16(uccf->p_utodr, UCC_FAST_TOD);
+#endif
spin_unlock_irq(&ugeth->lock);
return 0;
const struct ethtool_ops ucc_geth_ethtool_ops = { };
-static phy_interface_t to_phy_interface(const char *interface_type)
+static phy_interface_t to_phy_interface(const char *phy_connection_type)
{
- if (strcasecmp(interface_type, "mii") == 0)
+ if (strcasecmp(phy_connection_type, "mii") == 0)
return PHY_INTERFACE_MODE_MII;
- if (strcasecmp(interface_type, "gmii") == 0)
+ if (strcasecmp(phy_connection_type, "gmii") == 0)
return PHY_INTERFACE_MODE_GMII;
- if (strcasecmp(interface_type, "tbi") == 0)
+ if (strcasecmp(phy_connection_type, "tbi") == 0)
return PHY_INTERFACE_MODE_TBI;
- if (strcasecmp(interface_type, "rmii") == 0)
+ if (strcasecmp(phy_connection_type, "rmii") == 0)
return PHY_INTERFACE_MODE_RMII;
- if (strcasecmp(interface_type, "rgmii") == 0)
+ if (strcasecmp(phy_connection_type, "rgmii") == 0)
return PHY_INTERFACE_MODE_RGMII;
- if (strcasecmp(interface_type, "rgmii-id") == 0)
+ if (strcasecmp(phy_connection_type, "rgmii-id") == 0)
return PHY_INTERFACE_MODE_RGMII_ID;
- if (strcasecmp(interface_type, "rtbi") == 0)
+ if (strcasecmp(phy_connection_type, "rtbi") == 0)
return PHY_INTERFACE_MODE_RTBI;
return PHY_INTERFACE_MODE_MII;
ugeth_vdbg("%s: IN", __FUNCTION__);
- prop = get_property(np, "device-id", NULL);
+ prop = of_get_property(np, "device-id", NULL);
ucc_num = *prop - 1;
if ((ucc_num < 0) || (ucc_num > 7))
return -ENODEV;
ug_info = &ugeth_info[ucc_num];
ug_info->uf_info.ucc_num = ucc_num;
- prop = get_property(np, "rx-clock", NULL);
+ prop = of_get_property(np, "rx-clock", NULL);
ug_info->uf_info.rx_clock = *prop;
- prop = get_property(np, "tx-clock", NULL);
+ prop = of_get_property(np, "tx-clock", NULL);
ug_info->uf_info.tx_clock = *prop;
err = of_address_to_resource(np, 0, &res);
if (err)
ug_info->uf_info.regs = res.start;
ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
- ph = get_property(np, "phy-handle", NULL);
+ ph = of_get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
if (phy == NULL)
return -ENODEV;
/* set the PHY address */
- prop = get_property(phy, "reg", NULL);
+ prop = of_get_property(phy, "reg", NULL);
if (prop == NULL)
return -1;
ug_info->phy_address = *prop;
/* get the phy interface type, or default to MII */
- prop = get_property(np, "interface-type", NULL);
+ prop = of_get_property(np, "phy-connection-type", NULL);
if (!prop) {
/* handle interface property present in old trees */
- prop = get_property(phy, "interface", NULL);
- if (prop != NULL)
+ prop = of_get_property(phy, "interface", NULL);
+ if (prop != NULL) {
phy_interface = enet_to_phy_interface[*prop];
- else
+ max_speed = enet_to_speed[*prop];
+ } else
phy_interface = PHY_INTERFACE_MODE_MII;
} else {
phy_interface = to_phy_interface((const char *)prop);
}
- /* get speed, or derive from interface */
- prop = get_property(np, "max-speed", NULL);
- if (!prop) {
- /* handle interface property present in old trees */
- prop = get_property(phy, "interface", NULL);
- if (prop != NULL)
- max_speed = enet_to_speed[*prop];
- } else {
- max_speed = *prop;
- }
- if (!max_speed) {
+ /* get speed, or derive from PHY interface */
+ if (max_speed == 0)
switch (phy_interface) {
case PHY_INTERFACE_MODE_GMII:
case PHY_INTERFACE_MODE_RGMII:
max_speed = SPEED_100;
break;
}
- }
if (max_speed == SPEED_1000) {
+ /* configure muram FIFOs for gigabit operation */
ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT;
ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT;
ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT;
MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL");