Browse Source

[phantom] Update interrupt support to match current firmware

The interrupt control mechanism on Phantom cards has changed
substantially since the driver was initially written.  This updates
the code to match the mechanism used in production firmware.

This is sufficient to allow DOS wget to function successfully using
the 3Com UNDI/NDIS, Intel UNDI/NDIS, and UNDIPD.COM UNDI/PD stacks.

Signed-off-by: Michael Brown <mcb30@etherboot.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
b3533dd2bb
2 changed files with 91 additions and 23 deletions
  1. 69
    19
      src/drivers/net/phantom/phantom.c
  2. 22
    4
      src/drivers/net/phantom/phantom.h

+ 69
- 19
src/drivers/net/phantom/phantom.c View File

45
  */
45
  */
46
 
46
 
47
 /** Maximum number of ports */
47
 /** Maximum number of ports */
48
-#define PHN_MAX_NUM_PORTS 4
48
+#define PHN_MAX_NUM_PORTS 8
49
 
49
 
50
 /** Maximum time to wait for command PEG to initialise
50
 /** Maximum time to wait for command PEG to initialise
51
  *
51
  *
154
 	unsigned long rds_producer_crb;
154
 	unsigned long rds_producer_crb;
155
 	/** RX status descriptor consumer CRB offset */
155
 	/** RX status descriptor consumer CRB offset */
156
 	unsigned long sds_consumer_crb;
156
 	unsigned long sds_consumer_crb;
157
+	/** RX interrupt mask CRB offset */
158
+	unsigned long sds_irq_mask_crb;
159
+	/** RX interrupts enabled */
160
+	unsigned int sds_irq_enabled;
157
 
161
 
158
 	/** RX producer index */
162
 	/** RX producer index */
159
 	unsigned int rds_producer_idx;
163
 	unsigned int rds_producer_idx;
192
 	struct settings settings;
196
 	struct settings settings;
193
 };
197
 };
194
 
198
 
199
+/** Interrupt mask registers */
200
+static const unsigned long phantom_irq_mask_reg[PHN_MAX_NUM_PORTS] = {
201
+	UNM_PCIE_IRQ_MASK_F0,
202
+	UNM_PCIE_IRQ_MASK_F1,
203
+	UNM_PCIE_IRQ_MASK_F2,
204
+	UNM_PCIE_IRQ_MASK_F3,
205
+	UNM_PCIE_IRQ_MASK_F4,
206
+	UNM_PCIE_IRQ_MASK_F5,
207
+	UNM_PCIE_IRQ_MASK_F6,
208
+	UNM_PCIE_IRQ_MASK_F7,
209
+};
210
+
211
+/** Interrupt status registers */
212
+static const unsigned long phantom_irq_status_reg[PHN_MAX_NUM_PORTS] = {
213
+	UNM_PCIE_IRQ_STATUS_F0,
214
+	UNM_PCIE_IRQ_STATUS_F1,
215
+	UNM_PCIE_IRQ_STATUS_F2,
216
+	UNM_PCIE_IRQ_STATUS_F3,
217
+	UNM_PCIE_IRQ_STATUS_F4,
218
+	UNM_PCIE_IRQ_STATUS_F5,
219
+	UNM_PCIE_IRQ_STATUS_F6,
220
+	UNM_PCIE_IRQ_STATUS_F7,
221
+};
222
+
195
 /***************************************************************************
223
 /***************************************************************************
196
  *
224
  *
197
  * CRB register access
225
  * CRB register access
664
 		le16_to_cpu ( buf->cardrsp.rx_ctx.context_id );
692
 		le16_to_cpu ( buf->cardrsp.rx_ctx.context_id );
665
 	phantom->rds_producer_crb =
693
 	phantom->rds_producer_crb =
666
 		( UNM_CAM_RAM +
694
 		( UNM_CAM_RAM +
667
-		  le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ));
695
+		  le32_to_cpu ( buf->cardrsp.rds.host_producer_crb ) );
668
 	phantom->sds_consumer_crb =
696
 	phantom->sds_consumer_crb =
669
 		( UNM_CAM_RAM +
697
 		( UNM_CAM_RAM +
670
-		  le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ));
698
+		  le32_to_cpu ( buf->cardrsp.sds.host_consumer_crb ) );
699
+	phantom->sds_irq_mask_crb =
700
+		( UNM_CAM_RAM +
701
+		  le32_to_cpu ( buf->cardrsp.sds.interrupt_crb ) );
671
 
702
 
672
 	DBGC ( phantom, "Phantom %p created RX context (id %04x, port phys "
703
 	DBGC ( phantom, "Phantom %p created RX context (id %04x, port phys "
673
 	       "%02x virt %02x)\n", phantom, phantom->rx_context_id,
704
 	       "%02x virt %02x)\n", phantom, phantom->rx_context_id,
678
 	       phantom, phantom->rds_producer_crb );
709
 	       phantom, phantom->rds_producer_crb );
679
 	DBGC ( phantom, "Phantom %p SDS consumer CRB is %08lx\n",
710
 	DBGC ( phantom, "Phantom %p SDS consumer CRB is %08lx\n",
680
 	       phantom, phantom->sds_consumer_crb );
711
 	       phantom, phantom->sds_consumer_crb );
712
+	DBGC ( phantom, "Phantom %p SDS interrupt mask CRB is %08lx\n",
713
+	       phantom, phantom->sds_irq_mask_crb );
681
 
714
 
682
  out:
715
  out:
683
 	free_dma ( buf, sizeof ( *buf ) );
716
 	free_dma ( buf, sizeof ( *buf ) );
1263
 static void phantom_poll ( struct net_device *netdev ) {
1296
 static void phantom_poll ( struct net_device *netdev ) {
1264
 	struct phantom_nic *phantom = netdev_priv ( netdev );
1297
 	struct phantom_nic *phantom = netdev_priv ( netdev );
1265
 	struct io_buffer *iobuf;
1298
 	struct io_buffer *iobuf;
1299
+	unsigned int irq_vector;
1300
+	unsigned int irq_state;
1266
 	unsigned int cds_consumer_idx;
1301
 	unsigned int cds_consumer_idx;
1267
 	unsigned int raw_new_cds_consumer_idx;
1302
 	unsigned int raw_new_cds_consumer_idx;
1268
 	unsigned int new_cds_consumer_idx;
1303
 	unsigned int new_cds_consumer_idx;
1272
 	unsigned int sds_handle;
1307
 	unsigned int sds_handle;
1273
 	unsigned int sds_opcode;
1308
 	unsigned int sds_opcode;
1274
 
1309
 
1310
+	/* Occasionally poll the link state */
1311
+	if ( phantom->link_poll_timer-- == 0 ) {
1312
+		phantom_poll_link_state ( netdev );
1313
+		/* Reset the link poll timer */
1314
+		phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
1315
+	}
1316
+
1317
+	/* Check for interrupts */
1318
+	if ( phantom->sds_irq_enabled ) {
1319
+
1320
+		/* Do nothing unless an interrupt is asserted */
1321
+		irq_vector = phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
1322
+		if ( ! ( irq_vector & UNM_PCIE_IRQ_VECTOR_BIT( phantom->port )))
1323
+			return;
1324
+
1325
+		/* Do nothing unless interrupt state machine has stabilised */
1326
+		irq_state = phantom_readl ( phantom, UNM_PCIE_IRQ_STATE );
1327
+		if ( ! UNM_PCIE_IRQ_STATE_TRIGGERED ( irq_state ) )
1328
+			return;
1329
+
1330
+		/* Acknowledge interrupt */
1331
+		phantom_writel ( phantom, UNM_PCIE_IRQ_STATUS_MAGIC,
1332
+				 phantom_irq_status_reg[phantom->port] );
1333
+		phantom_readl ( phantom, UNM_PCIE_IRQ_VECTOR );
1334
+	}
1335
+
1275
 	/* Check for TX completions */
1336
 	/* Check for TX completions */
1276
 	cds_consumer_idx = phantom->cds_consumer_idx;
1337
 	cds_consumer_idx = phantom->cds_consumer_idx;
1277
 	raw_new_cds_consumer_idx = phantom->desc->cmd_cons;
1338
 	raw_new_cds_consumer_idx = phantom->desc->cmd_cons;
1361
 
1422
 
1362
 	/* Refill the RX descriptor ring */
1423
 	/* Refill the RX descriptor ring */
1363
 	phantom_refill_rx_ring ( netdev );
1424
 	phantom_refill_rx_ring ( netdev );
1364
-
1365
-	/* Occasionally poll the link state */
1366
-	if ( phantom->link_poll_timer-- == 0 ) {
1367
-		phantom_poll_link_state ( netdev );
1368
-		/* Reset the link poll timer */
1369
-		phantom->link_poll_timer = PHN_LINK_POLL_FREQUENCY;
1370
-	}
1371
 }
1425
 }
1372
 
1426
 
1373
 /**
1427
 /**
1378
  */
1432
  */
1379
 static void phantom_irq ( struct net_device *netdev, int enable ) {
1433
 static void phantom_irq ( struct net_device *netdev, int enable ) {
1380
 	struct phantom_nic *phantom = netdev_priv ( netdev );
1434
 	struct phantom_nic *phantom = netdev_priv ( netdev );
1381
-	static const unsigned long sw_int_mask_reg[PHN_MAX_NUM_PORTS] = {
1382
-		UNM_NIC_REG_SW_INT_MASK_0,
1383
-		UNM_NIC_REG_SW_INT_MASK_1,
1384
-		UNM_NIC_REG_SW_INT_MASK_2,
1385
-		UNM_NIC_REG_SW_INT_MASK_3
1386
-	};
1387
 
1435
 
1388
-	phantom_writel ( phantom,
1389
-			 ( enable ? 1 : 0 ),
1390
-			 sw_int_mask_reg[phantom->port] );
1436
+	phantom_writel ( phantom, ( enable ? 1 : 0 ),
1437
+			 phantom->sds_irq_mask_crb );
1438
+	phantom_writel ( phantom, UNM_PCIE_IRQ_MASK_MAGIC,
1439
+			 phantom_irq_mask_reg[phantom->port] );
1440
+	phantom->sds_irq_enabled = enable;
1391
 }
1441
 }
1392
 
1442
 
1393
 /** Phantom net device operations */
1443
 /** Phantom net device operations */

+ 22
- 4
src/drivers/net/phantom/phantom.h View File

89
 #define UNM_CRB_PCIE			UNM_CRB_BASE ( UNM_CRB_BLK_PCIE )
89
 #define UNM_CRB_PCIE			UNM_CRB_BASE ( UNM_CRB_BLK_PCIE )
90
 #define UNM_PCIE_SEM2_LOCK		( UNM_CRB_PCIE + 0x1c010 )
90
 #define UNM_PCIE_SEM2_LOCK		( UNM_CRB_PCIE + 0x1c010 )
91
 #define UNM_PCIE_SEM2_UNLOCK		( UNM_CRB_PCIE + 0x1c014 )
91
 #define UNM_PCIE_SEM2_UNLOCK		( UNM_CRB_PCIE + 0x1c014 )
92
+#define UNM_PCIE_IRQ_VECTOR		( UNM_CRB_PCIE + 0x10100 )
93
+#define UNM_PCIE_IRQ_VECTOR_BIT(n)		( 1 << ( (n) + 7 ) )
94
+#define UNM_PCIE_IRQ_STATE		( UNM_CRB_PCIE + 0x1206c )
95
+#define UNM_PCIE_IRQ_STATE_TRIGGERED(state)	(( (state) & 0x300 ) == 0x200 )
96
+#define UNM_PCIE_IRQ_MASK_F0		( UNM_CRB_PCIE + 0x10128 )
97
+#define UNM_PCIE_IRQ_MASK_F1		( UNM_CRB_PCIE + 0x10170 )
98
+#define UNM_PCIE_IRQ_MASK_F2		( UNM_CRB_PCIE + 0x10174 )
99
+#define UNM_PCIE_IRQ_MASK_F3		( UNM_CRB_PCIE + 0x10178 )
100
+#define UNM_PCIE_IRQ_MASK_F4		( UNM_CRB_PCIE + 0x10370 )
101
+#define UNM_PCIE_IRQ_MASK_F5		( UNM_CRB_PCIE + 0x10374 )
102
+#define UNM_PCIE_IRQ_MASK_F6		( UNM_CRB_PCIE + 0x10378 )
103
+#define UNM_PCIE_IRQ_MASK_F7		( UNM_CRB_PCIE + 0x1037c )
104
+#define UNM_PCIE_IRQ_MASK_MAGIC			0x0000fbffUL
105
+#define UNM_PCIE_IRQ_STATUS_F0		( UNM_CRB_PCIE + 0x10118 )
106
+#define UNM_PCIE_IRQ_STATUS_F1		( UNM_CRB_PCIE + 0x10160 )
107
+#define UNM_PCIE_IRQ_STATUS_F2		( UNM_CRB_PCIE + 0x10164 )
108
+#define UNM_PCIE_IRQ_STATUS_F3		( UNM_CRB_PCIE + 0x10168 )
109
+#define UNM_PCIE_IRQ_STATUS_F4		( UNM_CRB_PCIE + 0x10360 )
110
+#define UNM_PCIE_IRQ_STATUS_F5		( UNM_CRB_PCIE + 0x10364 )
111
+#define UNM_PCIE_IRQ_STATUS_F6		( UNM_CRB_PCIE + 0x10368 )
112
+#define UNM_PCIE_IRQ_STATUS_F7		( UNM_CRB_PCIE + 0x1036c )
113
+#define UNM_PCIE_IRQ_STATUS_MAGIC		0xffffffffUL
92
 
114
 
93
 #define UNM_CRB_CAM			UNM_CRB_BASE ( UNM_CRB_BLK_CAM )
115
 #define UNM_CRB_CAM			UNM_CRB_BASE ( UNM_CRB_BLK_CAM )
94
 
116
 
137
 #define UNM_NIC_REG_XG_STATE_P3_LINK_DOWN	0x02
159
 #define UNM_NIC_REG_XG_STATE_P3_LINK_DOWN	0x02
138
 #define UNM_NIC_REG_RCVPEG_STATE	( UNM_NIC_REG + 0x0013c )
160
 #define UNM_NIC_REG_RCVPEG_STATE	( UNM_NIC_REG + 0x0013c )
139
 #define UNM_NIC_REG_RCVPEG_STATE_INITIALIZED	0xff01
161
 #define UNM_NIC_REG_RCVPEG_STATE_INITIALIZED	0xff01
140
-#define UNM_NIC_REG_SW_INT_MASK_0	( UNM_NIC_REG + 0x001d8 )
141
-#define UNM_NIC_REG_SW_INT_MASK_1	( UNM_NIC_REG + 0x001e0 )
142
-#define UNM_NIC_REG_SW_INT_MASK_2	( UNM_NIC_REG + 0x001e4 )
143
-#define UNM_NIC_REG_SW_INT_MASK_3	( UNM_NIC_REG + 0x001e8 )
144
 
162
 
145
 #define UNM_CRB_ROMUSB			UNM_CRB_BASE ( UNM_CRB_BLK_ROMUSB )
163
 #define UNM_CRB_ROMUSB			UNM_CRB_BASE ( UNM_CRB_BLK_ROMUSB )
146
 
164
 

Loading…
Cancel
Save