2005-04-16 15:20:36 -07:00
/*
Retrieve encoded MAC address from 24 C16 serial 2 - wire EEPROM ,
decode it and store it in the associated adapter struct for
use by dvb_net . c
This card appear to have the 24 C16 write protect held to ground ,
thus permitting normal read / write operation . Theoretically it
would be possible to write routines to burn a different ( encoded )
MAC address into the EEPROM .
Robert Schlabbach GMX
Michael Glaum KVH Industries
Holger Waechtler Convergence
Copyright ( C ) 2002 - 2003 Ralph Metzler < rjkm @ metzlerbros . de >
2006-01-09 15:25:34 -02:00
Metzler Brothers Systementwicklung GbR
2005-04-16 15:20:36 -07:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <asm/errno.h>
# include <linux/init.h>
# include <linux/module.h>
# include <linux/string.h>
# include <linux/i2c.h>
2005-12-01 00:51:53 -08:00
# include "ttpci-eeprom.h"
2005-04-16 15:20:36 -07:00
# if 1
# define dprintk(x...) do { printk(x); } while (0)
# else
# define dprintk(x...) do { } while (0)
# endif
static int check_mac_tt ( u8 * buf )
{
2005-12-12 00:37:24 -08:00
int i ;
u16 tmp = 0xffff ;
for ( i = 0 ; i < 8 ; i + + ) {
tmp = ( tmp < < 8 ) | ( ( tmp > > 8 ) ^ buf [ i ] ) ;
tmp ^ = ( tmp > > 4 ) & 0x0f ;
tmp ^ = ( tmp < < 12 ) ^ ( ( tmp & 0xff ) < < 5 ) ;
}
tmp ^ = 0xffff ;
return ( ( ( tmp > > 8 ) ^ buf [ 8 ] ) | ( ( tmp & 0xff ) ^ buf [ 9 ] ) ) ;
2005-04-16 15:20:36 -07:00
}
static int getmac_tt ( u8 * decodedMAC , u8 * encodedMAC )
{
2005-12-12 00:37:24 -08:00
u8 xor [ 20 ] = { 0x72 , 0x23 , 0x68 , 0x19 , 0x5c , 0xa8 , 0x71 , 0x2c ,
2005-04-16 15:20:36 -07:00
0x54 , 0xd3 , 0x7b , 0xf1 , 0x9E , 0x23 , 0x16 , 0xf6 ,
0x1d , 0x36 , 0x64 , 0x78 } ;
2005-12-12 00:37:24 -08:00
u8 data [ 20 ] ;
int i ;
2005-04-16 15:20:36 -07:00
/* In case there is a sig check failure have the orig contents available */
memcpy ( data , encodedMAC , 20 ) ;
for ( i = 0 ; i < 20 ; i + + )
2005-12-12 00:37:24 -08:00
data [ i ] ^ = xor [ i ] ;
for ( i = 0 ; i < 10 ; i + + )
data [ i ] = ( ( data [ 2 * i + 1 ] < < 8 ) | data [ 2 * i ] )
2005-04-16 15:20:36 -07:00
> > ( ( data [ 2 * i + 1 ] > > 6 ) & 3 ) ;
2005-12-12 00:37:24 -08:00
if ( check_mac_tt ( data ) )
return - ENODEV ;
2005-04-16 15:20:36 -07:00
decodedMAC [ 0 ] = data [ 2 ] ; decodedMAC [ 1 ] = data [ 1 ] ; decodedMAC [ 2 ] = data [ 0 ] ;
decodedMAC [ 3 ] = data [ 6 ] ; decodedMAC [ 4 ] = data [ 5 ] ; decodedMAC [ 5 ] = data [ 4 ] ;
2005-12-12 00:37:24 -08:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
static int ttpci_eeprom_read_encodedMAC ( struct i2c_adapter * adapter , u8 * encodedMAC )
{
int ret ;
u8 b0 [ ] = { 0xcc } ;
struct i2c_msg msg [ ] = {
{ . addr = 0x50 , . flags = 0 , . buf = b0 , . len = 1 } ,
{ . addr = 0x50 , . flags = I2C_M_RD , . buf = encodedMAC , . len = 20 }
} ;
2008-04-08 23:20:00 -03:00
/* dprintk("%s\n", __func__); */
2005-04-16 15:20:36 -07:00
ret = i2c_transfer ( adapter , msg , 2 ) ;
if ( ret ! = 2 ) /* Assume EEPROM isn't there */
return ( - ENODEV ) ;
return 0 ;
}
int ttpci_eeprom_parse_mac ( struct i2c_adapter * adapter , u8 * proposed_mac )
{
int ret , i ;
u8 encodedMAC [ 20 ] ;
u8 decodedMAC [ 6 ] ;
ret = ttpci_eeprom_read_encodedMAC ( adapter , encodedMAC ) ;
if ( ret ! = 0 ) { /* Will only be -ENODEV */
dprintk ( " Couldn't read from EEPROM: not there? \n " ) ;
memset ( proposed_mac , 0 , 6 ) ;
return ret ;
}
ret = getmac_tt ( decodedMAC , encodedMAC ) ;
if ( ret ! = 0 ) {
dprintk ( " adapter failed MAC signature check \n " ) ;
dprintk ( " encoded MAC from EEPROM was " ) ;
for ( i = 0 ; i < 19 ; i + + ) {
dprintk ( " %.2x: " , encodedMAC [ i ] ) ;
}
dprintk ( " %.2x \n " , encodedMAC [ 19 ] ) ;
memset ( proposed_mac , 0 , 6 ) ;
return ret ;
}
memcpy ( proposed_mac , decodedMAC , 6 ) ;
dprintk ( " adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x \n " ,
decodedMAC [ 0 ] , decodedMAC [ 1 ] , decodedMAC [ 2 ] ,
decodedMAC [ 3 ] , decodedMAC [ 4 ] , decodedMAC [ 5 ] ) ;
return 0 ;
}
EXPORT_SYMBOL ( ttpci_eeprom_parse_mac ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Ralph Metzler, Marcus Metzler, others " ) ;
MODULE_DESCRIPTION ( " Decode dvb_net MAC address from EEPROM of PCI DVB cards "
" made by Siemens, Technotrend, Hauppauge " ) ;