Newer
Older
int rc, unit, pci_bar;
struct vortex_chip_info *vci;
void __iomem *ioaddr;
unit = vortex_cards_found;
if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
/* Determine the default if the user didn't override us */
vci = &vortex_info_tbl[ent->driver_data];
pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;
} else if (unit < MAX_UNITS && use_mmio[unit] >= 0)
pci_bar = use_mmio[unit] ? 1 : 0;
else
pci_bar = global_use_mmio ? 1 : 0;
ioaddr = pci_iomap(pdev, pci_bar, 0);
if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
ioaddr = pci_iomap(pdev, 0, 0);
if (!ioaddr) {
pci_disable_device(pdev);
rc = -ENOMEM;
goto out;
}
rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
ent->driver_data, unit);
goto out;
}
vortex_cards_found++;
out:
return rc;
}
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
static const struct net_device_ops boomrang_netdev_ops = {
.ndo_open = vortex_open,
.ndo_stop = vortex_close,
.ndo_start_xmit = boomerang_start_xmit,
.ndo_tx_timeout = vortex_tx_timeout,
.ndo_get_stats = vortex_get_stats,
#ifdef CONFIG_PCI
.ndo_do_ioctl = vortex_ioctl,
#endif
.ndo_set_multicast_list = set_rx_mode,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = poll_vortex,
#endif
};
static const struct net_device_ops vortex_netdev_ops = {
.ndo_open = vortex_open,
.ndo_stop = vortex_close,
.ndo_start_xmit = vortex_start_xmit,
.ndo_tx_timeout = vortex_tx_timeout,
.ndo_get_stats = vortex_get_stats,
#ifdef CONFIG_PCI
.ndo_do_ioctl = vortex_ioctl,
#endif
.ndo_set_multicast_list = set_rx_mode,
.ndo_change_mtu = eth_change_mtu,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = poll_vortex,
#endif
};
/*
* Start up the PCI/EISA device which is described by *gendev.
* Return 0 on success.
*
* NOTE: pdev can be NULL, for the case of a Compaq device
*/
static int __devinit vortex_probe1(struct device *gendev,
void __iomem *ioaddr, int irq,
int chip_idx, int card_idx)
{
struct vortex_private *vp;
int option;
unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */
int i, step;
struct net_device *dev;
static int printed_version;
int retval, print_info;
struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
const char *print_name = "3c59x";
struct pci_dev *pdev = NULL;
struct eisa_device *edev = NULL;
if (!printed_version) {
printed_version = 1;
}
if (gendev) {
if ((pdev = DEVICE_PCI(gendev))) {
print_name = pci_name(pdev);
}
if ((edev = DEVICE_EISA(gendev))) {
print_name = dev_name(&edev->dev);
}
}
dev = alloc_etherdev(sizeof(*vp));
retval = -ENOMEM;
if (!dev) {
pr_err(PFX "unable to allocate etherdev, aborting\n");
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
goto out;
}
SET_NETDEV_DEV(dev, gendev);
vp = netdev_priv(dev);
option = global_options;
/* The lower four bits are the media type. */
if (dev->mem_start) {
/*
* The 'options' param is passed in as the third arg to the
* LILO 'ether=' argument for non-modular use
*/
option = dev->mem_start;
}
else if (card_idx < MAX_UNITS) {
if (options[card_idx] >= 0)
option = options[card_idx];
}
if (option > 0) {
if (option & 0x8000)
vortex_debug = 7;
if (option & 0x4000)
vortex_debug = 2;
if (option & 0x0400)
vp->enable_wol = 1;
}
print_info = (vortex_debug > 1);
if (print_info)
pr_info("See Documentation/networking/vortex.txt\n");
pr_info("%s: 3Com %s %s at %p.\n",
print_name,
pdev ? "PCI" : "EISA",
vci->name,
ioaddr);
dev->base_addr = (unsigned long)ioaddr;
vp->large_frames = mtu > 1500;
vp->drv_flags = vci->drv_flags;
vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
vp->io_size = vci->io_size;
vp->card_idx = card_idx;
vp->window = -1;
/* module list only for Compaq device */
if (gendev == NULL) {
compaq_net_device = dev;
}
/* PCI-only startup logic */
if (pdev) {
/* EISA resources already marked, so only PCI needs to do this here */
/* Ignore return value, because Cardbus drivers already allocate for us */
if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
/* enable bus-mastering if necessary */
if (vci->drv_flags & IS_VORTEX) {
u8 pci_latency;
u8 new_latency = 248;
/* Check the PCI latency value. On the 3c590 series the latency timer
must be set to the maximum value to avoid data corruption that occurs
when the timer expires during a transfer. This bug exists the Vortex
chip only. */
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < new_latency) {
pr_info("%s: Overriding PCI latency timer (CFLT) setting of %d, new value is %d.\n",
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
spin_lock_init(&vp->mii_lock);
spin_lock_init(&vp->window_lock);
vp->gendev = gendev;
vp->mii.dev = dev;
vp->mii.mdio_read = mdio_read;
vp->mii.mdio_write = mdio_write;
vp->mii.phy_id_mask = 0x1f;
vp->mii.reg_num_mask = 0x1f;
/* Makes sure rings are at least 16 byte aligned. */
vp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE
+ sizeof(struct boom_tx_desc) * TX_RING_SIZE,
&vp->rx_ring_dma);
retval = -ENOMEM;
goto free_region;
vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE);
vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE;
/* if we are a PCI driver, we store info in pdev->driver_data
if (pdev)
pci_set_drvdata(pdev, dev);
if (edev)
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
vp->media_override = 7;
if (option >= 0) {
vp->media_override = ((option & 7) == 2) ? 0 : option & 15;
if (vp->media_override != 7)
vp->medialock = 1;
vp->full_duplex = (option & 0x200) ? 1 : 0;
vp->bus_master = (option & 16) ? 1 : 0;
}
if (global_full_duplex > 0)
vp->full_duplex = 1;
if (global_enable_wol > 0)
vp->enable_wol = 1;
if (card_idx < MAX_UNITS) {
if (full_duplex[card_idx] > 0)
vp->full_duplex = 1;
if (flow_ctrl[card_idx] > 0)
vp->flow_ctrl = 1;
if (enable_wol[card_idx] > 0)
vp->enable_wol = 1;
}
vp->mii.force_media = vp->full_duplex;
vp->options = option;
/* Read the station address from the EEPROM. */
{
int base;
if (vci->drv_flags & EEPROM_8BIT)
base = 0x230;
else if (vci->drv_flags & EEPROM_OFFSET)
base = EEPROM_Read + 0x30;
else
base = EEPROM_Read;
for (i = 0; i < 0x40; i++) {
int timer;
window_write16(vp, base + i, 0, Wn0EepromCmd);
/* Pause for at least 162 us. for the read to take place. */
for (timer = 10; timer >= 0; timer--) {
udelay(162);
if ((window_read16(vp, 0, Wn0EepromCmd) &
0x8000) == 0)
eeprom[i] = window_read16(vp, 0, Wn0EepromData);
}
}
for (i = 0; i < 0x18; i++)
checksum ^= eeprom[i];
checksum = (checksum ^ (checksum >> 8)) & 0xff;
if (checksum != 0x00) { /* Grrr, needless incompatible change 3Com. */
while (i < 0x21)
checksum ^= eeprom[i++];
checksum = (checksum ^ (checksum >> 8)) & 0xff;
}
if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
if (print_info)
pr_cont(" %pM", dev->dev_addr);
/* Unfortunately an all zero eeprom passes the checksum and this
gets found in the wild in failure cases. Crypto is hard 8) */
if (!is_valid_ether_addr(dev->dev_addr)) {
retval = -EINVAL;
pr_err("*** EEPROM MAC address is invalid.\n");
goto free_ring; /* With every pack */
}
for (i = 0; i < 6; i++)
window_write8(vp, dev->dev_addr[i], 2, i);
pr_cont(", IRQ %d\n", dev->irq);
pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
step = (window_read8(vp, 4, Wn4_NetDiag) & 0x1e) >> 1;
pr_info(" product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
}
if (pdev && vci->drv_flags & HAS_CB_FNS) {
unsigned short n;
vp->cb_fn_base = pci_iomap(pdev, 2, 0);
if (!vp->cb_fn_base) {
pr_info("%s: CardBus functions mapped %16.16llx->%p\n",
Greg Kroah-Hartman
committed
print_name,
(unsigned long long)pci_resource_start(pdev, 2),
n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010;
if (vp->drv_flags & INVERT_LED_PWR)
n |= 0x10;
if (vp->drv_flags & INVERT_MII_PWR)
n |= 0x4000;
window_write16(vp, n, 2, Wn2_ResetOptions);
window_write16(vp, 0x0800, 0, 0);
}
}
/* Extract our information from the EEPROM data. */
vp->info1 = eeprom[13];
vp->info2 = eeprom[15];
vp->capabilities = eeprom[16];
if (vp->info1 & 0x8000) {
vp->full_duplex = 1;
if (print_info)
pr_info("Full duplex capable\n");
static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
vp->available_media = window_read16(vp, 3, Wn3_Options);
if ((vp->available_media & 0xff) == 0) /* Broken 3c916 */
vp->available_media = 0x40;
config = window_read32(vp, 3, Wn3_Config);
pr_debug(" Internal config register is %4.4x, transceivers %#x.\n",
config, window_read16(vp, 3, Wn3_Options));
pr_info(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
8 << RAM_SIZE(config),
RAM_WIDTH(config) ? "word" : "byte",
ram_split[RAM_SPLIT(config)],
AUTOSELECT(config) ? "autoselect/" : "",
XCVR(config) > XCVR_ExtMII ? "<invalid transceiver>" :
media_tbl[XCVR(config)].name);
}
vp->default_media = XCVR(config);
if (vp->default_media == XCVR_NWAY)
vp->has_nway = 1;
vp->autoselect = AUTOSELECT(config);
}
if (vp->media_override != 7) {
pr_info("%s: Media override to transceiver type %d (%s).\n",
print_name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
} else
dev->if_port = vp->default_media;
if ((vp->available_media & 0x40) || (vci->drv_flags & HAS_NWAY) ||
dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
int phy, phy_idx = 0;
mii_preamble_required++;
if (vp->drv_flags & EXTRA_PREAMBLE)
mii_preamble_required++;
mdio_sync(vp, 32);
mdio_read(dev, 24, MII_BMSR);
for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
int mii_status, phyx;
/*
* For the 3c905CX we look at index 24 first, because it bogusly
* reports an external PHY at all indices
*/
if (phy == 0)
phyx = 24;
else if (phy <= 24)
phyx = phy - 1;
else
phyx = phy;
mii_status = mdio_read(dev, phyx, MII_BMSR);
if (mii_status && mii_status != 0xffff) {
vp->phys[phy_idx++] = phyx;
if (print_info) {
pr_info(" MII transceiver found at address %d, status %4x.\n",
phyx, mii_status);
}
if ((mii_status & 0x0040) == 0)
mii_preamble_required++;
}
}
mii_preamble_required--;
if (phy_idx == 0) {
pr_warning(" ***WARNING*** No MII transceivers found!\n");
vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
if (vp->full_duplex) {
/* Only advertise the FD media types. */
vp->advertising &= ~0x02A0;
mdio_write(dev, vp->phys[0], 4, vp->advertising);
}
}
vp->mii.phy_id = vp->phys[0];
}
if (vp->capabilities & CapBusMaster) {
vp->full_bus_master_tx = 1;
if (print_info) {
pr_info(" Enabling bus-master transmits and %s receives.\n",
(vp->info2 & 1) ? "early" : "whole-frame" );
}
vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
vp->bus_master = 0; /* AKPM: vortex only */
}
/* The 3c59x-specific entries in the device structure. */
if (vp->full_bus_master_tx) {
dev->netdev_ops = &boomrang_netdev_ops;
if (card_idx < MAX_UNITS &&
((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
hw_checksums[card_idx] == 1)) {
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
} else
dev->netdev_ops = &vortex_netdev_ops;
pr_info("%s: scatter/gather %sabled. h/w checksums %sabled\n",
print_name,
(dev->features & NETIF_F_SG) ? "en":"dis",
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
}
dev->ethtool_ops = &vortex_ethtool_ops;
dev->watchdog_timeo = (watchdog * HZ) / 1000;
if (pdev) {
vp->pm_state_valid = 1;
pci_save_state(VORTEX_PCI(vp));
acpi_set_WOL(dev);
}
retval = register_netdev(dev);
if (retval == 0)
return 0;
free_ring:
pci_free_consistent(pdev,
sizeof(struct boom_rx_desc) * RX_RING_SIZE
+ sizeof(struct boom_tx_desc) * TX_RING_SIZE,
vp->rx_ring,
vp->rx_ring_dma);
free_region:
if (vp->must_free_region)
release_region(dev->base_addr, vci->io_size);
pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval);
out:
return retval;
}
static void
issue_and_wait(struct net_device *dev, int cmd)
{
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
iowrite16(cmd, ioaddr + EL3_CMD);
if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
return;
}
/* OK, that didn't work. Do it the slow way. One second */
for (i = 0; i < 100000; i++) {
if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
pr_info("%s: command 0x%04x took %d usecs\n",
dev->name, cmd, i * 10);
return;
}
udelay(10);
}
pr_err("%s: command 0x%04x did not complete! Status=0x%x\n",
dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
static void
vortex_set_duplex(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
pr_info("%s: setting %s-duplex.\n",
dev->name, (vp->full_duplex) ? "full" : "half");
/* Set the full-duplex bit. */
window_write16(vp,
((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
(vp->large_frames ? 0x40 : 0) |
((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ?
0x100 : 0),
3, Wn3_MAC_Ctrl);
}
static void vortex_check_media(struct net_device *dev, unsigned int init)
{
struct vortex_private *vp = netdev_priv(dev);
unsigned int ok_to_print = 0;
if (vortex_debug > 3)
ok_to_print = 1;
if (mii_check_media(&vp->mii, ok_to_print, init)) {
vp->full_duplex = vp->mii.full_duplex;
vortex_set_duplex(dev);
} else if (init) {
vortex_set_duplex(dev);
}
}
vortex_up(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
int i, mii_reg1, mii_reg5, err = 0;
if (VORTEX_PCI(vp)) {
pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */
if (vp->pm_state_valid)
pci_restore_state(VORTEX_PCI(vp));
err = pci_enable_device(VORTEX_PCI(vp));
if (err) {
pr_warning("%s: Could not enable device\n",
dev->name);
goto err_out;
}
}
/* Before initializing select the active media port. */
config = window_read32(vp, 3, Wn3_Config);
pr_info("%s: Media override to transceiver %d (%s).\n",
dev->name, vp->media_override,
media_tbl[vp->media_override].name);
dev->if_port = vp->media_override;
} else if (vp->autoselect) {
if (vp->has_nway) {
if (vortex_debug > 1)
pr_info("%s: using NWAY device table, not %d\n",
dev->name, dev->if_port);
dev->if_port = XCVR_NWAY;
} else {
/* Find first available media type, starting with 100baseTx. */
dev->if_port = XCVR_100baseTx;
while (! (vp->available_media & media_tbl[dev->if_port].mask))
dev->if_port = media_tbl[dev->if_port].next;
if (vortex_debug > 1)
pr_info("%s: first available media type: %s\n",
dev->name, media_tbl[dev->if_port].name);
}
} else {
dev->if_port = vp->default_media;
if (vortex_debug > 1)
pr_info("%s: using default media %s\n",
dev->name, media_tbl[dev->if_port].name);
}
init_timer(&vp->timer);
vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
vp->timer.data = (unsigned long)dev;
vp->timer.function = vortex_timer; /* timer handler */
add_timer(&vp->timer);
init_timer(&vp->rx_oom_timer);
vp->rx_oom_timer.data = (unsigned long)dev;
vp->rx_oom_timer.function = rx_oom_timer;
if (vortex_debug > 1)
pr_debug("%s: Initial media type %s.\n",
vp->full_duplex = vp->mii.force_media;
config = BFINS(config, dev->if_port, 20, 4);
if (vortex_debug > 6)
pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config);
window_write32(vp, config, 3, Wn3_Config);
if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
vp->mii.full_duplex = vp->full_duplex;
else
vortex_set_duplex(dev);
issue_and_wait(dev, TxReset);
/*
* Don't reset the PHY - that upsets autonegotiation during DHCP operations.
*/
issue_and_wait(dev, RxReset|0x04);
iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
pr_debug("%s: vortex_up() irq %d media status %4.4x.\n",
dev->name, dev->irq, window_read16(vp, 4, Wn4_Media));
}
/* Set the station address and mask in window 2 each time opened. */
for (i = 0; i < 6; i++)
window_write8(vp, dev->dev_addr[i], 2, i);
window_write16(vp, 0, 2, i);
unsigned short n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010;
if (vp->drv_flags & INVERT_LED_PWR)
n |= 0x10;
if (vp->drv_flags & INVERT_MII_PWR)
n |= 0x4000;
window_write16(vp, n, 2, Wn2_ResetOptions);
}
if (dev->if_port == XCVR_10base2)
/* Start the thinnet transceiver. We should really wait 50ms...*/
iowrite16(StartCoax, ioaddr + EL3_CMD);
window_write16(vp,
(window_read16(vp, 4, Wn4_Media) &
~(Media_10TP|Media_SQE)) |
media_tbl[dev->if_port].media_bits,
4, Wn4_Media);
}
/* Switch to the stats window, and clear all stats by reading. */
iowrite16(StatsDisable, ioaddr + EL3_CMD);
window_read8(vp, 6, i);
window_read16(vp, 6, 10);
window_read16(vp, 6, 12);
/* New: On the Vortex we must also clear the BadSSD counter. */
window_read8(vp, 4, 12);
/* ..and on the Boomerang we enable the extra statistics bits. */
window_write16(vp, 0x0040, 4, Wn4_NetDiag);
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
vp->cur_rx = vp->dirty_rx = 0;
/* Initialize the RxEarly register as recommended. */
iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
iowrite32(0x0020, ioaddr + PktStatus);
iowrite32(vp->rx_ring_dma, ioaddr + UpListPtr);
}
if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */
vp->cur_tx = vp->dirty_tx = 0;
if (vp->drv_flags & IS_BOOMERANG)
iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
/* Clear the Rx, Tx rings. */
for (i = 0; i < RX_RING_SIZE; i++) /* AKPM: this is done in vortex_open, too */
vp->rx_ring[i].status = 0;
for (i = 0; i < TX_RING_SIZE; i++)
vp->tx_skbuff[i] = NULL;
iowrite32(0, ioaddr + DownListPtr);
}
/* Set receiver mode: presumably accept b-case and phys addr only. */
set_rx_mode(dev);
/* enable 802.1q tagged frames */
set_8021q_mode(dev, 1);
iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
/* Allow status bits to be seen. */
vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete|
(vp->full_bus_master_tx ? DownComplete : TxAvailable) |
(vp->full_bus_master_rx ? UpComplete : RxComplete) |
(vp->bus_master ? DMADone : 0);
vp->intr_enable = SetIntrEnb | IntLatch | TxAvailable |
(vp->full_bus_master_rx ? 0 : RxComplete) |
StatsFull | HostError | TxComplete | IntReq
| (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
iowrite16(vp->status_enable, ioaddr + EL3_CMD);
/* Ack all pending events, and set active indicator mask. */
iowrite16(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
if (vp->cb_fn_base) /* The PCMCIA people are idiots. */
iowrite32(0x8000, vp->cb_fn_base + 4);
}
static int
vortex_open(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
int i;
int retval;
/* Use the now-standard shared IRQ implementation. */
if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
}
if (vp->full_bus_master_rx) { /* Boomerang bus master. */
if (vortex_debug > 2)
pr_debug("%s: Filling in the Rx ring.\n", dev->name);
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
vp->rx_ring[i].status = 0; /* Clear complete bit. */
vp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG);
skb = __netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN,
GFP_KERNEL);
vp->rx_skbuff[i] = skb;
if (skb == NULL)
break; /* Bad news! */
skb_reserve(skb, NET_IP_ALIGN); /* Align IP on 16 byte boundaries */
vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
pr_emerg("%s: no memory for rx ring\n", dev->name);
for (j = 0; j < i; j++) {
if (vp->rx_skbuff[j]) {
dev_kfree_skb(vp->rx_skbuff[j]);
vp->rx_skbuff[j] = NULL;
}
}
retval = -ENOMEM;
}
/* Wrap the ring. */
vp->rx_ring[i-1].next = cpu_to_le32(vp->rx_ring_dma);
}
retval = vortex_up(dev);
if (!retval)
goto out;
pr_err("%s: vortex_open() fails: returning %d\n", dev->name, retval);
return retval;
}
static void
vortex_timer(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
int media_status;
pr_debug("%s: Media selection timer tick happened, %s.\n",
pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
media_status = window_read16(vp, 4, Wn4_Media);
switch (dev->if_port) {
case XCVR_10baseT: case XCVR_100baseTx: case XCVR_100baseFx:
if (media_status & Media_LnkBeat) {
netif_carrier_on(dev);
ok = 1;
if (vortex_debug > 1)
pr_debug("%s: Media %s has link beat, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
} else {
netif_carrier_off(dev);
if (vortex_debug > 1) {
pr_debug("%s: Media %s has no link beat, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
}
}
break;
case XCVR_MII: case XCVR_NWAY:
{
ok = 1;
}
break;
default: /* Other media types handled by Tx timeouts. */
if (vortex_debug > 1)
pr_debug("%s: Media %s has no indication, %x.\n",
dev->name, media_tbl[dev->if_port].name, media_status);
ok = 1;
}
if (!netif_carrier_ok(dev))
next_tick = 5*HZ;
if (vp->medialock)
goto leave_media_alone;
spin_lock_irq(&vp->lock);
do {
dev->if_port = media_tbl[dev->if_port].next;
} while ( ! (vp->available_media & media_tbl[dev->if_port].mask));
if (dev->if_port == XCVR_Default) { /* Go back to default. */
dev->if_port = vp->default_media;
if (vortex_debug > 1)
pr_debug("%s: Media selection failing, using default %s port.\n",
dev->name, media_tbl[dev->if_port].name);
} else {
if (vortex_debug > 1)
pr_debug("%s: Media selection failed, now trying %s port.\n",
dev->name, media_tbl[dev->if_port].name);
next_tick = media_tbl[dev->if_port].wait;
}
window_write16(vp,
(media_status & ~(Media_10TP|Media_SQE)) |
media_tbl[dev->if_port].media_bits,
4, Wn4_Media);
config = window_read32(vp, 3, Wn3_Config);
window_write32(vp, config, 3, Wn3_Config);
iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
pr_debug("wrote 0x%08x to Wn3_Config\n", config);
/* AKPM: FIXME: Should reset Rx & Tx here. P60 of 3c90xc.pdf */
spin_unlock_irq(&vp->lock);
}
leave_media_alone:
if (vortex_debug > 2)
pr_debug("%s: Media selection timer finished, %s.\n",
dev->name, media_tbl[dev->if_port].name);
mod_timer(&vp->timer, RUN_AT(next_tick));
if (vp->deferred)
iowrite16(FakeIntr, ioaddr + EL3_CMD);
}
static void vortex_tx_timeout(struct net_device *dev)
{
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
dev->name, ioread8(ioaddr + TxStatus),
ioread16(ioaddr + EL3_STATUS));
pr_err(" diagnostics: net %04x media %04x dma %08x fifo %04x\n",
window_read16(vp, 4, Wn4_NetDiag),
window_read16(vp, 4, Wn4_Media),
ioread32(ioaddr + PktStatus),
window_read16(vp, 4, Wn4_FIFODiag));
if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
pr_err("%s: Transmitter encountered 16 collisions --"
if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
pr_err("%s: Interrupt posted but not delivered --"
" IRQ blocked by another device?\n", dev->name);
/* Bad idea here.. but we might as well handle a few events. */
{
/*
* Block interrupts because vortex_interrupt does a bare spin_lock()
*/
unsigned long flags;
local_irq_save(flags);
if (vp->full_bus_master_tx)
boomerang_interrupt(dev->irq, dev);
vortex_interrupt(dev->irq, dev);
local_irq_restore(flags);
}
}
if (vortex_debug > 0)
dump_tx_ring(dev);
issue_and_wait(dev, TxReset);
pr_debug("%s: Resetting the Tx ring pointer.\n", dev->name);
if (vp->cur_tx - vp->dirty_tx > 0 && ioread32(ioaddr + DownListPtr) == 0)
iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
ioaddr + DownListPtr);
if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE)
netif_wake_queue (dev);
if (vp->drv_flags & IS_BOOMERANG)
iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
iowrite16(DownUnstall, ioaddr + EL3_CMD);
dev->stats.tx_dropped++;
iowrite16(TxEnable, ioaddr + EL3_CMD);
dev->trans_start = jiffies; /* prevent tx timeout */
}
/*
* Handle uncommon interrupt sources. This is a separate routine to minimize
* the cache impact.
*/
static void
vortex_error(struct net_device *dev, int status)
{
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
int do_tx_reset = 0, reset_mask = 0;
unsigned char tx_status = 0;
if (vortex_debug > 2) {
pr_err("%s: vortex_error(), status=0x%x\n", dev->name, status);
}
if (status & TxComplete) { /* Really "TxError" for us. */
tx_status = ioread8(ioaddr + TxStatus);
/* Presumably a tx-timeout. We must merely re-enable. */
if (vortex_debug > 2 ||
(tx_status != 0x88 && vortex_debug > 0)) {
pr_err("%s: Transmit error, Tx status register %2.2x.\n",
pr_err("Probably a duplex mismatch. See "
"Documentation/networking/vortex.txt\n");
}
dump_tx_ring(dev);
}
if (tx_status & 0x14) dev->stats.tx_fifo_errors++;
if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
if (tx_status & 0x08) vp->xstats.tx_max_collisions++;
iowrite8(0, ioaddr + TxStatus);
if (tx_status & 0x30) { /* txJabber or txUnderrun */
do_tx_reset = 1;
} else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */
do_tx_reset = 1;
reset_mask = 0x0108; /* Reset interface logic, but not download logic */
} else { /* Merely re-enable the transmitter. */
iowrite16(TxEnable, ioaddr + EL3_CMD);
if (status & RxEarly) /* Rx early is unused. */
iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);