Преглед на файлове

Update to use the generic i2c bit-bashing code.

tags/v0.9.3
Michael Brown преди 18 години
родител
ревизия
7ce44f7480
променени са 1 файла, в които са добавени 68 реда и са изтрити 223 реда
  1. 68
    223
      src/drivers/net/etherfabric.c

+ 68
- 223
src/drivers/net/etherfabric.c Целия файл

@@ -19,6 +19,8 @@
19 19
 #include "etherboot.h"
20 20
 #include "nic.h"
21 21
 #include <gpxe/pci.h>
22
+#include <gpxe/bitbash.h>
23
+#include <gpxe/i2c.h>
22 24
 #include "timer.h"
23 25
 #define dma_addr_t unsigned long
24 26
 #include "etherfabric.h"
@@ -185,224 +187,12 @@ struct efab_nic {
185 187
 
186 188
 	/** INT_REG_KER for Falcon */
187 189
 	efab_oword_t int_ker __attribute__ (( aligned ( 16 ) ));
188
-};
189
-
190
-/**************************************************************************
191
- *
192
- * EEPROM access
193
- *
194
- **************************************************************************
195
- */
196
-
197
-#define EFAB_EEPROM_SDA		0x80000000u
198
-#define EFAB_EEPROM_SCL		0x40000000u
199
-#define ARIZONA_24xx00_SLAVE	0xa0
200
-#define EFAB_EEPROM_READ_SELECT	( ARIZONA_24xx00_SLAVE | 1 )
201
-#define EFAB_EEPROM_WRITE_SELECT ( ARIZONA_24xx00_SLAVE | 0 )
202
-
203
-static void eeprom_release ( uint32_t *eeprom_reg ) {
204
-	unsigned int dev;
205
-
206
-	udelay ( 10 );
207
-	dev = readl ( eeprom_reg );
208
-	writel ( dev | ( EFAB_EEPROM_SDA | EFAB_EEPROM_SCL ),
209
-		 eeprom_reg );
210
-	udelay ( 10 );
211
-}
212
-
213
-static void eeprom_start ( uint32_t *eeprom_reg ) {
214
-	unsigned int dev;
215
-	
216
-	udelay ( 10 );
217
-	dev = readl ( eeprom_reg );
218
-	
219
-	if ( ( dev & ( EFAB_EEPROM_SDA | EFAB_EEPROM_SCL ) ) !=
220
-	     ( EFAB_EEPROM_SDA | EFAB_EEPROM_SCL ) ) {
221
-		udelay ( 10 );
222
-		writel ( dev | ( EFAB_EEPROM_SDA | EFAB_EEPROM_SCL ),
223
-			 eeprom_reg );
224
-		udelay ( 1 );
225
-	}
226
-	dev &=~ ( EFAB_EEPROM_SDA | EFAB_EEPROM_SCL );
227
-	
228
-	udelay ( 10 );
229
-	writel ( dev | EFAB_EEPROM_SCL, eeprom_reg) ;
230
-	udelay ( 1) ;
231
-
232
-	udelay ( 10 );
233
-	writel ( dev, eeprom_reg );
234
-	udelay ( 10 );
235
-}
236
-
237
-static void eeprom_stop ( uint32_t *eeprom_reg ) { 
238
-	unsigned int dev;
239
-	
240
-	udelay ( 10 );
241
-	dev = readl ( eeprom_reg );
242
-	EFAB_ASSERT ( ! ( dev & EFAB_EEPROM_SCL ) );
243
-	
244
-	if ( dev & ( EFAB_EEPROM_SDA | EFAB_EEPROM_SCL ) ) {
245
-		dev &=~ ( EFAB_EEPROM_SDA | EFAB_EEPROM_SCL );
246
-		udelay ( 10 );
247
-		writel ( dev, eeprom_reg );
248
-		udelay ( 10 );
249
-	}
250
-	
251
-	udelay ( 10 );
252
-	dev |= EFAB_EEPROM_SCL;
253
-	writel ( dev, eeprom_reg );
254
-	udelay ( 10 );
255
-	
256
-	udelay ( 10 );
257
-	dev |= EFAB_EEPROM_SDA;
258
-	writel ( dev, eeprom_reg );
259
-	udelay ( 10 );
260
-}
261 190
 
262
-static void eeprom_write ( uint32_t *eeprom_reg, unsigned char data ) {
263
-	int i;
264
-	unsigned int dev;
265
-	
266
-	udelay ( 10 );
267
-	dev = readl ( eeprom_reg );
268
-	udelay ( 10 );
269
-	EFAB_ASSERT ( ! ( dev & EFAB_EEPROM_SCL ) );
270
-	
271
-	for ( i = 0 ; i < 8 ; i++, data <<= 1 ) {
272
-		if ( data & 0x80 ) {
273
-			dev |=  EFAB_EEPROM_SDA;
274
-		} else {
275
-			dev &=~ EFAB_EEPROM_SDA;
276
-		}
277
-		udelay ( 10 );
278
-		writel ( dev, eeprom_reg );
279
-		udelay ( 10 );
280
-		
281
-		udelay ( 10 );
282
-		writel ( dev | EFAB_EEPROM_SCL, eeprom_reg );
283
-		udelay ( 10 );
284
-		
285
-		udelay ( 10 );
286
-		writel ( dev, eeprom_reg );
287
-		udelay ( 10 );
288
-	}
289
-	
290
-	if( ! ( dev & EFAB_EEPROM_SDA ) ) {
291
-		udelay ( 10 );
292
-		writel ( dev | EFAB_EEPROM_SDA, eeprom_reg );
293
-		udelay ( 10 );
294
-	}
295
-}
296
-
297
-static unsigned char eeprom_read ( uint32_t *eeprom_reg ) {
298
-	unsigned int i, dev, rd;
299
-	unsigned char val = 0;
300
-	
301
-	udelay ( 10 );
302
-	dev = readl ( eeprom_reg );
303
-	udelay ( 10 );
304
-	EFAB_ASSERT ( ! ( dev & EFAB_EEPROM_SCL ) );
305
-	
306
-	if( ! ( dev & EFAB_EEPROM_SDA ) ) {
307
-		dev |= EFAB_EEPROM_SDA;
308
-		udelay ( 10 );
309
-		writel ( dev, eeprom_reg );
310
-		udelay ( 10 );
311
-	}
312
-	
313
-	for( i = 0 ; i < 8 ; i++ ) {
314
-		udelay ( 10 );
315
-		writel ( dev | EFAB_EEPROM_SCL, eeprom_reg );
316
-		udelay ( 10 );
317
-		
318
-		udelay ( 10 );
319
-		rd = readl ( eeprom_reg );
320
-		udelay ( 10 );
321
-		val = ( val << 1 ) | ( ( rd & EFAB_EEPROM_SDA ) != 0 );
322
-		
323
-		udelay ( 10 );
324
-		writel ( dev, eeprom_reg );
325
-		udelay ( 10 );
326
-	}
327
-
328
-	return val;
329
-}
330
-
331
-static int eeprom_check_ack ( uint32_t *eeprom_reg ) {
332
-	int ack;
333
-	unsigned int dev;
334
-	
335
-	udelay ( 10 );
336
-	dev = readl ( eeprom_reg );
337
-	EFAB_ASSERT ( ! ( dev & EFAB_EEPROM_SCL ) );
338
-	
339
-	writel ( dev | EFAB_EEPROM_SCL, eeprom_reg );
340
-	udelay ( 10 );
341
-	
342
-	udelay ( 10 );
343
-	ack = readl ( eeprom_reg ) & EFAB_EEPROM_SDA;
344
-	
345
-	udelay ( 10 );
346
-	writel ( ack & ~EFAB_EEPROM_SCL, eeprom_reg );
347
-	udelay ( 10 );
348
-	
349
-	return ( ack == 0 );
350
-}
351
-
352
-static void eeprom_send_ack ( uint32_t *eeprom_reg ) {
353
-	unsigned int dev;
354
-	
355
-	udelay ( 10 );
356
-	dev = readl ( eeprom_reg );
357
-	EFAB_ASSERT ( ! ( dev & EFAB_EEPROM_SCL ) );
358
-	
359
-	udelay ( 10 );
360
-	dev &= ~EFAB_EEPROM_SDA;	
361
-	writel ( dev, eeprom_reg );
362
-	udelay ( 10 );
363
-	
364
-	udelay ( 10 );
365
-	dev |= EFAB_EEPROM_SCL;     
366
-	writel ( dev, eeprom_reg );
367
-	udelay ( 10 );
368
-	
369
-	udelay ( 10 );
370
-	dev |= EFAB_EEPROM_SDA;	
371
-	writel ( dev & ~EFAB_EEPROM_SCL, eeprom_reg );
372
-	udelay ( 10 );
373
-}
374
-
375
-static int efab_eeprom_read_mac ( uint32_t *eeprom_reg, uint8_t *mac_addr ) {
376
-	int i;
377
-
378
-	eeprom_start ( eeprom_reg );
379
-
380
-	eeprom_write ( eeprom_reg, EFAB_EEPROM_WRITE_SELECT );
381
-	if ( ! eeprom_check_ack ( eeprom_reg ) )
382
-		return 0;
383
-	
384
-	eeprom_write ( eeprom_reg, 0 );
385
-	if ( ! eeprom_check_ack ( eeprom_reg ) )
386
-		return 0;
387
-	
388
-	eeprom_stop ( eeprom_reg );
389
-	eeprom_start ( eeprom_reg );
390
-	
391
-	eeprom_write ( eeprom_reg, EFAB_EEPROM_READ_SELECT );
392
-	if ( ! eeprom_check_ack ( eeprom_reg ) )
393
-		return 0;
394
-	
395
-	for ( i = 0 ; i < ETH_ALEN ; i++ ) {
396
-		mac_addr[i] = eeprom_read ( eeprom_reg );
397
-		eeprom_send_ack ( eeprom_reg );
398
-	}
399
-	
400
-	eeprom_stop ( eeprom_reg );
401
-	
402
-	eeprom_release ( eeprom_reg );
403
-	
404
-	return 1;
405
-}
191
+	/** EEPROM access */
192
+	struct i2c_bit_basher ef1002_i2c;
193
+	unsigned long ef1002_i2c_outputs;
194
+	struct i2c_device ef1002_eeprom;
195
+};
406 196
 
407 197
 /**************************************************************************
408 198
  *
@@ -973,6 +763,8 @@ static int mentormac_mdio_read ( struct efab_nic *efab, int phy_id,
973 763
 
974 764
 /** EEPROM access */
975 765
 #define EF1_EEPROM_REG 0x0040
766
+#define EF1_EEPROM_LBN 0
767
+#define EF1_EEPROM_WIDTH 32
976 768
 
977 769
 /** Control register 2 */
978 770
 #define EF1_CTL2_REG 0x4c
@@ -1107,6 +899,12 @@ static int mentormac_mdio_read ( struct efab_nic *efab, int phy_id,
1107 899
 #define EF1_TX_EV_IDX_LBN 0
1108 900
 #define EF1_TX_EV_IDX_WIDTH 16
1109 901
 
902
+/* I2C ID of the EEPROM */
903
+#define EF1_EEPROM_I2C_ID 0x50
904
+
905
+/* Offset of MAC address within EEPROM */
906
+#define EF1_EEPROM_HWADDR_OFFSET 0x0
907
+
1110 908
 /**
1111 909
  * Write dword to EF1002 register
1112 910
  *
@@ -1164,6 +962,49 @@ struct efab_pci_reg {
1164 962
 	uint32_t reg[EFAB_NUM_PCI_REG];
1165 963
 };
1166 964
 
965
+/*
966
+ * I2C interface and EEPROM
967
+ *
968
+ */
969
+
970
+static unsigned long ef1002_i2c_bits[] = {
971
+	[I2C_BIT_SCL] = ( 1 << 30 ),
972
+	[I2C_BIT_SDA] = ( 1 << 31 ),
973
+};
974
+
975
+static void ef1002_i2c_write_bit ( struct bit_basher *basher,
976
+				   unsigned int bit_id, unsigned long data ) {
977
+	struct efab_nic *efab = container_of ( basher, struct efab_nic,
978
+					       ef1002_i2c.basher );
979
+	unsigned long mask;
980
+	efab_dword_t reg;
981
+
982
+	mask = ef1002_i2c_bits[bit_id];
983
+	efab->ef1002_i2c_outputs &= ~mask;
984
+	efab->ef1002_i2c_outputs |= ( data & mask );
985
+	EFAB_POPULATE_DWORD_1 ( reg, EF1_EEPROM, efab->ef1002_i2c_outputs );
986
+	ef1002_writel ( efab, &reg, EF1_EEPROM_REG );
987
+}
988
+
989
+static int ef1002_i2c_read_bit ( struct bit_basher *basher,
990
+				 unsigned int bit_id ) {
991
+	struct efab_nic *efab = container_of ( basher, struct efab_nic,
992
+					       ef1002_i2c.basher );
993
+	unsigned long mask;
994
+	efab_dword_t reg;
995
+
996
+	mask = ef1002_i2c_bits[bit_id];
997
+	ef1002_readl ( efab, &reg, EF1_EEPROM_REG );
998
+	return ( EFAB_DWORD_FIELD ( reg, EF1_EEPROM ) & mask );
999
+}
1000
+
1001
+static void ef1002_init_eeprom ( struct efab_nic *efab ) {
1002
+	efab->ef1002_i2c.basher.write = ef1002_i2c_write_bit;
1003
+	efab->ef1002_i2c.basher.read = ef1002_i2c_read_bit;
1004
+	init_i2c_bit_basher ( &efab->ef1002_i2c );
1005
+	efab->ef1002_eeprom.address = EF1_EEPROM_I2C_ID;
1006
+}
1007
+
1167 1008
 /**
1168 1009
  * Reset device
1169 1010
  *
@@ -1295,6 +1136,9 @@ static int ef1002_init_nic ( struct efab_nic *efab ) {
1295 1136
 	/* Give PHY time to wake up.  It takes a while. */
1296 1137
 	sleep ( 2 );
1297 1138
 
1139
+	/* Attach I2C bus */
1140
+	ef1002_init_eeprom ( efab );
1141
+
1298 1142
 	return 1;
1299 1143
 }
1300 1144
 
@@ -1303,8 +1147,11 @@ static int ef1002_init_nic ( struct efab_nic *efab ) {
1303 1147
  *
1304 1148
  */
1305 1149
 static int ef1002_read_eeprom ( struct efab_nic *efab ) {
1306
-	return efab_eeprom_read_mac ( efab->membase + EF1_EEPROM_REG,
1307
-				      efab->mac_addr );
1150
+	struct i2c_interface *i2c = &efab->ef1002_i2c.i2c;
1151
+	struct i2c_device *i2cdev = &efab->ef1002_eeprom;
1152
+
1153
+	return i2c->read ( i2c, i2cdev, EF1_EEPROM_HWADDR_OFFSET,
1154
+			   efab->mac_addr, sizeof ( efab->mac_addr ) );
1308 1155
 }
1309 1156
 
1310 1157
 /** RX descriptor */
@@ -2921,8 +2768,7 @@ static void etherfabric_transmit ( struct nic *nic, const char *dest,
2921 2768
 /**************************************************************************
2922 2769
 DISABLE - Turn off ethernet interface
2923 2770
 ***************************************************************************/
2924
-static void etherfabric_disable ( struct nic *nic,
2925
-				  struct pci_device *pci __unused ) {
2771
+static void etherfabric_disable ( struct nic *nic ) {
2926 2772
 	struct efab_nic *efab = nic->priv_data;
2927 2773
 
2928 2774
 	efab->op->reset ( efab );
@@ -2962,8 +2808,7 @@ static struct nic_operations etherfabric_operations = {
2962 2808
 /**************************************************************************
2963 2809
 PROBE - Look for an adapter, this routine's visible to the outside
2964 2810
 ***************************************************************************/
2965
-static int etherfabric_probe ( struct dev *dev, struct pci_device *pci ) {
2966
-	struct nic *nic = ( struct nic * ) dev;
2811
+static int etherfabric_probe ( struct nic *nic, struct pci_device *pci ) {
2967 2812
 	static struct efab_nic efab;
2968 2813
 	static int nic_port = 1;
2969 2814
 	struct efab_buffers *buffers;

Loading…
Отказ
Запис