Commit 528026e6 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/davem/net-2.5

into home.osdl.org:/home/torvalds/v2.5/linux
parents ce24f192 30b3370d
......@@ -19,7 +19,7 @@ quiet_cmd_btfix = BTFIX $@
BTOBJS := $(HEAD_Y) $(INIT_Y)
BTLIBS := $(CORE_Y) $(LIBS_Y) $(DRIVERS_Y) $(NET_Y)
LDFLAGS_image := -T arch/sparc/vmlinux.lds.s $(BTOBJS) --start-group $(BTLIBS) --end-group
LDFLAGS_image := -T arch/sparc/kernel/vmlinux.lds.s $(BTOBJS) --start-group $(BTLIBS) --end-group
# Actual linking
$(obj)/image: $(obj)/btfix.o FORCE
......
......@@ -38,7 +38,7 @@
#define curptr g6
#define NR_SYSCALLS 266 /* Each OS is different... */
#define NR_SYSCALLS 267 /* Each OS is different... */
/* These are just handy. */
#define _SV save %sp, -STACKFRAME_SZ, %sp
......
......@@ -511,6 +511,26 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size,
}
}
/*
* Same as pci_map_single, but with pages.
*/
dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
unsigned long offset, size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
BUG();
/* IIep is write-through, not flushing. */
return page_to_phys(page) + offset;
}
void pci_unmap_page(struct pci_dev *hwdev,
dma_addr_t dma_address, size_t size, int direction)
{
if (direction == PCI_DMA_NONE)
BUG();
/* mmu_inval_dma_area XXX */
}
/* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
* above pci_map_single interface. Here the scatter gather list
......
......@@ -72,7 +72,7 @@ sys_call_table:
/*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
/*255*/ .long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
/*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
/*261*/ .long sys_timer_delete, sys_nis_syscall
/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall
#ifdef CONFIG_SUNOS_EMUL
/* Now the SunOS syscall table. */
......@@ -171,6 +171,6 @@ sunos_sys_table:
.long sunos_nosys
/*260*/ .long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys, sunos_nosys, sunos_nosys
.long sunos_nosys
.long sunos_nosys, sunos_nosys
#endif
......@@ -26,7 +26,7 @@
#define curptr g6
#define NR_SYSCALLS 266 /* Each OS is different... */
#define NR_SYSCALLS 267 /* Each OS is different... */
.text
.align 32
......
......@@ -1097,6 +1097,18 @@ void init_irqwork_curcpu(void)
memset(__irq_work + smp_processor_id(), 0, sizeof(*workp));
/* Make sure we are called with PSTATE_IE disabled. */
__asm__ __volatile__("rdpr %%pstate, %0\n\t"
: "=r" (tmp));
if (tmp & PSTATE_IE) {
prom_printf("BUG: init_irqwork_curcpu() called with "
"PSTATE_IE enabled, bailing.\n");
__asm__ __volatile__("mov %%i7, %0\n\t"
: "=r" (tmp));
prom_printf("BUG: Called from %lx\n", tmp);
prom_halt();
}
/* Set interrupt globals. */
workp = &__irq_work[smp_processor_id()];
__asm__ __volatile__(
......@@ -1105,7 +1117,7 @@ void init_irqwork_curcpu(void)
"mov %2, %%g6\n\t"
"wrpr %0, 0x0, %%pstate\n\t"
: "=&r" (tmp)
: "i" (PSTATE_IG | PSTATE_IE), "r" (workp));
: "i" (PSTATE_IG), "r" (workp));
}
/* Only invoked on boot processor. */
......
......@@ -874,6 +874,46 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
#define PSYCHO_PCI_AFAR_A 0x2018UL
#define PSYCHO_PCI_AFAR_B 0x4018UL
static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm_a)
{
unsigned long csr_reg, csr, csr_error_bits;
irqreturn_t ret = IRQ_NONE;
u16 stat;
if (is_pbm_a) {
csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL;
} else {
csr_reg = pbm->controller_regs + PSYCHO_PCIB_CTRL;
}
csr = psycho_read(csr_reg);
csr_error_bits =
csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR);
if (csr_error_bits) {
/* Clear the errors. */
psycho_write(csr_reg, csr);
/* Log 'em. */
if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR)
printk("%s: PCI streaming byte hole error asserted.\n",
pbm->name);
if (csr_error_bits & PSYCHO_PCICTRL_SERR)
printk("%s: PCI SERR signal asserted.\n", pbm->name);
ret = IRQ_HANDLED;
}
pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
if (stat & (PCI_STATUS_PARITY |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR)) {
printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
pbm->name, stat);
pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
ret = IRQ_HANDLED;
}
return ret;
}
static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct pci_pbm_info *pbm = dev_id;
......@@ -902,7 +942,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA |
PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR);
if (!error_bits)
return IRQ_NONE;
return psycho_pcierr_intr_other(pbm, is_pbm_a);
psycho_write(afsr_reg, error_bits);
/* Log the error. */
......@@ -1008,6 +1048,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
prom_halt();
}
pbm = &p->pbm_A;
irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_A_INO);
if (request_irq(irq, psycho_pcierr_intr,
SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_A) < 0) {
......@@ -1016,6 +1057,7 @@ static void __init psycho_register_error_handlers(struct pci_controller_info *p)
prom_halt();
}
pbm = &p->pbm_B;
irq = psycho_irq_build(pbm, NULL, (portid << 6) | PSYCHO_PCIERR_B_INO);
if (request_irq(irq, psycho_pcierr_intr,
SA_SHIRQ, "PSYCHO PCIERR", &p->pbm_B) < 0) {
......
......@@ -221,6 +221,7 @@
((unsigned long)(REG)))
static int hummingbird_p;
static struct pci_bus *sabre_root_bus;
static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,
unsigned char bus,
......@@ -860,6 +861,42 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p)
{
unsigned long csr_reg, csr, csr_error_bits;
irqreturn_t ret = IRQ_NONE;
u16 stat;
csr_reg = p->pbm_A.controller_regs + SABRE_PCICTRL;
csr = sabre_read(csr_reg);
csr_error_bits =
csr & SABRE_PCICTRL_SERR;
if (csr_error_bits) {
/* Clear the errors. */
sabre_write(csr_reg, csr);
/* Log 'em. */
if (csr_error_bits & SABRE_PCICTRL_SERR)
printk("SABRE%d: PCI SERR signal asserted.\n",
p->index);
ret = IRQ_HANDLED;
}
pci_read_config_word(sabre_root_bus->self,
PCI_STATUS, &stat);
if (stat & (PCI_STATUS_PARITY |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR)) {
printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n",
p->index, stat);
pci_write_config_word(sabre_root_bus->self,
PCI_STATUS, 0xffff);
ret = IRQ_HANDLED;
}
return ret;
}
static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct pci_controller_info *p = dev_id;
......@@ -881,7 +918,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs
SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA |
SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR);
if (!error_bits)
return IRQ_NONE;
return sabre_pcierr_intr_other(p);
sabre_write(afsr_reg, error_bits);
/* Log the error. */
......@@ -1168,6 +1205,8 @@ static void __init sabre_scan_bus(struct pci_controller_info *p)
pci_fixup_host_bridge_self(sabre_bus);
sabre_bus->self->sysdata = cookie;
sabre_root_bus = sabre_bus;
apb_init(p, sabre_bus);
sabres_scanned = 0;
......
......@@ -845,6 +845,88 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs)
#define SCHIZO_PCIAFSR_MEM 0x0000000020000000UL /* Schizo/Tomatillo */
#define SCHIZO_PCIAFSR_IO 0x0000000010000000UL /* Schizo/Tomatillo */
#define SCHIZO_PCI_CTRL (0x2000UL)
#define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */
#define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */
#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */
#define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */
#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */
#define SCHIZO_PCICTRL_SERR (1UL << 34UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) /* Safari */
#define SCHIZO_PCICTRL_MRM_PREF (1UL << 28UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDO_PREF (1UL << 27UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDL_PREF (1UL << 26UL) /* Tomatillo */
#define SCHIZO_PCICTRL_PTO (3UL << 24UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PTO_SHIFT 24UL
#define SCHIZO_PCICTRL_TRWSW (7UL << 21UL) /* Tomatillo */
#define SCHIZO_PCICTRL_F_TGT_A (1UL << 20UL) /* Tomatillo */
#define SCHIZO_PCICTRL_S_DTO_INT (1UL << 19UL) /* Safari */
#define SCHIZO_PCICTRL_F_TGT_RT (1UL << 19UL) /* Tomatillo */
#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL) /* Safari */
#define SCHIZO_PCICTRL_T_DTO_INT (1UL << 18UL) /* Tomatillo */
#define SCHIZO_PCICTRL_EEN (1UL << 17UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PARK (1UL << 16UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PCIRST (1UL << 8UL) /* Safari */
#define SCHIZO_PCICTRL_ARB_S (0x3fUL << 0UL) /* Safari */
#define SCHIZO_PCICTRL_ARB_T (0xffUL << 0UL) /* Tomatillo */
static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm)
{
unsigned long csr_reg, csr, csr_error_bits;
irqreturn_t ret = IRQ_NONE;
u16 stat;
csr_reg = pbm->pbm_regs + SCHIZO_PCI_CTRL;
csr = schizo_read(csr_reg);
csr_error_bits =
csr & (SCHIZO_PCICTRL_BUS_UNUS |
SCHIZO_PCICTRL_TTO_ERR |
SCHIZO_PCICTRL_RTRY_ERR |
SCHIZO_PCICTRL_DTO_ERR |
SCHIZO_PCICTRL_SBH_ERR |
SCHIZO_PCICTRL_SERR);
if (csr_error_bits) {
/* Clear the errors. */
schizo_write(csr_reg, csr);
/* Log 'em. */
if (csr_error_bits & SCHIZO_PCICTRL_BUS_UNUS)
printk("%s: Bus unusable error asserted.\n",
pbm->name);
if (csr_error_bits & SCHIZO_PCICTRL_TTO_ERR)
printk("%s: PCI TRDY# timeout error asserted.\n",
pbm->name);
if (csr_error_bits & SCHIZO_PCICTRL_RTRY_ERR)
printk("%s: PCI excessive retry error asserted.\n",
pbm->name);
if (csr_error_bits & SCHIZO_PCICTRL_DTO_ERR)
printk("%s: PCI discard timeout error asserted.\n",
pbm->name);
if (csr_error_bits & SCHIZO_PCICTRL_SBH_ERR)
printk("%s: PCI streaming byte hole error asserted.\n",
pbm->name);
if (csr_error_bits & SCHIZO_PCICTRL_SERR)
printk("%s: PCI SERR signal asserted.\n",
pbm->name);
ret = IRQ_HANDLED;
}
pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
if (stat & (PCI_STATUS_PARITY |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR)) {
printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
pbm->name, stat);
pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
ret = IRQ_HANDLED;
}
return ret;
}
static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *regs)
{
struct pci_pbm_info *pbm = dev_id;
......@@ -871,7 +953,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id, struct pt_regs *reg
SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR |
SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS);
if (!error_bits)
return IRQ_NONE;
return schizo_pcierr_intr_other(pbm);
schizo_write(afsr_reg, error_bits);
/* Log the error. */
......@@ -1044,34 +1126,6 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id, struct pt_regs *
#define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */
#define SCHIZO_SERR_INO 0x34 /* Safari interface error */
#define SCHIZO_PCI_CTRL (0x2000UL)
#define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */
#define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */
#define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */
#define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */
#define SCHIZO_PCICTRL_TTO_ERR (1UL << 38UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_RTRY_ERR (1UL << 37UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_DTO_ERR (1UL << 36UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_SBH_ERR (1UL << 35UL) /* Safari */
#define SCHIZO_PCICTRL_SERR (1UL << 34UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PCISPD (1UL << 33UL) /* Safari */
#define SCHIZO_PCICTRL_MRM_PREF (1UL << 28UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDO_PREF (1UL << 27UL) /* Tomatillo */
#define SCHIZO_PCICTRL_RDL_PREF (1UL << 26UL) /* Tomatillo */
#define SCHIZO_PCICTRL_PTO (3UL << 24UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PTO_SHIFT 24UL
#define SCHIZO_PCICTRL_TRWSW (7UL << 21UL) /* Tomatillo */
#define SCHIZO_PCICTRL_F_TGT_A (1UL << 20UL) /* Tomatillo */
#define SCHIZO_PCICTRL_S_DTO_INT (1UL << 19UL) /* Safari */
#define SCHIZO_PCICTRL_F_TGT_RT (1UL << 19UL) /* Tomatillo */
#define SCHIZO_PCICTRL_SBH_INT (1UL << 18UL) /* Safari */
#define SCHIZO_PCICTRL_T_DTO_INT (1UL << 18UL) /* Tomatillo */
#define SCHIZO_PCICTRL_EEN (1UL << 17UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PARK (1UL << 16UL) /* Safari/Tomatillo */
#define SCHIZO_PCICTRL_PCIRST (1UL << 8UL) /* Safari */
#define SCHIZO_PCICTRL_ARB_S (0x3fUL << 0UL) /* Safari */
#define SCHIZO_PCICTRL_ARB_T (0xffUL << 0UL) /* Tomatillo */
struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino)
{
ino &= IMAP_INO;
......
......@@ -388,7 +388,7 @@ struct shmid64_ds32 {
*
* This is really horribly ugly.
*/
#define IPCOP_MASK(__x) (1UL << (__x))
#define IPCOP_MASK(__x) (1UL << ((__x)&~IPC_64))
static int do_sys32_semctl(int first, int second, int third, void *uptr)
{
union semun fourth;
......@@ -400,7 +400,7 @@ static int do_sys32_semctl(int first, int second, int third, void *uptr)
err = -EFAULT;
if (get_user (pad, (u32 *)uptr))
goto out;
if(third == SETVAL)
if ((third & ~IPC_64) == SETVAL)
fourth.val = (int)pad;
else
fourth.__pad = (void *)A(pad);
......@@ -2779,3 +2779,41 @@ long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf, size_t len
return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
buf, len);
}
extern asmlinkage long
sys_timer_create(clockid_t which_clock, struct sigevent *timer_event_spec,
timer_t * created_timer_id);
long
sys32_timer_create(u32 clock, struct sigevent32 *se32, timer_t *timer_id)
{
struct sigevent se;
mm_segment_t oldfs;
timer_t t;
long err;
if (se32 == NULL)
return sys_timer_create(clock, NULL, timer_id);
memset(&se, 0, sizeof(struct sigevent));
if (get_user(se.sigev_value.sival_int, &se32->sigev_value.sival_int) ||
__get_user(se.sigev_signo, &se32->sigev_signo) ||
__get_user(se.sigev_notify, &se32->sigev_notify) ||
__copy_from_user(&se._sigev_un._pad, &se32->_sigev_un._pad,
sizeof(se._sigev_un._pad)))
return -EFAULT;
if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
return -EFAULT;
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_timer_create(clock, &se, &t);
set_fs(oldfs);
if (!err)
err = __put_user (t, timer_id);
return err;
}
......@@ -72,7 +72,7 @@ sys_call_table32:
/*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
.word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep
/*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun
.word sys_timer_delete, sys_ni_syscall
.word sys_timer_delete, sys32_timer_create, sys_ni_syscall
/* Now the 64-bit native Linux syscall table. */
......@@ -133,7 +133,7 @@ sys_call_table:
/*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
.word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep
/*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun
.word sys_timer_delete, sys_ni_syscall
.word sys_timer_delete, sys_timer_create, sys_ni_syscall
#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
defined(CONFIG_SOLARIS_EMUL_MODULE)
......@@ -228,10 +228,10 @@ sunos_sys_table:
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys
/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sys_ni_syscall
.word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
.word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
.word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
.word sys_ni_syscall, sys_ni_syscall
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_nosys, sunos_nosys, sunos_nosys
#endif
......@@ -294,4 +294,5 @@ solaris_sys_table:
.word solaris_unimplemented /* 264 */
.word solaris_unimplemented /* 265 */
.word solaris_unimplemented /* 266 */
.word solaris_unimplemented /* 267 */
/* $Id: sunbmac.c,v 1.30 2002/01/15 06:48:55 davem Exp $
* sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
* Copyright (C) 1997, 1998, 1999, 2003 David S. Miller (davem@redhat.com)
*/
#include <linux/module.h>
......@@ -18,6 +18,7 @@
#include <linux/init.h>
#include <linux/crc32.h>
#include <linux/errno.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
......@@ -37,7 +38,7 @@
#include "sunbmac.h"
static char version[] __initdata =
"sunbmac.c:v1.9 11/Sep/99 David S. Miller (davem@redhat.com)\n";
"sunbmac.c:v2.0 24/Nov/03 David S. Miller (davem@redhat.com)\n";
#undef DEBUG_PROBE
#undef DEBUG_TX
......@@ -1035,6 +1036,33 @@ static void bigmac_set_multicast(struct net_device *dev)
sbus_writel(tmp, bregs + BMAC_RXCFG);
}
/* Ethtool support... */
static void bigmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct bigmac *bp = dev->priv;
strcpy(info->driver, "sunbmac");
strcpy(info->version, "2.0");
sprintf(info->bus_info, "SBUS:%d",
bp->qec_sdev->slot);
}
static u32 bigmac_get_link(struct net_device *dev)
{
struct bigmac *bp = dev->priv;
spin_lock_irq(&bp->lock);
bp->sw_bmsr = bigmac_tcvr_read(bp, bp->tregs, BIGMAC_BMSR);
spin_unlock_irq(&bp->lock);
return (bp->sw_bmsr & BMSR_LSTATUS);
}
static struct ethtool_ops bigmac_ethtool_ops = {
.get_drvinfo = bigmac_get_drvinfo,
.get_link = bigmac_get_link,
};
static int __init bigmac_ether_init(struct sbus_dev *qec_sdev)
{
struct net_device *dev;
......@@ -1169,6 +1197,7 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev)
dev->open = &bigmac_open;
dev->stop = &bigmac_close;
dev->hard_start_xmit = &bigmac_start_xmit;
dev->ethtool_ops = &bigmac_ethtool_ops;
/* Set links to BigMAC statistic and multi-cast loading code. */
dev->get_stats = &bigmac_get_stats;
......
/* $Id: sungem.c,v 1.44.2.22 2002/03/13 01:18:12 davem Exp $
* sungem.c: Sun GEM ethernet driver.
*
* Copyright (C) 2000, 2001, 2002 David S. Miller (davem@redhat.com)
* Copyright (C) 2000, 2001, 2002, 2003 David S. Miller (davem@redhat.com)
*
* Support for Apple GMAC and assorted PHYs by
* Benjamin Herrenscmidt (benh@kernel.crashing.org)
......@@ -70,8 +70,8 @@
SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
#define DRV_NAME "sungem"
#define DRV_VERSION "0.97"
#define DRV_RELDATE "3/20/02"
#define DRV_VERSION "0.98"
#define DRV_RELDATE "8/24/03"
#define DRV_AUTHOR "David S. Miller (davem@redhat.com)"
static char version[] __devinitdata =
......@@ -2317,177 +2317,134 @@ static void gem_set_multicast(struct net_device *dev)
spin_unlock_irq(&gp->lock);
}
/* Eventually add support for changing the advertisement
* on autoneg.
*/
static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user)
static void gem_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct gem *gp = dev->priv;
strcpy(info->driver, DRV_NAME);
strcpy(info->version, DRV_VERSION);
strcpy(info->bus_info, pci_name(gp->pdev));
}
static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct gem *gp = dev->priv;
struct ethtool_cmd ecmd;
if (copy_from_user(&ecmd, ep_user, sizeof(ecmd)))
return -EFAULT;
switch(ecmd.cmd) {
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { .cmd = ETHTOOL_GDRVINFO };
strncpy(info.driver, DRV_NAME, ETHTOOL_BUSINFO_LEN);
strncpy(info.version, DRV_VERSION, ETHTOOL_BUSINFO_LEN);
info.fw_version[0] = '\0';
strncpy(info.bus_info, pci_name(gp->pdev), ETHTOOL_BUSINFO_LEN);
info.regdump_len = 0; /*SUNGEM_NREGS;*/
if (gp->phy_type == phy_mii_mdio0 ||
gp->phy_type == phy_mii_mdio1) {
if (gp->phy_mii.def)
cmd->supported = gp->phy_mii.def->features;
else
cmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full);
if (copy_to_user(ep_user, &info, sizeof(info)))
return -EFAULT;
/* XXX hardcoded stuff for now */
cmd->port = PORT_MII;
cmd->transceiver = XCVR_EXTERNAL;
cmd->phy_address = 0; /* XXX fixed PHYAD */
return 0;
}
case ETHTOOL_GSET:
if (gp->phy_type == phy_mii_mdio0 ||
gp->phy_type == phy_mii_mdio1) {
if (gp->phy_mii.def)
ecmd.supported = gp->phy_mii.def->features;
else
ecmd.supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full;
/* XXX hardcoded stuff for now */
ecmd.port = PORT_MII;
ecmd.transceiver = XCVR_EXTERNAL;
ecmd.phy_address = 0; /* XXX fixed PHYAD */
/* Return current PHY settings */
spin_lock_irq(&gp->lock);
ecmd.autoneg = gp->want_autoneg;
ecmd.speed = gp->phy_mii.speed;
ecmd.duplex = gp->phy_mii.duplex;
ecmd.advertising = gp->phy_mii.advertising;
/* If we started with a forced mode, we don't have a default
* advertise set, we need to return something sensible so
* userland can re-enable autoneg properly */
if (ecmd.advertising == 0)
ecmd.advertising = ecmd.supported;
spin_unlock_irq(&gp->lock);
} else { // XXX PCS ?
ecmd.supported =
/* Return current PHY settings */
spin_lock_irq(&gp->lock);
cmd->autoneg = gp->want_autoneg;
cmd->speed = gp->phy_mii.speed;
cmd->duplex = gp->phy_mii.duplex;
cmd->advertising = gp->phy_mii.advertising;
/* If we started with a forced mode, we don't have a default
* advertise set, we need to return something sensible so
* userland can re-enable autoneg properly.
*/
if (cmd->advertising == 0)
cmd->advertising = cmd->supported;
spin_unlock_irq(&gp->lock);
} else { // XXX PCS ?
cmd->supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg);
ecmd.advertising = ecmd.supported;
}
if (copy_to_user(ep_user, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
case ETHTOOL_SSET:
/* Verify the settings we care about. */
if (ecmd.autoneg != AUTONEG_ENABLE &&
ecmd.autoneg != AUTONEG_DISABLE)
return -EINVAL;
if (ecmd.autoneg == AUTONEG_ENABLE &&
ecmd.advertising == 0)
return -EINVAL;
if (ecmd.autoneg == AUTONEG_DISABLE &&
((ecmd.speed != SPEED_1000 &&
ecmd.speed != SPEED_100 &&
ecmd.speed != SPEED_10) ||
(ecmd.duplex != DUPLEX_HALF &&
ecmd.duplex != DUPLEX_FULL)))
return -EINVAL;
/* Apply settings and restart link process. */
spin_lock_irq(&gp->lock);
gem_begin_auto_negotiation(gp, &ecmd);
spin_unlock_irq(&gp->lock);
return 0;
case ETHTOOL_NWAY_RST:
if (!gp->want_autoneg)
return -EINVAL;
cmd->advertising = cmd->supported;
cmd->speed = 0;
cmd->duplex = cmd->port = cmd->phy_address =
cmd->transceiver = cmd->autoneg = 0;
}
cmd->maxtxpkt = cmd->maxrxpkt = 0;
/* Restart link process. */
spin_lock_irq(&gp->lock);
gem_begin_auto_negotiation(gp, NULL);
spin_unlock_irq(&gp->lock);
return 0;
}
return 0;
static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct gem *gp = dev->priv;
case ETHTOOL_GWOL:
case ETHTOOL_SWOL:
break; /* todo */
/* Verify the settings we care about. */
if (cmd->autoneg != AUTONEG_ENABLE &&
cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = { .cmd = ETHTOOL_GLINK };
if (cmd->autoneg == AUTONEG_ENABLE &&
cmd->advertising == 0)
return -EINVAL;
edata.data = (gp->lstate == link_up);
if (copy_to_user(ep_user, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
if (cmd->autoneg == AUTONEG_DISABLE &&
((cmd->speed != SPEED_1000 &&
cmd->speed != SPEED_100 &&
cmd->speed != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)))
return -EINVAL;
/* Apply settings and restart link process. */
spin_lock_irq(&gp->lock);
gem_begin_auto_negotiation(gp, cmd);
spin_unlock_irq(&gp->lock);
/* get message-level */
case ETHTOOL_GMSGLVL: {
struct ethtool_value edata = { .cmd = ETHTOOL_GMSGLVL };
return 0;
}
edata.data = gp->msg_enable;
if (copy_to_user(ep_user, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
static int gem_nway_reset(struct net_device *dev)
{
struct gem *gp = dev->priv;
/* set message-level */
case ETHTOOL_SMSGLVL: {
struct ethtool_value edata;
if (!gp->want_autoneg)
return -EINVAL;
if (copy_from_user(&edata, ep_user, sizeof(edata)))
return -EFAULT;
gp->msg_enable = edata.data;
return 0;
}
/* Restart link process. */
spin_lock_irq(&gp->lock);
gem_begin_auto_negotiation(gp, NULL);
spin_unlock_irq(&gp->lock);
#if 0
case ETHTOOL_GREGS: {
struct ethtool_regs regs;
u32 *regbuf;
int r = 0;
return 0;
}
if (copy_from_user(&regs, useraddr, sizeof(regs)))
return -EFAULT;
if (regs.len > SUNGEM_NREGS) {
regs.len = SUNGEM_NREGS;
}
regs.version = 0;
if (copy_to_user(useraddr, &regs, sizeof(regs)))
return -EFAULT;
static u32 gem_get_link(struct net_device *dev)
{
struct gem *gp = dev->priv;
if (!gp->hw_running)
return -ENODEV;
useraddr += offsetof(struct ethtool_regs, data);
/* Use kmalloc to avoid bloating the stack */
regbuf = kmalloc(4 * SUNGEM_NREGS, GFP_KERNEL);
if (!regbuf)
return -ENOMEM;
spin_lock_irq(&np->lock);
gem_get_regs(gp, regbuf);
spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, regbuf, regs.len*sizeof(u32)))
r = -EFAULT;
kfree(regbuf);
return r;
}
#endif
};
return (gp->lstate == link_up);
}
return -EOPNOTSUPP;
static u32 gem_get_msglevel(struct net_device *dev)
{
struct gem *gp = dev->priv;
return gp->msg_enable;
}
static void gem_set_msglevel(struct net_device *dev, u32 value)
{
struct gem *gp = dev->priv;
gp->msg_enable = value;
}
static struct ethtool_ops gem_ethtool_ops = {
.get_drvinfo = gem_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_settings = gem_get_settings,
.set_settings = gem_set_settings,
.nway_reset = gem_nway_reset,
.get_link = gem_get_link,
.get_msglevel = gem_get_msglevel,
.set_msglevel = gem_set_msglevel,
};
static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
......@@ -2501,10 +2458,6 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
down(&gp->pm_sem);
switch (cmd) {
case SIOCETHTOOL:
rc = gem_ethtool_ioctl(dev, ifr->ifr_data);
break;
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = gp->mii_phy_addr;
/* Fallthrough... */
......@@ -2812,6 +2765,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
dev->get_stats = gem_get_stats;
dev->set_multicast_list = gem_set_multicast;
dev->do_ioctl = gem_ioctl;
dev->ethtool_ops = &gem_ethtool_ops;
dev->tx_timeout = gem_tx_timeout;
dev->watchdog_timeo = 5 * HZ;
dev->change_mtu = gem_change_mtu;
......
......@@ -3,7 +3,7 @@
* auto carrier detecting ethernet driver. Also known as the
* "Happy Meal Ethernet" found on SunSwift SBUS cards.
*
* Copyright (C) 1996, 1998, 1999, 2002 David S. Miller (davem@redhat.com)
* Copyright (C) 1996, 1998, 1999, 2002, 2003 David S. Miller (davem@redhat.com)
*
* Changes :
* 2000/11/11 Willy Tarreau <willy AT meta-x.org>
......@@ -14,7 +14,7 @@
*/
static char version[] =
"sunhme.c:v2.01 26/Mar/2002 David S. Miller (davem@redhat.com)\n";
"sunhme.c:v2.02 24/Aug/2003 David S. Miller (davem@redhat.com)\n";
#include <linux/module.h>
#include <linux/config.h>
......@@ -2426,85 +2426,109 @@ static void happy_meal_set_multicast(struct net_device *dev)
}
/* Ethtool support... */
static int happy_meal_ioctl(struct net_device *dev,
struct ifreq *rq, int cmd)
static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct happy_meal *hp = dev->priv;
struct ethtool_cmd *ep_user = (struct ethtool_cmd *) rq->ifr_data;
struct ethtool_cmd ecmd;
if (cmd != SIOCETHTOOL)
return -EOPNOTSUPP;
if (copy_from_user(&ecmd, ep_user, sizeof(ecmd)))
return -EFAULT;
if (ecmd.cmd == ETHTOOL_GSET) {
ecmd.supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
/* XXX hardcoded stuff for now */
ecmd.port = PORT_TP; /* XXX no MII support */
ecmd.transceiver = XCVR_INTERNAL; /* XXX no external xcvr support */
ecmd.phy_address = 0; /* XXX fixed PHYAD */
/* Record PHY settings. */
spin_lock_irq(&hp->happy_lock);
hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
hp->sw_lpa = happy_meal_tcvr_read(hp, hp->tcvregs, MII_LPA);
spin_unlock_irq(&hp->happy_lock);
if (hp->sw_bmcr & BMCR_ANENABLE) {
ecmd.autoneg = AUTONEG_ENABLE;
ecmd.speed =
(hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
SPEED_100 : SPEED_10;
if (ecmd.speed == SPEED_100)
ecmd.duplex =
(hp->sw_lpa & (LPA_100FULL)) ?
DUPLEX_FULL : DUPLEX_HALF;
else
ecmd.duplex =
(hp->sw_lpa & (LPA_10FULL)) ?
DUPLEX_FULL : DUPLEX_HALF;
} else {
ecmd.autoneg = AUTONEG_DISABLE;
ecmd.speed =
(hp->sw_bmcr & BMCR_SPEED100) ?
SPEED_100 : SPEED_10;
ecmd.duplex =
(hp->sw_bmcr & BMCR_FULLDPLX) ?
cmd->supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
/* XXX hardcoded stuff for now */
cmd->port = PORT_TP; /* XXX no MII support */
cmd->transceiver = XCVR_INTERNAL; /* XXX no external xcvr support */
cmd->phy_address = 0; /* XXX fixed PHYAD */
/* Record PHY settings. */
spin_lock_irq(&hp->happy_lock);
hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
hp->sw_lpa = happy_meal_tcvr_read(hp, hp->tcvregs, MII_LPA);
spin_unlock_irq(&hp->happy_lock);
if (hp->sw_bmcr & BMCR_ANENABLE) {
cmd->autoneg = AUTONEG_ENABLE;
cmd->speed =
(hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
SPEED_100 : SPEED_10;
if (cmd->speed == SPEED_100)
cmd->duplex =
(hp->sw_lpa & (LPA_100FULL)) ?
DUPLEX_FULL : DUPLEX_HALF;
}
if (copy_to_user(ep_user, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
} else if (ecmd.cmd == ETHTOOL_SSET) {
/* Verify the settings we care about. */
if (ecmd.autoneg != AUTONEG_ENABLE &&
ecmd.autoneg != AUTONEG_DISABLE)
return -EINVAL;
if (ecmd.autoneg == AUTONEG_DISABLE &&
((ecmd.speed != SPEED_100 &&
ecmd.speed != SPEED_10) ||
(ecmd.duplex != DUPLEX_HALF &&
ecmd.duplex != DUPLEX_FULL)))
return -EINVAL;
/* Ok, do it to it. */
spin_lock_irq(&hp->happy_lock);
del_timer(&hp->happy_timer);
happy_meal_begin_auto_negotiation(hp,
hp->tcvregs,
&ecmd);
spin_unlock_irq(&hp->happy_lock);
else
cmd->duplex =
(hp->sw_lpa & (LPA_10FULL)) ?
DUPLEX_FULL : DUPLEX_HALF;
} else {
cmd->autoneg = AUTONEG_DISABLE;
cmd->speed =
(hp->sw_bmcr & BMCR_SPEED100) ?
SPEED_100 : SPEED_10;
cmd->duplex =
(hp->sw_bmcr & BMCR_FULLDPLX) ?
DUPLEX_FULL : DUPLEX_HALF;
}
return 0;
}
return 0;
} else
return -EOPNOTSUPP;
static int hme_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct happy_meal *hp = dev->priv;
/* Verify the settings we care about. */
if (cmd->autoneg != AUTONEG_ENABLE &&
cmd->autoneg != AUTONEG_DISABLE)
return -EINVAL;
if (cmd->autoneg == AUTONEG_DISABLE &&
((cmd->speed != SPEED_100 &&
cmd->speed != SPEED_10) ||
(cmd->duplex != DUPLEX_HALF &&
cmd->duplex != DUPLEX_FULL)))
return -EINVAL;
/* Ok, do it to it. */
spin_lock_irq(&hp->happy_lock);
del_timer(&hp->happy_timer);
happy_meal_begin_auto_negotiation(hp, hp->tcvregs, cmd);
spin_unlock_irq(&hp->happy_lock);
return 0;
}
static void hme_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct happy_meal *hp = dev->priv;
strcpy(info->driver, "sunhme");
strcpy(info->version, "2.02");
if (hp->happy_flags & HFLAG_PCI) {
struct pci_dev *pdev = hp->happy_dev;
strcpy(info->bus_info, pci_name(pdev));
} else {
struct sbus_dev *sdev = hp->happy_dev;
sprintf(info->bus_info, "SBUS:%d",
sdev->slot);
}
}
static u32 hme_get_link(struct net_device *dev)
{
struct happy_meal *hp = dev->priv;
spin_lock_irq(&hp->happy_lock);
hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR);
spin_unlock_irq(&hp->happy_lock);
return (hp->sw_bmsr & BMSR_LSTATUS);
}
static struct ethtool_ops hme_ethtool_ops = {
.get_settings = hme_get_settings,
.set_settings = hme_set_settings,
.get_drvinfo = hme_get_drvinfo,
.get_link = hme_get_link,
};
static int hme_version_printed;
#ifdef CONFIG_SBUS
......@@ -2797,7 +2821,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
dev->set_multicast_list = &happy_meal_set_multicast;
dev->tx_timeout = &happy_meal_tx_timeout;
dev->watchdog_timeo = 5*HZ;
dev->do_ioctl = &happy_meal_ioctl;
dev->ethtool_ops = &hme_ethtool_ops;
/* Happy Meal can do it all... except VLAN. */
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_VLAN_CHALLENGED;
......@@ -3141,7 +3165,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
dev->set_multicast_list = &happy_meal_set_multicast;
dev->tx_timeout = &happy_meal_tx_timeout;
dev->watchdog_timeo = 5*HZ;
dev->do_ioctl = &happy_meal_ioctl;
dev->ethtool_ops = &hme_ethtool_ops;
dev->irq = pdev->irq;
dev->dma = 0;
......
......@@ -70,7 +70,7 @@
#undef DEBUG_DRIVER
static char version[] =
"sunlance.c:v2.01 08/Nov/01 Miguel de Icaza (miguel@nuclecu.unam.mx)\n";
"sunlance.c:v2.02 24/Aug/03 Miguel de Icaza (miguel@nuclecu.unam.mx)\n";
static char lancestr[] = "LANCE";
......@@ -93,6 +93,7 @@ static char lancestr[] = "LANCE";
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <asm/system.h>
#include <asm/bitops.h>
......@@ -1287,6 +1288,30 @@ static void lance_free_hwresources(struct lance_private *lp)
}
}
/* Ethtool support... */
static void sparc_lance_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct lance_private *lp = dev->priv;
strcpy(info->driver, "sunlance");
strcpy(info->version, "2.02");
sprintf(info->bus_info, "SBUS:%d",
lp->sdev->slot);
}
static u32 sparc_lance_get_link(struct net_device *dev)
{
/* We really do not keep track of this, but this
* is better than not reporting anything at all.
*/
return 1;
}
static struct ethtool_ops sparc_lance_ethtool_ops = {
.get_drvinfo = sparc_lance_get_drvinfo,
.get_link = sparc_lance_get_link,
};
static int __init sparc_lance_init(struct net_device *dev,
struct sbus_dev *sdev,
struct sbus_dma *ledma,
......@@ -1456,6 +1481,7 @@ static int __init sparc_lance_init(struct net_device *dev,
dev->watchdog_timeo = 5*HZ;
dev->get_stats = &lance_get_stats;
dev->set_multicast_list = &lance_set_multicast;
dev->ethtool_ops = &sparc_lance_ethtool_ops;
dev->irq = sdev->irqs[0];
......
......@@ -4,11 +4,11 @@
* controller out there can be most efficiently programmed
* if you make it look like a LANCE.
*
* Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com)
* Copyright (C) 1996, 1999, 2003 David S. Miller (davem@redhat.com)
*/
static char version[] =
"sunqe.c:v2.9 9/11/99 David S. Miller (davem@redhat.com)\n";
"sunqe.c:v3.0 8/24/03 David S. Miller (davem@redhat.com)\n";
#include <linux/module.h>
#include <linux/kernel.h>
......@@ -26,6 +26,7 @@ static char version[] =
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <asm/system.h>
#include <asm/bitops.h>
......@@ -684,6 +685,35 @@ static void qe_set_multicast(struct net_device *dev)
netif_wake_queue(dev);
}
/* Ethtool support... */
static void qe_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
struct sunqe *qep = dev->priv;
strcpy(info->driver, "sunqe");
strcpy(info->version, "3.0");
sprintf(info->bus_info, "SBUS:%d",
qep->qe_sdev->slot);
}
static u32 qe_get_link(struct net_device *dev)
{
struct sunqe *qep = dev->priv;
unsigned long mregs = qep->mregs;
u8 phyconfig;
spin_lock_irq(&qep->lock);
phyconfig = sbus_readb(mregs + MREGS_PHYCONFIG);
spin_unlock_irq(&qep->lock);
return (phyconfig & MREGS_PHYCONFIG_LSTAT);
}
static struct ethtool_ops qe_ethtool_ops = {
.get_drvinfo = qe_get_drvinfo,
.get_link = qe_get_link,
};
/* This is only called once at boot time for each card probed. */
static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
{
......@@ -850,6 +880,7 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
qe_devs[i]->watchdog_timeo = 5*HZ;
qe_devs[i]->irq = sdev->irqs[0];
qe_devs[i]->dma = 0;
qe_devs[i]->ethtool_ops = &qe_ethtool_ops;
}
/* QEC receives interrupts from each QE, then it sends the actual
......
......@@ -28,7 +28,7 @@
static int rtc_busy = 0;
/* Retrieve the current date and time from the real time clock. */
void get_rtc_time(struct rtc_time *t)
static void get_rtc_time(struct rtc_time *t)
{
unsigned long regs = mstk48t02_regs;
u8 tmp;
......
......@@ -78,6 +78,14 @@ extern void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t
#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
(((PTR)->LEN_NAME) = (VAL))
/*
* Same as above, only with pages instead of mapped addresses.
*/
extern dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
unsigned long offset, size_t size, int direction);
extern void pci_unmap_page(struct pci_dev *hwdev,
dma_addr_t dma_address, size_t size, int direction);
/* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
* above pci_map_single interface. Here the scatter gather list
......
......@@ -8,11 +8,13 @@
#include <linux/config.h>
#include <linux/threads.h>
#include <linux/cpumask.h>
#include <asm/head.h>
#include <asm/btfixup.h>
#ifndef __ASSEMBLY__
#include <linux/cpumask.h>
/* PROM provided per-processor information we need
* to start them all up.
*/
......
......@@ -282,10 +282,11 @@
#define __NR_timer_gettime 263
#define __NR_timer_getoverrun 264
#define __NR_timer_delete 265
/* WARNING: You MAY NOT add syscall numbers larger than 265, since
#define __NR_timer_create 266
/* WARNING: You MAY NOT add syscall numbers larger than 266, since
* all of the syscall tables in the Sparc kernel are
* sized to have 266 entries (starting at zero). Therefore
* find a free slot in the 0-265 range.
* sized to have 267 entries (starting at zero). Therefore
* find a free slot in the 0-266 range.
*/
#define _syscall0(type,name) \
......
......@@ -83,7 +83,7 @@ typedef struct siginfo32 {
#ifdef __KERNEL__
typedef struct sigevent32 {
sigval_t sigev_value;
sigval_t32 sigev_value;
int sigev_signo;
int sigev_notify;
union {
......
......@@ -284,10 +284,11 @@
#define __NR_timer_gettime 263
#define __NR_timer_getoverrun 264
#define __NR_timer_delete 265
/* WARNING: You MAY NOT add syscall numbers larger than 265, since
#define __NR_timer_create 266
/* WARNING: You MAY NOT add syscall numbers larger than 266, since
* all of the syscall tables in the Sparc kernel are
* sized to have 266 entries (starting at zero). Therefore
* find a free slot in the 0-265 range.
* sized to have 267 entries (starting at zero). Therefore
* find a free slot in the 0-266 range.
*/
#define _syscall0(type,name) \
......
......@@ -464,6 +464,7 @@ long compat_timer_settime(timer_t timer_id, int flags,
if (get_compat_itimerspec(&newts, new))
return -EFAULT;
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_timer_settime(timer_id, flags, &newts, &oldts);
set_fs(oldfs);
if (!err && old && put_compat_itimerspec(old, &oldts))
......@@ -477,6 +478,7 @@ long compat_timer_gettime(timer_t timer_id, struct compat_itimerspec *setting)
mm_segment_t oldfs;
struct itimerspec ts;
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_timer_gettime(timer_id, &ts);
set_fs(oldfs);
if (!err && put_compat_itimerspec(setting, &ts))
......@@ -494,7 +496,8 @@ long compat_clock_settime(clockid_t which_clock, struct compat_timespec *tp)
struct timespec ts;
if (get_compat_timespec(&ts, tp))
return -EFAULT;
oldfs = get_fs();
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_clock_settime(which_clock, &ts);
set_fs(oldfs);
return err;
......@@ -508,7 +511,8 @@ long compat_clock_gettime(clockid_t which_clock, struct compat_timespec *tp)
long err;
mm_segment_t oldfs;
struct timespec ts;
oldfs = get_fs();
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_clock_gettime(which_clock, &ts);
set_fs(oldfs);
if (!err && put_compat_timespec(&ts, tp))
......@@ -524,7 +528,8 @@ long compat_clock_getres(clockid_t which_clock, struct compat_timespec *tp)
long err;
mm_segment_t oldfs;
struct timespec ts;
oldfs = get_fs();
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_clock_getres(which_clock, &ts);
set_fs(oldfs);
if (!err && put_compat_timespec(&ts, tp))
......@@ -546,7 +551,8 @@ long compat_clock_nanosleep(clockid_t which_clock, int flags,
struct timespec in, out;
if (get_compat_timespec(&in, rqtp))
return -EFAULT;
oldfs = get_fs();
oldfs = get_fs();
set_fs(KERNEL_DS);
err = sys_clock_nanosleep(which_clock, flags, &in, &out);
set_fs(oldfs);
if ((err == -ERESTART_RESTARTBLOCK) && rmtp &&
......
......@@ -948,11 +948,15 @@ void exit_itimers(struct task_struct *tsk)
*/
static int do_posix_gettime(struct k_clock *clock, struct timespec *tp)
{
struct timeval tv;
if (clock->clock_get)
return clock->clock_get(tp);
do_gettimeofday((struct timeval *) tp);
tp->tv_nsec *= NSEC_PER_USEC;
do_gettimeofday(&tv);
tp->tv_sec = tv.tv_sec;
tp->tv_nsec = tv.tv_usec * NSEC_PER_USEC;
return 0;
}
......
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