sky2: memory barriers change
[safe/jmp/linux-2.6] / drivers / net / ucc_geth.c
index 60be1e7..c2ccbd0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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>
@@ -46,8 +46,9 @@
 
 #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)
@@ -292,7 +293,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
                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);
@@ -1626,14 +1627,6 @@ static int init_phy(struct net_device *dev)
 }
 
 
-#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)
 {
@@ -2141,6 +2134,8 @@ static void ucc_geth_memclean(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,
@@ -2308,6 +2303,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
        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__);
@@ -2595,7 +2594,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                        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]);
@@ -2630,7 +2629,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                        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]);
@@ -2714,7 +2713,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        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__);
@@ -2736,7 +2735,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                           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__);
@@ -2764,7 +2763,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
            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__);
@@ -2807,7 +2806,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                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__);
@@ -2855,7 +2854,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                    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__);
@@ -2894,7 +2893,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        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__);
@@ -2915,7 +2914,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
            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__);
@@ -2938,7 +2937,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                    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__);
@@ -2958,9 +2957,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        /* 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__);
@@ -3028,7 +3027,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                           (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__);
@@ -3117,7 +3116,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                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__);
@@ -3140,13 +3139,6 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                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;
@@ -3266,7 +3258,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 
        /* 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__);
@@ -3343,6 +3335,9 @@ static void ucc_geth_timeout(struct net_device *dev)
 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;
@@ -3401,6 +3396,10 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
                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;
@@ -3738,21 +3737,21 @@ static int ucc_geth_close(struct net_device *dev)
 
 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;
@@ -3788,7 +3787,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 
        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;
@@ -3796,9 +3795,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
        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)
@@ -3807,42 +3806,34 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
        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:
@@ -3855,9 +3846,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
                        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;
@@ -4008,4 +3999,5 @@ module_exit(ucc_geth_exit);
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");