#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/version.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <asm/io.h>
MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver");
#define VELOCITY_PARAM(N,D) \
- static const int N[MAX_UNITS]=OPTION_DEFAULT;\
- MODULE_PARM(N, "1-" __MODULE_STRING(MAX_UNITS) "i");\
+ static int N[MAX_UNITS]=OPTION_DEFAULT;\
+ module_param_array(N, int, NULL, 0); \
MODULE_PARM_DESC(N, D);
#define RX_DESC_MIN 64
VELOCITY_PARAM(int_works, "Number of packets per interrupt services");
static int rx_copybreak = 200;
-MODULE_PARM(rx_copybreak, "i");
+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_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *);
static int velocity_soft_reset(struct velocity_info *vptr);
static void mii_init(struct velocity_info *vptr, u32 mii_status);
+static u32 velocity_get_link(struct net_device *dev);
static u32 velocity_get_opt_media_mode(struct velocity_info *vptr);
static void velocity_print_link_status(struct velocity_info *vptr);
-static void safe_disable_mii_autopoll(struct mac_regs * regs);
+static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs);
static void velocity_shutdown(struct velocity_info *vptr);
static void enable_flow_control_ability(struct velocity_info *vptr);
-static void enable_mii_autopoll(struct mac_regs * regs);
-static int velocity_mii_read(struct mac_regs *, u8 byIdx, u16 * pdata);
-static int velocity_mii_write(struct mac_regs *, u8 byMiiAddr, u16 data);
-static u32 mii_check_media_mode(struct mac_regs * regs);
-static u32 check_connection_type(struct mac_regs * regs);
+static void enable_mii_autopoll(struct mac_regs __iomem * regs);
+static int velocity_mii_read(struct mac_regs __iomem *, u8 byIdx, u16 * pdata);
+static int velocity_mii_write(struct mac_regs __iomem *, u8 byMiiAddr, u16 data);
+static u32 mii_check_media_mode(struct mac_regs __iomem * regs);
+static u32 check_connection_type(struct mac_regs __iomem * regs);
static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status);
#ifdef CONFIG_PM
-static int velocity_suspend(struct pci_dev *pdev, u32 state);
+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);
.notifier_call = velocity_netdev_event,
};
-static spinlock_t velocity_dev_list_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(velocity_dev_list_lock);
static LIST_HEAD(velocity_dev_list);
static void velocity_register_notifier(void)
static void velocity_init_cam_filter(struct velocity_info *vptr)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
/* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG);
static void velocity_rx_reset(struct velocity_info *vptr)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
int i;
vptr->rd_dirty = vptr->rd_filled = vptr->rd_curr = 0;
static void velocity_init_registers(struct velocity_info *vptr,
enum velocity_init_type type)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
int i, mii_status;
mac_wol_reset(regs);
static int velocity_soft_reset(struct velocity_info *vptr)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
int i = 0;
writel(CR0_SFRST, ®s->CR0Set);
int i;
struct velocity_info_tbl *info = (struct velocity_info_tbl *) ent->driver_data;
struct velocity_info *vptr;
- struct mac_regs * regs;
+ struct mac_regs __iomem * regs;
int ret = -ENOMEM;
if (velocity_nics >= MAX_UNITS) {
#endif
if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
- dev->features |= NETIF_F_HW_CSUM;
+ dev->features |= NETIF_F_IP_CSUM;
}
ret = register_netdev(dev);
if (ret < 0)
goto err_iounmap;
+ if (velocity_get_link(dev))
+ netif_carrier_off(dev);
+
velocity_print_info(vptr);
pci_set_drvdata(pdev, dev);
/* and leave the chip powered down */
- pci_set_power_state(pdev, 3);
+ pci_set_power_state(pdev, PCI_D3hot);
#ifdef CONFIG_PM
{
unsigned long flags;
static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
{
- struct mac_regs *regs = vptr->mac_regs;
+ struct mac_regs __iomem *regs = vptr->mac_regs;
int avail, dirty, unusable;
/*
for (i = 0; i < vptr->options.numrx; i++) {
struct velocity_rd_info *rd_info = &(vptr->rd_info[i]);
+ struct rx_desc *rd = vptr->rd_ring + i;
+
+ memset(rd, 0, sizeof(*rd));
if (!rd_info->skb)
continue;
velocity_free_td_ring_entry(vptr, j, i);
}
- if (vptr->td_infos[j]) {
- kfree(vptr->td_infos[j]);
- vptr->td_infos[j] = NULL;
- }
+ kfree(vptr->td_infos[j]);
+ vptr->td_infos[j] = NULL;
}
}
if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN)
skb_reserve(new_skb, 2);
- memcpy(new_skb->data, rx_skb[0]->tail, pkt_size);
+ memcpy(new_skb->data, rx_skb[0]->data, pkt_size);
*rx_skb = new_skb;
ret = 0;
}
* Do the gymnastics to get the buffer head for data at
* 64byte alignment.
*/
- skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63);
+ 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->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
/*
* Fill in the descriptor to match
{
if (status & ISR_TXSTLI) {
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
printk(KERN_ERR "TD structure errror TDindex=%hx\n", readw(®s->TDIdx[0]));
BYTE_REG_BITS_ON(TXESR_TDSTR, ®s->TXESR);
}
if (status & ISR_SRCI) {
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
int linked;
if (vptr->options.spd_dpx == SPD_DPX_AUTO) {
if (linked) {
vptr->mii_status &= ~VELOCITY_LINK_FAIL;
+ netif_carrier_on(vptr->dev);
} else {
vptr->mii_status |= VELOCITY_LINK_FAIL;
+ netif_carrier_off(vptr->dev);
}
velocity_print_link_status(vptr);
goto err_free_rd_ring;
/* Ensure chip is running */
- pci_set_power_state(vptr->pdev, 0);
+ pci_set_power_state(vptr->pdev, PCI_D0);
velocity_init_registers(vptr, VELOCITY_INIT_COLD);
dev->name, dev);
if (ret < 0) {
/* Power down the chip */
- pci_set_power_state(vptr->pdev, 3);
+ pci_set_power_state(vptr->pdev, PCI_D3hot);
goto err_free_td_ring;
}
static void velocity_shutdown(struct velocity_info *vptr)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
mac_disable_int(regs);
writel(CR0_STOP, ®s->CR0Set);
writew(0xFFFF, ®s->TDCSRClr);
free_irq(dev->irq, dev);
/* Power down the chip */
- pci_set_power_state(vptr->pdev, 3);
+ pci_set_power_state(vptr->pdev, PCI_D3hot);
/* Free the resources */
velocity_free_td_ring(vptr);
int pktlen = skb->len;
+#ifdef VELOCITY_ZERO_COPY_SUPPORT
+ if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
+ kfree_skb(skb);
+ return 0;
+ }
+#endif
+
spin_lock_irqsave(&vptr->lock, flags);
index = vptr->td_curr[qnum];
*/
if (pktlen < ETH_ZLEN) {
/* Cannot occur until ZC support */
- if(skb_linearize(skb, GFP_ATOMIC))
- return 0;
pktlen = ETH_ZLEN;
memcpy(tdinfo->buf, skb->data, skb->len);
memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
int nfrags = skb_shinfo(skb)->nr_frags;
tdinfo->skb = skb;
if (nfrags > 6) {
- skb_linearize(skb, GFP_ATOMIC);
memcpy(tdinfo->buf, skb->data, skb->len);
tdinfo->skb_dma[0] = tdinfo->buf_dma;
td_ptr->tdesc0.pktsize =
static void velocity_set_multi(struct net_device *dev)
{
struct velocity_info *vptr = dev->priv;
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
u8 rx_mode;
int i;
struct dev_mc_list *mclist;
/* 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 */
- if(!netif_running(dev))
- pci_set_power_state(vptr->pdev, 0);
+ if (!netif_running(dev))
+ pci_set_power_state(vptr->pdev, PCI_D0);
switch (cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
default:
ret = -EOPNOTSUPP;
}
- if(!netif_running(dev))
- pci_set_power_state(vptr->pdev, 3);
+ if (!netif_running(dev))
+ pci_set_power_state(vptr->pdev, PCI_D3hot);
return ret;
* Turn off the autopoll and wait for it to disable on the chip
*/
-static void safe_disable_mii_autopoll(struct mac_regs * regs)
+static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs)
{
u16 ww;
* hardware. Wait for it to enable.
*/
-static void enable_mii_autopoll(struct mac_regs * regs)
+static void enable_mii_autopoll(struct mac_regs __iomem * regs)
{
int ii;
* on success or -ETIMEDOUT if the PHY did not respond.
*/
-static int velocity_mii_read(struct mac_regs * regs, u8 index, u16 *data)
+static int velocity_mii_read(struct mac_regs __iomem *regs, u8 index, u16 *data)
{
u16 ww;
* on success or -ETIMEDOUT if the PHY did not respond.
*/
-static int velocity_mii_write(struct mac_regs * regs, u8 mii_addr, u16 data)
+static int velocity_mii_write(struct mac_regs __iomem *regs, u8 mii_addr, u16 data)
{
u16 ww;
static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
{
u32 curr_status;
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
vptr->mii_status = mii_check_media_mode(vptr->mac_regs);
curr_status = vptr->mii_status & (~VELOCITY_LINK_FAIL);
* accordingly
*/
-static u32 mii_check_media_mode(struct mac_regs * regs)
+static u32 mii_check_media_mode(struct mac_regs __iomem * regs)
{
u32 status = 0;
u16 ANAR;
return status;
}
-static u32 check_connection_type(struct mac_regs * regs)
+static u32 check_connection_type(struct mac_regs __iomem * regs)
{
u32 status = 0;
u8 PHYSR0;
static void enable_flow_control_ability(struct velocity_info *vptr)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
switch (vptr->options.flow_cntl) {
static int velocity_ethtool_up(struct net_device *dev)
{
struct velocity_info *vptr = dev->priv;
- if(!netif_running(dev))
- pci_set_power_state(vptr->pdev, 0);
+ if (!netif_running(dev))
+ pci_set_power_state(vptr->pdev, PCI_D0);
return 0;
}
static void velocity_ethtool_down(struct net_device *dev)
{
struct velocity_info *vptr = dev->priv;
- if(!netif_running(dev))
- pci_set_power_state(vptr->pdev, 3);
+ 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 velocity_info *vptr = dev->priv;
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
u32 status;
status = check_connection_type(vptr->mac_regs);
static u32 velocity_get_link(struct net_device *dev)
{
struct velocity_info *vptr = dev->priv;
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 0 : 1;
}
struct velocity_info *vptr = dev->priv;
strcpy(info->driver, VELOCITY_NAME);
strcpy(info->version, VELOCITY_VERSION);
- strcpy(info->bus_info, vptr->pdev->slot_name);
+ strcpy(info->bus_info, pci_name(vptr->pdev));
}
static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct velocity_info *vptr = dev->priv;
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
unsigned long flags;
struct mii_ioctl_data *miidata = if_mii(ifr);
int err;
static void velocity_save_context(struct velocity_info *vptr, struct velocity_context * context)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
u16 i;
- u8 *ptr = (u8 *)regs;
+ u8 __iomem *ptr = (u8 __iomem *)regs;
for (i = MAC_REG_PAR; i < MAC_REG_CR0_CLR; i += 4)
*((u32 *) (context->mac_reg + i)) = readl(ptr + i);
static void velocity_restore_context(struct velocity_info *vptr, struct velocity_context *context)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
int i;
- u8 *ptr = (u8 *)regs;
+ u8 __iomem *ptr = (u8 __iomem *)regs;
for (i = MAC_REG_PAR; i < MAC_REG_CR0_SET; i += 4) {
writel(*((u32 *) (context->mac_reg + i)), ptr + i);
* we are interested in.
*/
-u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
+static u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
{
u16 crc = 0xFFFF;
u8 mask;
static int velocity_set_wol(struct velocity_info *vptr)
{
- struct mac_regs * regs = vptr->mac_regs;
+ struct mac_regs __iomem * regs = vptr->mac_regs;
static u8 buf[256];
int i;
return 0;
}
-static int velocity_suspend(struct pci_dev *pdev, u32 state)
+static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct velocity_info *vptr = pci_get_drvdata(pdev);
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct velocity_info *vptr = netdev_priv(dev);
unsigned long flags;
if(!netif_running(vptr->dev))
netif_device_detach(vptr->dev);
spin_lock_irqsave(&vptr->lock, flags);
- pci_save_state(pdev, vptr->pci_state);
+ pci_save_state(pdev);
#ifdef ETHTOOL_GWOL
if (vptr->flags & VELOCITY_FLAGS_WOL_ENABLED) {
velocity_get_ip(vptr);
velocity_shutdown(vptr);
velocity_set_wol(vptr);
pci_enable_wake(pdev, 3, 1);
- pci_set_power_state(pdev, 3);
+ pci_set_power_state(pdev, PCI_D3hot);
} else {
velocity_save_context(vptr, &vptr->context);
velocity_shutdown(vptr);
pci_disable_device(pdev);
- pci_set_power_state(pdev, state);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
}
#else
- pci_set_power_state(pdev, state);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
#endif
spin_unlock_irqrestore(&vptr->lock, flags);
return 0;
static int velocity_resume(struct pci_dev *pdev)
{
- struct velocity_info *vptr = pci_get_drvdata(pdev);
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct velocity_info *vptr = netdev_priv(dev);
unsigned long flags;
int i;
if(!netif_running(vptr->dev))
return 0;
- pci_set_power_state(pdev, 0);
+ pci_set_power_state(pdev, PCI_D0);
pci_enable_wake(pdev, 0, 0);
- pci_restore_state(pdev, vptr->pci_state);
+ pci_restore_state(pdev);
mac_wol_reset(vptr->mac_regs);