1 /* 2 * this file included by nicstar.c 3 */ 4 5 /* 6 * nicstarmac.c 7 * Read this ForeRunner's MAC address from eprom/eeprom 8 */ 9 10 typedef void __iomem *virt_addr_t; 11 12 #define CYCLE_DELAY 5 13 14 /* This was the original definition 15 #define osp_MicroDelay(microsec) \ 16 do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) 17 */ 18 #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \ 19 udelay((useconds));} 20 21 22 /* The following tables represent the timing diagrams found in 23 * the Data Sheet for the Xicor X25020 EEProm. The #defines below 24 * represent the bits in the NICStAR's General Purpose register 25 * that must be toggled for the corresponding actions on the EEProm 26 * to occur. 27 */ 28 29 /* Write Data To EEProm from SI line on rising edge of CLK */ 30 /* Read Data From EEProm on falling edge of CLK */ 31 32 #define CS_HIGH 0x0002 /* Chip select high */ 33 #define CS_LOW 0x0000 /* Chip select low (active low)*/ 34 #define CLK_HIGH 0x0004 /* Clock high */ 35 #define CLK_LOW 0x0000 /* Clock low */ 36 #define SI_HIGH 0x0001 /* Serial input data high */ 37 #define SI_LOW 0x0000 /* Serial input data low */ 38 39 /* Read Status Register = 0000 0101b */ 40 #if 0 41 static u_int32_t rdsrtab[] = 42 { 43 CS_HIGH | CLK_HIGH, 44 CS_LOW | CLK_LOW, 45 CLK_HIGH, /* 0 */ 46 CLK_LOW, 47 CLK_HIGH, /* 0 */ 48 CLK_LOW, 49 CLK_HIGH, /* 0 */ 50 CLK_LOW, 51 CLK_HIGH, /* 0 */ 52 CLK_LOW, 53 CLK_HIGH, /* 0 */ 54 CLK_LOW | SI_HIGH, 55 CLK_HIGH | SI_HIGH, /* 1 */ 56 CLK_LOW | SI_LOW, 57 CLK_HIGH, /* 0 */ 58 CLK_LOW | SI_HIGH, 59 CLK_HIGH | SI_HIGH /* 1 */ 60 }; 61 #endif /* 0 */ 62 63 64 /* Read from EEPROM = 0000 0011b */ 65 static u_int32_t readtab[] = 66 { 67 /* 68 CS_HIGH | CLK_HIGH, 69 */ 70 CS_LOW | CLK_LOW, 71 CLK_HIGH, /* 0 */ 72 CLK_LOW, 73 CLK_HIGH, /* 0 */ 74 CLK_LOW, 75 CLK_HIGH, /* 0 */ 76 CLK_LOW, 77 CLK_HIGH, /* 0 */ 78 CLK_LOW, 79 CLK_HIGH, /* 0 */ 80 CLK_LOW, 81 CLK_HIGH, /* 0 */ 82 CLK_LOW | SI_HIGH, 83 CLK_HIGH | SI_HIGH, /* 1 */ 84 CLK_LOW | SI_HIGH, 85 CLK_HIGH | SI_HIGH /* 1 */ 86 }; 87 88 89 /* Clock to read from/write to the eeprom */ 90 static u_int32_t clocktab[] = 91 { 92 CLK_LOW, 93 CLK_HIGH, 94 CLK_LOW, 95 CLK_HIGH, 96 CLK_LOW, 97 CLK_HIGH, 98 CLK_LOW, 99 CLK_HIGH, 100 CLK_LOW, 101 CLK_HIGH, 102 CLK_LOW, 103 CLK_HIGH, 104 CLK_LOW, 105 CLK_HIGH, 106 CLK_LOW, 107 CLK_HIGH, 108 CLK_LOW 109 }; 110 111 112 #define NICSTAR_REG_WRITE(bs, reg, val) \ 113 while ( readl(bs + STAT) & 0x0200 ) ; \ 114 writel((val),(base)+(reg)) 115 #define NICSTAR_REG_READ(bs, reg) \ 116 readl((base)+(reg)) 117 #define NICSTAR_REG_GENERAL_PURPOSE GP 118 119 /* 120 * This routine will clock the Read_Status_reg function into the X2520 121 * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 122 * register. 123 */ 124 #if 0 125 u_int32_t 126 nicstar_read_eprom_status( virt_addr_t base ) 127 { 128 u_int32_t val; 129 u_int32_t rbyte; 130 int32_t i, j; 131 132 /* Send read instruction */ 133 val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; 134 135 for (i=0; i<sizeof rdsrtab/sizeof rdsrtab[0]; i++) 136 { 137 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 138 (val | rdsrtab[i]) ); 139 osp_MicroDelay( CYCLE_DELAY ); 140 } 141 142 /* Done sending instruction - now pull data off of bit 16, MSB first */ 143 /* Data clocked out of eeprom on falling edge of clock */ 144 145 rbyte = 0; 146 for (i=7, j=0; i>=0; i--) 147 { 148 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 149 (val | clocktab[j++]) ); 150 rbyte |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE) 151 & 0x00010000) >> 16) << i); 152 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 153 (val | clocktab[j++]) ); 154 osp_MicroDelay( CYCLE_DELAY ); 155 } 156 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 ); 157 osp_MicroDelay( CYCLE_DELAY ); 158 return rbyte; 159 } 160 #endif /* 0 */ 161 162 163 /* 164 * This routine will clock the Read_data function into the X2520 165 * eeprom, followed by the address to read from, through the NicSTaR's General 166 * Purpose register. 167 */ 168 169 static u_int8_t 170 read_eprom_byte(virt_addr_t base, u_int8_t offset) 171 { 172 u_int32_t val = 0; 173 int i,j=0; 174 u_int8_t tempread = 0; 175 176 val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; 177 178 /* Send READ instruction */ 179 for (i=0; i<sizeof readtab/sizeof readtab[0]; i++) 180 { 181 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 182 (val | readtab[i]) ); 183 osp_MicroDelay( CYCLE_DELAY ); 184 } 185 186 /* Next, we need to send the byte address to read from */ 187 for (i=7; i>=0; i--) 188 { 189 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 190 (val | clocktab[j++] | ((offset >> i) & 1) ) ); 191 osp_MicroDelay(CYCLE_DELAY); 192 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 193 (val | clocktab[j++] | ((offset >> i) & 1) ) ); 194 osp_MicroDelay( CYCLE_DELAY ); 195 } 196 197 j = 0; 198 199 /* Now, we can read data from the eeprom by clocking it in */ 200 for (i=7; i>=0; i--) 201 { 202 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 203 (val | clocktab[j++]) ); 204 osp_MicroDelay( CYCLE_DELAY ); 205 tempread |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) 206 & 0x00010000) >> 16) << i); 207 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 208 (val | clocktab[j++]) ); 209 osp_MicroDelay( CYCLE_DELAY ); 210 } 211 212 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 ); 213 osp_MicroDelay( CYCLE_DELAY ); 214 return tempread; 215 } 216 217 218 static void 219 nicstar_init_eprom( virt_addr_t base ) 220 { 221 u_int32_t val; 222 223 /* 224 * turn chip select off 225 */ 226 val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0; 227 228 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 229 (val | CS_HIGH | CLK_HIGH)); 230 osp_MicroDelay( CYCLE_DELAY ); 231 232 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 233 (val | CS_HIGH | CLK_LOW)); 234 osp_MicroDelay( CYCLE_DELAY ); 235 236 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 237 (val | CS_HIGH | CLK_HIGH)); 238 osp_MicroDelay( CYCLE_DELAY ); 239 240 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 241 (val | CS_HIGH | CLK_LOW)); 242 osp_MicroDelay( CYCLE_DELAY ); 243 } 244 245 246 /* 247 * This routine will be the interface to the ReadPromByte function 248 * above. 249 */ 250 251 static void 252 nicstar_read_eprom( 253 virt_addr_t base, 254 u_int8_t prom_offset, 255 u_int8_t *buffer, 256 u_int32_t nbytes ) 257 { 258 u_int i; 259 260 for (i=0; i<nbytes; i++) 261 { 262 buffer[i] = read_eprom_byte( base, prom_offset ); 263 ++prom_offset; 264 osp_MicroDelay( CYCLE_DELAY ); 265 } 266 } 267 268 269 /* 270 void osp_MicroDelay(int x) { 271 272 } 273 */ 274 275