net/fm: Fix the endian issue to support both endianness platforms
authorHou Zhiqiang <B48286@freescale.com>
Mon, 26 Oct 2015 11:47:43 +0000 (19:47 +0800)
committerYork Sun <yorksun@freescale.com>
Thu, 29 Oct 2015 17:33:59 +0000 (10:33 -0700)
The Frame Manager(FMan) is a big-endian peripheral, so the
registers, internal MURAM and BDs, which are allocated in main
memory and used to communication between core and FMan, should
be accessed in big-endian. The big-endian platforms can access
them directly as the code implemented so far, while for the
little-endian platforms it need to swap the byte-order.

Signed-off-by: Hou Zhiqiang <B48286@freescale.com>
Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
Signed-off-by: Mingkai Hu <Mingkai.Hu@freescale.com>
Signed-off-by: Gong Qianyu <Qianyu.Gong@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
drivers/net/fm/eth.c
drivers/net/fm/fm.c

index 6702f5a5202809a56ef9c73c1c2c60fd86a78f34..368d5544751470669b5fed859597efbd354411e1 100644 (file)
@@ -109,7 +109,7 @@ static int tgec_is_fibre(struct eth_device *dev)
 static u16 muram_readw(u16 *addr)
 {
        u32 base = (u32)addr & ~0x3;
-       u32 val32 = *(u32 *)base;
+       u32 val32 = in_be32((u32 *)base);
        int byte_pos;
        u16 ret;
 
@@ -125,7 +125,7 @@ static u16 muram_readw(u16 *addr)
 static void muram_writew(u16 *addr, u16 val)
 {
        u32 base = (u32)addr & ~0x3;
-       u32 org32 = *(u32 *)base;
+       u32 org32 = in_be32((u32 *)base);
        u32 val32;
        int byte_pos;
 
@@ -135,7 +135,7 @@ static void muram_writew(u16 *addr, u16 val)
        else
                val32 = (org32 & 0x0000ffff) | ((u32)val << 16);
 
-       *(u32 *)base = val32;
+       out_be32((u32 *)base, val32);
 }
 
 static void bmi_rx_port_disable(struct fm_bmi_rx_port *rx_port)
@@ -213,10 +213,10 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
        pram_page_offset = (u32)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);
@@ -243,10 +243,11 @@ 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);
+               muram_writew(&rxbd->buf_ptr_hi, 0);
+               out_be32(&rxbd->buf_ptr_lo, (u32)rx_buf_pool +
+                               i * MAX_RXBUF_LEN);
                rxbd++;
        }
 
@@ -254,7 +255,7 @@ static int fm_eth_rx_port_parameter_init(struct fm_eth *fm_eth)
        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;
+       out_be32(&rxqd->bd_ring_base_lo, (u32)rx_bd_ring_base);
        muram_writew(&rxqd->bd_ring_size, sizeof(struct fm_port_bd)
                        * RX_BD_RING_SIZE);
        muram_writew(&rxqd->offset_in, 0);
@@ -285,10 +286,10 @@ static int fm_eth_tx_port_parameter_init(struct fm_eth *fm_eth)
        pram_page_offset = (u32)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)
@@ -304,16 +305,17 @@ 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;
+       out_be32(&txqd->bd_ring_base_lo, (u32)tx_bd_ring_base);
        muram_writew(&txqd->bd_ring_size, sizeof(struct fm_port_bd)
                        * TX_BD_RING_SIZE);
        muram_writew(&txqd->offset_in, 0);
@@ -368,7 +370,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 +380,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();
 }
 
@@ -469,19 +471,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, 0);
+       out_be32(&txbd->buf_ptr_lo, (u32)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 +496,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;
                }
        }
@@ -525,12 +529,12 @@ 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;
+                       data = (u8 *)in_be32(&rxbd->buf_ptr_lo);
+                       len = muram_readw(&rxbd->len);
                        net_process_received_packet(data, len);
                } else {
                        printf("%s: Rx error\n", dev->name);
@@ -538,8 +542,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 +552,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);
index 400e9dd5e24902bc8ce8bdf2cdecbd9fc8dcc855..eb0eb3d5da8a3f10584baa30f0441ed128a53b7f 100644 (file)
@@ -80,11 +80,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 +177,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);
                }
        }