summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--isys/Makefile2
-rw-r--r--isys/isys.c14
-rw-r--r--isys/isys.h3
-rw-r--r--isys/isys.py3
-rw-r--r--isys/linkdetect.c103
-rw-r--r--isys/mii.h84
6 files changed, 208 insertions, 1 deletions
diff --git a/isys/Makefile b/isys/Makefile
index e630f4e22..c06b9df7b 100644
--- a/isys/Makefile
+++ b/isys/Makefile
@@ -4,7 +4,7 @@ CFLAGS = -ffunction-sections -I$(PYTHONINCLUDE) -I.. -Wall -Os -g -DHAVE_NFS -D
OBJECTS = nfsmount.o nfsmount_clnt.o nfsmount_xdr.o imount.o \
smp.o moduleinfo.o devnodes.o cpio.o probe.o uncpio.o \
- lang.o isofs.o pdc.o dns.o
+ lang.o isofs.o pdc.o dns.o linkdetect.o
SOBJECTS = $(patsubst %.o,%.lo,$(OBJECTS))
SOURCES = $(patsubst %.o,%.c,$(OBJECTS)) isys.c
STATICOBJS = otherinsmod.o
diff --git a/isys/isys.c b/isys/isys.c
index a4c0bbf9b..4b3d1a91b 100644
--- a/isys/isys.c
+++ b/isys/isys.c
@@ -102,6 +102,7 @@ static PyObject * getFramebufferInfo(PyObject * s, PyObject * args);
static PyObject * printObject(PyObject * s, PyObject * args);
static PyObject * doGetPageSize(PyObject * s, PyObject * args);
static PyObject * py_bind_textdomain_codeset(PyObject * o, PyObject * args);
+static PyObject * getLinkStatus(PyObject * s, PyObject * args);
static PyMethodDef isysModuleMethods[] = {
{ "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL },
@@ -158,6 +159,7 @@ static PyMethodDef isysModuleMethods[] = {
{ "getpagesize", (PyCFunction) doGetPageSize, METH_VARARGS, NULL},
{ "printObject", (PyCFunction) printObject, METH_VARARGS, NULL},
{ "bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, METH_VARARGS, NULL},
+ { "getLinkStatus", (PyCFunction) getLinkStatus, METH_VARARGS, NULL },
{ NULL }
} ;
@@ -1611,6 +1613,18 @@ static PyObject * doGetPageSize(PyObject * s, PyObject * args) {
return Py_BuildValue("i", getpagesize());
}
+static PyObject * getLinkStatus(PyObject * s, PyObject * args) {
+ char *dev;
+ int ret;
+
+ if (!PyArg_ParseTuple(args, "s", &dev))
+ return NULL;
+
+ ret = get_link_status(dev);
+ /* returns 1 for link, 0 for no link, -1 for unknown */
+ return Py_BuildValue("i", ret);
+}
+
static PyObject * printObject (PyObject * o, PyObject * args) {
PyObject * obj;
char buf[256];
diff --git a/isys/isys.h b/isys/isys.h
index 4483b80f3..38fb0358e 100644
--- a/isys/isys.h
+++ b/isys/isys.h
@@ -56,4 +56,7 @@ int rmmod(char * modName);
/* returns 0 for true, !0 for false */
int fileIsIso(const char * file);
+/* returns 1 for link, 0 for no link, -1 for unknown */
+int get_link_status(char *ifname);
+
#endif
diff --git a/isys/isys.py b/isys/isys.py
index 0262bcf99..0c4f3502d 100644
--- a/isys/isys.py
+++ b/isys/isys.py
@@ -501,6 +501,9 @@ def ideCdRwList():
def getpagesize():
return _isys.getpagesize()
+def getLinkStatus(dev):
+ return _isys.getLinkStatus(dev)
+
printObject = _isys.printObject
bind_textdomain_codeset = _isys.bind_textdomain_codeset
diff --git a/isys/linkdetect.c b/isys/linkdetect.c
new file mode 100644
index 000000000..466cfd60d
--- /dev/null
+++ b/isys/linkdetect.c
@@ -0,0 +1,103 @@
+/*
+ * linkdetect.c - simple link detection
+ *
+ * heavily based on mii-tool.c from net-tools, just cut down to what we need
+ * for anaconda
+ *
+ * Copyright 2002 Red Hat, Inc.
+ * Copyright 2000 David A. Hinds -- dhinds@pcmcia.sourceforge.org
+ *
+ * Jeremy Katz <katzj@redhat.com>
+ *
+ * This software may be freely redistributed under the terms of the GNU
+ * general public license.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <net/if.h>
+
+#include "mii.h"
+
+static struct ifreq ifr;
+
+static int mdio_read(int skfd, int location)
+{
+ struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
+ mii->reg_num = location;
+ if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) {
+ fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name,
+ strerror(errno));
+ return -1;
+ }
+ return mii->val_out;
+}
+
+/* we don't need writing right now */
+#if 0
+static void mdio_write(int skfd, int location, int value)
+{
+ struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
+ mii->reg_num = location;
+ mii->val_in = value;
+ if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) {
+ fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name,
+ strerror(errno));
+ }
+}
+#endif
+
+
+
+int get_link_status(char *ifname) {
+ struct mii_data *mii = (struct mii_data *)&ifr.ifr_data;
+ int sock, i, mii_val[32];
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
+ return -1;
+ }
+
+ /* Get the vitals from the interface. */
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) {
+ if (errno != ENODEV)
+ fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n",
+ ifname, strerror(errno));
+ return -1;
+ }
+
+ /* Some bits in the BMSR are latched, but we can't rely on being
+ the only reader, so only the current values are meaningful */
+ mdio_read(sock, MII_BMSR);
+ for (i = 0; i < 8; i++)
+ mii_val[i] = mdio_read(sock, i);
+
+ if (mii_val[MII_BMCR] == 0xffff) {
+ fprintf(stderr, " No MII transceiver present!.\n");
+ return -1;
+ }
+
+ if (mii_val[MII_BMSR] & MII_BMSR_LINK_VALID)
+ return 1;
+ else
+ return 0;
+}
+
+#ifdef STANDALONE
+/* hooray for stupid test programs! */
+int main(int argc, char **argv) {
+ printf("link status of eth0 is %d\n", get_link_status("eth0"));
+}
+#endif
diff --git a/isys/mii.h b/isys/mii.h
new file mode 100644
index 000000000..2ec6425b5
--- /dev/null
+++ b/isys/mii.h
@@ -0,0 +1,84 @@
+/*
+ * mii.h 1.4 2000/04/25 22:06:15
+ *
+ * Media Independent Interface support: register layout and ioctl's
+ *
+ * Copyright (C) 2000 David A. Hinds -- dhinds@pcmcia.sourceforge.org
+ */
+
+#ifndef _LINUX_MII_H
+#define _LINUX_MII_H
+
+/* network interface ioctl's for MII commands */
+#ifndef SIOCGMIIPHY
+#define SIOCGMIIPHY 0x8947 /* Read from current PHY */
+#define SIOCGMIIREG 0x8948 /* Read any PHY register */
+#define SIOCSMIIREG 0x8949 /* Write any PHY register */
+#endif
+
+#include <linux/types.h>
+
+/* This data structure is used for all the MII ioctl's */
+struct mii_data {
+ __u16 phy_id;
+ __u16 reg_num;
+ __u16 val_in;
+ __u16 val_out;
+};
+
+/* Basic Mode Control Register */
+#define MII_BMCR 0x00
+#define MII_BMCR_RESET 0x8000
+#define MII_BMCR_LOOPBACK 0x4000
+#define MII_BMCR_100MBIT 0x2000
+#define MII_BMCR_AN_ENA 0x1000
+#define MII_BMCR_ISOLATE 0x0400
+#define MII_BMCR_RESTART 0x0200
+#define MII_BMCR_DUPLEX 0x0100
+#define MII_BMCR_COLTEST 0x0080
+
+/* Basic Mode Status Register */
+#define MII_BMSR 0x01
+#define MII_BMSR_CAP_MASK 0xf800
+#define MII_BMSR_100BASET4 0x8000
+#define MII_BMSR_100BASETX_FD 0x4000
+#define MII_BMSR_100BASETX_HD 0x2000
+#define MII_BMSR_10BASET_FD 0x1000
+#define MII_BMSR_10BASET_HD 0x0800
+#define MII_BMSR_NO_PREAMBLE 0x0040
+#define MII_BMSR_AN_COMPLETE 0x0020
+#define MII_BMSR_REMOTE_FAULT 0x0010
+#define MII_BMSR_AN_ABLE 0x0008
+#define MII_BMSR_LINK_VALID 0x0004
+#define MII_BMSR_JABBER 0x0002
+#define MII_BMSR_EXT_CAP 0x0001
+
+#define MII_PHY_ID1 0x02
+#define MII_PHY_ID2 0x03
+
+/* Auto-Negotiation Advertisement Register */
+#define MII_ANAR 0x04
+/* Auto-Negotiation Link Partner Ability Register */
+#define MII_ANLPAR 0x05
+#define MII_AN_NEXT_PAGE 0x8000
+#define MII_AN_ACK 0x4000
+#define MII_AN_REMOTE_FAULT 0x2000
+#define MII_AN_ABILITY_MASK 0x07e0
+#define MII_AN_FLOW_CONTROL 0x0400
+#define MII_AN_100BASET4 0x0200
+#define MII_AN_100BASETX_FD 0x0100
+#define MII_AN_100BASETX_HD 0x0080
+#define MII_AN_10BASET_FD 0x0040
+#define MII_AN_10BASET_HD 0x0020
+#define MII_AN_PROT_MASK 0x001f
+#define MII_AN_PROT_802_3 0x0001
+
+/* Auto-Negotiation Expansion Register */
+#define MII_ANER 0x06
+#define MII_ANER_MULT_FAULT 0x0010
+#define MII_ANER_LP_NP_ABLE 0x0008
+#define MII_ANER_NP_ABLE 0x0004
+#define MII_ANER_PAGE_RX 0x0002
+#define MII_ANER_LP_AN_ABLE 0x0001
+
+#endif /* _LINUX_MII_H */