netdev_info(dev, "Xircom cardbus revision %i at irq %i\n",
pdev->revision, pdev->irq); /* start the transmitter to get a heartbeat */ /* TODO: send 2 dummy packets here */
transceiver_voodoo(private);
#ifdefined DEBUG && DEBUG > 1
print_binary(status);
pr_debug("tx status 0x%08x 0x%08x\n",
card->tx_buffer[0], card->tx_buffer[4]);
pr_debug("rx status 0x%08x 0x%08x\n",
card->rx_buffer[0], card->rx_buffer[4]); #endif /* Handle shared irq and hotplug */ if (status == 0 || status == 0xffffffff) {
spin_unlock(&card->lock); return IRQ_NONE;
}
if (link_status_changed(card)) { int newlink;
netdev_dbg(dev, "Link status has changed\n");
newlink = link_status(card);
netdev_info(dev, "Link is %d mbit\n", newlink); if (newlink)
netif_carrier_on(dev); else
netif_carrier_off(dev);
}
/* Clear all remaining interrupts */
status |= 0xffffffff; /* FIXME: make this clear only the
real existing bits */
xw32(CSR5, status);
for (i=0;i<NUMDESCRIPTORS;i++)
investigate_write_descriptor(dev,card,i,bufferoffsets[i]); for (i=0;i<NUMDESCRIPTORS;i++)
investigate_read_descriptor(dev,card,i,bufferoffsets[i]);
spin_unlock(&card->lock); return IRQ_HANDLED;
}
static netdev_tx_t xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ struct xircom_private *card; unsignedlong flags; int nextdescriptor; int desc;
/* First see if we can free some descriptors */ for (desc=0;desc<NUMDESCRIPTORS;desc++)
investigate_write_descriptor(dev,card,desc,bufferoffsets[desc]);
/* only send the packet if the descriptor is free */ if (card->tx_buffer[4*desc]==0) { /* Copy the packet data; zero the memory first as the card
sometimes sends more than you ask it to. */
memset(&card->tx_buffer[bufferoffsets[desc]/4],0,1536);
skb_copy_from_linear_data(skb,
&(card->tx_buffer[bufferoffsets[desc] / 4]),
skb->len); /* FIXME: The specification tells us that the length we send HAS to be a multiple of
4 bytes. */
card->tx_buffer[4*desc+1] = cpu_to_le32(skb->len); if (desc == NUMDESCRIPTORS - 1) /* bit 25: last descriptor of the ring */
card->tx_buffer[4*desc+1] |= cpu_to_le32(1<<25);
wmb(); /* This gives the descriptor to the card */
card->tx_buffer[4*desc] = cpu_to_le32(0x80000000);
trigger_transmit(card); if (card->tx_buffer[nextdescriptor*4] & cpu_to_le32(0x8000000)) { /* next descriptor is occupied... */
netif_stop_queue(dev);
}
card->transmit_used = nextdescriptor;
spin_unlock_irqrestore(&card->lock,flags); return NETDEV_TX_OK;
}
/* Uh oh... no free descriptor... drop the packet */
netif_stop_queue(dev);
spin_unlock_irqrestore(&card->lock,flags);
trigger_transmit(card);
card = netdev_priv(dev);
netif_stop_queue(dev); /* we don't want new packets */
spin_lock_irqsave(&card->lock,flags);
disable_all_interrupts(card); #if0 /* We can enable this again once we send dummy packets on ifconfig ethX up */
deactivate_receiver(card);
deactivate_transmitter(card); #endif
remove_descriptors(card);
wmb(); /* Write the receive descriptor ring address to the card */
address = card->rx_dma_handle;
xw32(CSR3, address); /* Receive descr list address */
for (i=0;i<NUMDESCRIPTORS;i++ ) { /* Tx Descr0: Empty, we own it, no errors -> 0x00000000 */
card->tx_buffer[i*4 + 0] = 0x00000000; /* Tx Descr1: buffer 1 is 1536 bytes, buffer 2 is 0 bytes */
card->tx_buffer[i*4 + 1] = cpu_to_le32(1536); if (i == NUMDESCRIPTORS - 1) /* bit 25 is "last descriptor" */
card->tx_buffer[i*4 + 1] |= cpu_to_le32(1 << 25);
/* Tx Descr2: address of the buffer
we store the buffer at the 2nd half of the page */
address = card->tx_dma_handle;
card->tx_buffer[i*4 + 2] = cpu_to_le32(address + bufferoffsets[i]); /* Tx Desc3: address of 2nd buffer -> 0 */
card->tx_buffer[i*4 + 3] = 0;
}
wmb(); /* wite the transmit descriptor ring to the card */
address = card->tx_dma_handle;
xw32(CSR4, address); /* xmit descr list address */
}
/* If the "active" bit is set and the receiver is already
active, no need to do the expensive thing */ if ((val&2) && (receive_active(card))) return;
val = val & ~2; /* disable the receiver */
xw32(CSR6, val);
counter = 10; while (counter > 0) { if (!receive_active(card)) break; /* wait a while */
udelay(50);
counter--; if (counter <= 0)
netdev_err(card->dev, "Receiver failed to deactivate\n");
}
/* enable the receiver */
val = xr32(CSR6); /* Operation mode */
val = val | 2; /* enable the receiver */
xw32(CSR6, val);
/* now wait for the card to activate again */
counter = 10; while (counter > 0) { if (receive_active(card)) break; /* wait a while */
udelay(50);
counter--; if (counter <= 0)
netdev_err(card->dev, "Receiver failed to re-activate\n");
}
}
val = xr32(CSR6); /* Operation mode */
val = val & ~2; /* disable the receiver */
xw32(CSR6, val);
counter = 10; while (counter > 0) { if (!receive_active(card)) break; /* wait a while */
udelay(50);
counter--; if (counter <= 0)
netdev_err(card->dev, "Receiver failed to deactivate\n");
}
}
/* If the "active" bit is set and the receiver is already
active, no need to do the expensive thing */ if ((val&(1<<13)) && (transmit_active(card))) return;
val = val & ~(1 << 13); /* disable the transmitter */
xw32(CSR6, val);
counter = 10; while (counter > 0) { if (!transmit_active(card)) break; /* wait a while */
udelay(50);
counter--; if (counter <= 0)
netdev_err(card->dev, "Transmitter failed to deactivate\n");
}
/* enable the transmitter */
val = xr32(CSR6); /* Operation mode */
val = val | (1 << 13); /* enable the transmitter */
xw32(CSR6, val);
/* now wait for the card to activate again */
counter = 10; while (counter > 0) { if (transmit_active(card)) break; /* wait a while */
udelay(50);
counter--; if (counter <= 0)
netdev_err(card->dev, "Transmitter failed to re-activate\n");
}
}
val = xr32(CSR6); /* Operation mode */
val = val & ~2; /* disable the transmitter */
xw32(CSR6, val);
counter = 20; while (counter > 0) { if (!transmit_active(card)) break; /* wait a while */
udelay(50);
counter--; if (counter <= 0)
netdev_err(card->dev, "Transmitter failed to deactivate\n");
}
}
/* bit 2 is 0 for 10mbit link, 1 for not an 10mbit link */ if (!(val & (1 << 2))) return10; /* bit 1 is 0 for 100mbit link, 1 for not an 100mbit link */ if (!(val & (1 << 1))) return100;
/* The card can have received packets already, read them away now */ for (i=0;i<NUMDESCRIPTORS;i++)
investigate_read_descriptor(card->dev,card,i,bufferoffsets[i]);
/* Bufferoffset is in BYTES */ staticvoid
investigate_read_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsignedint bufferoffset)
{ int status;
status = le32_to_cpu(card->rx_buffer[4*descnr]);
if (status > 0) { /* packet received */
/* TODO: discard error packets */
short pkt_len = ((status >> 16) & 0x7ff) - 4; /* minus 4, we don't want the CRC */ struct sk_buff *skb;
if (pkt_len > 1518) {
netdev_err(dev, "Packet length %i is bogus\n", pkt_len);
pkt_len = 1518;
}
out: /* give the buffer back to the card */
card->rx_buffer[4*descnr] = cpu_to_le32(0x80000000);
trigger_receive(card);
}
}
/* Bufferoffset is in BYTES */ staticvoid
investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsignedint bufferoffset)
{ int status;
status = le32_to_cpu(card->tx_buffer[4*descnr]); #if0 if (status & 0x8000) { /* Major error */
pr_err("Major transmit error status %x\n", status);
card->tx_buffer[4*descnr] = 0;
netif_wake_queue (dev);
} #endif if (status > 0) { /* bit 31 is 0 when done */ if (card->tx_skb[descnr]!=NULL) {
dev->stats.tx_bytes += card->tx_skb[descnr]->len;
dev_kfree_skb_irq(card->tx_skb[descnr]);
}
card->tx_skb[descnr] = NULL; /* Bit 8 in the status field is 1 if there was a collision */ if (status & (1 << 8))
dev->stats.collisions++;
card->tx_buffer[4*descnr] = 0; /* descriptor is free again */
netif_wake_queue (dev);
dev->stats.tx_packets++;
}
}
module_pci_driver(xircom_driver);
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet am 2026-10-04)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.