This commit is contained in:
attilio 2011-05-29 18:33:13 +00:00
parent bc42b89c8c
commit 8dd6262cd3
11 changed files with 534 additions and 17 deletions

View File

@ -1753,7 +1753,12 @@ void
enable_multicast_if(struct interface *iface, struct sockaddr_storage *maddr)
{
#ifdef MCAST
#ifdef IP_MULTICAST_LOOP
/*u_char*/ TYPEOF_IP_MULTICAST_LOOP off = 0;
#endif
#ifdef IPV6_MULTICAST_LOOP
u_int off6 = 0; /* RFC 3493, 5.2. defines type unsigned int */
#endif
switch (maddr->ss_family)
{
@ -1797,9 +1802,9 @@ enable_multicast_if(struct interface *iface, struct sockaddr_storage *maddr)
* Don't send back to itself, but allow it to fail to set it
*/
if (setsockopt(iface->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
(char *) &off, sizeof(off)) == -1) {
(char *) &off6, sizeof(off6)) == -1) {
netsyslog(LOG_ERR,
"setsockopt IP_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
"setsockopt IPV6_MULTICAST_LOOP failure: %m on socket %d, addr %s for multicast address %s",
iface->fd, stoa(&iface->sin), stoa(maddr));
}
#endif

View File

@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd November 23, 2010
.Dd May 29, 2011
.Dt VGE 4
.Os
.Sh NAME
@ -66,13 +66,14 @@ The MAC supports TCP/IP hardware
checksums (IPv4 only), TCP large send, VLAN tag insertion and stripping,
as well as VLAN filtering, a 64-entry CAM filter and a 64-entry VLAN filter,
64-bit multicast hash filter, 4 separate transmit DMA queues, flow control
and jumbo frames up to 16K in size.
and jumbo frames (not on VT6130/VT6132) up to 16K in size.
The Velocity family controllers have a 16K receive FIFO and 48K transmit FIFO.
.Pp
The
.Nm
driver takes advantage of the controller's checksum offload and VLAN
tagging features, as well as the jumbo frame and CAM filter support.
tagging features, as well as the jumbo frame (except VT6130/VT6132) and CAM
filter support.
The CAM filter is used for multicast address filtering to provide
64 perfect multicast address filter support.
If it is necessary for the interface to join more than 64 multicast
@ -81,6 +82,8 @@ groups, the driver will switch over to using the hash filter.
The jumbo frame support can be enabled by setting the interface MTU
to any value larger than the default of 1500 bytes, up to a maximum
of 9000 bytes.
Jumbo frames are disabled on the VT6130/VT6132 controllers because the TX
MAC will hang when trying to send a frame that is larger than 4K.
The receive and transmit checksum offload support
can be toggled on and off using the
.Xr ifconfig 8

View File

@ -103,6 +103,7 @@ loader.help: help.common help.ofw
.PATH: ${.CURDIR}/../../forth
FILES= loader.help loader.4th support.4th loader.conf
FILES+= screen.4th frames.4th
FILES+= beastie.4th brand.4th check-password.4th color.4th delay.4th
FILES+= menu.4th menu-commands.4th shortcuts.4th version.4th
FILESDIR_loader.conf= /boot/defaults

View File

@ -27,6 +27,7 @@ dev/cfi/cfi_bus_fdt.c optional cfi fdt
dev/fb/fb.c optional sc
dev/fdt/fdt_powerpc.c optional fdt
dev/hwpmc/hwpmc_powerpc.c optional hwpmc
dev/iicbus/ad7417.c optional ad7417 powermac
dev/iicbus/ds1775.c optional ds1775 powermac
dev/iicbus/max6690.c optional max6690 powermac
dev/kbd/kbd.c optional sc

457
sys/dev/iicbus/ad7417.c Normal file
View File

@ -0,0 +1,457 @@
/*-
* Copyright (c) 2010 Andreas Tobler
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/callout.h>
#include <sys/conf.h>
#include <sys/cpu.h>
#include <sys/ctype.h>
#include <sys/kernel.h>
#include <sys/reboot.h>
#include <sys/rman.h>
#include <sys/sysctl.h>
#include <sys/limits.h>
#include <machine/bus.h>
#include <machine/md_var.h>
#include <dev/iicbus/iicbus.h>
#include <dev/iicbus/iiconf.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#define FCU_ZERO_C_TO_K 2732
/* CPU A/B sensors, temp and adc: AD7417. */
#define AD7417_TEMP 0x00
#define AD7417_CONFIG 0x01
#define AD7417_ADC 0x04
#define AD7417_CONFIG2 0x05
#define AD7417_CONFMASK 0xe0
uint8_t adc741x_config;
struct ad7417_sensor {
int id;
char location[32];
enum {
ADC7417_TEMP_SENSOR,
ADC7417_ADC_SENSOR
} type;
};
/* Regular bus attachment functions */
static int ad7417_probe(device_t);
static int ad7417_attach(device_t);
/* Utility functions */
static int ad7417_sensor_sysctl(SYSCTL_HANDLER_ARGS);
static int ad7417_write(device_t dev, uint32_t addr, uint8_t reg,
uint8_t *buf, int len);
static int ad7417_read_1(device_t dev, uint32_t addr, uint8_t reg,
uint8_t *data);
static int ad7417_read_2(device_t dev, uint32_t addr, uint8_t reg,
uint16_t *data);
struct ad7417_softc {
device_t sc_dev;
uint32_t sc_addr;
struct ad7417_sensor *sc_sensors;
int sc_nsensors;
};
static device_method_t ad7417_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ad7417_probe),
DEVMETHOD(device_attach, ad7417_attach),
{ 0, 0 },
};
static driver_t ad7417_driver = {
"ad7417",
ad7417_methods,
sizeof(struct ad7417_softc)
};
static devclass_t ad7417_devclass;
DRIVER_MODULE(ad7417, iicbus, ad7417_driver, ad7417_devclass, 0, 0);
MALLOC_DEFINE(M_AD7417, "ad7417", "Supply-Monitor AD7417");
static int
ad7417_write(device_t dev, uint32_t addr, uint8_t reg, uint8_t *buff, int len)
{
unsigned char buf[4];
struct iic_msg msg[] = {
{ addr, IIC_M_WR, 0, buf }
};
msg[0].len = len + 1;
buf[0] = reg;
memcpy(buf + 1, buff, len);
if (iicbus_transfer(dev, msg, 1) != 0) {
device_printf(dev, "iicbus write failed\n");
return (EIO);
}
return (0);
}
static int
ad7417_read_1(device_t dev, uint32_t addr, uint8_t reg, uint8_t *data)
{
uint8_t buf[4];
struct iic_msg msg[2] = {
{ addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
{ addr, IIC_M_RD, 1, buf },
};
if (iicbus_transfer(dev, msg, 2) != 0) {
device_printf(dev, "iicbus read failed\n");
return (EIO);
}
*data = *((uint8_t*)buf);
return (0);
}
static int
ad7417_read_2(device_t dev, uint32_t addr, uint8_t reg, uint16_t *data)
{
uint8_t buf[4];
struct iic_msg msg[2] = {
{ addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
{ addr, IIC_M_RD, 2, buf },
};
if (iicbus_transfer(dev, msg, 2) != 0) {
device_printf(dev, "iicbus read failed\n");
return (EIO);
}
*data = *((uint16_t*)buf);
return (0);
}
static int
ad7417_init_adc(device_t dev, uint32_t addr)
{
uint8_t buf;
adc741x_config = 0;
/* Clear Config2 */
buf = 0;
ad7417_write(dev, addr, AD7417_CONFIG2, &buf, 1);
/* Read & cache Config1 */
buf = 0;
ad7417_write(dev, addr, AD7417_CONFIG, &buf, 1);
ad7417_read_1(dev, addr, AD7417_CONFIG, &buf);
adc741x_config = (uint8_t)buf;
/* Disable shutdown mode */
adc741x_config &= 0xfe;
buf = adc741x_config;
ad7417_write(dev, addr, AD7417_CONFIG, &buf, 1);
return (0);
}
static int
ad7417_probe(device_t dev)
{
const char *name, *compatible;
struct ad7417_softc *sc;
name = ofw_bus_get_name(dev);
compatible = ofw_bus_get_compat(dev);
if (!name)
return (ENXIO);
if (strcmp(name, "supply-monitor") != 0 ||
strcmp(compatible, "ad7417") != 0)
return (ENXIO);
sc = device_get_softc(dev);
sc->sc_dev = dev;
sc->sc_addr = iicbus_get_addr(dev);
device_set_desc(dev, "Supply-Monitor AD7417");
return (0);
}
/*
* This function returns the number of sensors. If we call it the second time
* and we have allocated memory for sc->sc_sensors, we fill in the properties.
*/
static int
ad7417_fill_sensor_prop(device_t dev)
{
phandle_t child;
struct ad7417_softc *sc;
u_int id[10];
char location[96];
char type[32];
int i = 0, j, len = 0, prop_len, prev_len = 0;
sc = device_get_softc(dev);
child = ofw_bus_get_node(dev);
/* Fill the sensor location property. */
prop_len = OF_getprop(child, "hwsensor-location", location,
sizeof(location));
while (len < prop_len) {
if (sc->sc_sensors != NULL)
strcpy(sc->sc_sensors[i].location, location + len);
prev_len = strlen(location + len) + 1;
len += prev_len;
i++;
}
if (sc->sc_sensors == NULL)
return (i);
/* Fill the fan type property. */
len = 0;
i = 0;
prev_len = 0;
prop_len = OF_getprop(child, "hwsensor-type", type, sizeof(type));
while (len < prop_len) {
if (strcmp(type + len, "temperature") == 0)
sc->sc_sensors[i].type = ADC7417_TEMP_SENSOR;
else
sc->sc_sensors[i].type = ADC7417_ADC_SENSOR;
prev_len = strlen(type + len) + 1;
len += prev_len;
i++;
}
/* Fill the sensor id property. Taken from OF. */
prop_len = OF_getprop(child, "hwsensor-id", id, sizeof(id));
for (j = 0; j < i; j++)
sc->sc_sensors[j].id = id[j];
return (i);
}
static int
ad7417_attach(device_t dev)
{
struct ad7417_softc *sc;
struct sysctl_oid *oid, *sensroot_oid;
struct sysctl_ctx_list *ctx;
char sysctl_name[32];
int i, j;
const char *unit;
const char *desc;
sc = device_get_softc(dev);
sc->sc_nsensors = 0;
/* Count the actual number of sensors. */
sc->sc_nsensors = ad7417_fill_sensor_prop(dev);
device_printf(dev, "%d sensors detected.\n", sc->sc_nsensors);
if (sc->sc_nsensors == 0)
device_printf(dev, "WARNING: No AD7417 sensors detected!\n");
sc->sc_sensors = malloc (sc->sc_nsensors * sizeof(struct ad7417_sensor),
M_AD7417, M_WAITOK | M_ZERO);
ctx = device_get_sysctl_ctx(dev);
sensroot_oid = SYSCTL_ADD_NODE(ctx,
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "sensor",
CTLFLAG_RD, 0, "AD7417 Sensor Information");
/* Now we can fill the properties into the allocated struct. */
sc->sc_nsensors = ad7417_fill_sensor_prop(dev);
/* Add sysctls for the sensors. */
for (i = 0; i < sc->sc_nsensors; i++) {
for (j = 0; j < strlen(sc->sc_sensors[i].location); j++) {
sysctl_name[j] = tolower(sc->sc_sensors[i].location[j]);
if (isspace(sysctl_name[j]))
sysctl_name[j] = '_';
}
sysctl_name[j] = 0;
oid = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(sensroot_oid),
OID_AUTO,
sysctl_name, CTLFLAG_RD, 0,
"Sensor Information");
if (sc->sc_sensors[i].type == ADC7417_TEMP_SENSOR) {
unit = "temp";
desc = "Sensor temp in C";
} else {
unit = "volt";
desc = "Sensor Volt in V";
}
/* I use i to pass the sensor id. */
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
unit, CTLTYPE_INT | CTLFLAG_RD, dev,
i, ad7417_sensor_sysctl,
sc->sc_sensors[i].type == ADC7417_TEMP_SENSOR ?
"IK" : "I", desc);
}
/* Dump sensor location, ID & type. */
if (bootverbose) {
device_printf(dev, "Sensors\n");
for (i = 0; i < sc->sc_nsensors; i++) {
device_printf(dev, "Location: %s ID: %d type: %d\n",
sc->sc_sensors[i].location,
sc->sc_sensors[i].id,
sc->sc_sensors[i].type);
}
}
return (0);
}
static int
ad7417_get_temp(device_t dev, uint32_t addr, int *temp)
{
uint16_t buf[2];
uint16_t read;
ad7417_read_2(dev, addr, AD7417_TEMP, buf);
read = *((int16_t*)buf);
/* The ADC is 10 bit, the resolution is 0.25 C.
The temperature is in tenth kelvin.
*/
*temp = (((int16_t)(read & 0xffc0)) >> 6) * 25 / 10;
return (0);
}
static int
ad7417_get_adc(device_t dev, uint32_t addr, unsigned int *value,
uint8_t chan)
{
uint8_t cfg1, tmp;
uint16_t read, buf[2];
ad7417_read_1(dev, addr, AD7417_CONFIG, &cfg1);
tmp = chan << 5;
cfg1 = (cfg1 & ~AD7417_CONFMASK) | (tmp & AD7417_CONFMASK);
ad7417_write(dev, addr, AD7417_CONFIG, &cfg1, 1);
ad7417_read_2(dev, addr, AD7417_ADC, buf);
read = *((uint16_t*)buf);
*value = ((uint32_t)read) >> 6;
return (0);
}
static int
ad7417_sensor_read(device_t dev, struct ad7417_sensor *sens, int *temp)
{
struct ad7417_softc *sc;
sc = device_get_softc(dev);
/* Init the ADC. */
ad7417_init_adc(sc->sc_dev, sc->sc_addr);
if (sens->type == ADC7417_TEMP_SENSOR) {
ad7417_get_temp(sc->sc_dev, sc->sc_addr, temp);
*temp += FCU_ZERO_C_TO_K;
} else {
uint8_t chan;
switch (sens->id) {
case 11:
case 16:
chan = 1;
break;
case 12:
case 17:
chan = 2;
break;
case 13:
case 18:
chan = 3;
break;
case 14:
case 19:
chan = 4;
break;
default:
chan = 1;
}
ad7417_get_adc(sc->sc_dev, sc->sc_addr, temp, chan);
}
return (0);
}
static int
ad7417_sensor_sysctl(SYSCTL_HANDLER_ARGS)
{
device_t dev;
struct ad7417_softc *sc;
struct ad7417_sensor *sens;
int value = 0;
int error;
int temp;
dev = arg1;
sc = device_get_softc(dev);
sens = &sc->sc_sensors[arg2];
error = ad7417_sensor_read(dev, sens, &value);
if (error != 0)
return (error);
temp = value;
error = sysctl_handle_int(oidp, &temp, 0, req);
return (error);
}

View File

@ -1845,10 +1845,16 @@ dontblock:
}
SBLASTRECORDCHK(&so->so_rcv);
SBLASTMBUFCHK(&so->so_rcv);
error = sbwait(&so->so_rcv);
if (error) {
SOCKBUF_UNLOCK(&so->so_rcv);
goto release;
/*
* We could receive some data while was notifying
* the protocol. Skip blocking in this case.
*/
if (so->so_rcv.sb_mb == NULL) {
error = sbwait(&so->so_rcv);
if (error) {
SOCKBUF_UNLOCK(&so->so_rcv);
goto release;
}
}
m = so->so_rcv.sb_mb;
if (m != NULL)

View File

@ -548,7 +548,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
* is the same as before, then the call is
* un-necessarily executed here.
*/
in_ifscrub(ifp, ia, 0);
in_ifscrub(ifp, ia, LLE_STATIC);
ia->ia_sockmask = ifra->ifra_mask;
ia->ia_sockmask.sin_family = AF_INET;
ia->ia_subnetmask =
@ -557,7 +557,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
}
if ((ifp->if_flags & IFF_POINTOPOINT) &&
(ifra->ifra_dstaddr.sin_family == AF_INET)) {
in_ifscrub(ifp, ia, 0);
in_ifscrub(ifp, ia, LLE_STATIC);
ia->ia_dstaddr = ifra->ifra_dstaddr;
maskIsNew = 1; /* We lie; but the effect's the same */
}
@ -1179,14 +1179,20 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags)
&& (ia->ia_ifp->if_type != IFT_CARP)) {
ifa_ref(&ia->ia_ifa);
IN_IFADDR_RUNLOCK();
rtinit(&(target->ia_ifa), (int)RTM_DELETE,
error = rtinit(&(target->ia_ifa), (int)RTM_DELETE,
rtinitflags(target));
target->ia_flags &= ~IFA_ROUTE;
if (error == 0)
target->ia_flags &= ~IFA_ROUTE;
else
log(LOG_INFO, "in_scrubprefix: err=%d, old prefix delete failed\n",
error);
error = rtinit(&ia->ia_ifa, (int)RTM_ADD,
rtinitflags(ia) | RTF_UP);
if (error == 0)
ia->ia_flags |= IFA_ROUTE;
else
log(LOG_INFO, "in_scrubprefix: err=%d, new prefix add failed\n",
error);
ifa_free(&ia->ia_ifa);
return (error);
}
@ -1210,9 +1216,12 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags)
/*
* As no-one seem to have this prefix, we can remove the route.
*/
rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
target->ia_flags &= ~IFA_ROUTE;
return (0);
error = rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target));
if (error == 0)
target->ia_flags &= ~IFA_ROUTE;
else
log(LOG_INFO, "in_scrubprefix: err=%d, prefix delete failed\n", error);
return (error);
}
#undef rtinitflags

View File

@ -174,6 +174,7 @@ device sbp # SCSI over FireWire (Requires scbus and da)
device fwe # Ethernet over FireWire (non-standard!)
# Misc
device ad7417 # PowerMac7,2 temperature sensor
device ds1775 # PowerMac7,2 temperature sensor
device fcu # Apple Fan Control Unit
device max6690 # PowerMac7,2 temperature sensor

View File

@ -175,6 +175,7 @@ device sbp # SCSI over FireWire (Requires scbus and da)
device fwe # Ethernet over FireWire (non-standard!)
# Misc
device ad7417 # PowerMac7,2 temperature sensor
device ds1775 # PowerMac7,2 temperature sensor
device fcu # Apple Fan Control Unit
device max6690 # PowerMac7,2 temperature sensor

View File

@ -39,6 +39,7 @@ device kiic # Apple Keywest I2C Controller
device ofwd # Open Firmware disks
device adb # Apple Desktop Bus
device cuda # VIA-CUDA ADB interface
device ad7417 # PowerMac7,2 temperature sensor
device ds1775 # PowerMac7,2 temperature sensor
device fcu # Apple Fan Control Unit
device max6690 # PowerMac7,2 temperature sensor

View File

@ -0,0 +1,32 @@
# $FreeBSD: projects/largeSMP/tools/regression/bin/sh/builtins/set1.0 222451 2011-05-29 15:02:10Z jilles $
set +C
set +f
set -e
settings=$(set +o)
set -C
set -f
set +e
case $- in
*C*) ;;
*) echo missing C ;;
esac
case $- in
*f*) ;;
*) echo missing C ;;
esac
case $- in
*e*) echo bad e ;;
esac
eval "$settings"
case $- in
*C*) echo bad C ;;
esac
case $- in
*f*) echo bad f ;;
esac
case $- in
*e*) ;;
*) echo missing e ;;
esac