Browse Source

[intel] Apply PBS/PBA errata workaround only to ICH8 PCI device IDs

ICH8 devices have an errata which requires us to reconfigure the
packet buffer size (PBS) register, and correspondingly adjust the
packet buffer allocation (PBA) register.  The "Intel I/O Controller
Hub ICH8/9/10 and 82566/82567/82562V Software Developer's Manual"
notes for the PBS register that:

  10.4.20   Packet Buffer Size - PBS (01008h; R/W)

  Note: The default setting of this register is 20 KB and is
        incorrect. This register must be programmed to 16 KB.

  Initial value: 0014h
                 0018h (ICH9/ICH10)

It is unclear from this comment precisely which devices require the
workaround to be applied.  We currently attempt to err on the side of
caution: if we detect an initial value of either 0x14 or 0x18 then the
workaround will be applied.  If the workaround is applied
unnecessarily, then the effect should be just that we use less than
the full amount of the available packet buffer memory.

Unfortunately this approach does not play nicely with other device
drivers.  For example, the Linux e1000e driver will rewrite PBA while
assuming that PBS still contains the default value, which can result
in inconsistent values between the two registers, and a corresponding
inability to transmit or receive packets.  Even more unfortunately,
the contents of PBS and PBA are not reset by anything less than a
power cycle, meaning that this error condition will survive a hardware
reset.

The Linux driver (written and maintained by Intel) applies the PBS/PBA
errata workaround only for devices in the ICH8 family, identified via
the PCI device ID.  Adopt a similar approach, using the PCI_ROM()
driver data field to indicate when the workaround is required.

Reported-by: Donald Bindner <dbindner@truman.edu>
Debugged-by: Donald Bindner <dbindner@truman.edu>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
ead70bf920
2 changed files with 22 additions and 13 deletions
  1. 14
    13
      src/drivers/net/intel.c
  2. 8
    0
      src/drivers/net/intel.h

+ 14
- 13
src/drivers/net/intel.c View File

294
 	/* Force RX and TX packet buffer allocation, to work around an
294
 	/* Force RX and TX packet buffer allocation, to work around an
295
 	 * errata in ICH devices.
295
 	 * errata in ICH devices.
296
 	 */
296
 	 */
297
-	pbs = readl ( intel->regs + INTEL_PBS );
298
-	if ( ( pbs == 0x14 ) || ( pbs == 0x18 ) ) {
297
+	if ( intel->flags & INTEL_PBS_ERRATA ) {
299
 		DBGC ( intel, "INTEL %p WARNING: applying ICH PBS/PBA errata\n",
298
 		DBGC ( intel, "INTEL %p WARNING: applying ICH PBS/PBA errata\n",
300
 		       intel );
299
 		       intel );
300
+		pbs = readl ( intel->regs + INTEL_PBS );
301
 		pba = readl ( intel->regs + INTEL_PBA );
301
 		pba = readl ( intel->regs + INTEL_PBA );
302
 		writel ( 0x08, intel->regs + INTEL_PBA );
302
 		writel ( 0x08, intel->regs + INTEL_PBA );
303
 		writel ( 0x10, intel->regs + INTEL_PBS );
303
 		writel ( 0x10, intel->regs + INTEL_PBS );
816
 	netdev->dev = &pci->dev;
816
 	netdev->dev = &pci->dev;
817
 	memset ( intel, 0, sizeof ( *intel ) );
817
 	memset ( intel, 0, sizeof ( *intel ) );
818
 	intel->port = PCI_FUNC ( pci->busdevfn );
818
 	intel->port = PCI_FUNC ( pci->busdevfn );
819
+	intel->flags = pci->id->driver_data;
819
 	intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTEL_TD );
820
 	intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTEL_TD );
820
 	intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTEL_RD );
821
 	intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTEL_RD );
821
 
822
 
911
 	PCI_ROM ( 0x8086, 0x1026, "82545gm", "82545GM", 0 ),
912
 	PCI_ROM ( 0x8086, 0x1026, "82545gm", "82545GM", 0 ),
912
 	PCI_ROM ( 0x8086, 0x1027, "82545gm-1", "82545GM", 0 ),
913
 	PCI_ROM ( 0x8086, 0x1027, "82545gm-1", "82545GM", 0 ),
913
 	PCI_ROM ( 0x8086, 0x1028, "82545gm-2", "82545GM", 0 ),
914
 	PCI_ROM ( 0x8086, 0x1028, "82545gm-2", "82545GM", 0 ),
914
-	PCI_ROM ( 0x8086, 0x1049, "82566mm", "82566MM", 0 ),
915
-	PCI_ROM ( 0x8086, 0x104a, "82566dm", "82566DM", 0 ),
916
-	PCI_ROM ( 0x8086, 0x104b, "82566dc", "82566DC", 0 ),
917
-	PCI_ROM ( 0x8086, 0x104c, "82562v", "82562V 10/100", 0 ),
918
-	PCI_ROM ( 0x8086, 0x104d, "82566mc", "82566MC", 0 ),
915
+	PCI_ROM ( 0x8086, 0x1049, "82566mm", "82566MM", INTEL_PBS_ERRATA ),
916
+	PCI_ROM ( 0x8086, 0x104a, "82566dm", "82566DM", INTEL_PBS_ERRATA ),
917
+	PCI_ROM ( 0x8086, 0x104b, "82566dc", "82566DC", INTEL_PBS_ERRATA ),
918
+	PCI_ROM ( 0x8086, 0x104c, "82562v", "82562V", INTEL_PBS_ERRATA ),
919
+	PCI_ROM ( 0x8086, 0x104d, "82566mc", "82566MC", INTEL_PBS_ERRATA ),
919
 	PCI_ROM ( 0x8086, 0x105e, "82571eb", "82571EB", 0 ),
920
 	PCI_ROM ( 0x8086, 0x105e, "82571eb", "82571EB", 0 ),
920
 	PCI_ROM ( 0x8086, 0x105f, "82571eb-1", "82571EB", 0 ),
921
 	PCI_ROM ( 0x8086, 0x105f, "82571eb-1", "82571EB", 0 ),
921
 	PCI_ROM ( 0x8086, 0x1060, "82571eb-2", "82571EB", 0 ),
922
 	PCI_ROM ( 0x8086, 0x1060, "82571eb-2", "82571EB", 0 ),
948
 	PCI_ROM ( 0x8086, 0x10bc, "82571eb", "82571EB (Copper)", 0 ),
949
 	PCI_ROM ( 0x8086, 0x10bc, "82571eb", "82571EB (Copper)", 0 ),
949
 	PCI_ROM ( 0x8086, 0x10bd, "82566dm-2", "82566DM-2", 0 ),
950
 	PCI_ROM ( 0x8086, 0x10bd, "82566dm-2", "82566DM-2", 0 ),
950
 	PCI_ROM ( 0x8086, 0x10bf, "82567lf", "82567LF", 0 ),
951
 	PCI_ROM ( 0x8086, 0x10bf, "82567lf", "82567LF", 0 ),
951
-	PCI_ROM ( 0x8086, 0x10c0, "82562v-2", "82562V-2 10/100", 0 ),
952
-	PCI_ROM ( 0x8086, 0x10c2, "82562g-2", "82562G-2 10/100", 0 ),
953
-	PCI_ROM ( 0x8086, 0x10c3, "82562gt-2", "82562GT-2 10/100", 0 ),
954
-	PCI_ROM ( 0x8086, 0x10c4, "82562gt", "82562GT 10/100", 0 ),
955
-	PCI_ROM ( 0x8086, 0x10c5, "82562g", "82562G 10/100", 0 ),
952
+	PCI_ROM ( 0x8086, 0x10c0, "82562v-2", "82562V-2", 0 ),
953
+	PCI_ROM ( 0x8086, 0x10c2, "82562g-2", "82562G-2", 0 ),
954
+	PCI_ROM ( 0x8086, 0x10c3, "82562gt-2", "82562GT-2", 0 ),
955
+	PCI_ROM ( 0x8086, 0x10c4, "82562gt", "82562GT", INTEL_PBS_ERRATA ),
956
+	PCI_ROM ( 0x8086, 0x10c5, "82562g", "82562G", INTEL_PBS_ERRATA ),
956
 	PCI_ROM ( 0x8086, 0x10c9, "82576", "82576", 0 ),
957
 	PCI_ROM ( 0x8086, 0x10c9, "82576", "82576", 0 ),
957
 	PCI_ROM ( 0x8086, 0x10cb, "82567v", "82567V", 0 ),
958
 	PCI_ROM ( 0x8086, 0x10cb, "82567v", "82567V", 0 ),
958
 	PCI_ROM ( 0x8086, 0x10cc, "82567lm-2", "82567LM-2", 0 ),
959
 	PCI_ROM ( 0x8086, 0x10cc, "82567lm-2", "82567LM-2", 0 ),
975
 	PCI_ROM ( 0x8086, 0x10f0, "82578dc", "82578DC", 0 ),
976
 	PCI_ROM ( 0x8086, 0x10f0, "82578dc", "82578DC", 0 ),
976
 	PCI_ROM ( 0x8086, 0x10f5, "82567lm", "82567LM", 0 ),
977
 	PCI_ROM ( 0x8086, 0x10f5, "82567lm", "82567LM", 0 ),
977
 	PCI_ROM ( 0x8086, 0x10f6, "82574l", "82574L", 0 ),
978
 	PCI_ROM ( 0x8086, 0x10f6, "82574l", "82574L", 0 ),
978
-	PCI_ROM ( 0x8086, 0x1501, "82567v-3", "82567V-3", 0 ),
979
+	PCI_ROM ( 0x8086, 0x1501, "82567v-3", "82567V-3", INTEL_PBS_ERRATA ),
979
 	PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", 0 ),
980
 	PCI_ROM ( 0x8086, 0x1502, "82579lm", "82579LM", 0 ),
980
 	PCI_ROM ( 0x8086, 0x1503, "82579v", "82579V", 0 ),
981
 	PCI_ROM ( 0x8086, 0x1503, "82579v", "82579V", 0 ),
981
 	PCI_ROM ( 0x8086, 0x150a, "82576ns", "82576NS", 0 ),
982
 	PCI_ROM ( 0x8086, 0x150a, "82576ns", "82576NS", 0 ),

+ 8
- 0
src/drivers/net/intel.h View File

229
 	void *regs;
229
 	void *regs;
230
 	/** Port number (for multi-port devices) */
230
 	/** Port number (for multi-port devices) */
231
 	unsigned int port;
231
 	unsigned int port;
232
+	/** Flags */
233
+	unsigned int flags;
232
 
234
 
233
 	/** EEPROM */
235
 	/** EEPROM */
234
 	struct nvs_device eeprom;
236
 	struct nvs_device eeprom;
245
 	struct io_buffer *rx_iobuf[INTEL_NUM_RX_DESC];
247
 	struct io_buffer *rx_iobuf[INTEL_NUM_RX_DESC];
246
 };
248
 };
247
 
249
 
250
+/** Driver flags */
251
+enum intel_flags {
252
+	/** PBS/PBA errata workaround required */
253
+	INTEL_PBS_ERRATA = 0x0001,
254
+};
255
+
248
 extern int intel_create_ring ( struct intel_nic *intel,
256
 extern int intel_create_ring ( struct intel_nic *intel,
249
 			       struct intel_ring *ring );
257
 			       struct intel_ring *ring );
250
 extern void intel_destroy_ring ( struct intel_nic *intel,
258
 extern void intel_destroy_ring ( struct intel_nic *intel,

Loading…
Cancel
Save