Browse Source

[phantom] Unhalt/halt all PEGs during driver startup/shutdown

A hardware bug means that reads through the expansion ROM BAR can
return corrupted data if the PEGs are running.  This breaks platforms
that re-read the expansion ROM after invoking gPXE code, such as IBM
blade servers.

Halt PEGs during driver shutdown, and unhalt PEGs during driver
startup if we detect that this is not the first startup since
power-on.
tags/v0.9.6
Michael Brown 16 years ago
parent
commit
664f4cf365
2 changed files with 70 additions and 0 deletions
  1. 45
    0
      src/drivers/net/phantom/phantom.c
  2. 25
    0
      src/drivers/net/phantom/phantom.h

+ 45
- 0
src/drivers/net/phantom/phantom.c View File

294
 		{ UNM_CRB_BLK_CAM,	0x416 },
294
 		{ UNM_CRB_BLK_CAM,	0x416 },
295
 		{ UNM_CRB_BLK_ROMUSB,	0x421 },
295
 		{ UNM_CRB_BLK_ROMUSB,	0x421 },
296
 		{ UNM_CRB_BLK_TEST,	0x295 },
296
 		{ UNM_CRB_BLK_TEST,	0x295 },
297
+		{ UNM_CRB_BLK_PEG_0,	0x340 },
298
+		{ UNM_CRB_BLK_PEG_1,	0x341 },
299
+		{ UNM_CRB_BLK_PEG_2,	0x342 },
300
+		{ UNM_CRB_BLK_PEG_3,	0x343 },
301
+		{ UNM_CRB_BLK_PEG_4,	0x34b },
297
 	};
302
 	};
298
 	unsigned int block = UNM_CRB_BLK ( reg );
303
 	unsigned int block = UNM_CRB_BLK ( reg );
299
 	unsigned long offset = UNM_CRB_OFFSET ( reg );
304
 	unsigned long offset = UNM_CRB_OFFSET ( reg );
1687
 	return 0;
1692
 	return 0;
1688
 }
1693
 }
1689
 
1694
 
1695
+/**
1696
+ * Halt all PEGs
1697
+ *
1698
+ * @v phantom		Phantom NIC
1699
+ */
1700
+static void phantom_halt_pegs ( struct phantom_nic *phantom ) {
1701
+	phantom_writel ( phantom, 1, UNM_PEG_0_HALT );
1702
+	phantom_writel ( phantom, 1, UNM_PEG_1_HALT );
1703
+	phantom_writel ( phantom, 1, UNM_PEG_2_HALT );
1704
+	phantom_writel ( phantom, 1, UNM_PEG_3_HALT );
1705
+	phantom_writel ( phantom, 1, UNM_PEG_4_HALT );
1706
+}
1707
+
1708
+/**
1709
+ * Unhalt all PEGs
1710
+ *
1711
+ * @v phantom		Phantom NIC
1712
+ */
1713
+static void phantom_unhalt_pegs ( struct phantom_nic *phantom ) {
1714
+	uint32_t halt_status;
1715
+
1716
+	halt_status = phantom_readl ( phantom, UNM_PEG_0_HALT_STATUS );
1717
+	phantom_writel ( phantom, halt_status, UNM_PEG_0_HALT_STATUS );
1718
+	halt_status = phantom_readl ( phantom, UNM_PEG_1_HALT_STATUS );
1719
+	phantom_writel ( phantom, halt_status, UNM_PEG_1_HALT_STATUS );
1720
+	halt_status = phantom_readl ( phantom, UNM_PEG_2_HALT_STATUS );
1721
+	phantom_writel ( phantom, halt_status, UNM_PEG_2_HALT_STATUS );
1722
+	halt_status = phantom_readl ( phantom, UNM_PEG_3_HALT_STATUS );
1723
+	phantom_writel ( phantom, halt_status, UNM_PEG_3_HALT_STATUS );
1724
+	halt_status = phantom_readl ( phantom, UNM_PEG_4_HALT_STATUS );
1725
+	phantom_writel ( phantom, halt_status, UNM_PEG_4_HALT_STATUS );
1726
+}
1727
+
1690
 /**
1728
 /**
1691
  * Initialise the Phantom command PEG
1729
  * Initialise the Phantom command PEG
1692
  *
1730
  *
1709
 	if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK ) {
1747
 	if ( cmdpeg_state == UNM_NIC_REG_CMDPEG_STATE_INITIALIZE_ACK ) {
1710
 		DBGC ( phantom, "Phantom %p command PEG already initialized\n",
1748
 		DBGC ( phantom, "Phantom %p command PEG already initialized\n",
1711
 		       phantom );
1749
 		       phantom );
1750
+		/* Unhalt the PEGs.  Previous firmware (e.g. BOFM) may
1751
+		 * have halted the PEGs to prevent internal bus
1752
+		 * collisions when the BIOS re-reads the expansion ROM.
1753
+		 */
1754
+		phantom_unhalt_pegs ( phantom );
1712
 		return 0;
1755
 		return 0;
1713
 	}
1756
 	}
1714
 
1757
 
1942
 	for ( ; i >= 0 ; i-- )
1985
 	for ( ; i >= 0 ; i-- )
1943
 		unregister_netdev ( phantom->netdev[i] );
1986
 		unregister_netdev ( phantom->netdev[i] );
1944
  err_init_rcvpeg:
1987
  err_init_rcvpeg:
1988
+	phantom_halt_pegs ( phantom );
1945
  err_init_cmdpeg:
1989
  err_init_cmdpeg:
1946
 	free_dma ( phantom->dma_buf, sizeof ( *(phantom->dma_buf) ) );
1990
 	free_dma ( phantom->dma_buf, sizeof ( *(phantom->dma_buf) ) );
1947
 	phantom->dma_buf = NULL;
1991
 	phantom->dma_buf = NULL;
1970
 
2014
 
1971
 	for ( i = ( phantom->num_ports - 1 ) ; i >= 0 ; i-- )
2015
 	for ( i = ( phantom->num_ports - 1 ) ; i >= 0 ; i-- )
1972
 		unregister_netdev ( phantom->netdev[i] );
2016
 		unregister_netdev ( phantom->netdev[i] );
2017
+	phantom_halt_pegs ( phantom );
1973
 	free_dma ( phantom->dma_buf, sizeof ( *(phantom->dma_buf) ) );
2018
 	free_dma ( phantom->dma_buf, sizeof ( *(phantom->dma_buf) ) );
1974
 	phantom->dma_buf = NULL;
2019
 	phantom->dma_buf = NULL;
1975
 	for ( i = ( phantom->num_ports - 1 ) ; i >= 0 ; i-- ) {
2020
 	for ( i = ( phantom->num_ports - 1 ) ; i >= 0 ; i-- ) {

+ 25
- 0
src/drivers/net/phantom/phantom.h View File

80
 	UNM_CRB_BLK_CAM		= 0x22,
80
 	UNM_CRB_BLK_CAM		= 0x22,
81
 	UNM_CRB_BLK_ROMUSB	= 0x33,
81
 	UNM_CRB_BLK_ROMUSB	= 0x33,
82
 	UNM_CRB_BLK_TEST	= 0x02,
82
 	UNM_CRB_BLK_TEST	= 0x02,
83
+	UNM_CRB_BLK_PEG_0	= 0x11,
84
+	UNM_CRB_BLK_PEG_1	= 0x12,
85
+	UNM_CRB_BLK_PEG_2	= 0x13,
86
+	UNM_CRB_BLK_PEG_3	= 0x14,
87
+	UNM_CRB_BLK_PEG_4	= 0x0f,
83
 };
88
 };
84
 #define UNM_CRB_BASE(blk)		( (blk) << 20 )
89
 #define UNM_CRB_BASE(blk)		( (blk) << 20 )
85
 #define UNM_CRB_BLK(reg)		( (reg) >> 20 )
90
 #define UNM_CRB_BLK(reg)		( (reg) >> 20 )
160
 #define UNM_TEST_RDDATA_LO		( UNM_CRB_TEST + 0x000a8 )
165
 #define UNM_TEST_RDDATA_LO		( UNM_CRB_TEST + 0x000a8 )
161
 #define UNM_TEST_RDDATA_HI		( UNM_CRB_TEST + 0x000ac )
166
 #define UNM_TEST_RDDATA_HI		( UNM_CRB_TEST + 0x000ac )
162
 
167
 
168
+#define UNM_CRB_PEG_0			UNM_CRB_BASE ( UNM_CRB_BLK_PEG_0 )
169
+#define UNM_PEG_0_HALT_STATUS		( UNM_CRB_PEG_0 + 0x00030 )
170
+#define UNM_PEG_0_HALT			( UNM_CRB_PEG_0 + 0x0003c )
171
+
172
+#define UNM_CRB_PEG_1			UNM_CRB_BASE ( UNM_CRB_BLK_PEG_1 )
173
+#define UNM_PEG_1_HALT_STATUS		( UNM_CRB_PEG_1 + 0x00030 )
174
+#define UNM_PEG_1_HALT			( UNM_CRB_PEG_1 + 0x0003c )
175
+
176
+#define UNM_CRB_PEG_2			UNM_CRB_BASE ( UNM_CRB_BLK_PEG_2 )
177
+#define UNM_PEG_2_HALT_STATUS		( UNM_CRB_PEG_2 + 0x00030 )
178
+#define UNM_PEG_2_HALT			( UNM_CRB_PEG_2 + 0x0003c )
179
+
180
+#define UNM_CRB_PEG_3			UNM_CRB_BASE ( UNM_CRB_BLK_PEG_3 )
181
+#define UNM_PEG_3_HALT_STATUS		( UNM_CRB_PEG_3 + 0x00030 )
182
+#define UNM_PEG_3_HALT			( UNM_CRB_PEG_3 + 0x0003c )
183
+
184
+#define UNM_CRB_PEG_4			UNM_CRB_BASE ( UNM_CRB_BLK_PEG_4 )
185
+#define UNM_PEG_4_HALT_STATUS		( UNM_CRB_PEG_4 + 0x00030 )
186
+#define UNM_PEG_4_HALT			( UNM_CRB_PEG_4 + 0x0003c )
187
+
163
 /******************************************************************************
188
 /******************************************************************************
164
  *
189
  *
165
  * Flash layout
190
  * Flash layout

Loading…
Cancel
Save