diff mbox

[RFC,1/2] OMAP2+: add cpu id register to MAC address helper

Message ID 20110324212729.14936.98130.stgit@otae.warmcat.com
State New
Headers show

Commit Message

Andy Green March 24, 2011, 9:27 p.m. UTC
Introduce a generic helper function that can set a MAC address using
data from the OMAP unique CPU ID register.

For comparison purposes this produces a MAC address of

  2e:40:70:f0:12:06

for the ethernet device on my Panda.


Note that this patch requires the fix patch for CPU ID register
indexes previously posted to linux-omap, otherwise the CPU ID is
misread on Panda by the existing function to do it.  This patch
is already on linux-omap.

"OMAP2+:Common CPU DIE ID reading code reads wrong registers for OMAP4430"
http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=commit;h=b235e007831dbf57710e59cd4a120e2f374eecb9

Signed-off-by: Andy Green <andy.green@linaro.org>
---

 arch/arm/mach-omap2/id.c              |   39 +++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/include/mach/id.h |    1 +
 2 files changed, 40 insertions(+), 0 deletions(-)

Comments

Arnd Bergmann March 25, 2011, 11:49 a.m. UTC | #1
On Thursday 24 March 2011, Andy Green wrote:
> Introduce a generic helper function that can set a MAC address using
> data from the OMAP unique CPU ID register.
> 
> For comparison purposes this produces a MAC address of
> 
>   2e:40:70:f0:12:06
> 
> for the ethernet device on my Panda.
> 
> 
> Note that this patch requires the fix patch for CPU ID register
> indexes previously posted to linux-omap, otherwise the CPU ID is
> misread on Panda by the existing function to do it.  This patch
> is already on linux-omap.
> 
> "OMAP2+:Common CPU DIE ID reading code reads wrong registers for OMAP4430"
> http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=commit;h=b235e007831dbf57710e59cd4a120e2f374eecb9
> 
> Signed-off-by: Andy Green <andy.green@linaro.org>

Acked-by: Arnd Bergmann <arnd@arndb.de>

TI folks: While this is a working solution, I still think it would
be good to get an officially sanctioned method that allows the creation
of a IEEE 802 MAC address in a range assigned to TI instead of using
an address from the locally administered range.

Is that something that can be done?

	Arnd
Andy Green March 25, 2011, 12:08 p.m. UTC | #2
On 03/25/2011 11:49 AM, Somebody in the thread at some point said:
> On Thursday 24 March 2011, Andy Green wrote:
>> Introduce a generic helper function that can set a MAC address using
>> data from the OMAP unique CPU ID register.
>>
>> For comparison purposes this produces a MAC address of
>>
>>    2e:40:70:f0:12:06
>>
>> for the ethernet device on my Panda.
>>
>>
>> Note that this patch requires the fix patch for CPU ID register
>> indexes previously posted to linux-omap, otherwise the CPU ID is
>> misread on Panda by the existing function to do it.  This patch
>> is already on linux-omap.
>>
>> "OMAP2+:Common CPU DIE ID reading code reads wrong registers for OMAP4430"
>> http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=commit;h=b235e007831dbf57710e59cd4a120e2f374eecb9
>>
>> Signed-off-by: Andy Green<andy.green@linaro.org>
>
> Acked-by: Arnd Bergmann<arnd@arndb.de>

Thanks.

> TI folks: While this is a working solution, I still think it would
> be good to get an officially sanctioned method that allows the creation
> of a IEEE 802 MAC address in a range assigned to TI instead of using
> an address from the locally administered range.
>
> Is that something that can be done?

Having a proper MAC from IEEE assigned for each interface is of course 
ideal.

But even if that happened today though, on Panda there is no "board 
identity storage" to put the reserved MAC addresses in to bind it to the 
physical board.  If you try to manage them on SD Card, you have the 
problem of dealing with correct MAC addresses needing putting there 
again every time it is nuked.  So it doesn't in itself help in the Panda 
case.

David Anders mentioned yesterday that for next OMAP board, he probably 
puts a general board identity EEPROM where one could stash MACs.  This 
kind of API can be extended to query the EEPROM at device-register-time 
and fetch the MAC instead of compute it.  So I think we go in a 
reasonable direction even when it is possible to get assigned MACs.

-Andy
Arnd Bergmann March 25, 2011, 1:24 p.m. UTC | #3
On Friday 25 March 2011, Andy Green wrote:
> Having a proper MAC from IEEE assigned for each interface is of course 
> ideal.
> 
> But even if that happened today though, on Panda there is no "board 
> identity storage" to put the reserved MAC addresses in to bind it to the 
> physical board.  If you try to manage them on SD Card, you have the 
> problem of dealing with correct MAC addresses needing putting there 
> again every time it is nuked.  So it doesn't in itself help in the Panda 
> case.

What I meant is computing an official MAC address from the same input
data as you already do. Unfortunately that would mean having at most 24
bits available instead of the 44 or so bits you currently use, because
the upper half of the address then becomes fixed.

Also it would require
1. defining an new algorithm that computes the lower 24 bits from the
   die ID in a way that minimises the chances of collision
2. Getting an official identifier for the upper half of the address
   assigned to the OMAP3/OMAP4 CPUs
3. Documenting this method in the OMAP data sheets.

	Arnd
Andy Green March 25, 2011, 1:34 p.m. UTC | #4
On 03/25/2011 01:24 PM, Somebody in the thread at some point said:
> On Friday 25 March 2011, Andy Green wrote:
>> Having a proper MAC from IEEE assigned for each interface is of course
>> ideal.
>>
>> But even if that happened today though, on Panda there is no "board
>> identity storage" to put the reserved MAC addresses in to bind it to the
>> physical board.  If you try to manage them on SD Card, you have the
>> problem of dealing with correct MAC addresses needing putting there
>> again every time it is nuked.  So it doesn't in itself help in the Panda
>> case.
>
> What I meant is computing an official MAC address from the same input
> data as you already do. Unfortunately that would mean having at most 24
> bits available instead of the 44 or so bits you currently use, because
> the upper half of the address then becomes fixed.
>
> Also it would require
> 1. defining an new algorithm that computes the lower 24 bits from the
>     die ID in a way that minimises the chances of collision
> 2. Getting an official identifier for the upper half of the address
>     assigned to the OMAP3/OMAP4 CPUs
> 3. Documenting this method in the OMAP data sheets.

I see.  It would work OK then.  They probably wouldn't want to blow 
their $1750 just on Panda though, so maybe they set 4 bits or whatever 
and let 20 be computed.

However, the only practical advantage is that it would show up as a TI 
MAC in an OUI database.  The "locally administered" address as used at 
the moment is otherwise legal in every respect AFAIK.

-Andy
Arnd Bergmann March 25, 2011, 2:50 p.m. UTC | #5
On Friday 25 March 2011, Andy Green wrote:
> I see.  It would work OK then.  They probably wouldn't want to blow 
> their $1750 just on Panda though, so maybe they set 4 bits or whatever 
> and let 20 be computed.

Well, if the algorithm is defined well, it could be used for any device
based on OMAP. The marketing department could turn this into a win by
declaring "does not require external EEPROM for ethernet mac address" ;-)
 
> However, the only practical advantage is that it would show up as a TI 
> MAC in an OUI database.  The "locally administered" address as used at 
> the moment is otherwise legal in every respect AFAIK.

It should work almost always, except in very special corner cases:

* If you have a netboot setup, you want the boot loader to use the
same mac address for requesting the kernel image that you use later,
otherwise the switch might consider it a MAC spoofing attach and disable
the port. The obvious workaround is to put your code into the boot loader
as well.

* Some environments might be configured to disallow locally administered
MAC addresses for "security" reasons. A bit bogus, but not unheard of.

* Some places try to keep a database of all used machines and their MAC
addresses to monitor who connects to the network. This requires the address
to be stable. It also prevents the use of virtualization, so it's becoming
less common.

	Arnd
Andy Green March 25, 2011, 3 p.m. UTC | #6
On 03/25/2011 02:50 PM, Somebody in the thread at some point said:
> On Friday 25 March 2011, Andy Green wrote:
>> I see.  It would work OK then.  They probably wouldn't want to blow
>> their $1750 just on Panda though, so maybe they set 4 bits or whatever
>> and let 20 be computed.
>
> Well, if the algorithm is defined well, it could be used for any device
> based on OMAP. The marketing department could turn this into a win by
> declaring "does not require external EEPROM for ethernet mac address" ;-)

Okay, can't argue with it ^^

> * Some places try to keep a database of all used machines and their MAC
> addresses to monitor who connects to the network. This requires the address
> to be stable. It also prevents the use of virtualization, so it's becoming
> less common.

They will probably just be happy the crazy noise they have been seeing 
from current Panda MACs changing every session will go away, it doesn't 
seem to add anything it's an OUI namespace MAC.  In the patch case the 
"locally administered" mac will be "stable".

Anyway since I understood it, I can see your idea is a cool approach, 
it's up to TI what they will do about it but I guess it's OK with or 
without it.

-Andy
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 2537090..e46b430 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -557,3 +557,42 @@  void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
 	else
 		tap_prod_id = 0x0208;
 }
+
+/*
+ * this uses the unique per-cpu info from the cpu fuses set at factory to
+ * generate a 6-byte MAC address.  Two bits in the generated code are used
+ * to elaborate the generated address into four, so it can be used on multiple
+ * network interfaces.
+ */
+
+void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype)
+{
+	struct omap_die_id odi;
+	u32 tap = read_tap_reg(OMAP_TAP_IDCODE);
+
+	omap_get_die_id(&odi);
+
+	mac[0] = odi.id_2;
+	mac[1] = odi.id_2 >> 8;
+	mac[2] = odi.id_1;
+	mac[3] = odi.id_1 >> 8;
+	mac[4] = odi.id_1 >> 16;
+	mac[5] = odi.id_1 >> 24;
+
+	/* XOR other chip-specific data with ID */
+
+	tap ^= odi.id_3;
+
+	mac[0] ^= tap;
+	mac[1] ^= tap >> 8;
+	mac[2] ^= tap >> 16;
+	mac[3] ^= tap >> 24;
+
+	/* allow four MACs from this same basic data */
+
+	mac[1] = (mac[1] & ~0xc0) | ((subtype & 3) << 6);
+
+	/* mark it as not multicast and outside official 80211 MAC namespace */
+
+	mac[0] = (mac[0] & ~1) | 2;
+}
diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h
index 02ed3aa..373313a 100644
--- a/arch/arm/mach-omap2/include/mach/id.h
+++ b/arch/arm/mach-omap2/include/mach/id.h
@@ -18,5 +18,6 @@  struct omap_die_id {
 };
 
 void omap_get_die_id(struct omap_die_id *odi);
+void omap2_die_id_to_ethernet_mac(u8 *mac, int subtype);
 
 #endif