Re: [PATCH try#2] Blackfin ethernet driver: on chip ethernet MAC controller driver

2007-07-15 Thread Michael Buesch
On Sunday 15 July 2007 11:27:09 Bryan Wu wrote:
 +#if defined(CONFIG_BFIN_MAC_USE_L1)
 +# define bfin_mac_alloc(dma_handle, size)  l1_data_sram_zalloc(size)
 +# define bfin_mac_free(dma_handle, ptr)l1_data_sram_free(ptr)
 +#else
 +# define bfin_mac_alloc(dma_handle, size) \
 +  dma_alloc_coherent(NULL, size, dma_handle, GFP_NORMAL)

What is GFP_NORMAL? It's not defined in latest linus' tree.
I think you should use GFP_KERNEL, if you can sleep, or GFP_ATOMIC,
if you can't.

The rest looks OK. Except the endianess issues. It might be no
issue on the hardware this runs on, but in favour of clean code
you might use leXX_to_cpu and friends anyway. :)
This kind of bugs is done so often, even in places where it _does_
matter. So, at least for the human reader, the leXX_to_cpu stuff
says that you really understood what you were doing when writing
the code. The current code says (to me), that it works by
accident, somehow, although it seems you knew what you were doing. :)

-- 
Greetings Michael.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH try#2] Blackfin ethernet driver: on chip ethernet MAC controller driver

2007-07-15 Thread Christoph Hellwig
On Sun, Jul 15, 2007 at 12:36:51PM +0200, Michael Buesch wrote:
 On Sunday 15 July 2007 11:27:09 Bryan Wu wrote:
  +#if defined(CONFIG_BFIN_MAC_USE_L1)
  +# define bfin_mac_alloc(dma_handle, size)  l1_data_sram_zalloc(size)
  +# define bfin_mac_free(dma_handle, ptr)l1_data_sram_free(ptr)
  +#else
  +# define bfin_mac_alloc(dma_handle, size) \
  +dma_alloc_coherent(NULL, size, dma_handle, GFP_NORMAL)
 
 What is GFP_NORMAL? It's not defined in latest linus' tree.
 I think you should use GFP_KERNEL, if you can sleep, or GFP_ATOMIC,
 if you can't.

Actually this whole thing looks fishy.  There should be a struct device
for the dma allocation, through a platform_device.  And the
CONFIG_BFIN_MAC_USE_L1 should go away, the l1 sram should have a dma
provider so this can be handled through the dma api.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH try#2] Blackfin ethernet driver: on chip ethernet MAC controller driver

2007-07-15 Thread Bryan Wu
On Sun, 2007-07-15 at 12:36 +0200, Michael Buesch wrote:
 On Sunday 15 July 2007 11:27:09 Bryan Wu wrote:
  +#if defined(CONFIG_BFIN_MAC_USE_L1)
  +# define bfin_mac_alloc(dma_handle, size)  l1_data_sram_zalloc(size)
  +# define bfin_mac_free(dma_handle, ptr)l1_data_sram_free(ptr)
  +#else
  +# define bfin_mac_alloc(dma_handle, size) \
  +dma_alloc_coherent(NULL, size, dma_handle, GFP_NORMAL)
 
 What is GFP_NORMAL? It's not defined in latest linus' tree.
 I think you should use GFP_KERNEL, if you can sleep, or GFP_ATOMIC,
 if you can't.
 

Yes, it should be GFP_KERNEL, i missed up with ZONE_NORMAL and ZONE_DMA.

 The rest looks OK. Except the endianess issues. It might be no
 issue on the hardware this runs on, but in favour of clean code
 you might use leXX_to_cpu and friends anyway. :)
 This kind of bugs is done so often, even in places where it _does_
 matter. So, at least for the human reader, the leXX_to_cpu stuff
 says that you really understood what you were doing when writing
 the code. The current code says (to me), that it works by
 accident, somehow, although it seems you knew what you were doing. :)
 

As you know, this driver is original developed by Luke Yang. Now I am
maintaining it.
I just don't understand in this driver where should use leXX_to_cpu()
and where should
use cpu_to_leXX(). please give me some comments about the following
change:

---
@@ -483,9 +487,12 @@
 
 void setup_mac_addr(u8 * mac_addr)
 {
+   u32 addr_low = le32_to_cpu(*(u32 *)  mac_addr[0]);
+   u16 addr_hi = le16_to_cpu(*(u16 *)  mac_addr[4]);
+
/* this depends on a little-endian machine */
-   bfin_write_EMAC_ADDRLO(*(u32 *)  mac_addr[0]);
-   bfin_write_EMAC_ADDRHI(*(u16 *)  mac_addr[4]);
+   bfin_write_EMAC_ADDRLO(addr_low);
+   bfin_write_EMAC_ADDRHI(addr_hi);
 }
 
 static void adjust_tx_list(void)
@@ -866,10 +873,10 @@
int retval;
 
/* Grab the MAC address in the MAC */
-   *(u32 *) ((dev-dev_addr[0])) = bfin_read_EMAC_ADDRLO();
-   *(u16 *) ((dev-dev_addr[4])) = (u16) bfin_read_EMAC_ADDRHI();
+   *(u32 *) ((dev-dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
+   *(u16 *) ((dev-dev_addr[4])) = cpu_to_le16((u16) 
bfin_read_EMAC_ADDRHI());
---

Thanks
- Bryan Wu
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH try#2] Blackfin ethernet driver: on chip ethernet MAC controller driver

2007-07-15 Thread Bryan Wu
On Sun, 2007-07-15 at 11:53 +0100, Christoph Hellwig wrote:
 On Sun, Jul 15, 2007 at 12:36:51PM +0200, Michael Buesch wrote:
  On Sunday 15 July 2007 11:27:09 Bryan Wu wrote:
   +#if defined(CONFIG_BFIN_MAC_USE_L1)
   +# define bfin_mac_alloc(dma_handle, size)  l1_data_sram_zalloc(size)
   +# define bfin_mac_free(dma_handle, ptr)l1_data_sram_free(ptr)
   +#else
   +# define bfin_mac_alloc(dma_handle, size) \
   +  dma_alloc_coherent(NULL, size, dma_handle, GFP_NORMAL)
  
  What is GFP_NORMAL? It's not defined in latest linus' tree.
  I think you should use GFP_KERNEL, if you can sleep, or GFP_ATOMIC,
  if you can't.
 
 Actually this whole thing looks fishy.  There should be a struct device
 for the dma allocation, through a platform_device.  And the
 CONFIG_BFIN_MAC_USE_L1 should go away, the l1 sram should have a dma
 provider so this can be handled through the dma api.

We do have L1 memory DMA allocator and manager, it is depends on
Blackfin arch.
And this driver is Blackfin on-chip ethernet MAC controller. 

So it is OK, any idea?

Thanks
- Bryan Wu
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH try#2] Blackfin ethernet driver: on chip ethernet MAC controller driver

2007-07-15 Thread Michael Buesch
On Sunday 15 July 2007 14:07:44 Bryan Wu wrote:
 @@ -483,9 +487,12 @@
  
  void setup_mac_addr(u8 * mac_addr)
  {
 + u32 addr_low = le32_to_cpu(*(u32 *)  mac_addr[0]);
 + u16 addr_hi = le16_to_cpu(*(u16 *)  mac_addr[4]);
 +
   /* this depends on a little-endian machine */
 - bfin_write_EMAC_ADDRLO(*(u32 *)  mac_addr[0]);
 - bfin_write_EMAC_ADDRHI(*(u16 *)  mac_addr[4]);
 + bfin_write_EMAC_ADDRLO(addr_low);
 + bfin_write_EMAC_ADDRHI(addr_hi);
  }
  
  static void adjust_tx_list(void)
 @@ -866,10 +873,10 @@
   int retval;
  
   /* Grab the MAC address in the MAC */
 - *(u32 *) ((dev-dev_addr[0])) = bfin_read_EMAC_ADDRLO();
 - *(u16 *) ((dev-dev_addr[4])) = (u16) bfin_read_EMAC_ADDRHI();
 + *(u32 *) ((dev-dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
 + *(u16 *) ((dev-dev_addr[4])) = cpu_to_le16((u16) 
 bfin_read_EMAC_ADDRHI());

Try something like this:

@@ -483,9 +487,12 @@
 
 void setup_mac_addr(u8 * mac_addr)
 {
+   u32 addr_low = le32_to_cpu(*(__le32 *)  mac_addr[0]);
+   u16 addr_hi = le16_to_cpu(*(__le16 *)  mac_addr[4]);
+
-   /* this depends on a little-endian machine */
-   bfin_write_EMAC_ADDRLO(*(u32 *)  mac_addr[0]);
-   bfin_write_EMAC_ADDRHI(*(u16 *)  mac_addr[4]);
+   bfin_write_EMAC_ADDRLO(addr_low);
+   bfin_write_EMAC_ADDRHI(addr_hi);
 }
 
 static void adjust_tx_list(void)
@@ -866,10 +873,10 @@
int retval;
 
/* Grab the MAC address in the MAC */
-   *(u32 *) ((dev-dev_addr[0])) = bfin_read_EMAC_ADDRLO();
-   *(u16 *) ((dev-dev_addr[4])) = (u16) bfin_read_EMAC_ADDRHI();
+   *(__le32 *) ((dev-dev_addr[0])) = 
cpu_to_le32(bfin_read_EMAC_ADDRLO());
+   *(__le16 *) ((dev-dev_addr[4])) = cpu_to_le16((u16) 
bfin_read_EMAC_ADDRHI());

-- 
Greetings Michael.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH try#2] Blackfin ethernet driver: on chip ethernet MAC controller driver

2007-07-15 Thread Robert Hancock

Bryan Wu wrote:

On Sun, 2007-07-15 at 14:17 +0200, Michael Buesch wrote:

On Sunday 15 July 2007 14:07:44 Bryan Wu wrote:

@@ -483,9 +487,12 @@
 
 void setup_mac_addr(u8 * mac_addr)

 {
+   u32 addr_low = le32_to_cpu(*(u32 *)  mac_addr[0]);
+   u16 addr_hi = le16_to_cpu(*(u16 *)  mac_addr[4]);
+
/* this depends on a little-endian machine */
-   bfin_write_EMAC_ADDRLO(*(u32 *)  mac_addr[0]);
-   bfin_write_EMAC_ADDRHI(*(u16 *)  mac_addr[4]);
+   bfin_write_EMAC_ADDRLO(addr_low);
+   bfin_write_EMAC_ADDRHI(addr_hi);
 }
 
 static void adjust_tx_list(void)

@@ -866,10 +873,10 @@
int retval;
 
 	/* Grab the MAC address in the MAC */

-   *(u32 *) ((dev-dev_addr[0])) = bfin_read_EMAC_ADDRLO();
-   *(u16 *) ((dev-dev_addr[4])) = (u16) bfin_read_EMAC_ADDRHI();
+   *(u32 *) ((dev-dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
+   *(u16 *) ((dev-dev_addr[4])) = cpu_to_le16((u16) 
bfin_read_EMAC_ADDRHI());

Try something like this:

@@ -483,9 +487,12 @@
 
 void setup_mac_addr(u8 * mac_addr)

 {
+   u32 addr_low = le32_to_cpu(*(__le32 *)  mac_addr[0]);
+   u16 addr_hi = le16_to_cpu(*(__le16 *)  mac_addr[4]);
+
-   /* this depends on a little-endian machine */
-   bfin_write_EMAC_ADDRLO(*(u32 *)  mac_addr[0]);
-   bfin_write_EMAC_ADDRHI(*(u16 *)  mac_addr[4]);
+   bfin_write_EMAC_ADDRLO(addr_low);
+   bfin_write_EMAC_ADDRHI(addr_hi);
 }
 
 static void adjust_tx_list(void)

@@ -866,10 +873,10 @@
int retval;
 
/* Grab the MAC address in the MAC */

-   *(u32 *) ((dev-dev_addr[0])) = bfin_read_EMAC_ADDRLO();
-   *(u16 *) ((dev-dev_addr[4])) = (u16) bfin_read_EMAC_ADDRHI();
+   *(__le32 *) ((dev-dev_addr[0])) = 
cpu_to_le32(bfin_read_EMAC_ADDRLO());
+   *(__le16 *) ((dev-dev_addr[4])) = cpu_to_le16((u16) 
bfin_read_EMAC_ADDRHI());



Thanks a lot, Michael. 


I got a generic question about this endianess check. When should use it
in a driver or something else? I grep it in the driver/net/

---
drivers/net/e100.c: ns-tx_window_errors += 
le32_to_cpu(s-tx_late_collisions);
drivers/net/e100.c: ns-tx_carrier_errors += 
le32_to_cpu(s-tx_lost_crs);
drivers/net/e100.c: ns-tx_fifo_errors += 
le32_to_cpu(s-tx_underruns);
drivers/net/e100.c: ns-tx_errors += 
le32_to_cpu(s-tx_max_collisions) +
drivers/net/e100.c: le32_to_cpu(s-tx_lost_crs);
drivers/net/e100.c: ns-rx_length_errors += 
le32_to_cpu(s-rx_short_frame_errors) +
drivers/net/e100.c: ns-rx_crc_errors += 
le32_to_cpu(s-rx_crc_errors);
drivers/net/e100.c: ns-rx_frame_errors += 
le32_to_cpu(s-rx_alignment_errors);
drivers/net/e100.c: ns-rx_over_errors += 
le32_to_cpu(s-rx_overrun_errors);
drivers/net/e100.c: ns-rx_fifo_errors += 
le32_to_cpu(s-rx_overrun_errors);
drivers/net/e100.c: ns-rx_missed_errors += 
le32_to_cpu(s-rx_resource_errors);
drivers/net/e100.c: ns-rx_errors += le32_to_cpu(s-rx_crc_errors) +
drivers/net/e100.c: le32_to_cpu(s-rx_alignment_errors) +
drivers/net/e100.c: le32_to_cpu(s-rx_short_frame_errors) +
drivers/net/e100.c: le32_to_cpu(s-rx_cdt_errors);
drivers/net/e100.c: nic-tx_deferred += le32_to_cpu(s-tx_deferred);
drivers/net/e100.c: le32_to_cpu(s-tx_single_collisions);
drivers/net/e100.c: le32_to_cpu(s-tx_multiple_collisions);
drivers/net/e100.c: nic-tx_fc_pause += 
le32_to_cpu(s-fc_xmt_pause);
drivers/net/e100.c: nic-rx_fc_pause += 
le32_to_cpu(s-fc_rcv_pause);
drivers/net/e100.c: 
le32_to_cpu(s-fc_rcv_unsupported);
drivers/net/e100.c: 
le32_to_cpu(cb-u.tcb.tbd.buf_addr),
drivers/net/e100.c: 
le32_to_cpu(cb-u.tcb.tbd.buf_addr),
---

Normally, it is used to protect some rx/tx status flags or dma buf addr.

Any guide line for this leXX_to_cpu usage?


It has to be used when accessing any data structure stored in RAM that 
the device will access and where byte order is significant. cpu_to_le32 
when writing to the RAM, le32_to_cpu when reading it. (or le16, etc. if 
needed).


--
Robert Hancock  Saskatoon, SK, Canada
To email, remove nospam from [EMAIL PROTECTED]
Home Page: http://www.roberthancock.com/

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH try#2] Blackfin ethernet driver: on chip ethernet MAC controller driver

2007-07-15 Thread Michael Buesch
On Sunday 15 July 2007 16:01, Bryan Wu wrote:

 drivers/net/e100.c: ns-tx_window_errors += 
 le32_to_cpu(s-tx_late_collisions);
 drivers/net/e100.c: ns-tx_carrier_errors += 
 le32_to_cpu(s-tx_lost_crs);
 drivers/net/e100.c: ns-tx_fifo_errors += 
 le32_to_cpu(s-tx_underruns);
 drivers/net/e100.c: ns-tx_errors += 
 le32_to_cpu(s-tx_max_collisions) +
 drivers/net/e100.c: le32_to_cpu(s-tx_lost_crs);
 drivers/net/e100.c: ns-rx_length_errors += 
 le32_to_cpu(s-rx_short_frame_errors) +
 drivers/net/e100.c: ns-rx_crc_errors += 
 le32_to_cpu(s-rx_crc_errors);
 drivers/net/e100.c: ns-rx_frame_errors += 
 le32_to_cpu(s-rx_alignment_errors);
 drivers/net/e100.c: ns-rx_over_errors += 
 le32_to_cpu(s-rx_overrun_errors);
 drivers/net/e100.c: ns-rx_fifo_errors += 
 le32_to_cpu(s-rx_overrun_errors);
 drivers/net/e100.c: ns-rx_missed_errors += 
 le32_to_cpu(s-rx_resource_errors);
 drivers/net/e100.c: ns-rx_errors += 
 le32_to_cpu(s-rx_crc_errors) +
 drivers/net/e100.c: le32_to_cpu(s-rx_alignment_errors) +
 drivers/net/e100.c: le32_to_cpu(s-rx_short_frame_errors) 
 +
 drivers/net/e100.c: le32_to_cpu(s-rx_cdt_errors);
 drivers/net/e100.c: nic-tx_deferred += 
 le32_to_cpu(s-tx_deferred);
 drivers/net/e100.c: le32_to_cpu(s-tx_single_collisions);
 drivers/net/e100.c: 
 le32_to_cpu(s-tx_multiple_collisions);
 drivers/net/e100.c: nic-tx_fc_pause += 
 le32_to_cpu(s-fc_xmt_pause);
 drivers/net/e100.c: nic-rx_fc_pause += 
 le32_to_cpu(s-fc_rcv_pause);
 drivers/net/e100.c: 
 le32_to_cpu(s-fc_rcv_unsupported);
 drivers/net/e100.c: 
 le32_to_cpu(cb-u.tcb.tbd.buf_addr),
 drivers/net/e100.c: 
 le32_to_cpu(cb-u.tcb.tbd.buf_addr),
 ---
 
 Normally, it is used to protect some rx/tx status flags or dma buf addr.
 
 Any guide line for this leXX_to_cpu usage?

Easy.

leXX_to_cpu converts a little endian value to CPU-endianess.
So if your CPU is LE, this is a no-op.
The cpu_to_leXX func converts from CPU-endianess to LE.
Same goes for the bigendian variants of the funcs.

In drivers you often have values with specific endianess
(mostly LE, sometimes BE). For example when values are put
by the device to DMA memory. So if the device works in LE,
you must convert the value from LE to CPU endianess after
reading it from DMA.

I your case, however, the issue is different. You had a byte
array and did pointer casting tricks on it. Pointer casting
_is_ a common source for endianess issues. In general, if
you try to cast a pointer, think twice about it. It's likely
a bug. So you had a pointer to a byte array, which is u8*.
You casted that to u16* and u32*. That's broken, because
an u8 array is little endian. LE means the least significant
part of the entity comes first in memory. Which is obviously
always true for a byte array. So you must use
leXX_to_cpu when doing this kind of pointer tricks.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html