mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 08:26:59 +00:00
8139too: Support RX-ALL logic.
This allows the NIC to receive Runts and frames with bad Ethernet Frame Checksums (FCS). Useful to sniffing & diagnosing bad networks. Signed-off-by: Ben Greear <greearb@candelatech.com>
This commit is contained in:
parent
b0d1562c82
commit
d95089dc54
1 changed files with 52 additions and 0 deletions
|
@ -907,6 +907,33 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
|
||||||
return ERR_PTR(rc);
|
return ERR_PTR(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rtl8139_set_features(struct net_device *dev, netdev_features_t features)
|
||||||
|
{
|
||||||
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
|
unsigned long flags;
|
||||||
|
netdev_features_t changed = features ^ dev->features;
|
||||||
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
|
|
||||||
|
if (!(changed & (NETIF_F_RXALL)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tp->lock, flags);
|
||||||
|
|
||||||
|
if (changed & NETIF_F_RXALL) {
|
||||||
|
int rx_mode = tp->rx_config;
|
||||||
|
if (features & NETIF_F_RXALL)
|
||||||
|
rx_mode |= (AcceptErr | AcceptRunt);
|
||||||
|
else
|
||||||
|
rx_mode &= ~(AcceptErr | AcceptRunt);
|
||||||
|
tp->rx_config = rtl8139_rx_config | rx_mode;
|
||||||
|
RTL_W32_F(RxConfig, tp->rx_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&tp->lock, flags);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct net_device_ops rtl8139_netdev_ops = {
|
static const struct net_device_ops rtl8139_netdev_ops = {
|
||||||
.ndo_open = rtl8139_open,
|
.ndo_open = rtl8139_open,
|
||||||
.ndo_stop = rtl8139_close,
|
.ndo_stop = rtl8139_close,
|
||||||
|
@ -921,6 +948,7 @@ static const struct net_device_ops rtl8139_netdev_ops = {
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
.ndo_poll_controller = rtl8139_poll_controller,
|
.ndo_poll_controller = rtl8139_poll_controller,
|
||||||
#endif
|
#endif
|
||||||
|
.ndo_set_features = rtl8139_set_features,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
|
@ -994,6 +1022,8 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
|
||||||
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
|
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
|
||||||
dev->vlan_features = dev->features;
|
dev->vlan_features = dev->features;
|
||||||
|
|
||||||
|
dev->hw_features |= NETIF_F_RXALL;
|
||||||
|
|
||||||
dev->irq = pdev->irq;
|
dev->irq = pdev->irq;
|
||||||
|
|
||||||
/* tp zeroed and aligned in alloc_etherdev */
|
/* tp zeroed and aligned in alloc_etherdev */
|
||||||
|
@ -1978,11 +2008,30 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
|
||||||
if (unlikely((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
|
if (unlikely((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
|
||||||
(rx_size < 8) ||
|
(rx_size < 8) ||
|
||||||
(!(rx_status & RxStatusOK)))) {
|
(!(rx_status & RxStatusOK)))) {
|
||||||
|
if ((dev->features & NETIF_F_RXALL) &&
|
||||||
|
(rx_size <= (MAX_ETH_FRAME_SIZE + 4)) &&
|
||||||
|
(rx_size >= 8) &&
|
||||||
|
(!(rx_status & RxStatusOK))) {
|
||||||
|
/* Length is at least mostly OK, but pkt has
|
||||||
|
* error. I'm hoping we can handle some of these
|
||||||
|
* errors without resetting the chip. --Ben
|
||||||
|
*/
|
||||||
|
dev->stats.rx_errors++;
|
||||||
|
if (rx_status & RxCRCErr) {
|
||||||
|
dev->stats.rx_crc_errors++;
|
||||||
|
goto keep_pkt;
|
||||||
|
}
|
||||||
|
if (rx_status & RxRunt) {
|
||||||
|
dev->stats.rx_length_errors++;
|
||||||
|
goto keep_pkt;
|
||||||
|
}
|
||||||
|
}
|
||||||
rtl8139_rx_err (rx_status, dev, tp, ioaddr);
|
rtl8139_rx_err (rx_status, dev, tp, ioaddr);
|
||||||
received = -1;
|
received = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keep_pkt:
|
||||||
/* Malloc up new buffer, compatible with net-2e. */
|
/* Malloc up new buffer, compatible with net-2e. */
|
||||||
/* Omit the four octet CRC from the length. */
|
/* Omit the four octet CRC from the length. */
|
||||||
|
|
||||||
|
@ -2515,6 +2564,9 @@ static void __set_rx_mode (struct net_device *dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev->features & NETIF_F_RXALL)
|
||||||
|
rx_mode |= (AcceptErr | AcceptRunt);
|
||||||
|
|
||||||
/* We can safely update without stopping the chip. */
|
/* We can safely update without stopping the chip. */
|
||||||
tmp = rtl8139_rx_config | rx_mode;
|
tmp = rtl8139_rx_config | rx_mode;
|
||||||
if (tp->rx_config != tmp) {
|
if (tp->rx_config != tmp) {
|
||||||
|
|
Loading…
Reference in a new issue