Path: blob/master/drivers/media/dvb/ttpci/ttpci-eeprom.c
15111 views
/*1Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM,2decode it and store it in the associated adapter struct for3use by dvb_net.c45This card appear to have the 24C16 write protect held to ground,6thus permitting normal read/write operation. Theoretically it7would be possible to write routines to burn a different (encoded)8MAC address into the EEPROM.910Robert Schlabbach GMX11Michael Glaum KVH Industries12Holger Waechtler Convergence1314Copyright (C) 2002-2003 Ralph Metzler <[email protected]>15Metzler Brothers Systementwicklung GbR1617This program is free software; you can redistribute it and/or modify18it under the terms of the GNU General Public License as published by19the Free Software Foundation; either version 2 of the License, or20(at your option) any later version.2122This program is distributed in the hope that it will be useful,23but WITHOUT ANY WARRANTY; without even the implied warranty of24MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the25GNU General Public License for more details.2627You should have received a copy of the GNU General Public License28along with this program; if not, write to the Free Software29Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.3031*/3233#include <asm/errno.h>34#include <linux/init.h>35#include <linux/module.h>36#include <linux/string.h>37#include <linux/i2c.h>3839#include "ttpci-eeprom.h"4041#if 142#define dprintk(x...) do { printk(x); } while (0)43#else44#define dprintk(x...) do { } while (0)45#endif464748static int check_mac_tt(u8 *buf)49{50int i;51u16 tmp = 0xffff;5253for (i = 0; i < 8; i++) {54tmp = (tmp << 8) | ((tmp >> 8) ^ buf[i]);55tmp ^= (tmp >> 4) & 0x0f;56tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5);57}58tmp ^= 0xffff;59return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9]));60}6162static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC)63{64u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,650x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,660x1d, 0x36, 0x64, 0x78};67u8 data[20];68int i;6970/* In case there is a sig check failure have the orig contents available */71memcpy(data, encodedMAC, 20);7273for (i = 0; i < 20; i++)74data[i] ^= xor[i];75for (i = 0; i < 10; i++)76data[i] = ((data[2 * i + 1] << 8) | data[2 * i])77>> ((data[2 * i + 1] >> 6) & 3);7879if (check_mac_tt(data))80return -ENODEV;8182decodedMAC[0] = data[2]; decodedMAC[1] = data[1]; decodedMAC[2] = data[0];83decodedMAC[3] = data[6]; decodedMAC[4] = data[5]; decodedMAC[5] = data[4];84return 0;85}8687static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC)88{89int ret;90u8 b0[] = { 0xcc };9192struct i2c_msg msg[] = {93{ .addr = 0x50, .flags = 0, .buf = b0, .len = 1 },94{ .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 }95};9697/* dprintk("%s\n", __func__); */9899ret = i2c_transfer(adapter, msg, 2);100101if (ret != 2) /* Assume EEPROM isn't there */102return (-ENODEV);103104return 0;105}106107108int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac)109{110int ret, i;111u8 encodedMAC[20];112u8 decodedMAC[6];113114ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC);115116if (ret != 0) { /* Will only be -ENODEV */117dprintk("Couldn't read from EEPROM: not there?\n");118memset(proposed_mac, 0, 6);119return ret;120}121122ret = getmac_tt(decodedMAC, encodedMAC);123if( ret != 0 ) {124dprintk("adapter failed MAC signature check\n");125dprintk("encoded MAC from EEPROM was " );126for(i=0; i<19; i++) {127dprintk( "%.2x:", encodedMAC[i]);128}129dprintk("%.2x\n", encodedMAC[19]);130memset(proposed_mac, 0, 6);131return ret;132}133134memcpy(proposed_mac, decodedMAC, 6);135dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",136decodedMAC[0], decodedMAC[1], decodedMAC[2],137decodedMAC[3], decodedMAC[4], decodedMAC[5]);138return 0;139}140141EXPORT_SYMBOL(ttpci_eeprom_parse_mac);142143MODULE_LICENSE("GPL");144MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");145MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards "146"made by Siemens, Technotrend, Hauppauge");147148149