Commit 03965cfa authored by Dave Jones's avatar Dave Jones Committed by Jeff Garzik

Merge ioc3-eth net drvr changes from 2.4.x:

- Improved MAC address discovery.
- endian fixes
parent cefa7b19
...@@ -341,14 +341,15 @@ static int nic_init(struct ioc3 *ioc3) ...@@ -341,14 +341,15 @@ static int nic_init(struct ioc3 *ioc3)
} }
/* /*
* Read the NIC (Number-In-a-Can) device. * Read the NIC (Number-In-a-Can) device used to store the MAC address on
* SN0 / SN00 nodeboards and PCI cards.
*/ */
static void ioc3_get_eaddr(struct ioc3_private *ip) static void ioc3_get_eaddr_nic(struct ioc3_private *ip)
{ {
struct ioc3 *ioc3 = ip->regs; struct ioc3 *ioc3 = ip->regs;
u8 nic[14]; u8 nic[14];
int i;
int tries = 2; /* There may be some problem with the battery? */ int tries = 2; /* There may be some problem with the battery? */
int i;
ioc3_w(gpcr_s, (1 << 21)); ioc3_w(gpcr_s, (1 << 21));
...@@ -371,16 +372,123 @@ static void ioc3_get_eaddr(struct ioc3_private *ip) ...@@ -371,16 +372,123 @@ static void ioc3_get_eaddr(struct ioc3_private *ip)
for (i = 13; i >= 0; i--) for (i = 13; i >= 0; i--)
nic[i] = nic_read_byte(ioc3); nic[i] = nic_read_byte(ioc3);
printk("Ethernet address is "); for (i = 2; i < 8; i++)
for (i = 2; i < 8; i++) {
ip->dev->dev_addr[i - 2] = nic[i]; ip->dev->dev_addr[i - 2] = nic[i];
printk("%02x", nic[i]); }
#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2)
/*
* Get the ether-address on SN1 nodes
*/
static void ioc3_get_eaddr_sn(struct ioc3_private *ip)
{
int ibrick_mac_addr_get(nasid_t, char *);
struct ioc3 *ioc3 = ip->regs;
nasid_t nasid_of_ioc3;
char io7eaddr[20];
long mac;
int err_val;
/*
* err_val = ibrick_mac_addr_get(get_nasid(), io7eaddr );
*
* BAD!! The above call uses get_nasid() and assumes that
* the ioc3 pointed to by struct ioc3 is hooked up to the
* cbrick that we're running on. The proper way to make this call
* is to figure out which nasid the ioc3 is connected to
* and use that to call ibrick_mac_addr_get. Below is
* a hack to do just that.
*/
/*
* Get the nasid of the ioc3 from the ioc3's base addr.
* FIXME: the 8 at the end assumes we're in memory mode,
* not node mode (for that, we'd change it to a 9).
* Is there a call to extract this info from a physical
* addr somewhere in an sn header file already? If so,
* we should probably use that, or restructure this routine
* to use pci_dev and generic numa nodeid getting stuff.
*/
nasid_of_ioc3 = (((unsigned long)ioc3 >> 33) & ~(-1 << 8));
err_val = ibrick_mac_addr_get(nasid_of_ioc3, io7eaddr );
if (err_val) {
/* Couldn't read the eeprom; try OSLoadOptions. */
printk("WARNING: ibrick_mac_addr_get failed: %d\n", err_val);
/* this is where we hardwire the mac address
* 1st ibrick had 08:00:69:11:34:75
* 2nd ibrick had 08:00:69:11:35:35
*
* Eagan Machines:
* mankato1 08:00:69:11:BE:95
* warroad 08:00:69:11:bd:60
* duron 08:00:69:11:34:60
*
* an easy way to get the mac address is to hook
* up an ip35, then from L1 do 'cti serial'
* and then look for MAC line XXX THIS DOESN"T QUITE WORK!!
*/
printk("ioc3_get_eaddr: setting ethernet address to:\n -----> ");
ip->dev->dev_addr[0] = 0x8;
ip->dev->dev_addr[1] = 0x0;
ip->dev->dev_addr[2] = 0x69;
ip->dev->dev_addr[3] = 0x11;
ip->dev->dev_addr[4] = 0x34;
ip->dev->dev_addr[5] = 0x60;
}
else {
long simple_strtol(const char *,char **,unsigned int);
mac = simple_strtol(io7eaddr, (char **)0, 16);
ip->dev->dev_addr[0] = (mac >> 40) & 0xff;
ip->dev->dev_addr[1] = (mac >> 32) & 0xff;
ip->dev->dev_addr[2] = (mac >> 24) & 0xff;
ip->dev->dev_addr[3] = (mac >> 16) & 0xff;
ip->dev->dev_addr[4] = (mac >> 8) & 0xff;
ip->dev->dev_addr[5] = mac & 0xff;
}
}
#endif
/*
* Ok, this is hosed by design. It's necessary to know what machine the
* NIC is in in order to know how to read the NIC address. We also have
* to know if it's a PCI card or a NIC in on the node board ...
*/
static void ioc3_get_eaddr(struct ioc3_private *ip)
{
void (*do_get_eaddr)(struct ioc3_private *ip) = NULL;
int i;
/*
* We should also use this code for PCI cards, no matter what host
* machine but how to know that we're a PCI card?
*/
#ifdef CONFIG_SGI_IP27
do_get_eaddr = ioc3_get_eaddr_nic;
#endif
#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_SGI_SN2)
do_get_eaddr = ioc3_get_eaddr_sn;
#endif
if (!do_get_eaddr) {
printk(KERN_ERR "Don't know how to read MAC address of this "
"IOC3 NIC\n");
return;
}
printk("Ethernet address is ");
for (i = 0; i < 6; i++) {
printk("%02x", ip->dev->dev_addr[i]);
if (i < 7) if (i < 7)
printk(":"); printk(":");
} }
printk(".\n"); printk(".\n");
} }
/* /*
* Caller must hold the ioc3_lock ever for MII readers. This is also * Caller must hold the ioc3_lock ever for MII readers. This is also
* used to protect the transmitter side but it's low contention. * used to protect the transmitter side but it's low contention.
...@@ -435,10 +543,10 @@ ioc3_rx(struct ioc3_private *ip) ...@@ -435,10 +543,10 @@ ioc3_rx(struct ioc3_private *ip)
skb = ip->rx_skbs[rx_entry]; skb = ip->rx_skbs[rx_entry];
rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET); rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
w0 = rxb->w0; w0 = be32_to_cpu(rxb->w0);
while (w0 & ERXBUF_V) { while (w0 & ERXBUF_V) {
err = rxb->err; /* It's valid ... */ err = be32_to_cpu(rxb->err); /* It's valid ... */
if (err & ERXBUF_GOODPKT) { if (err & ERXBUF_GOODPKT) {
len = ((w0 >> ERXBUF_BYTECNT_SHIFT) & 0x7ff) - 4; len = ((w0 >> ERXBUF_BYTECNT_SHIFT) & 0x7ff) - 4;
skb_trim(skb, len); skb_trim(skb, len);
...@@ -479,8 +587,8 @@ ioc3_rx(struct ioc3_private *ip) ...@@ -479,8 +587,8 @@ ioc3_rx(struct ioc3_private *ip)
ip->stats.rx_frame_errors++; ip->stats.rx_frame_errors++;
next: next:
ip->rx_skbs[n_entry] = new_skb; ip->rx_skbs[n_entry] = new_skb;
rxr[n_entry] = (0xa5UL << 56) | rxr[n_entry] = cpu_to_be32((0xa5UL << 56) |
((unsigned long) rxb & TO_PHYS_MASK); ((unsigned long) rxb & TO_PHYS_MASK));
rxb->w0 = 0; /* Clear valid flag */ rxb->w0 = 0; /* Clear valid flag */
n_entry = (n_entry + 1) & 511; /* Update erpir */ n_entry = (n_entry + 1) & 511; /* Update erpir */
...@@ -488,7 +596,7 @@ ioc3_rx(struct ioc3_private *ip) ...@@ -488,7 +596,7 @@ ioc3_rx(struct ioc3_private *ip)
rx_entry = (rx_entry + 1) & 511; rx_entry = (rx_entry + 1) & 511;
skb = ip->rx_skbs[rx_entry]; skb = ip->rx_skbs[rx_entry];
rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET); rxb = (struct ioc3_erxbuf *) (skb->data - RX_OFFSET);
w0 = rxb->w0; w0 = be32_to_cpu(rxb->w0);
} }
ioc3->erpir = (n_entry << 3) | ERPIR_ARM; ioc3->erpir = (n_entry << 3) | ERPIR_ARM;
ip->rx_pi = n_entry; ip->rx_pi = n_entry;
...@@ -1190,8 +1298,8 @@ ioc3_alloc_rings(struct net_device *dev, struct ioc3_private *ip, ...@@ -1190,8 +1298,8 @@ ioc3_alloc_rings(struct net_device *dev, struct ioc3_private *ip,
/* Because we reserve afterwards. */ /* Because we reserve afterwards. */
skb_put(skb, (1664 + RX_OFFSET)); skb_put(skb, (1664 + RX_OFFSET));
rxb = (struct ioc3_erxbuf *) skb->data; rxb = (struct ioc3_erxbuf *) skb->data;
rxr[i] = (0xa5UL << 56) rxr[i] = cpu_to_be64((0xa5UL << 56) |
| ((unsigned long) rxb & TO_PHYS_MASK); ((unsigned long) rxb & TO_PHYS_MASK));
skb_reserve(skb, RX_OFFSET); skb_reserve(skb, RX_OFFSET);
} }
ip->rx_ci = 0; ip->rx_ci = 0;
...@@ -1555,8 +1663,8 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1555,8 +1663,8 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
memset(desc->data + len, 0, ETH_ZLEN - len); memset(desc->data + len, 0, ETH_ZLEN - len);
len = ETH_ZLEN; len = ETH_ZLEN;
} }
desc->cmd = len | ETXD_INTWHENDONE | ETXD_D0V; desc->cmd = cpu_to_be32(len | ETXD_INTWHENDONE | ETXD_D0V);
desc->bufcnt = len; desc->bufcnt = cpu_to_be32(len);
} else if ((data ^ (data + len)) & 0x4000) { } else if ((data ^ (data + len)) & 0x4000) {
unsigned long b2, s1, s2; unsigned long b2, s1, s2;
...@@ -1564,16 +1672,20 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1564,16 +1672,20 @@ ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
s1 = b2 - data; s1 = b2 - data;
s2 = data + len - b2; s2 = data + len - b2;
desc->cmd = len | ETXD_INTWHENDONE | ETXD_B1V | ETXD_B2V; desc->cmd = cpu_to_be32(len | ETXD_INTWHENDONE |
desc->bufcnt = (s1 << ETXD_B1CNT_SHIFT) | ETXD_B1V | ETXD_B2V);
(s2 << ETXD_B2CNT_SHIFT); desc->bufcnt = cpu_to_be32((s1 << ETXD_B1CNT_SHIFT)
desc->p1 = (0xa5UL << 56) | (data & TO_PHYS_MASK); | (s2 << ETXD_B2CNT_SHIFT));
desc->p2 = (0xa5UL << 56) | (data & TO_PHYS_MASK); desc->p1 = cpu_to_be64((0xa5UL << 56) |
(data & TO_PHYS_MASK));
desc->p2 = cpu_to_be64((0xa5UL << 56) |
(data & TO_PHYS_MASK));
} else { } else {
/* Normal sized packet that doesn't cross a page boundary. */ /* Normal sized packet that doesn't cross a page boundary. */
desc->cmd = len | ETXD_INTWHENDONE | ETXD_B1V; desc->cmd = cpu_to_be32(len | ETXD_INTWHENDONE | ETXD_B1V);
desc->bufcnt = len << ETXD_B1CNT_SHIFT; desc->bufcnt = cpu_to_be32(len << ETXD_B1CNT_SHIFT);
desc->p1 = (0xa5UL << 56) | (data & TO_PHYS_MASK); desc->p1 = cpu_to_be64((0xa5UL << 56) |
(data & TO_PHYS_MASK));
} }
BARRIER(); BARRIER();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment