* argument : macaddr=0x00,0x10,0x20,0x30,0x40,0x50
*/
-static char version[] =
- "sunhme.c:v2.02 24/Aug/2003 David S. Miller (davem@redhat.com)\n";
-
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <linux/bitops.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/byteorder.h>
#include "sunhme.h"
+#define DRV_NAME "sunhme"
+#define DRV_VERSION "2.02"
+#define DRV_RELDATE "8/24/03"
+#define DRV_AUTHOR "David S. Miller (davem@redhat.com)"
+
+static char version[] =
+ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
+
+MODULE_VERSION(DRV_VERSION);
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION("Sun HappyMealEthernet(HME) 10/100baseT ethernet driver");
+MODULE_LICENSE("GPL");
static int macaddr[6];
/* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
-MODULE_PARM(macaddr, "6i");
+module_param_array(macaddr, int, NULL, 0);
MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
-MODULE_LICENSE("GPL");
static struct happy_meal *root_happy_dev;
#define DEFAULT_IPG2 4 /* For all modes */
#define DEFAULT_JAMSIZE 4 /* Toe jam */
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && defined(MODULE)
/* This happy_pci_ids is declared __initdata because it is only used
as an advisory to depmod. If this is ported to the new PCI interface
where it could be referenced at any time due to hot plugging,
the __initdata reference should be removed. */
-struct pci_device_id happymeal_pci_ids[] = {
+static struct pci_device_id happymeal_pci_ids[] = {
{
.vendor = PCI_VENDOR_ID_SUN,
.device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
*/
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
-static void sbus_hme_write32(unsigned long reg, u32 val)
+static void sbus_hme_write32(void __iomem *reg, u32 val)
{
sbus_writel(val, reg);
}
-static u32 sbus_hme_read32(unsigned long reg)
+static u32 sbus_hme_read32(void __iomem *reg)
{
return sbus_readl(reg);
}
return *p;
}
-static void pci_hme_write32(unsigned long reg, u32 val)
+static void pci_hme_write32(void __iomem *reg, u32 val)
{
writel(val, reg);
}
-static u32 pci_hme_read32(unsigned long reg)
+static u32 pci_hme_read32(void __iomem *reg)
{
return readl(reg);
}
/* Oh yes, the MIF BitBang is mighty fun to program. BitBucket is more like it. */
-static void BB_PUT_BIT(struct happy_meal *hp, unsigned long tregs, int bit)
+static void BB_PUT_BIT(struct happy_meal *hp, void __iomem *tregs, int bit)
{
hme_write32(hp, tregs + TCVR_BBDATA, bit);
hme_write32(hp, tregs + TCVR_BBCLOCK, 0);
}
#if 0
-static u32 BB_GET_BIT(struct happy_meal *hp, unsigned long tregs, int internal)
+static u32 BB_GET_BIT(struct happy_meal *hp, void __iomem *tregs, int internal)
{
u32 ret;
}
#endif
-static u32 BB_GET_BIT2(struct happy_meal *hp, unsigned long tregs, int internal)
+static u32 BB_GET_BIT2(struct happy_meal *hp, void __iomem *tregs, int internal)
{
u32 retval;
#define TCVR_FAILURE 0x80000000 /* Impossible MIF read value */
static int happy_meal_bb_read(struct happy_meal *hp,
- unsigned long tregs, int reg)
+ void __iomem *tregs, int reg)
{
u32 tmp;
int retval = 0;
}
static void happy_meal_bb_write(struct happy_meal *hp,
- unsigned long tregs, int reg,
+ void __iomem *tregs, int reg,
unsigned short value)
{
u32 tmp;
#define TCVR_READ_TRIES 16
static int happy_meal_tcvr_read(struct happy_meal *hp,
- unsigned long tregs, int reg)
+ void __iomem *tregs, int reg)
{
int tries = TCVR_READ_TRIES;
int retval;
#define TCVR_WRITE_TRIES 16
static void happy_meal_tcvr_write(struct happy_meal *hp,
- unsigned long tregs, int reg,
+ void __iomem *tregs, int reg,
unsigned short value)
{
int tries = TCVR_WRITE_TRIES;
ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value));
/* Welcome to Sun Microsystems, can I take your order please? */
- if (!(hp->happy_flags & HFLAG_FENABLE))
- return happy_meal_bb_write(hp, tregs, reg, value);
+ if (!(hp->happy_flags & HFLAG_FENABLE)) {
+ happy_meal_bb_write(hp, tregs, reg, value);
+ return;
+ }
/* Would you like fries with that? */
hme_write32(hp, tregs + TCVR_FRAME,
* service routine, and the chip is reset, or the link is ifconfig'd down
* and then back up, this entire process repeats itself all over again.
*/
-static int try_next_permutation(struct happy_meal *hp, unsigned long tregs)
+static int try_next_permutation(struct happy_meal *hp, void __iomem *tregs)
{
hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
return -1;
}
-static void display_link_mode(struct happy_meal *hp, unsigned long tregs)
+static void display_link_mode(struct happy_meal *hp, void __iomem *tregs)
{
printk(KERN_INFO "%s: Link is up using ", hp->dev->name);
if (hp->tcvr_type == external)
}
}
-static void display_forced_link_mode(struct happy_meal *hp, unsigned long tregs)
+static void display_forced_link_mode(struct happy_meal *hp, void __iomem *tregs)
{
printk(KERN_INFO "%s: Link has been forced up using ", hp->dev->name);
if (hp->tcvr_type == external)
printk("Half Duplex.\n");
}
-static int set_happy_link_modes(struct happy_meal *hp, unsigned long tregs)
+static int set_happy_link_modes(struct happy_meal *hp, void __iomem *tregs)
{
int full;
static int is_lucent_phy(struct happy_meal *hp)
{
- unsigned long tregs = hp->tcvregs;
+ void __iomem *tregs = hp->tcvregs;
unsigned short mr2, mr3;
int ret = 0;
static void happy_meal_timer(unsigned long data)
{
struct happy_meal *hp = (struct happy_meal *) data;
- unsigned long tregs = hp->tcvregs;
+ void __iomem *tregs = hp->tcvregs;
int restart_timer = 0;
spin_lock_irq(&hp->happy_lock);
#define RX_RESET_TRIES 32
/* hp->happy_lock must be held */
-static void happy_meal_tx_reset(struct happy_meal *hp, unsigned long bregs)
+static void happy_meal_tx_reset(struct happy_meal *hp, void __iomem *bregs)
{
int tries = TX_RESET_TRIES;
}
/* hp->happy_lock must be held */
-static void happy_meal_rx_reset(struct happy_meal *hp, unsigned long bregs)
+static void happy_meal_rx_reset(struct happy_meal *hp, void __iomem *bregs)
{
int tries = RX_RESET_TRIES;
#define STOP_TRIES 16
/* hp->happy_lock must be held */
-static void happy_meal_stop(struct happy_meal *hp, unsigned long gregs)
+static void happy_meal_stop(struct happy_meal *hp, void __iomem *gregs)
{
int tries = STOP_TRIES;
}
/* hp->happy_lock must be held */
-static void happy_meal_get_counters(struct happy_meal *hp, unsigned long bregs)
+static void happy_meal_get_counters(struct happy_meal *hp, void __iomem *bregs)
{
struct net_device_stats *stats = &hp->net_stats;
}
/* hp->happy_lock must be held */
-static void happy_meal_poll_stop(struct happy_meal *hp, unsigned long tregs)
+static void happy_meal_poll_stop(struct happy_meal *hp, void __iomem *tregs)
{
ASD(("happy_meal_poll_stop: "));
#define TCVR_UNISOLATE_TRIES 32 /* Dis-isolation can take longer. */
/* hp->happy_lock must be held */
-static int happy_meal_tcvr_reset(struct happy_meal *hp, unsigned long tregs)
+static int happy_meal_tcvr_reset(struct happy_meal *hp, void __iomem *tregs)
{
u32 tconfig;
int result, tries = TCVR_RESET_TRIES;
*
* hp->happy_lock must be held
*/
-static void happy_meal_transceiver_check(struct happy_meal *hp, unsigned long tregs)
+static void happy_meal_transceiver_check(struct happy_meal *hp, void __iomem *tregs)
{
unsigned long tconfig = hme_read32(hp, tregs + TCVR_CFG);
/* hp->happy_lock must be held */
static void happy_meal_begin_auto_negotiation(struct happy_meal *hp,
- unsigned long tregs,
+ void __iomem *tregs,
struct ethtool_cmd *ep)
{
int timeout;
/* hp->happy_lock must be held */
static int happy_meal_init(struct happy_meal *hp)
{
- unsigned long gregs = hp->gregs;
- unsigned long etxregs = hp->etxregs;
- unsigned long erxregs = hp->erxregs;
- unsigned long bregs = hp->bigmacregs;
- unsigned long tregs = hp->tcvregs;
+ void __iomem *gregs = hp->gregs;
+ void __iomem *etxregs = hp->etxregs;
+ void __iomem *erxregs = hp->erxregs;
+ void __iomem *bregs = hp->bigmacregs;
+ void __iomem *tregs = hp->tcvregs;
u32 regtmp, rxcfg;
unsigned char *e = &hp->dev->dev_addr[0];
/* hp->happy_lock must be held */
static void happy_meal_set_initial_advertisement(struct happy_meal *hp)
{
- unsigned long tregs = hp->tcvregs;
- unsigned long bregs = hp->bigmacregs;
- unsigned long gregs = hp->gregs;
+ void __iomem *tregs = hp->tcvregs;
+ void __iomem *bregs = hp->bigmacregs;
+ void __iomem *gregs = hp->gregs;
happy_meal_stop(hp, gregs);
hme_write32(hp, tregs + TCVR_IMASK, 0xffff);
/* hp->happy_lock must be held */
static void happy_meal_mif_interrupt(struct happy_meal *hp)
{
- unsigned long tregs = hp->tcvregs;
+ void __iomem *tregs = hp->tcvregs;
printk(KERN_INFO "%s: Link status change.\n", hp->dev->name);
hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, MII_BMCR);
static void happy_meal_set_multicast(struct net_device *dev)
{
struct happy_meal *hp = dev->priv;
- unsigned long bregs = hp->bigmacregs;
+ void __iomem *bregs = hp->bigmacregs;
struct dev_mc_list *dmi = dev->mc_list;
char *addrs;
int i;
struct list_head *tmp;
int n_hmes;
- if (busdev->vendor != PCI_VENDOR_ID_DEC ||
+ if (busdev == NULL ||
+ busdev->vendor != PCI_VENDOR_ID_DEC ||
busdev->device != PCI_DEVICE_ID_DEC_21153)
return 0;
}
/* Fetch MAC address from vital product data of PCI ROM. */
-static void find_eth_addr_in_vpd(void *rom_base, int len, int index, unsigned char *dev_addr)
+static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, int index, unsigned char *dev_addr)
{
int this_offset;
for (this_offset = 0x20; this_offset < len; this_offset++) {
- void *p = rom_base + this_offset;
+ void __iomem *p = rom_base + this_offset;
if (readb(p + 0) != 0x90 ||
readb(p + 1) != 0x00 ||
for (i = 0; i < 6; i++)
dev_addr[i] = readb(p + i);
- break;
+ return 1;
}
index--;
}
+ return 0;
}
static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
{
- u32 rom_reg_orig;
- void *p;
- int index;
-
- index = 0;
- if (is_quattro_p(pdev))
- index = PCI_SLOT(pdev->devfn);
+ size_t size;
+ void __iomem *p = pci_map_rom(pdev, &size);
- if (pdev->resource[PCI_ROM_RESOURCE].parent == NULL) {
- if (pci_assign_resource(pdev, PCI_ROM_RESOURCE) < 0)
- goto use_random;
- }
-
- pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_reg_orig);
- pci_write_config_dword(pdev, pdev->rom_base_reg,
- rom_reg_orig | PCI_ROM_ADDRESS_ENABLE);
-
- p = ioremap(pci_resource_start(pdev, PCI_ROM_RESOURCE), (64 * 1024));
- if (p != NULL && readb(p) == 0x55 && readb(p + 1) == 0xaa)
- find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
+ if (p) {
+ int index = 0;
+ int found;
- if (p != NULL)
- iounmap(p);
+ if (is_quattro_p(pdev))
+ index = PCI_SLOT(pdev->devfn);
- pci_write_config_dword(pdev, pdev->rom_base_reg, rom_reg_orig);
- return;
+ found = readb(p) == 0x55 &&
+ readb(p + 1) == 0xaa &&
+ find_eth_addr_in_vpd(p, (64 * 1024), index, dev_addr);
+ pci_unmap_rom(pdev, p);
+ if (found)
+ return;
+ }
-use_random:
/* Sun MAC prefix then 3 random bytes. */
dev_addr[0] = 0x08;
dev_addr[1] = 0x00;
#endif
struct happy_meal *hp;
struct net_device *dev;
- unsigned long hpreg_base;
+ void __iomem *hpreg_base;
+ unsigned long hpreg_res;
int i, qfe_slot = -1;
char prom_name[64];
int err;
qp->happy_meals[qfe_slot] = dev;
}
- hpreg_base = pci_resource_start(pdev, 0);
+ hpreg_res = pci_resource_start(pdev, 0);
err = -ENODEV;
if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n");
goto err_out_clear_quattro;
}
- if (pci_request_regions(pdev, dev->name)) {
+ if (pci_request_regions(pdev, DRV_NAME)) {
printk(KERN_ERR "happymeal(PCI): Cannot obtain PCI resources, "
"aborting.\n");
goto err_out_clear_quattro;
}
- if ((hpreg_base = (unsigned long) ioremap(hpreg_base, 0x8000)) == 0) {
+ if ((hpreg_base = ioremap(hpreg_res, 0x8000)) == 0) {
printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n");
goto err_out_free_res;
}
return 0;
err_out_iounmap:
- iounmap((void *)hp->gregs);
+ iounmap(hp->gregs);
err_out_free_res:
pci_release_regions(pdev);
PAGE_SIZE,
hp->happy_block,
hp->hblock_dvma);
- iounmap((void *)hp->gregs);
+ iounmap(hp->gregs);
pci_release_regions(hp->happy_dev);
}
#endif