mirror of https://github.com/ipxe/ipxe.git
[intel] Reset all virtual function settings
Some VF data is not cleared with reset, so make sure to return all the settings to default before configuring the VF. This fixes an issue where network packets would fail to be received if the VF was previously used by the linux ixgbevf driver. Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/58/merge
parent
9db9221ea0
commit
1d04900262
|
@ -424,6 +424,61 @@ void intel_describe_rx ( struct intel_descriptor *rx, physaddr_t addr,
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Disable descriptor ring
|
||||
*
|
||||
* @v intel Intel device
|
||||
* @v reg Register block
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int intel_disable_ring ( struct intel_nic *intel, unsigned int reg ) {
|
||||
uint32_t dctl;
|
||||
unsigned int i;
|
||||
|
||||
/* Disable ring */
|
||||
writel ( 0, ( intel->regs + reg + INTEL_xDCTL ) );
|
||||
|
||||
/* Wait for disable to complete */
|
||||
for ( i = 0 ; i < INTEL_DISABLE_MAX_WAIT_MS ; i++ ) {
|
||||
|
||||
/* Check if ring is disabled */
|
||||
dctl = readl ( intel->regs + reg + INTEL_xDCTL );
|
||||
if ( ! ( dctl & INTEL_xDCTL_ENABLE ) )
|
||||
return 0;
|
||||
|
||||
/* Delay */
|
||||
mdelay ( 1 );
|
||||
}
|
||||
|
||||
DBGC ( intel, "INTEL %p ring %05x timed out waiting for disable "
|
||||
"(dctl %08x)\n", intel, reg, dctl );
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset descriptor ring
|
||||
*
|
||||
* @v intel Intel device
|
||||
* @v reg Register block
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
void intel_reset_ring ( struct intel_nic *intel, unsigned int reg ) {
|
||||
|
||||
/* Disable ring. Ignore errors and continue to reset the ring anyway */
|
||||
intel_disable_ring ( intel, reg );
|
||||
|
||||
/* Clear ring length */
|
||||
writel ( 0, ( intel->regs + reg + INTEL_xDLEN ) );
|
||||
|
||||
/* Clear ring address */
|
||||
writel ( 0, ( intel->regs + reg + INTEL_xDBAH ) );
|
||||
writel ( 0, ( intel->regs + reg + INTEL_xDBAL ) );
|
||||
|
||||
/* Reset head and tail pointers */
|
||||
writel ( 0, ( intel->regs + reg + INTEL_xDH ) );
|
||||
writel ( 0, ( intel->regs + reg + INTEL_xDT ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create descriptor ring
|
||||
*
|
||||
|
@ -484,12 +539,8 @@ int intel_create_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
|
|||
*/
|
||||
void intel_destroy_ring ( struct intel_nic *intel, struct intel_ring *ring ) {
|
||||
|
||||
/* Clear ring length */
|
||||
writel ( 0, ( intel->regs + ring->reg + INTEL_xDLEN ) );
|
||||
|
||||
/* Clear ring address */
|
||||
writel ( 0, ( intel->regs + ring->reg + INTEL_xDBAL ) );
|
||||
writel ( 0, ( intel->regs + ring->reg + INTEL_xDBAH ) );
|
||||
/* Reset ring */
|
||||
intel_reset_ring ( intel, ring->reg );
|
||||
|
||||
/* Free descriptor ring */
|
||||
free_dma ( ring->desc, ring->len );
|
||||
|
|
|
@ -185,6 +185,9 @@ struct intel_descriptor {
|
|||
#define INTEL_xDCTL 0x28
|
||||
#define INTEL_xDCTL_ENABLE 0x02000000UL /**< Queue enable */
|
||||
|
||||
/** Maximum time to wait for queue disable, in milliseconds */
|
||||
#define INTEL_DISABLE_MAX_WAIT_MS 100
|
||||
|
||||
/** Receive Address Low */
|
||||
#define INTEL_RAL0 0x05400UL
|
||||
|
||||
|
@ -330,6 +333,7 @@ extern void intel_describe_tx_adv ( struct intel_descriptor *tx,
|
|||
physaddr_t addr, size_t len );
|
||||
extern void intel_describe_rx ( struct intel_descriptor *rx,
|
||||
physaddr_t addr, size_t len );
|
||||
extern void intel_reset_ring ( struct intel_nic *intel, unsigned int reg );
|
||||
extern int intel_create_ring ( struct intel_nic *intel,
|
||||
struct intel_ring *ring );
|
||||
extern void intel_destroy_ring ( struct intel_nic *intel,
|
||||
|
|
|
@ -216,6 +216,7 @@ static int intelxvf_open ( struct net_device *netdev ) {
|
|||
uint32_t rxdctl;
|
||||
uint32_t srrctl;
|
||||
uint32_t dca_rxctrl;
|
||||
unsigned int i;
|
||||
int vlan_thing;
|
||||
int rc;
|
||||
|
||||
|
@ -252,6 +253,15 @@ static int intelxvf_open ( struct net_device *netdev ) {
|
|||
goto err_mbox_set_mtu;
|
||||
}
|
||||
|
||||
/* Reset all descriptor rings */
|
||||
for ( i = 0 ; i < INTELXVF_NUM_RINGS ; i++ ) {
|
||||
intel_reset_ring ( intel, INTELXVF_TD ( i ) );
|
||||
intel_reset_ring ( intel, INTELXVF_RD ( i ) );
|
||||
}
|
||||
|
||||
/* Reset packet split receive type register */
|
||||
writel ( 0, intel->regs + INTELXVF_PSRTYPE );
|
||||
|
||||
/* Get queue configuration. Ignore failures, since the host
|
||||
* may not support this message.
|
||||
*/
|
||||
|
@ -260,9 +270,9 @@ static int intelxvf_open ( struct net_device *netdev ) {
|
|||
if ( vlan_thing ) {
|
||||
DBGC ( intel, "INTEL %p stripping VLAN tags (thing=%d)\n",
|
||||
intel, vlan_thing );
|
||||
rxdctl = readl ( intel->regs + INTELXVF_RD + INTEL_xDCTL );
|
||||
rxdctl = readl ( intel->regs + INTELXVF_RD(0) + INTEL_xDCTL );
|
||||
rxdctl |= INTELX_RXDCTL_VME;
|
||||
writel ( rxdctl, intel->regs + INTELXVF_RD + INTEL_xDCTL );
|
||||
writel ( rxdctl, intel->regs + INTELXVF_RD(0) + INTEL_xDCTL );
|
||||
}
|
||||
|
||||
/* Create transmit descriptor ring */
|
||||
|
@ -283,9 +293,12 @@ static int intelxvf_open ( struct net_device *netdev ) {
|
|||
/* Configure receive buffer sizes and set receive descriptor type */
|
||||
srrctl = readl ( intel->regs + INTELXVF_SRRCTL );
|
||||
srrctl &= ~( INTELXVF_SRRCTL_BSIZE_MASK |
|
||||
INTELXVF_SRRCTL_BHDRSIZE_MASK |
|
||||
INTELXVF_SRRCTL_DESCTYPE_MASK );
|
||||
srrctl |= ( INTELXVF_SRRCTL_BSIZE_DEFAULT |
|
||||
INTELXVF_SRRCTL_DESCTYPE_DEFAULT );
|
||||
INTELXVF_SRRCTL_BHDRSIZE_DEFAULT |
|
||||
INTELXVF_SRRCTL_DESCTYPE_DEFAULT |
|
||||
INTELXVF_SRRCTL_DROP_EN );
|
||||
writel ( srrctl, intel->regs + INTELXVF_SRRCTL );
|
||||
|
||||
/* Clear "must-be-zero" bit for direct cache access (DCA). We
|
||||
|
@ -434,9 +447,9 @@ static int intelxvf_probe ( struct pci_device *pci ) {
|
|||
netdev->dev = &pci->dev;
|
||||
memset ( intel, 0, sizeof ( *intel ) );
|
||||
intel_init_mbox ( &intel->mbox, INTELXVF_MBCTRL, INTELXVF_MBMEM );
|
||||
intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD,
|
||||
intel_init_ring ( &intel->tx, INTEL_NUM_TX_DESC, INTELXVF_TD(0),
|
||||
intel_describe_tx_adv );
|
||||
intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD,
|
||||
intel_init_ring ( &intel->rx, INTEL_NUM_RX_DESC, INTELXVF_RD(0),
|
||||
intel_describe_rx );
|
||||
|
||||
/* Fix up PCI device */
|
||||
|
|
|
@ -55,8 +55,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
/** Mailbox Control Register */
|
||||
#define INTELXVF_MBCTRL 0x02fcUL
|
||||
|
||||
/** Packet Split Receive Type */
|
||||
#define INTELXVF_PSRTYPE 0x0300UL
|
||||
|
||||
/** Receive Descriptor register block */
|
||||
#define INTELXVF_RD 0x1000UL
|
||||
#define INTELXVF_RD(n) ( 0x1000UL + ( 0x40 * (n) ) )
|
||||
|
||||
/** RX DCA Control Register */
|
||||
#define INTELXVF_DCA_RXCTRL 0x100cUL
|
||||
|
@ -67,9 +70,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define INTELXVF_SRRCTL_BSIZE(kb) ( (kb) << 0 ) /**< Receive buffer size */
|
||||
#define INTELXVF_SRRCTL_BSIZE_DEFAULT INTELXVF_SRRCTL_BSIZE ( 0x02 )
|
||||
#define INTELXVF_SRRCTL_BSIZE_MASK INTELXVF_SRRCTL_BSIZE ( 0x1f )
|
||||
#define INTELXVF_SRRCTL_BHDRSIZE(kb) ( (kb) << 8 ) /**< Header size */
|
||||
#define INTELXVF_SRRCTL_BHDRSIZE_DEFAULT INTELXVF_SRRCTL_BHDRSIZE ( 0x04 )
|
||||
#define INTELXVF_SRRCTL_BHDRSIZE_MASK INTELXVF_SRRCTL_BHDRSIZE ( 0x0f )
|
||||
#define INTELXVF_SRRCTL_DESCTYPE(typ) ( (typ) << 25 ) /**< Descriptor type */
|
||||
#define INTELXVF_SRRCTL_DESCTYPE_DEFAULT INTELXVF_SRRCTL_DESCTYPE ( 0x00 )
|
||||
#define INTELXVF_SRRCTL_DESCTYPE_MASK INTELXVF_SRRCTL_DESCTYPE ( 0x07 )
|
||||
#define INTELXVF_SRRCTL_DROP_EN 0x10000000UL
|
||||
|
||||
/** Good Packets Received Count */
|
||||
#define INTELXVF_GPRC 0x101c
|
||||
|
@ -84,7 +91,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#define INTELXVF_MPRC 0x1034
|
||||
|
||||
/** Transmit Descriptor register block */
|
||||
#define INTELXVF_TD 0x2000UL
|
||||
#define INTELXVF_TD(n) ( 0x2000UL + ( 0x40 * (n) ) )
|
||||
|
||||
/** Good Packets Transmitted Count */
|
||||
#define INTELXVF_GPTC 0x201c
|
||||
|
@ -101,4 +108,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
/** API version 1.1 */
|
||||
#define INTELXVF_MSG_VERSION_1_1 0x00000002UL
|
||||
|
||||
/** Number of queues */
|
||||
#define INTELXVF_NUM_RINGS 8
|
||||
|
||||
#endif /* _INTELXVF_H */
|
||||
|
|
Loading…
Reference in New Issue