Module Name: src Committed By: phx Date: Sat Mar 12 16:41:23 UTC 2011
Modified Files: src/sys/arch/sandpoint/stand/altboot: brdsetup.c globals.h main.c nif.c stg.c Log Message: Introduced an optional shutdown function for all network interfaces. This is needed to stop a NIF and make it return to a known state. A running NIF may cause all sorts of bad effects, like for example making it impossible to reboot a board without a hardware-reset function. To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/sys/arch/sandpoint/stand/altboot/brdsetup.c \ src/sys/arch/sandpoint/stand/altboot/globals.h \ src/sys/arch/sandpoint/stand/altboot/main.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/sandpoint/stand/altboot/nif.c \ src/sys/arch/sandpoint/stand/altboot/stg.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/sandpoint/stand/altboot/brdsetup.c diff -u src/sys/arch/sandpoint/stand/altboot/brdsetup.c:1.9 src/sys/arch/sandpoint/stand/altboot/brdsetup.c:1.10 --- src/sys/arch/sandpoint/stand/altboot/brdsetup.c:1.9 Fri Mar 11 17:46:30 2011 +++ src/sys/arch/sandpoint/stand/altboot/brdsetup.c Sat Mar 12 16:41:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: brdsetup.c,v 1.9 2011/03/11 17:46:30 phx Exp $ */ +/* $NetBSD: brdsetup.c,v 1.10 2011/03/12 16:41:23 phx Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -31,6 +31,7 @@ #include <sys/param.h> +#include <powerpc/psl.h> #include <powerpc/oea/spr.h> #include <lib/libsa/stand.h> @@ -128,6 +129,8 @@ static void brdfixup(void); static void setup(void); +static inline uint32_t mfmsr(void); +static inline void mtmsr(uint32_t); static inline uint32_t cputype(void); static inline u_quad_t mftb(void); static void init_uart(unsigned, unsigned, uint8_t); @@ -252,7 +255,7 @@ busclock = (extclk * pci_to_memclk[(val >> 19) & 0x1f] + 10) / 10; /* PLLRATIO from HID1 */ - __asm ("mfspr %0,1009" : "=r"(val)); + asm volatile ("mfspr %0,1009" : "=r"(val)); cpuclock = ((uint64_t)busclock * mem_to_cpuclk[val >> 27] + 10) / 10; } else @@ -696,11 +699,23 @@ void _rtt(void) { + uint32_t msr; + + netif_shutdown_all(); if (brdprop->reset != NULL) (*brdprop->reset)(); - else + else { + msr = mfmsr(); + msr &= ~PSL_EE; + mtmsr(msr); + asm volatile ("sync; isync"); + asm volatile("mtspr %0,%1" : : "K"(81), "r"(0)); + msr &= ~(PSL_ME | PSL_DR | PSL_IR); + mtmsr(msr); + asm volatile ("sync; isync"); run(0, 0, 0, 0, (void *)0xFFF00100); /* reset entry */ + } /*NOTREACHED*/ } @@ -785,11 +800,26 @@ } static inline uint32_t +mfmsr(void) +{ + uint32_t msr; + + asm volatile ("mfmsr %0" : "=r"(msr)); + return msr; +} + +static inline void +mtmsr(uint32_t msr) +{ + asm volatile ("mtmsr %0" : : "r"(msr)); +} + +static inline uint32_t cputype(void) { uint32_t pvr; - __asm volatile ("mfpvr %0" : "=r"(pvr)); + asm volatile ("mfpvr %0" : "=r"(pvr)); return pvr >> 16; } @@ -801,7 +831,7 @@ asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw %0,%1; bne 1b" : "=r"(tb), "=r"(scratch)); - return (tb); + return tb; } static void Index: src/sys/arch/sandpoint/stand/altboot/globals.h diff -u src/sys/arch/sandpoint/stand/altboot/globals.h:1.9 src/sys/arch/sandpoint/stand/altboot/globals.h:1.10 --- src/sys/arch/sandpoint/stand/altboot/globals.h:1.9 Thu Mar 10 21:11:49 2011 +++ src/sys/arch/sandpoint/stand/altboot/globals.h Sat Mar 12 16:41:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: globals.h,v 1.9 2011/03/10 21:11:49 phx Exp $ */ +/* $NetBSD: globals.h,v 1.10 2011/03/12 16:41:23 phx Exp $ */ #ifdef DEBUG #define DPRINTF(x) printf x @@ -133,6 +133,7 @@ int net_strategy(void *, int, daddr_t, size_t, void *, size_t *); int netif_init(void *); +void netif_shutdown_all(void); int netif_open(void *); int netif_close(int); @@ -140,7 +141,8 @@ int xxx ## _match(unsigned, void *); \ void * xxx ## _init(unsigned, void *); \ int xxx ## _send(void *, char *, unsigned); \ - int xxx ## _recv(void *, char *, unsigned, unsigned) + int xxx ## _recv(void *, char *, unsigned, unsigned); \ + void xxx ## _shutdown(void *) NIF_DECL(fxp); NIF_DECL(tlp); Index: src/sys/arch/sandpoint/stand/altboot/main.c diff -u src/sys/arch/sandpoint/stand/altboot/main.c:1.9 src/sys/arch/sandpoint/stand/altboot/main.c:1.10 --- src/sys/arch/sandpoint/stand/altboot/main.c:1.9 Sun Mar 6 18:22:13 2011 +++ src/sys/arch/sandpoint/stand/altboot/main.c Sat Mar 12 16:41:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.9 2011/03/06 18:22:13 phx Exp $ */ +/* $NetBSD: main.c,v 1.10 2011/03/12 16:41:23 phx Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -250,6 +250,8 @@ btinfo_modulelist_size); } + netif_shutdown_all(); + __syncicache((void *)marks[MARK_ENTRY], (u_int)marks[MARK_SYM] - (u_int)marks[MARK_ENTRY]); Index: src/sys/arch/sandpoint/stand/altboot/nif.c diff -u src/sys/arch/sandpoint/stand/altboot/nif.c:1.4 src/sys/arch/sandpoint/stand/altboot/nif.c:1.5 --- src/sys/arch/sandpoint/stand/altboot/nif.c:1.4 Sun Mar 6 20:36:29 2011 +++ src/sys/arch/sandpoint/stand/altboot/nif.c Sat Mar 12 16:41:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: nif.c,v 1.4 2011/03/06 20:36:29 phx Exp $ */ +/* $NetBSD: nif.c,v 1.5 2011/03/12 16:41:23 phx Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -47,7 +47,7 @@ void *(*init)(unsigned, void *); int (*send)(void *, char *, unsigned); int (*recv)(void *, char *, unsigned, unsigned); - int (*halt)(void *, int); + void (*shutdown)(void *); void *priv; }; @@ -58,7 +58,7 @@ { "tlp", tlp_match, tlp_init, tlp_send, tlp_recv }, { "re", rge_match, rge_init, rge_send, rge_recv }, { "sk", skg_match, skg_init, skg_send, skg_recv }, - { "stge", stg_match, stg_init, stg_send, stg_recv }, + { "stge", stg_match, stg_init, stg_send, stg_recv, stg_shutdown }, }; static int nnifdv = sizeof(lnifdv)/sizeof(lnifdv[0]); @@ -80,6 +80,7 @@ if ((*dv->match)(tag, NULL) > 0) goto found; } + pci->drv = NULL; return 0; found: pci->drv = dv->priv = (*dv->init)(tag, enaddr); @@ -95,9 +96,23 @@ return 1; } +void +netif_shutdown_all(void) +{ + struct nifdv *dv; + + /* currently there can be only one NIF */ + dv = netdesc.io_netif; + if (dv != NULL) + if (dv->shutdown != NULL) + (*dv->shutdown)(dv->priv); + memset(&netdesc, 0, sizeof(netdesc)); +} + int netif_open(void *cookie) { + /* single action */ return 0; } @@ -105,6 +120,7 @@ int netif_close(int sock) { + /* nothing to do for the HW */ return 0; } Index: src/sys/arch/sandpoint/stand/altboot/stg.c diff -u src/sys/arch/sandpoint/stand/altboot/stg.c:1.4 src/sys/arch/sandpoint/stand/altboot/stg.c:1.5 --- src/sys/arch/sandpoint/stand/altboot/stg.c:1.4 Fri Mar 11 17:46:30 2011 +++ src/sys/arch/sandpoint/stand/altboot/stg.c Sat Mar 12 16:41:23 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: stg.c,v 1.4 2011/03/11 17:46:30 phx Exp $ */ +/* $NetBSD: stg.c,v 1.5 2011/03/12 16:41:23 phx Exp $ */ /*- * Copyright (c) 2011 Frank Wille. @@ -132,6 +132,7 @@ uint8_t phyctrl_saved; }; +static void stg_reset(struct local *); static int mii_read(struct local *, int, int); static void mii_write(struct local *, int, int, int); static void mii_initphy(struct local *); @@ -173,20 +174,7 @@ if (l->csr == 0) l->csr = DEVTOV(PCI_XIOBASE + (pcicfgread(tag, 0x10) & ~01)); - /* reset the chip */ - reg = CSR_READ_4(l, STGE_AsicCtrl); - CSR_WRITE_4(l, STGE_AsicCtrl, reg | AC_GlobalReset | AC_RxReset | - AC_TxReset | AC_DMA | AC_FIFO | AC_Network | AC_Host | - AC_AutoInit | ((reg & AC_PhyMedia) ? AC_RstOut : 0)); - DELAY(50000); - for (i = 0; i < 1000; i++) { - DELAY(5000); - if ((CSR_READ_4(l, STGE_AsicCtrl) & AC_ResetBusy) == 0) - break; - } - if (i >= 1000) - printf("NIC reset failed to complete!\n"); - DELAY(1000); + stg_reset(l); mii_initphy(l); @@ -286,6 +274,19 @@ return l; } +void +stg_shutdown(void *dev) +{ + struct local *l = dev; + + /* + * We have to reset the chip, when we don't need it anymore, + * otherwise bad things will happen (e.g. the DSM-G600 will no + * longer be able to reboot). + */ + stg_reset(l); +} + int stg_send(void *dev, char *buf, unsigned len) { @@ -353,6 +354,27 @@ return len; } +static void +stg_reset(struct local *l) +{ + uint32_t reg; + int i; + + reg = CSR_READ_4(l, STGE_AsicCtrl); + CSR_WRITE_4(l, STGE_AsicCtrl, reg | AC_GlobalReset | AC_RxReset | + AC_TxReset | AC_DMA | AC_FIFO | AC_Network | AC_Host | + AC_AutoInit | ((reg & AC_PhyMedia) ? AC_RstOut : 0)); + DELAY(50000); + for (i = 0; i < 1000; i++) { + DELAY(5000); + if ((CSR_READ_4(l, STGE_AsicCtrl) & AC_ResetBusy) == 0) + break; + } + if (i >= 1000) + printf("NIC reset failed to complete!\n"); + DELAY(1000); +} + #define R0110 6 /* 0110b read op */ #define W0101 5 /* 0101b write op */ #define A10 2 /* 10b ack turn around */