summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2007-10-21 00:55:56 +0000
committerBrad Smith <brad@cvs.openbsd.org>2007-10-21 00:55:56 +0000
commit5265482f2c277fda341da4b16011ffae3dcd7e96 (patch)
tree8db846500d97ba997449306bb7592579e1e0f220
parentb99208b992d5b3bb199cb2a5f8b182f62892df1a (diff)
Add ifmedia support.
Tested by todd@ From FreeBSD ok dlg@
-rw-r--r--sys/dev/isa/if_ex.c99
-rw-r--r--sys/dev/isa/if_exreg.h47
2 files changed, 121 insertions, 25 deletions
diff --git a/sys/dev/isa/if_ex.c b/sys/dev/isa/if_ex.c
index 7e27552cccf..7aad03f36c4 100644
--- a/sys/dev/isa/if_ex.c
+++ b/sys/dev/isa/if_ex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ex.c,v 1.29 2007/10/18 04:52:37 brad Exp $ */
+/* $OpenBSD: if_ex.c,v 1.30 2007/10/21 00:55:55 brad Exp $ */
/*
* Copyright (c) 1997, Donald A. Schmidt
* Copyright (c) 1996, Javier Martín Rueda (jmrueda@diatel.upm.es)
@@ -46,6 +46,7 @@
#include <sys/device.h>
#include <net/if.h>
+#include <net/if_media.h>
#ifdef INET
#include <netinet/in.h>
@@ -74,14 +75,10 @@ static int exintr_count = 0;
#define DODEBUG(level, action)
#endif
-#define Conn_BNC 1
-#define Conn_TPE 2
-#define Conn_AUI 3
-
struct ex_softc {
struct arpcom arpcom; /* Ethernet common data */
+ struct ifmedia ifmedia;
int iobase; /* I/O base address. */
- u_short connector; /* Connector type. */
u_short irq_no; /* IRQ number. */
u_int mem_size; /* Total memory size, in bytes. */
u_int rx_mem_size; /* Rx memory size (by default, first 3/4 of
@@ -113,6 +110,10 @@ void ex_stop(struct ex_softc *);
int ex_ioctl(struct ifnet *, u_long, caddr_t);
void ex_reset(struct ex_softc *);
void ex_watchdog(struct ifnet *);
+int ex_get_media(struct ex_softc *);
+
+int ex_ifmedia_upd(struct ifnet *);
+void ex_ifmedia_sts(struct ifnet *, struct ifmediareq *);
u_short ex_eeprom_read(struct ex_softc *, int);
int ex_look_for_card(struct isa_attach_args *, struct ex_softc *sc);
@@ -200,7 +201,6 @@ ex_probe(struct device *parent, void *match, void *aux)
* - Hardware Ethernet address.
* - IRQ number (if not supplied in config file, read it from
* EEPROM).
- * - Connector type.
*/
sc->iobase = ia->ia_iobase;
eaddr_tmp = ex_eeprom_read(sc, EE_Eth_Addr_Lo);
@@ -226,19 +226,10 @@ ex_probe(struct device *parent, void *match, void *aux)
printf("ex: invalid IRQ.\n");
return(0);
}
- CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
- tmp = CSR_READ_1(sc, REG3);
- if (tmp & TPE_bit)
- sc->connector = Conn_TPE;
- else if (tmp & BNC_bit)
- sc->connector = Conn_BNC;
- else
- sc->connector = Conn_AUI;
+
sc->mem_size = CARD_RAM_SIZE; /* XXX This should be read from the card
itself. */
- CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
-
DODEBUG(Start_End, printf("ex_probe: finish\n"););
return(1);
}
@@ -249,6 +240,8 @@ ex_attach(struct device *parent, struct device *self, void *aux)
struct ex_softc *sc = (void *)self;
struct isa_attach_args *ia = aux;
struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct ifmedia *ifm;
+ int temp;
DODEBUG(Start_End, printf("ex_attach: start\n"););
@@ -261,16 +254,28 @@ ex_attach(struct device *parent, struct device *self, void *aux)
| IFF_MULTICAST */
IFQ_SET_READY(&ifp->if_snd);
+ ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts);
+
+ temp = ex_eeprom_read(sc, EE_W5);
+ if (temp & EE_W5_PORT_TPE)
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL);
+ if (temp & EE_W5_PORT_BNC)
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL);
+ if (temp & EE_W5_PORT_AUI)
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL);
+
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_AUTO, 0, NULL);
+ ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_NONE, 0, NULL);
+ ifmedia_set(&sc->ifmedia, ex_get_media(sc));
+
+ ifm = &sc->ifmedia;
+ ifm->ifm_media = ifm->ifm_cur->ifm_media;
+ ex_ifmedia_upd(ifp);
+
if_attach(ifp);
ether_ifattach(ifp);
- printf(": address %s, connecter ",
+ printf(": address %s\n",
ether_sprintf(sc->arpcom.ac_enaddr));
- switch(sc->connector) {
- case Conn_TPE: printf("TPE\n"); break;
- case Conn_BNC: printf("BNC\n"); break;
- case Conn_AUI: printf("AUI\n"); break;
- default: printf("???\n");
- }
sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
IPL_NET, ex_intr, sc, self->dv_xname);
@@ -777,6 +782,10 @@ ex_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/* XXX Support not done yet. */
error = EINVAL;
break;
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd);
+ break;
default:
DODEBUG(Start_End, printf("unknown"););
error = ENOTTY;
@@ -820,6 +829,48 @@ ex_watchdog(struct ifnet *ifp)
DODEBUG(Start_End, printf("ex_watchdog: finish\n"););
}
+int
+ex_get_media(struct ex_softc *sc)
+{
+ int current, media;
+
+ media = ex_eeprom_read(sc, EE_W5);
+
+ CSR_WRITE_1(sc, CMD_REG, Bank2_Sel);
+ current = CSR_READ_1(sc, REG3);
+ CSR_WRITE_1(sc, CMD_REG, Bank0_Sel);
+
+ if ((current & TPE_bit) && (media & EE_W5_PORT_TPE))
+ return(IFM_ETHER|IFM_10_T);
+ if ((current & BNC_bit) && (media & EE_W5_PORT_BNC))
+ return(IFM_ETHER|IFM_10_2);
+
+ if (media & EE_W5_PORT_AUI)
+ return (IFM_ETHER|IFM_10_5);
+
+ return (IFM_ETHER|IFM_AUTO);
+}
+
+int
+ex_ifmedia_upd (struct ifnet *ifp)
+{
+ struct ex_softc *sc = ifp->if_softc;
+
+ if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER)
+ return (EINVAL);
+
+ return (0);
+}
+
+void
+ex_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
+{
+ struct ex_softc *sc = ifp->if_softc;
+
+ ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
+ ifmr->ifm_active = ex_get_media(sc);
+}
+
u_short
ex_eeprom_read(struct ex_softc *sc, int location)
{
diff --git a/sys/dev/isa/if_exreg.h b/sys/dev/isa/if_exreg.h
index 0e7c9a4065a..c511380e5b7 100644
--- a/sys/dev/isa/if_exreg.h
+++ b/sys/dev/isa/if_exreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_exreg.h,v 1.1 1997/09/11 21:30:49 gene Exp $ */
+/* $OpenBSD: if_exreg.h,v 1.2 2007/10/21 00:55:55 brad Exp $ */
/*
* Copyright (c) 1996, Javier Martín Rueda (jmrueda@diatel.upm.es)
* All rights reserved.
@@ -125,12 +125,57 @@
/* EEPROM memory positions (16-bit wide). */
+#define EE_W0 0x00
+# define EE_W0_PNP 0x0001
+# define EE_W0_BUS16 0x0004
+# define EE_W0_FLASH_ADDR_MASK 0x0038
+# define EE_W0_FLASH_ADDR_SHIFT 3
+# define EE_W0_AUTO_IO 0x0040
+# define EE_W0_FLASH 0x0100
+# define EE_W0_AUTO_NEG 0x0200
+# define EE_W0_IO_MASK 0xFC00
+# define EE_W0_IO_SHIFT 10
+
#define EE_IRQ_No 1
#define IRQ_No_Mask 0x07
+
+#define EE_W1 0x01
+# define EE_W1_INT_SEL 0x0007
+# define EE_W1_NO_LINK_INT 0x0008 /* Link Integrity Off */
+# define EE_W1_NO_POLARITY 0x0010 /* Polarity Correction Off */
+# define EE_W1_TPE_AUI 0x0020 /* 1 = TPE, 0 = AUI */
+# define EE_W1_NO_JABBER_PREV 0x0040 /* Jabber prevention Off */
+# define EE_W1_NO_AUTO_SELECT 0x0080 /* Auto Port Selection Off */
+# define EE_W1_SMOUT 0x0100 /* SMout Pin Control 0= Input */
+# define EE_W1_PROM 0x0200 /* Flash = 0, PROM = 1 */
+# define EE_W1_ALT_READY 0x2000 /* Alternate Ready, 0=normal */
+# define EE_W1_FULL_DUPLEX 0x8000
+
+#define EE_W2 0x02
+#define EE_W3 0x03
+#define EE_W4 0x04
+
#define EE_Eth_Addr_Lo 2
#define EE_Eth_Addr_Mid 3
#define EE_Eth_Addr_Hi 4
+#define EE_W5 0x05
+# define EE_W5_BNC_TPE 0x0001 /* 0 = TPE, 1 = BNC */
+# define EE_W5_BOOT_IPX 0x0002
+# define EE_W5_BOOT_ODI 0x0004
+# define EE_W5_BOOT_NDIS (EE_W5_BOOT_IPX|EE_W5_BOOT_ODI)
+# define EE_W5_NUM_CONN 0x0008 /* 0 = 2, 1 = 3 */
+# define EE_W5_NOFLASH 0x0010 /* No flash socket present */
+# define EE_W5_PORT_TPE 0x0020 /* TPE present */
+# define EE_W5_PORT_BNC 0x0040 /* BNC present */
+# define EE_W5_PORT_AUI 0x0080 /* AUI present */
+# define EE_W5_PWR_MGT 0x0100 /* Power Management */
+# define EE_W5_CP 0x0200 /* COncurrent Processing */
+
+#define EE_W6 0x05
+# define EE_W6_STEP_MASK 0x000F
+# define EE_W6_BOARD_MASK 0xF
+
/* EEPROM serial interface. */
#define EESK 0x01