module_param(rx_copybreak, int, 0644);
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
module_param(rx_copybreak, int, 0644);
MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
-static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info);
+static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr,
+ const struct velocity_info_tbl *info);
static int velocity_get_pci_info(struct velocity_info *, struct pci_dev *pdev);
static void velocity_print_info(struct velocity_info *vptr);
static int velocity_open(struct net_device *dev);
static int velocity_change_mtu(struct net_device *dev, int mtu);
static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
static int velocity_get_pci_info(struct velocity_info *, struct pci_dev *pdev);
static void velocity_print_info(struct velocity_info *vptr);
static int velocity_open(struct net_device *dev);
static int velocity_change_mtu(struct net_device *dev, int mtu);
static int velocity_xmit(struct sk_buff *skb, struct net_device *dev);
static void velocity_set_multi(struct net_device *dev);
static struct net_device_stats *velocity_get_stats(struct net_device *dev);
static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static void velocity_set_multi(struct net_device *dev);
static struct net_device_stats *velocity_get_stats(struct net_device *dev);
static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
static int velocity_resume(struct pci_dev *pdev);
static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
static int velocity_resume(struct pci_dev *pdev);
static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
static struct notifier_block velocity_inetaddr_notifier = {
.notifier_call = velocity_netdev_event,
};
static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
static struct notifier_block velocity_inetaddr_notifier = {
.notifier_call = velocity_netdev_event,
};
static void velocity_register_notifier(void)
{
register_inetaddr_notifier(&velocity_inetaddr_notifier);
static void velocity_register_notifier(void)
{
register_inetaddr_notifier(&velocity_inetaddr_notifier);
#define velocity_register_notifier() do {} while (0)
#define velocity_unregister_notifier() do {} while (0)
#define velocity_register_notifier() do {} while (0)
#define velocity_unregister_notifier() do {} while (0)
-static struct velocity_info_tbl chip_info_table[] = {
- {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 256, 1, 0x00FFFFFFUL},
- {0, NULL}
+static const struct velocity_info_tbl chip_info_table[] __devinitdata = {
+ {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 1, 0x00FFFFFFUL},
+ { }
-static struct pci_device_id velocity_id_table[] __devinitdata = {
- {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X,
- PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) chip_info_table},
- {0, }
+static const struct pci_device_id velocity_id_table[] __devinitdata = {
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) },
+ { }
static void __devexit velocity_remove1(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
static void __devexit velocity_remove1(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
devname, name, val ? "TRUE" : "FALSE");
*opt |= (val ? flag : 0);
}
devname, name, val ? "TRUE" : "FALSE");
*opt |= (val ? flag : 0);
}
VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
vptr->wol_opts = vptr->options.wol_opts;
vptr->flags = vptr->options.flags | (info->flags & 0xFF000000UL);
vptr->wol_opts = vptr->options.wol_opts;
velocity_print_info(vptr);
pci_set_drvdata(pdev, dev);
velocity_print_info(vptr);
pci_set_drvdata(pdev, dev);
struct net_device *dev = vptr->dev;
printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
struct net_device *dev = vptr->dev;
printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
- printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
- dev->name,
- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ dev->name,
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-static void __devinit velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info)
+static void __devinit velocity_init_info(struct pci_dev *pdev,
+ struct velocity_info *vptr,
+ const struct velocity_info_tbl *info)
{
memset(vptr, 0, sizeof(struct velocity_info));
vptr->pdev = pdev;
vptr->chip_id = info->chip_id;
{
memset(vptr, 0, sizeof(struct velocity_info));
vptr->pdev = pdev;
vptr->chip_id = info->chip_id;
vptr->num_txq = info->txqueue;
vptr->multicast_limit = MCAM_SIZE;
spin_lock_init(&vptr->lock);
vptr->num_txq = info->txqueue;
vptr->multicast_limit = MCAM_SIZE;
spin_lock_init(&vptr->lock);
pci_set_master(pdev);
vptr->ioaddr = pci_resource_start(pdev, 0);
vptr->memaddr = pci_resource_start(pdev, 1);
pci_set_master(pdev);
vptr->ioaddr = pci_resource_start(pdev, 0);
vptr->memaddr = pci_resource_start(pdev, 1);
-
- if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO))
- {
- printk(KERN_ERR "%s: region #0 is not an I/O resource, aborting.\n",
- pci_name(pdev));
+
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) {
+ dev_err(&pdev->dev,
+ "region #0 is not an I/O resource, aborting.\n");
- if((pci_resource_flags(pdev, 1) & IORESOURCE_IO))
- {
- printk(KERN_ERR "%s: region #1 is an I/O resource, aborting.\n",
- pci_name(pdev));
+ if ((pci_resource_flags(pdev, 1) & IORESOURCE_IO)) {
+ dev_err(&pdev->dev,
+ "region #1 is an I/O resource, aborting.\n");
- if(pci_resource_len(pdev, 1) < 256)
- {
- printk(KERN_ERR "%s: region #1 is too small.\n",
- pci_name(pdev));
+ if (pci_resource_len(pdev, 1) < VELOCITY_IO_SIZE) {
+ dev_err(&pdev->dev, "region #1 is too small.\n");
vptr->dev->name);
pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
return -ENOMEM;
vptr->dev->name);
pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
return -ENOMEM;
vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
td_info->skb->len, PCI_DMA_TODEVICE);
td_info->skb_dma[i] = (dma_addr_t) NULL;
}
td_info->skb->len, PCI_DMA_TODEVICE);
td_info->skb_dma[i] = (dma_addr_t) NULL;
}
* Free up the transmit ring for this particular velocity adapter.
* We free the ring contents but not the ring itself.
*/
* Free up the transmit ring for this particular velocity adapter.
* We free the ring contents but not the ring itself.
*/
static int velocity_rx_srv(struct velocity_info *vptr, int status)
{
struct net_device_stats *stats = &vptr->stats;
static int velocity_rx_srv(struct velocity_info *vptr, int status)
{
struct net_device_stats *stats = &vptr->stats;
* Process the status bits for the received packet and determine
* if the checksum was computed and verified by the hardware
*/
* Process the status bits for the received packet and determine
* if the checksum was computed and verified by the hardware
*/
static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
{
skb->ip_summed = CHECKSUM_NONE;
if (rd->rdesc1.CSM & CSM_IPKT) {
if (rd->rdesc1.CSM & CSM_IPOK) {
static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
{
skb->ip_summed = CHECKSUM_NONE;
if (rd->rdesc1.CSM & CSM_IPKT) {
if (rd->rdesc1.CSM & CSM_IPOK) {
* A packet has arrived. We process the packet and if appropriate
* pass the frame up the network stack
*/
* A packet has arrived. We process the packet and if appropriate
* pass the frame up the network stack
*/
static int velocity_receive_frame(struct velocity_info *vptr, int idx)
{
void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
static int velocity_receive_frame(struct velocity_info *vptr, int idx)
{
void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
if (rd->rdesc0.RSR & RSR_RL) {
stats->rx_length_errors++;
if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
if (rd->rdesc0.RSR & RSR_RL) {
stats->rx_length_errors++;
static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
{
struct rx_desc *rd = &(vptr->rd_ring[idx]);
static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
{
struct rx_desc *rd = &(vptr->rd_ring[idx]);
skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
rd_info->skb->dev = vptr->dev;
rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
rd_info->skb->dev = vptr->dev;
rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
* theoretically impossible errors but this could be fixed using
* the pci_device_failed logic to bounce the hardware
*
*/
* theoretically impossible errors but this could be fixed using
* the pci_device_failed logic to bounce the hardware
*
*/
BYTE_REG_BITS_ON(TXESR_TDSTR, ®s->TXESR);
writew(TRDCSR_RUN, ®s->TDCSRClr);
netif_stop_queue(vptr->dev);
BYTE_REG_BITS_ON(TXESR_TDSTR, ®s->TXESR);
writew(TRDCSR_RUN, ®s->TDCSRClr);
netif_stop_queue(vptr->dev);
* Release an transmit buffer. If the buffer was preallocated then
* recycle it, if not then unmap the buffer.
*/
* Release an transmit buffer. If the buffer was preallocated then
* recycle it, if not then unmap the buffer.
*/
static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
{
struct sk_buff *skb = tdinfo->skb;
static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *tdinfo)
{
struct sk_buff *skb = tdinfo->skb;
* All the ring allocation and set up is done on open for this
* adapter to minimise memory usage when inactive
*/
* All the ring allocation and set up is done on open for this
* adapter to minimise memory usage when inactive
*/
- ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ,
+ ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED,
* this interface. It gets called on a change by the network layer.
* Return zero for success or negative posix error code.
*/
* this interface. It gets called on a change by the network layer.
* Return zero for success or negative posix error code.
*/
* Shuts down the internal operations of the velocity and
* disables interrupts, autopolling, transmit and receive
*/
* Shuts down the internal operations of the velocity and
* disables interrupts, autopolling, transmit and receive
*/
static void velocity_shutdown(struct velocity_info *vptr)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
static void velocity_shutdown(struct velocity_info *vptr)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
/* Power down the chip */
pci_set_power_state(vptr->pdev, PCI_D3hot);
/* Power down the chip */
pci_set_power_state(vptr->pdev, PCI_D3hot);
* Called by the networ layer to request a packet is queued to
* the velocity. Returns zero on success.
*/
* Called by the networ layer to request a packet is queued to
* the velocity. Returns zero on success.
*/
spin_lock_irqsave(&vptr->lock, flags);
index = vptr->td_curr[qnum];
spin_lock_irqsave(&vptr->lock, flags);
index = vptr->td_curr[qnum];
pktlen = ETH_ZLEN;
memcpy(tdinfo->buf, skb->data, skb->len);
memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
pktlen = ETH_ZLEN;
memcpy(tdinfo->buf, skb->data, skb->len);
memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
memcpy(tdinfo->buf, skb->data, skb->len);
tdinfo->skb_dma[0] = tdinfo->buf_dma;
memcpy(tdinfo->buf, skb->data, skb->len);
tdinfo->skb_dma[0] = tdinfo->buf_dma;
td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
td_ptr->td_buf[0].pa_high = 0;
td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
td_ptr->td_buf[0].pa_high = 0;
td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
struct iphdr *ip = skb->nh.iph;
if (ip->protocol == IPPROTO_TCP)
td_ptr->tdesc1.TCR |= TCR0_TCPCK;
struct iphdr *ip = skb->nh.iph;
if (ip->protocol == IPPROTO_TCP)
td_ptr->tdesc1.TCR |= TCR0_TCPCK;
*
* Called whenever an interrupt is generated by the velocity
* adapter IRQ line. We may not be the source of the interrupt
* and need to identify initially if we are, and if not exit as
* efficiently as possible.
*/
*
* Called whenever an interrupt is generated by the velocity
* adapter IRQ line. We may not be the source of the interrupt
* and need to identify initially if we are, and if not exit as
* efficiently as possible.
*/
while (isr_status != 0) {
mac_write_isr(vptr->mac_regs, isr_status);
if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
while (isr_status != 0) {
mac_write_isr(vptr->mac_regs, isr_status);
if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
struct mac_regs __iomem * regs = vptr->mac_regs;
u8 rx_mode;
int i;
struct dev_mc_list *mclist;
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
struct mac_regs __iomem * regs = vptr->mac_regs;
u8 rx_mode;
int i;
struct dev_mc_list *mclist;
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
writel(0xffffffff, ®s->MARCAM[0]);
writel(0xffffffff, ®s->MARCAM[4]);
rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
writel(0xffffffff, ®s->MARCAM[0]);
writel(0xffffffff, ®s->MARCAM[4]);
rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
* Called when the user issues an ioctl request to the network
* device in question. The velocity interface supports MII.
*/
* Called when the user issues an ioctl request to the network
* device in question. The velocity interface supports MII.
*/
int ret;
/* If we are asked for information and the device is power
saving then we need to bring the device back up to talk to it */
int ret;
/* If we are asked for information and the device is power
saving then we need to bring the device back up to talk to it */
switch (cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCGMIIREG: /* Read MII PHY register. */
switch (cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCGMIIREG: /* Read MII PHY register. */
* Definition for our device driver. The PCI layer interface
* uses this to handle all our card discover and plugging
*/
* Definition for our device driver. The PCI layer interface
* uses this to handle all our card discover and plugging
*/
static struct pci_driver velocity_driver = {
.name = VELOCITY_NAME,
.id_table = velocity_id_table,
static struct pci_driver velocity_driver = {
.name = VELOCITY_NAME,
.id_table = velocity_id_table,
* driver interface for this hardware. This in turn cleans up
* all discovered interfaces before returning from the function
*/
* driver interface for this hardware. This in turn cleans up
* all discovered interfaces before returning from the function
*/
MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
/*
* Turn on ECHODIS bit in NWay-forced full mode and turn it
MII_REG_BITS_OFF((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
/*
* Turn on ECHODIS bit in NWay-forced full mode and turn it
MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
/*
* Turn on ECHODIS bit in NWay-forced full mode and turn it
MII_REG_BITS_ON((ANAR_ASMDIR | ANAR_PAUSE), MII_REG_ANAR, vptr->mac_regs);
/*
* Turn on ECHODIS bit in NWay-forced full mode and turn it
* Perform a single read of an MII 16bit register. Returns zero
* on success or -ETIMEDOUT if the PHY did not respond.
*/
* Perform a single read of an MII 16bit register. Returns zero
* on success or -ETIMEDOUT if the PHY did not respond.
*/
* Perform a single write to an MII 16bit register. Returns zero
* on success or -ETIMEDOUT if the PHY did not respond.
*/
* Perform a single write to an MII 16bit register. Returns zero
* on success or -ETIMEDOUT if the PHY did not respond.
*/
static void mii_set_auto_on(struct velocity_info *vptr)
{
if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
static void mii_set_auto_on(struct velocity_info *vptr)
{
if (MII_REG_BITS_IS_ON(BMCR_AUTO, MII_REG_BMCR, vptr->mac_regs))
* PHY and also velocity hardware setup accordingly. In particular
* we need to set up CD polling and frame bursting.
*/
* PHY and also velocity hardware setup accordingly. In particular
* we need to set up CD polling and frame bursting.
*/
* Called before an ethtool operation. We need to make sure the
* chip is out of D3 state before we poke at it.
*/
* Called before an ethtool operation. We need to make sure the
* chip is out of D3 state before we poke at it.
*/
if (!netif_running(dev))
pci_set_power_state(vptr->pdev, PCI_D3hot);
}
static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
if (!netif_running(dev))
pci_set_power_state(vptr->pdev, PCI_D3hot);
}
static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0;
}
static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0;
}
static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
strcpy(info->driver, VELOCITY_NAME);
strcpy(info->version, VELOCITY_VERSION);
strcpy(info->bus_info, pci_name(vptr->pdev));
strcpy(info->driver, VELOCITY_NAME);
strcpy(info->version, VELOCITY_VERSION);
strcpy(info->bus_info, pci_name(vptr->pdev));
.get_settings = velocity_get_settings,
.set_settings = velocity_set_settings,
.get_drvinfo = velocity_get_drvinfo,
.get_settings = velocity_get_settings,
.set_settings = velocity_set_settings,
.get_drvinfo = velocity_get_drvinfo,
* @context: buffer for stored context
*
* Retrieve the current configuration from the velocity hardware
* @context: buffer for stored context
*
* Retrieve the current configuration from the velocity hardware
static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
{
struct mac_regs __iomem * regs = vptr->mac_regs;
static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
{
struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;
static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr)
{
struct in_ifaddr *ifa = (struct in_ifaddr *) ptr;