Merge from head up to r262472.
This commit is contained in:
commit
b6b1de44ba
@ -40,14 +40,14 @@
|
||||
.Nd command interpreter (shell)
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl /+abCEefIimnPpTuVvx
|
||||
.Op Fl /+abCEefhIimnPpTuVvx
|
||||
.Op Fl /+o Ar longname
|
||||
.Oo
|
||||
.Ar script
|
||||
.Op Ar arg ...
|
||||
.Oc
|
||||
.Nm
|
||||
.Op Fl /+abCEefIimnPpTuVvx
|
||||
.Op Fl /+abCEefhIimnPpTuVvx
|
||||
.Op Fl /+o Ar longname
|
||||
.Fl c Ar string
|
||||
.Oo
|
||||
@ -55,7 +55,7 @@
|
||||
.Op Ar arg ...
|
||||
.Oc
|
||||
.Nm
|
||||
.Op Fl /+abCEefIimnPpTuVvx
|
||||
.Op Fl /+abCEefhIimnPpTuVvx
|
||||
.Op Fl /+o Ar longname
|
||||
.Fl s
|
||||
.Op Ar arg ...
|
||||
|
@ -339,7 +339,7 @@ name_found:
|
||||
|
||||
static int
|
||||
_citrus_prop_parse_element(struct _memstream * __restrict ms,
|
||||
const _citrus_prop_hint_t * __restrict hints, void ** __restrict context)
|
||||
const _citrus_prop_hint_t * __restrict hints, void * __restrict context)
|
||||
{
|
||||
int ch, errnum;
|
||||
#define _CITRUS_PROP_HINT_NAME_LEN_MAX 255
|
||||
@ -435,8 +435,7 @@ _citrus_prop_parse_variable(const _citrus_prop_hint_t * __restrict hints,
|
||||
if (ch == EOF || ch == '\0')
|
||||
break;
|
||||
_memstream_ungetc(&ms, ch);
|
||||
errnum = _citrus_prop_parse_element(
|
||||
&ms, hints, (void ** __restrict)context);
|
||||
errnum = _citrus_prop_parse_element(&ms, hints, context);
|
||||
if (errnum != 0)
|
||||
return (errnum);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ typedef struct _citrus_prop_hint_t _citrus_prop_hint_t;
|
||||
|
||||
#define _CITRUS_PROP_CB0_T(_func_, _type_) \
|
||||
typedef int (*_citrus_prop_##_func_##_cb_func_t) \
|
||||
(void ** __restrict, const char *, _type_); \
|
||||
(void * __restrict, const char *, _type_); \
|
||||
typedef struct { \
|
||||
_citrus_prop_##_func_##_cb_func_t func; \
|
||||
} _citrus_prop_##_func_##_cb_t;
|
||||
@ -52,7 +52,7 @@ _CITRUS_PROP_CB0_T(str, const char *)
|
||||
|
||||
#define _CITRUS_PROP_CB1_T(_func_, _type_) \
|
||||
typedef int (*_citrus_prop_##_func_##_cb_func_t) \
|
||||
(void ** __restrict, const char *, _type_, _type_); \
|
||||
(void * __restrict, const char *, _type_, _type_); \
|
||||
typedef struct { \
|
||||
_citrus_prop_##_func_##_cb_func_t func; \
|
||||
} _citrus_prop_##_func_##_cb_t;
|
||||
|
@ -172,7 +172,7 @@ _citrus_BIG5_check_excludes(_BIG5EncodingInfo *ei, wint_t c)
|
||||
}
|
||||
|
||||
static int
|
||||
_citrus_BIG5_fill_rowcol(void ** __restrict ctx, const char * __restrict s,
|
||||
_citrus_BIG5_fill_rowcol(void * __restrict ctx, const char * __restrict s,
|
||||
uint64_t start, uint64_t end)
|
||||
{
|
||||
_BIG5EncodingInfo *ei;
|
||||
@ -191,7 +191,7 @@ _citrus_BIG5_fill_rowcol(void ** __restrict ctx, const char * __restrict s,
|
||||
|
||||
static int
|
||||
/*ARGSUSED*/
|
||||
_citrus_BIG5_fill_excludes(void ** __restrict ctx,
|
||||
_citrus_BIG5_fill_excludes(void * __restrict ctx,
|
||||
const char * __restrict s __unused, uint64_t start, uint64_t end)
|
||||
{
|
||||
_BIG5EncodingInfo *ei;
|
||||
@ -237,7 +237,6 @@ static int
|
||||
_citrus_BIG5_encoding_module_init(_BIG5EncodingInfo * __restrict ei,
|
||||
const void * __restrict var, size_t lenvar)
|
||||
{
|
||||
void *ctx = (void *)ei;
|
||||
const char *s;
|
||||
int err;
|
||||
|
||||
@ -259,9 +258,9 @@ _citrus_BIG5_encoding_module_init(_BIG5EncodingInfo * __restrict ei,
|
||||
}
|
||||
|
||||
/* fallback Big5-1984, for backward compatibility. */
|
||||
_citrus_BIG5_fill_rowcol((void **)&ctx, "row", 0xA1, 0xFE);
|
||||
_citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0x40, 0x7E);
|
||||
_citrus_BIG5_fill_rowcol((void **)&ctx, "col", 0xA1, 0xFE);
|
||||
_citrus_BIG5_fill_rowcol(ei, "row", 0xA1, 0xFE);
|
||||
_citrus_BIG5_fill_rowcol(ei, "col", 0x40, 0x7E);
|
||||
_citrus_BIG5_fill_rowcol(ei, "col", 0xA1, 0xFE);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -65,8 +65,8 @@ typedef enum {
|
||||
} charset_t;
|
||||
|
||||
typedef struct {
|
||||
int end;
|
||||
int start;
|
||||
int end;
|
||||
int width;
|
||||
} range_t;
|
||||
|
||||
@ -505,12 +505,12 @@ _citrus_HZ_encoding_module_uninit(_HZEncodingInfo *ei)
|
||||
}
|
||||
|
||||
static int
|
||||
_citrus_HZ_parse_char(void **context, const char *name __unused, const char *s)
|
||||
_citrus_HZ_parse_char(void *context, const char *name __unused, const char *s)
|
||||
{
|
||||
escape_t *escape;
|
||||
void **p;
|
||||
|
||||
p = (void **)*context;
|
||||
p = (void **)context;
|
||||
escape = (escape_t *)p[0];
|
||||
if (escape->ch != '\0')
|
||||
return (EINVAL);
|
||||
@ -522,14 +522,14 @@ _citrus_HZ_parse_char(void **context, const char *name __unused, const char *s)
|
||||
}
|
||||
|
||||
static int
|
||||
_citrus_HZ_parse_graphic(void **context, const char *name, const char *s)
|
||||
_citrus_HZ_parse_graphic(void *context, const char *name, const char *s)
|
||||
{
|
||||
_HZEncodingInfo *ei;
|
||||
escape_t *escape;
|
||||
graphic_t *graphic;
|
||||
void **p;
|
||||
|
||||
p = (void **)*context;
|
||||
p = (void **)context;
|
||||
escape = (escape_t *)p[0];
|
||||
ei = (_HZEncodingInfo *)p[1];
|
||||
graphic = malloc(sizeof(*graphic));
|
||||
@ -591,13 +591,13 @@ _CITRUS_PROP_HINT_END
|
||||
};
|
||||
|
||||
static int
|
||||
_citrus_HZ_parse_escape(void **context, const char *name, const char *s)
|
||||
_citrus_HZ_parse_escape(void *context, const char *name, const char *s)
|
||||
{
|
||||
_HZEncodingInfo *ei;
|
||||
escape_t *escape;
|
||||
void *p[2];
|
||||
|
||||
ei = (_HZEncodingInfo *)*context;
|
||||
ei = (_HZEncodingInfo *)context;
|
||||
escape = malloc(sizeof(*escape));
|
||||
if (escape == NULL)
|
||||
return (EINVAL);
|
||||
|
@ -433,7 +433,6 @@ static int
|
||||
_citrus_VIQR_encoding_module_init(_VIQREncodingInfo * __restrict ei,
|
||||
const void * __restrict var __unused, size_t lenvar __unused)
|
||||
{
|
||||
const mnemonic_def_t *p;
|
||||
const char *s;
|
||||
size_t i, n;
|
||||
int errnum;
|
||||
@ -457,7 +456,10 @@ _citrus_VIQR_encoding_module_init(_VIQREncodingInfo * __restrict ei,
|
||||
return (errnum);
|
||||
}
|
||||
}
|
||||
for (i = 0;; ++i) {
|
||||
#if mnemonic_ext_size > 0
|
||||
for (i = 0; i < mnemonic_ext_size; ++i) {
|
||||
const mnemonic_def_t *p;
|
||||
|
||||
p = &mnemonic_ext[i];
|
||||
n = strlen(p->name);
|
||||
if (ei->mb_cur_max < n)
|
||||
@ -469,6 +471,7 @@ _citrus_VIQR_encoding_module_init(_VIQREncodingInfo * __restrict ei,
|
||||
return (errnum);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2009 Rohit Grover <rgrover1 at gmail dot com>.
|
||||
.\" Copyright (c) 2014 Rohit Grover <rgrover1 at gmail dot com>.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 7, 2014
|
||||
.Dd February 24, 2014
|
||||
.Dt ATP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -41,8 +41,7 @@ your kernel configuration file:
|
||||
.Cd "device usb"
|
||||
.Ed
|
||||
.Pp
|
||||
Alternatively, to load the driver as a
|
||||
module at boot time, place the following line in
|
||||
Alternatively, to load the driver as a module at boot time, place the following line in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
atp_load="YES"
|
||||
@ -50,24 +49,21 @@ atp_load="YES"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides support for the Apple Internal Trackpad
|
||||
device found in many Apple laptops.
|
||||
driver provides support for the Apple Internal Trackpad device found in many
|
||||
Apple laptops. Older (Fountain/Geyser) and the newer (Wellspring) trackpad
|
||||
families are all supported through a unified driver.
|
||||
.Pp
|
||||
The driver simulates a three\-button mouse using multi\-finger tap detection.
|
||||
Single finger tap generates a left\-button click; two\-finger tap maps to the
|
||||
middle button; whereas a three\-finger tap gets treated as a right button
|
||||
click.
|
||||
.Pp
|
||||
There is support for 2\-finger horizontal scrolling, which translates to
|
||||
page\-back/forward events; vertical multi\-finger scrolling emulates the mouse
|
||||
wheel.
|
||||
.Pp
|
||||
The driver simulates a three\-button mouse using multi\-finger tap
|
||||
detection.
|
||||
.
|
||||
A single\-finger tap generates a left button click;
|
||||
two\-finger tap maps to the middle button; whereas a three\-finger tap
|
||||
gets treated as a right button click.
|
||||
.
|
||||
A double\-tap followed by a drag is treated as a selection gesture; a
|
||||
virtual left\-button click is assumed for the lifespan of the drag.
|
||||
.
|
||||
.Nm
|
||||
attempts to filter away activity at the horizontal edges of the
|
||||
trackpad\-\-this is to keep unintentional palm movement from being
|
||||
considered as user input.
|
||||
.
|
||||
.Pp
|
||||
.Nm
|
||||
supports dynamic reconfiguration using
|
||||
@ -76,6 +72,28 @@ through nodes under
|
||||
.Nm hw.usb.atp .
|
||||
Pointer sensitivity can be controlled using the sysctl tunable
|
||||
.Nm hw.usb.atp.scale_factor .
|
||||
Smaller values of
|
||||
.Fa scale_factor
|
||||
result in faster movement.
|
||||
.
|
||||
A simple high-pass filter is used to reduce contributions
|
||||
from small movements; the threshold for this filter may be controlled by
|
||||
.Nm hw.usb.atp.small_movement .
|
||||
.
|
||||
The maximum tolerable duration of a touch gesture is controlled by
|
||||
.Nm hw.usb.atp.touch_timeout
|
||||
(in microseconds); beyond this period, touches are considered to be slides.
|
||||
(This conversion also happens when a finger stroke accumulates at least
|
||||
.Nm hw.usb.atp.slide_min_movement
|
||||
movement (in mickeys).
|
||||
.
|
||||
The maximum time (in microseconds) to allow an association between a double-
|
||||
tap and drag gesture may be controlled by
|
||||
.Nm hw.usb.atp.double_tap_threshold .
|
||||
.
|
||||
Should one want to disable tap detection and rely only upon physical button
|
||||
presses, set the following sysctl to a value of 2
|
||||
.Nm hw.usb.atp.tap_minimum .
|
||||
.
|
||||
.Sh HARDWARE
|
||||
The
|
||||
@ -84,6 +102,8 @@ driver provides support for the following Product IDs:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.It
|
||||
PowerBooks, iBooks (IDs: 0x020e, 0x020f, 0x0210, 0x0214, 0x0215, 0x0216)
|
||||
.It
|
||||
Core Duo MacBook & MacBook Pro (IDs: 0x0217, 0x0218, 0x0219)
|
||||
.It
|
||||
Core2 Duo MacBook & MacBook Pro (IDs: 0x021a, 0x021b, 0x021c)
|
||||
@ -95,6 +115,14 @@ Core2 Duo MacBook3,1 (IDs: 0x0229, 0x022a, 0x022b)
|
||||
15 inch PowerBook (IDs: 0x020e, 0x020f, 0x0215)
|
||||
.It
|
||||
17 inch PowerBook (ID: 0x020d)
|
||||
.It
|
||||
Almost all recent Macbook-Pros and Airs (IDs: 0x0223, 0x0223, 0x0224, 0x0224,
|
||||
0x0225, 0x0225, 0x0230, 0x0230, 0x0231, 0x0231, 0x0232, 0x0232, 0x0236,
|
||||
0x0236, 0x0237, 0x0237, 0x0238, 0x0238, 0x023f, 0x023f, 0x0240, 0x0241,
|
||||
0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0249, 0x024a, 0x024b,
|
||||
0x024c, 0x024d, 0x024e, 0x0252, 0x0252, 0x0253, 0x0253, 0x0254, 0x0254,
|
||||
0x0259, 0x025a, 0x025b, 0x0262, 0x0262, 0x0263, 0x0264, 0x0290, 0x0291,
|
||||
0x0292)
|
||||
.El
|
||||
.Pp
|
||||
To discover the product\-id of a touchpad, search for 'Trackpad' in the
|
||||
|
@ -383,6 +383,9 @@ a.out backward compatibility libraries
|
||||
DTrace library scripts
|
||||
.It Pa engines/
|
||||
OpenSSL (Cryptography/SSL toolkit) dynamically loadable engines
|
||||
.It Pa private/
|
||||
Private system libraries not for use by third-party programs.
|
||||
ABI and API stability are not guaranteed.
|
||||
.El
|
||||
.Pp
|
||||
.It Pa libdata/
|
||||
|
@ -146,6 +146,7 @@ struct cpu_functions arm7tdmi_cpufuncs = {
|
||||
(void *)arm7tdmi_cache_flushID, /* dcache_inv_range */
|
||||
(void *)cpufunc_nullop, /* dcache_wb_range */
|
||||
|
||||
cpufunc_nullop, /* idcache_inv_all */
|
||||
arm7tdmi_cache_flushID, /* idcache_wbinv_all */
|
||||
(void *)arm7tdmi_cache_flushID, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -208,6 +209,7 @@ struct cpu_functions arm8_cpufuncs = {
|
||||
/*XXX*/ (void *)arm8_cache_purgeID, /* dcache_inv_range */
|
||||
(void *)arm8_cache_cleanID, /* dcache_wb_range */
|
||||
|
||||
cpufunc_nullop, /* idcache_inv_all */
|
||||
arm8_cache_purgeID, /* idcache_wbinv_all */
|
||||
(void *)arm8_cache_purgeID, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -269,6 +271,7 @@ struct cpu_functions arm9_cpufuncs = {
|
||||
arm9_dcache_inv_range, /* dcache_inv_range */
|
||||
arm9_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv4_idcache_inv_all, /* idcache_inv_all */
|
||||
arm9_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
arm9_idcache_wbinv_range, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -331,6 +334,7 @@ struct cpu_functions armv5_ec_cpufuncs = {
|
||||
armv5_ec_dcache_inv_range, /* dcache_inv_range */
|
||||
armv5_ec_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv4_idcache_inv_all, /* idcache_inv_all */
|
||||
armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
armv5_ec_idcache_wbinv_range, /* idcache_wbinv_range */
|
||||
|
||||
@ -392,6 +396,7 @@ struct cpu_functions sheeva_cpufuncs = {
|
||||
sheeva_dcache_inv_range, /* dcache_inv_range */
|
||||
sheeva_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv4_idcache_inv_all, /* idcache_inv_all */
|
||||
armv5_ec_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
sheeva_idcache_wbinv_range, /* idcache_wbinv_all */
|
||||
|
||||
@ -454,6 +459,7 @@ struct cpu_functions arm10_cpufuncs = {
|
||||
arm10_dcache_inv_range, /* dcache_inv_range */
|
||||
arm10_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv4_idcache_inv_all, /* idcache_inv_all */
|
||||
arm10_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
arm10_idcache_wbinv_range, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -515,6 +521,7 @@ struct cpu_functions pj4bv7_cpufuncs = {
|
||||
armv7_dcache_inv_range, /* dcache_inv_range */
|
||||
armv7_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv7_idcache_inv_all, /* idcache_inv_all */
|
||||
armv7_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
armv7_idcache_wbinv_range, /* idcache_wbinv_all */
|
||||
|
||||
@ -577,6 +584,7 @@ struct cpu_functions sa110_cpufuncs = {
|
||||
/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */
|
||||
sa1_cache_cleanD_rng, /* dcache_wb_range */
|
||||
|
||||
sa1_cache_flushID, /* idcache_inv_all */
|
||||
sa1_cache_purgeID, /* idcache_wbinv_all */
|
||||
sa1_cache_purgeID_rng, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -638,6 +646,7 @@ struct cpu_functions sa11x0_cpufuncs = {
|
||||
/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */
|
||||
sa1_cache_cleanD_rng, /* dcache_wb_range */
|
||||
|
||||
sa1_cache_flushID, /* idcache_inv_all */
|
||||
sa1_cache_purgeID, /* idcache_wbinv_all */
|
||||
sa1_cache_purgeID_rng, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -699,6 +708,7 @@ struct cpu_functions ixp12x0_cpufuncs = {
|
||||
/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */
|
||||
sa1_cache_cleanD_rng, /* dcache_wb_range */
|
||||
|
||||
sa1_cache_flushID, /* idcache_inv_all */
|
||||
sa1_cache_purgeID, /* idcache_wbinv_all */
|
||||
sa1_cache_purgeID_rng, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -763,6 +773,7 @@ struct cpu_functions xscale_cpufuncs = {
|
||||
xscale_cache_flushD_rng, /* dcache_inv_range */
|
||||
xscale_cache_cleanD_rng, /* dcache_wb_range */
|
||||
|
||||
xscale_cache_flushID, /* idcache_inv_all */
|
||||
xscale_cache_purgeID, /* idcache_wbinv_all */
|
||||
xscale_cache_purgeID_rng, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -826,6 +837,7 @@ struct cpu_functions xscalec3_cpufuncs = {
|
||||
xscale_cache_flushD_rng, /* dcache_inv_range */
|
||||
xscalec3_cache_cleanD_rng, /* dcache_wb_range */
|
||||
|
||||
xscale_cache_flushID, /* idcache_inv_all */
|
||||
xscalec3_cache_purgeID, /* idcache_wbinv_all */
|
||||
xscalec3_cache_purgeID_rng, /* idcache_wbinv_range */
|
||||
xscalec3_l2cache_purge, /* l2cache_wbinv_all */
|
||||
@ -888,6 +900,7 @@ struct cpu_functions fa526_cpufuncs = {
|
||||
fa526_dcache_inv_range, /* dcache_inv_range */
|
||||
fa526_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv4_idcache_inv_all, /* idcache_inv_all */
|
||||
fa526_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
fa526_idcache_wbinv_range, /* idcache_wbinv_range */
|
||||
cpufunc_nullop, /* l2cache_wbinv_all */
|
||||
@ -949,6 +962,7 @@ struct cpu_functions arm1136_cpufuncs = {
|
||||
armv6_dcache_inv_range, /* dcache_inv_range */
|
||||
armv6_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv6_idcache_inv_all, /* idcache_inv_all */
|
||||
arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */
|
||||
|
||||
@ -1010,6 +1024,7 @@ struct cpu_functions arm1176_cpufuncs = {
|
||||
armv6_dcache_inv_range, /* dcache_inv_range */
|
||||
armv6_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv6_idcache_inv_all, /* idcache_inv_all */
|
||||
arm11x6_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
arm11x6_idcache_wbinv_range, /* idcache_wbinv_range */
|
||||
|
||||
@ -1072,6 +1087,7 @@ struct cpu_functions cortexa_cpufuncs = {
|
||||
armv7_dcache_inv_range, /* dcache_inv_range */
|
||||
armv7_dcache_wb_range, /* dcache_wb_range */
|
||||
|
||||
armv7_idcache_inv_all, /* idcache_inv_all */
|
||||
armv7_idcache_wbinv_all, /* idcache_wbinv_all */
|
||||
armv7_idcache_wbinv_range, /* idcache_wbinv_range */
|
||||
|
||||
|
@ -71,3 +71,9 @@ ENTRY(armv4_drain_writebuf)
|
||||
RET
|
||||
END(armv4_drain_writebuf)
|
||||
|
||||
ENTRY(armv4_idcache_inv_all)
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7, 0 /* invalidate all I+D cache */
|
||||
RET
|
||||
END(armv4_drain_writebuf)
|
||||
|
||||
|
@ -148,3 +148,9 @@ ENTRY(armv6_dcache_wbinv_all)
|
||||
END(armv6_idcache_wbinv_all)
|
||||
END(armv6_dcache_wbinv_all)
|
||||
|
||||
ENTRY(armv6_idcache_inv_all)
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7, 0 /* invalidate all I+D cache */
|
||||
RET
|
||||
END(armv6_idcache_inv_all)
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2010 Per Odlund <per.odlund@armagedon.se>
|
||||
* Copyright (C) 2011 MARVELL INTERNATIONAL LTD.
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -305,3 +306,40 @@ ENTRY(armv7_auxctrl)
|
||||
RET
|
||||
END(armv7_auxctrl)
|
||||
|
||||
ENTRY(armv7_idcache_inv_all)
|
||||
mov r0, #0
|
||||
mcr p15, 2, r0, c0, c0, 0 @ set cache level to L1
|
||||
mrc p15, 1, r0, c0, c0, 0 @ read CCSIDR
|
||||
|
||||
ubfx r2, r0, #13, #15 @ get num sets - 1 from CCSIDR
|
||||
ubfx r3, r0, #3, #10 @ get numways - 1 from CCSIDR
|
||||
clz r1, r3 @ number of bits to MSB of way
|
||||
lsl r3, r3, r1 @ shift into position
|
||||
mov ip, #1 @
|
||||
lsl ip, ip, r1 @ ip now contains the way decr
|
||||
|
||||
ubfx r0, r0, #0, #3 @ get linesize from CCSIDR
|
||||
add r0, r0, #4 @ apply bias
|
||||
lsl r2, r2, r0 @ shift sets by log2(linesize)
|
||||
add r3, r3, r2 @ merge numsets - 1 with numways - 1
|
||||
sub ip, ip, r2 @ subtract numsets - 1 from way decr
|
||||
mov r1, #1
|
||||
lsl r1, r1, r0 @ r1 now contains the set decr
|
||||
mov r2, ip @ r2 now contains set way decr
|
||||
|
||||
/* r3 = ways/sets, r2 = way decr, r1 = set decr, r0 and ip are free */
|
||||
1: mcr p15, 0, r3, c7, c6, 2 @ invalidate line
|
||||
movs r0, r3 @ get current way/set
|
||||
beq 2f @ at 0 means we are done.
|
||||
movs r0, r0, lsl #10 @ clear way bits leaving only set bits
|
||||
subne r3, r3, r1 @ non-zero?, decrement set #
|
||||
subeq r3, r3, r2 @ zero?, decrement way # and restore set count
|
||||
b 1b
|
||||
|
||||
2: dsb @ wait for stores to finish
|
||||
mov r0, #0 @ and ...
|
||||
mcr p15, 0, r0, c7, c5, 0 @ invalidate instruction+branch cache
|
||||
isb @ instruction sync barrier
|
||||
bx lr @ return
|
||||
END(armv7_l1cache_inv_all)
|
||||
|
||||
|
@ -128,10 +128,10 @@ cpu_mp_start(void)
|
||||
bzero((void *)temp_pagetable_va, L1_TABLE_SIZE);
|
||||
for (addr = arm_physmem_kernaddr; addr <= addr_end; addr += L1_S_SIZE) {
|
||||
((int *)(temp_pagetable_va))[addr >> L1_S_SHIFT] =
|
||||
L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)|L1_S_DOM(PMAP_DOMAIN_KERNEL)|addr;
|
||||
L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_B|L1_S_AP(AP_KRW)|L1_S_DOM(PMAP_DOMAIN_KERNEL)|addr;
|
||||
((int *)(temp_pagetable_va))[(addr -
|
||||
arm_physmem_kernaddr + KERNVIRTADDR) >> L1_S_SHIFT] =
|
||||
L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW)|L1_S_DOM(PMAP_DOMAIN_KERNEL)|addr;
|
||||
L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_B|L1_S_AP(AP_KRW)|L1_S_DOM(PMAP_DOMAIN_KERNEL)|addr;
|
||||
}
|
||||
|
||||
#if defined(CPU_MV_PJ4B)
|
||||
@ -173,6 +173,8 @@ init_secondary(int cpu)
|
||||
uint32_t loop_counter;
|
||||
int start = 0, end = 0;
|
||||
|
||||
cpu_idcache_inv_all();
|
||||
|
||||
cpu_setup(NULL);
|
||||
setttb(pmap_pa);
|
||||
cpu_tlb_flushID();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
ident IMX6
|
||||
include "../freescale/imx/std.imx6"
|
||||
|
||||
options HZ=250 # Scheduling quantum is 4 milliseconds.
|
||||
|
26
sys/arm/conf/QUARTZ
Normal file
26
sys/arm/conf/QUARTZ
Normal file
@ -0,0 +1,26 @@
|
||||
# Kernel configuration for Device Solutions Quartz Module.
|
||||
#
|
||||
# For more information on this file, please read the config(5) manual page,
|
||||
# and/or the handbook section on Kernel Configuration Files:
|
||||
#
|
||||
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
|
||||
#
|
||||
# The handbook is also available locally in /usr/share/doc/handbook
|
||||
# if you've installed the doc distribution, otherwise always see the
|
||||
# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
|
||||
# latest information.
|
||||
#
|
||||
# An exhaustive list of options and more detailed explanations of the
|
||||
# device lines is also present in the ../../conf/NOTES and NOTES files.
|
||||
# If you are in doubt as to the purpose or necessity of a line, check first
|
||||
# in NOTES.
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
include "VYBRID.common"
|
||||
ident QUARTZ
|
||||
|
||||
#FDT
|
||||
options FDT
|
||||
options FDT_DTB_STATIC
|
||||
makeoptions FDT_DTS_FILE=vybrid-quartz.dts
|
@ -22,6 +22,7 @@ arm/freescale/imx/common.c standard
|
||||
arm/freescale/imx/imx6_anatop.c standard
|
||||
arm/freescale/imx/imx6_ccm.c standard
|
||||
arm/freescale/imx/imx6_machdep.c standard
|
||||
arm/freescale/imx/imx6_mp.c optional smp
|
||||
arm/freescale/imx/imx6_pl310.c standard
|
||||
arm/freescale/imx/imx_machdep.c standard
|
||||
arm/freescale/imx/imx_gpt.c standard
|
||||
|
166
sys/arm/freescale/imx/imx6_mp.c
Normal file
166
sys/arm/freescale/imx/imx6_mp.c
Normal file
@ -0,0 +1,166 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Juergen Weiss <weiss@uni-mainz.de>
|
||||
* Copyright (c) 2014 Ian Lepore <ian@freebsd.org>
|
||||
* 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/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/smp.h>
|
||||
|
||||
#include <machine/smp.h>
|
||||
#include <machine/fdt.h>
|
||||
#include <machine/intr.h>
|
||||
|
||||
#define SCU_PHYSBASE 0x00a00000
|
||||
#define SCU_SIZE 0x00001000
|
||||
|
||||
#define SCU_CONTROL_REG 0x00
|
||||
#define SCU_CONTROL_ENABLE (1 << 0)
|
||||
#define SCU_CONFIG_REG 0x04
|
||||
#define SCU_CONFIG_REG_NCPU_MASK 0x03
|
||||
#define SCU_CPUPOWER_REG 0x08
|
||||
#define SCU_INV_TAGS_REG 0x0c
|
||||
#define SCU_DIAG_CONTROL 0x30
|
||||
#define SCU_DIAG_DISABLE_MIGBIT (1 << 0)
|
||||
#define SCU_FILTER_START_REG 0x40
|
||||
#define SCU_FILTER_END_REG 0x44
|
||||
#define SCU_SECURE_ACCESS_REG 0x50
|
||||
#define SCU_NONSECURE_ACCESS_REG 0x54
|
||||
|
||||
#define SRC_PHYSBASE 0x020d8000
|
||||
#define SRC_SIZE 0x4000
|
||||
#define SRC_CONTROL_REG 0x00
|
||||
#define SRC_CONTROL_C1ENA_SHIFT 22 /* Bit for Core 1 enable */
|
||||
#define SRC_CONTROL_C1RST_SHIFT 14 /* Bit for Core 1 reset */
|
||||
#define SRC_GPR0_C1FUNC 0x20 /* Register for Core 1 entry func */
|
||||
#define SRC_GPR1_C1ARG 0x24 /* Register for Core 1 entry arg */
|
||||
|
||||
void
|
||||
platform_mp_init_secondary(void)
|
||||
{
|
||||
|
||||
gic_init_secondary();
|
||||
}
|
||||
|
||||
void
|
||||
platform_mp_setmaxid(void)
|
||||
{
|
||||
bus_space_handle_t scu;
|
||||
uint32_t val;
|
||||
|
||||
/* If we've already set the global vars don't bother to do it again. */
|
||||
if (mp_ncpus != 0)
|
||||
return;
|
||||
|
||||
if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
|
||||
panic("Couldn't map the SCU\n");
|
||||
val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONFIG_REG);
|
||||
bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
|
||||
|
||||
mp_maxid = (val & SCU_CONFIG_REG_NCPU_MASK);
|
||||
mp_ncpus = mp_maxid + 1;
|
||||
}
|
||||
|
||||
int
|
||||
platform_mp_probe(void)
|
||||
{
|
||||
|
||||
/* I think platform_mp_setmaxid must get called first, but be safe. */
|
||||
if (mp_ncpus == 0)
|
||||
platform_mp_setmaxid();
|
||||
|
||||
return (mp_ncpus > 1);
|
||||
}
|
||||
|
||||
void
|
||||
platform_mp_start_ap(void)
|
||||
{
|
||||
bus_space_handle_t scu;
|
||||
bus_space_handle_t src;
|
||||
|
||||
uint32_t val;
|
||||
int i;
|
||||
|
||||
if (bus_space_map(fdtbus_bs_tag, SCU_PHYSBASE, SCU_SIZE, 0, &scu) != 0)
|
||||
panic("Couldn't map the SCU\n");
|
||||
if (bus_space_map(fdtbus_bs_tag, SRC_PHYSBASE, SRC_SIZE, 0, &src) != 0)
|
||||
panic("Couldn't map the system reset controller (SRC)\n");
|
||||
|
||||
/*
|
||||
* Invalidate SCU cache tags. The 0x0000fff0 constant invalidates all
|
||||
* ways on all cores 1-3 (leaving core 0 alone). Per the ARM docs, it's
|
||||
* harmless to write to the bits for cores that are not present.
|
||||
*/
|
||||
bus_space_write_4(fdtbus_bs_tag, scu, SCU_INV_TAGS_REG, 0x0000fff0);
|
||||
|
||||
/*
|
||||
* Erratum ARM/MP: 764369 (problems with cache maintenance).
|
||||
* Setting the "disable-migratory bit" in the undocumented SCU
|
||||
* Diagnostic Control Register helps work around the problem.
|
||||
*/
|
||||
val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL);
|
||||
bus_space_write_4(fdtbus_bs_tag, scu, SCU_DIAG_CONTROL,
|
||||
val | SCU_DIAG_DISABLE_MIGBIT);
|
||||
|
||||
/* Enable the SCU. */
|
||||
val = bus_space_read_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG);
|
||||
bus_space_write_4(fdtbus_bs_tag, scu, SCU_CONTROL_REG,
|
||||
val | SCU_CONTROL_ENABLE);
|
||||
|
||||
cpu_idcache_wbinv_all();
|
||||
cpu_l2cache_wbinv_all();
|
||||
|
||||
/*
|
||||
* For each AP core, set the entry point address and argument registers,
|
||||
* and set the core-enable and core-reset bits in the control register.
|
||||
*/
|
||||
val = bus_space_read_4(fdtbus_bs_tag, src, SRC_CONTROL_REG);
|
||||
for (i=1; i < mp_ncpus; i++) {
|
||||
bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR0_C1FUNC + 8*i,
|
||||
pmap_kextract((vm_offset_t)mpentry));
|
||||
bus_space_write_4(fdtbus_bs_tag, src, SRC_GPR1_C1ARG + 8*i, 0);
|
||||
|
||||
val |= ((1 << (SRC_CONTROL_C1ENA_SHIFT - 1 + i )) |
|
||||
( 1 << (SRC_CONTROL_C1RST_SHIFT - 1 + i)));
|
||||
|
||||
}
|
||||
bus_space_write_4(fdtbus_bs_tag, src, 0, val);
|
||||
|
||||
armv7_sev();
|
||||
|
||||
bus_space_unmap(fdtbus_bs_tag, scu, SCU_SIZE);
|
||||
bus_space_unmap(fdtbus_bs_tag, src, SRC_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
platform_ipi_send(cpuset_t cpus, u_int ipi)
|
||||
{
|
||||
|
||||
pic_ipi_send(cpus, ipi);
|
||||
}
|
@ -10,5 +10,8 @@ options KERNPHYSADDR = 0x12000000
|
||||
makeoptions KERNPHYSADDR = 0x12000000
|
||||
options PHYSADDR = 0x10000000
|
||||
|
||||
options IPI_IRQ_START=0
|
||||
options IPI_IRQ_END=15
|
||||
|
||||
files "../freescale/imx/files.imx6"
|
||||
|
||||
|
@ -104,6 +104,12 @@ struct cpu_functions {
|
||||
*
|
||||
* There are some rules that must be followed:
|
||||
*
|
||||
* ID-cache Invalidate All:
|
||||
* Unlike other functions, this one must never write back.
|
||||
* It is used to intialize the MMU when it is in an unknown
|
||||
* state (such as when it may have lines tagged as valid
|
||||
* that belong to a previous set of mappings).
|
||||
*
|
||||
* I-cache Synch (all or range):
|
||||
* The goal is to synchronize the instruction stream,
|
||||
* so you may beed to write-back dirty D-cache blocks
|
||||
@ -138,6 +144,7 @@ struct cpu_functions {
|
||||
void (*cf_dcache_inv_range) (vm_offset_t, vm_size_t);
|
||||
void (*cf_dcache_wb_range) (vm_offset_t, vm_size_t);
|
||||
|
||||
void (*cf_idcache_inv_all) (void);
|
||||
void (*cf_idcache_wbinv_all) (void);
|
||||
void (*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
|
||||
void (*cf_l2cache_wbinv_all) (void);
|
||||
@ -238,6 +245,7 @@ void tlb_broadcast(int);
|
||||
#define cpu_dcache_inv_range(a, s) cpufuncs.cf_dcache_inv_range((a), (s))
|
||||
#define cpu_dcache_wb_range(a, s) cpufuncs.cf_dcache_wb_range((a), (s))
|
||||
|
||||
#define cpu_idcache_inv_all() cpufuncs.cf_idcache_inv_all()
|
||||
#define cpu_idcache_wbinv_all() cpufuncs.cf_idcache_wbinv_all()
|
||||
#define cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
|
||||
#define cpu_l2cache_wbinv_all() cpufuncs.cf_l2cache_wbinv_all()
|
||||
@ -495,6 +503,7 @@ void armv6_dcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
void armv6_dcache_inv_range (vm_offset_t, vm_size_t);
|
||||
void armv6_dcache_wb_range (vm_offset_t, vm_size_t);
|
||||
|
||||
void armv6_idcache_inv_all (void);
|
||||
void armv6_idcache_wbinv_all (void);
|
||||
void armv6_idcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
|
||||
@ -503,6 +512,7 @@ void armv7_tlb_flushID (void);
|
||||
void armv7_tlb_flushID_SE (u_int);
|
||||
void armv7_icache_sync_range (vm_offset_t, vm_size_t);
|
||||
void armv7_idcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
void armv7_idcache_inv_all (void);
|
||||
void armv7_dcache_wbinv_all (void);
|
||||
void armv7_idcache_wbinv_all (void);
|
||||
void armv7_dcache_wbinv_range (vm_offset_t, vm_size_t);
|
||||
@ -587,6 +597,7 @@ void armv4_tlb_flushD (void);
|
||||
void armv4_tlb_flushD_SE (u_int va);
|
||||
|
||||
void armv4_drain_writebuf (void);
|
||||
void armv4_idcache_inv_all (void);
|
||||
#endif
|
||||
|
||||
#if defined(CPU_IXP12X0)
|
||||
|
@ -18,7 +18,7 @@ SRCS+= load_elf32.c reloc_elf32.c
|
||||
SRCS+= load_elf64.c reloc_elf64.c
|
||||
.elif ${MACHINE_CPUARCH} == "sparc64"
|
||||
SRCS+= load_elf64.c reloc_elf64.c
|
||||
.elif ${MACHINE_ARCH} == "mips64"
|
||||
.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
|
||||
SRCS+= load_elf64.c reloc_elf64.c
|
||||
.endif
|
||||
|
||||
|
@ -210,6 +210,26 @@
|
||||
i2c-device-id = <0>;
|
||||
};
|
||||
|
||||
i2c1: i2c@4802a000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "ti,i2c";
|
||||
reg =< 0x4802a000 0x1000 >;
|
||||
interrupts = <71>;
|
||||
interrupt-parent = <&AINTC>;
|
||||
i2c-device-id = <1>;
|
||||
};
|
||||
|
||||
i2c2: i2c@4819c000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "ti,i2c";
|
||||
reg =< 0x4819c000 0x1000 >;
|
||||
interrupts = <30>;
|
||||
interrupt-parent = <&AINTC>;
|
||||
i2c-device-id = <2>;
|
||||
};
|
||||
|
||||
pwm@48300000 {
|
||||
compatible = "ti,am335x-pwm";
|
||||
#address-cells = <1>;
|
||||
|
@ -52,6 +52,12 @@
|
||||
/* I2C0 */
|
||||
"I2C0_SDA", "I2C0_SDA","i2c",
|
||||
"I2C0_SCL", "I2C0_SCL","i2c",
|
||||
/* I2C1 */
|
||||
"SPI0_D1", "I2C1_SDA", "i2c",
|
||||
"SPI0_CS0", "I2C1_SCL", "i2c",
|
||||
/* I2C2 */
|
||||
"UART1_CTSn", "I2C2_SDA", "i2c",
|
||||
"UART1_RTSn", "I2C2_SCL", "i2c",
|
||||
/* Ethernet */
|
||||
"MII1_RX_ER", "gmii1_rxerr", "input_pulldown",
|
||||
"MII1_TX_EN", "gmii1_txen", "output",
|
||||
|
65
sys/boot/fdt/dts/vybrid-quartz.dts
Normal file
65
sys/boot/fdt/dts/vybrid-quartz.dts
Normal file
@ -0,0 +1,65 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/include/ "vybrid.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Device Solutions Quartz Module";
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = < 0x80000000 0x10000000 >; /* 256MB RAM */
|
||||
};
|
||||
|
||||
SOC: vybrid {
|
||||
serial0: serial@40027000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
fec1: ethernet@400D1000 {
|
||||
status = "okay";
|
||||
iomux_config = < 54 0x1 55 0x1
|
||||
56 0x1 57 0x1
|
||||
58 0x1 59 0x1
|
||||
60 0x1 61 0x1
|
||||
62 0x1 0 0x2 >;
|
||||
};
|
||||
|
||||
edma1: edma@40098000 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
chosen {
|
||||
bootargs = "-v";
|
||||
stdin = "serial0";
|
||||
stdout = "serial0";
|
||||
};
|
||||
};
|
@ -5,7 +5,7 @@ FICLDIR?= ${.CURDIR}
|
||||
|
||||
.if !defined(FICL64)
|
||||
.PATH: ${FICLDIR}/${MACHINE_CPUARCH:S/amd64/i386/}
|
||||
.elif ${MACHINE_ARCH} == "mips64"
|
||||
.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
|
||||
.PATH: ${FICLDIR}/${MACHINE_ARCH}
|
||||
.else
|
||||
.PATH: ${FICLDIR}/${MACHINE_CPUARCH}
|
||||
|
@ -168,6 +168,9 @@ static dtrace_pops_t systrace_pops = {
|
||||
static struct cdev *systrace_cdev;
|
||||
static dtrace_provider_id_t systrace_id;
|
||||
|
||||
typedef void (*systrace_dtrace_probe)(dtrace_id_t, uintptr_t, uintptr_t,
|
||||
uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
|
||||
|
||||
#if !defined(LINUX_SYSTRACE)
|
||||
/*
|
||||
* Probe callback function.
|
||||
@ -211,7 +214,8 @@ systrace_probe(u_int32_t id, int sysnum, struct sysent *sysent, void *params,
|
||||
}
|
||||
|
||||
/* Process the probe using the converted argments. */
|
||||
dtrace_probe(id, uargs[0], uargs[1], uargs[2], uargs[3], uargs[4]);
|
||||
((systrace_dtrace_probe)(dtrace_probe))(id, uargs[0], uargs[1],
|
||||
uargs[2], uargs[3], uargs[4], uargs[5], uargs[6], uargs[7]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1343,6 +1343,7 @@ dev/etherswitch/arswitch/arswitch_phy.c optional arswitch
|
||||
dev/etherswitch/arswitch/arswitch_8216.c optional arswitch
|
||||
dev/etherswitch/arswitch/arswitch_8226.c optional arswitch
|
||||
dev/etherswitch/arswitch/arswitch_8316.c optional arswitch
|
||||
dev/etherswitch/arswitch/arswitch_8327.c optional arswitch
|
||||
dev/etherswitch/arswitch/arswitch_7240.c optional arswitch
|
||||
dev/etherswitch/arswitch/arswitch_9340.c optional arswitch
|
||||
dev/etherswitch/arswitch/arswitch_vlans.c optional arswitch
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include <dev/etherswitch/arswitch/arswitch_8216.h>
|
||||
#include <dev/etherswitch/arswitch/arswitch_8226.h>
|
||||
#include <dev/etherswitch/arswitch/arswitch_8316.h>
|
||||
#include <dev/etherswitch/arswitch/arswitch_8327.h>
|
||||
#include <dev/etherswitch/arswitch/arswitch_9340.h>
|
||||
|
||||
#include "mdio_if.h"
|
||||
@ -222,7 +223,7 @@ arswitch_set_vlan_mode(struct arswitch_softc *sc, uint32_t mode)
|
||||
};
|
||||
|
||||
/* Reset VLANs. */
|
||||
arswitch_reset_vlans(sc);
|
||||
sc->hal.arswitch_vlan_init_hw(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -274,6 +275,11 @@ arswitch_attach(device_t dev)
|
||||
sc->hal.arswitch_port_init = ar8xxx_port_init;
|
||||
sc->hal.arswitch_port_vlan_setup = ar8xxx_port_vlan_setup;
|
||||
sc->hal.arswitch_port_vlan_get = ar8xxx_port_vlan_get;
|
||||
sc->hal.arswitch_vlan_init_hw = ar8xxx_reset_vlans;
|
||||
sc->hal.arswitch_vlan_getvgroup = ar8xxx_getvgroup;
|
||||
sc->hal.arswitch_vlan_setvgroup = ar8xxx_setvgroup;
|
||||
sc->hal.arswitch_vlan_get_pvid = ar8xxx_get_pvid;
|
||||
sc->hal.arswitch_vlan_set_pvid = ar8xxx_set_pvid;
|
||||
|
||||
/*
|
||||
* Attach switch related functions
|
||||
@ -288,6 +294,8 @@ arswitch_attach(device_t dev)
|
||||
ar8226_attach(sc);
|
||||
else if (AR8X16_IS_SWITCH(sc, AR8316))
|
||||
ar8316_attach(sc);
|
||||
else if (AR8X16_IS_SWITCH(sc, AR8327))
|
||||
ar8327_attach(sc);
|
||||
else
|
||||
return (ENXIO);
|
||||
|
||||
@ -538,7 +546,7 @@ ar8xxx_port_vlan_get(struct arswitch_softc *sc, etherswitch_port_t *p)
|
||||
ARSWITCH_LOCK(sc);
|
||||
|
||||
/* Retrieve the PVID. */
|
||||
arswitch_get_pvid(sc, p->es_port, &p->es_pvid);
|
||||
sc->hal.arswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
|
||||
|
||||
/* Port flags. */
|
||||
reg = arswitch_readreg(sc->sc_dev, AR8X16_REG_PORT_CTRL(p->es_port));
|
||||
@ -602,7 +610,7 @@ ar8xxx_port_vlan_setup(struct arswitch_softc *sc, etherswitch_port_t *p)
|
||||
|
||||
/* Set the PVID. */
|
||||
if (p->es_pvid != 0)
|
||||
arswitch_set_pvid(sc, p->es_port, p->es_pvid);
|
||||
sc->hal.arswitch_vlan_set_pvid(sc, p->es_port, p->es_pvid);
|
||||
|
||||
/* Mutually exclusive. */
|
||||
if (p->es_flags & ETHERSWITCH_PORT_ADDTAG &&
|
||||
@ -730,6 +738,22 @@ arswitch_setconf(device_t dev, etherswitch_conf_t *conf)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
arswitch_getvgroup(device_t dev, etherswitch_vlangroup_t *e)
|
||||
{
|
||||
struct arswitch_softc *sc = device_get_softc(dev);
|
||||
|
||||
return (sc->hal.arswitch_vlan_getvgroup(sc, e));
|
||||
}
|
||||
|
||||
static int
|
||||
arswitch_setvgroup(device_t dev, etherswitch_vlangroup_t *e)
|
||||
{
|
||||
struct arswitch_softc *sc = device_get_softc(dev);
|
||||
|
||||
return (sc->hal.arswitch_vlan_setvgroup(sc, e));
|
||||
}
|
||||
|
||||
static device_method_t arswitch_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, arswitch_probe),
|
||||
|
481
sys/dev/etherswitch/arswitch/arswitch_8327.c
Normal file
481
sys/dev/etherswitch/arswitch/arswitch_8327.c
Normal file
@ -0,0 +1,481 @@
|
||||
/*-
|
||||
* Copyright (c) 2011-2012 Stefan Bethke.
|
||||
* Copyright (c) 2014 Adrian Chadd.
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <dev/iicbus/iic.h>
|
||||
#include <dev/iicbus/iiconf.h>
|
||||
#include <dev/iicbus/iicbus.h>
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
#include <dev/etherswitch/mdio.h>
|
||||
|
||||
#include <dev/etherswitch/etherswitch.h>
|
||||
|
||||
#include <dev/etherswitch/arswitch/arswitchreg.h>
|
||||
#include <dev/etherswitch/arswitch/arswitchvar.h>
|
||||
#include <dev/etherswitch/arswitch/arswitch_reg.h>
|
||||
#include <dev/etherswitch/arswitch/arswitch_8327.h>
|
||||
|
||||
#include "mdio_if.h"
|
||||
#include "miibus_if.h"
|
||||
#include "etherswitch_if.h"
|
||||
|
||||
static void
|
||||
ar8327_phy_fixup(struct arswitch_softc *sc, int phy)
|
||||
{
|
||||
|
||||
switch (sc->chip_rev) {
|
||||
case 1:
|
||||
/* For 100M waveform */
|
||||
arswitch_writedbg(sc->sc_dev, phy, 0, 0x02ea);
|
||||
/* Turn on Gigabit clock */
|
||||
arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x68a0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
arswitch_writemmd(sc->sc_dev, phy, 0x7, 0x3c);
|
||||
arswitch_writemmd(sc->sc_dev, phy, 0x4007, 0x0);
|
||||
/* fallthrough */
|
||||
case 4:
|
||||
arswitch_writemmd(sc->sc_dev, phy, 0x3, 0x800d);
|
||||
arswitch_writemmd(sc->sc_dev, phy, 0x4003, 0x803f);
|
||||
|
||||
arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x6860);
|
||||
arswitch_writedbg(sc->sc_dev, phy, 0x5, 0x2c46);
|
||||
arswitch_writedbg(sc->sc_dev, phy, 0x3c, 0x6000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ar8327_get_pad_cfg(struct ar8327_pad_cfg *cfg)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
if (!cfg)
|
||||
return (0);
|
||||
|
||||
t = 0;
|
||||
switch (cfg->mode) {
|
||||
case AR8327_PAD_NC:
|
||||
break;
|
||||
|
||||
case AR8327_PAD_MAC2MAC_MII:
|
||||
t = AR8327_PAD_MAC_MII_EN;
|
||||
if (cfg->rxclk_sel)
|
||||
t |= AR8327_PAD_MAC_MII_RXCLK_SEL;
|
||||
if (cfg->txclk_sel)
|
||||
t |= AR8327_PAD_MAC_MII_TXCLK_SEL;
|
||||
break;
|
||||
|
||||
case AR8327_PAD_MAC2MAC_GMII:
|
||||
t = AR8327_PAD_MAC_GMII_EN;
|
||||
if (cfg->rxclk_sel)
|
||||
t |= AR8327_PAD_MAC_GMII_RXCLK_SEL;
|
||||
if (cfg->txclk_sel)
|
||||
t |= AR8327_PAD_MAC_GMII_TXCLK_SEL;
|
||||
break;
|
||||
|
||||
case AR8327_PAD_MAC_SGMII:
|
||||
t = AR8327_PAD_SGMII_EN;
|
||||
|
||||
/*
|
||||
* WAR for the Qualcomm Atheros AP136 board.
|
||||
* It seems that RGMII TX/RX delay settings needs to be
|
||||
* applied for SGMII mode as well, The ethernet is not
|
||||
* reliable without this.
|
||||
*/
|
||||
t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
|
||||
t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
|
||||
if (cfg->rxclk_delay_en)
|
||||
t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
|
||||
if (cfg->txclk_delay_en)
|
||||
t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
|
||||
|
||||
if (cfg->sgmii_delay_en)
|
||||
t |= AR8327_PAD_SGMII_DELAY_EN;
|
||||
|
||||
break;
|
||||
|
||||
case AR8327_PAD_MAC2PHY_MII:
|
||||
t = AR8327_PAD_PHY_MII_EN;
|
||||
if (cfg->rxclk_sel)
|
||||
t |= AR8327_PAD_PHY_MII_RXCLK_SEL;
|
||||
if (cfg->txclk_sel)
|
||||
t |= AR8327_PAD_PHY_MII_TXCLK_SEL;
|
||||
break;
|
||||
|
||||
case AR8327_PAD_MAC2PHY_GMII:
|
||||
t = AR8327_PAD_PHY_GMII_EN;
|
||||
if (cfg->pipe_rxclk_sel)
|
||||
t |= AR8327_PAD_PHY_GMII_PIPE_RXCLK_SEL;
|
||||
if (cfg->rxclk_sel)
|
||||
t |= AR8327_PAD_PHY_GMII_RXCLK_SEL;
|
||||
if (cfg->txclk_sel)
|
||||
t |= AR8327_PAD_PHY_GMII_TXCLK_SEL;
|
||||
break;
|
||||
|
||||
case AR8327_PAD_MAC_RGMII:
|
||||
t = AR8327_PAD_RGMII_EN;
|
||||
t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
|
||||
t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
|
||||
if (cfg->rxclk_delay_en)
|
||||
t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
|
||||
if (cfg->txclk_delay_en)
|
||||
t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
|
||||
break;
|
||||
|
||||
case AR8327_PAD_PHY_GMII:
|
||||
t = AR8327_PAD_PHYX_GMII_EN;
|
||||
break;
|
||||
|
||||
case AR8327_PAD_PHY_RGMII:
|
||||
t = AR8327_PAD_PHYX_RGMII_EN;
|
||||
break;
|
||||
|
||||
case AR8327_PAD_PHY_MII:
|
||||
t = AR8327_PAD_PHYX_MII_EN;
|
||||
break;
|
||||
}
|
||||
|
||||
return (t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the hard-coded port config from the switch setup to
|
||||
* the chipset port config (status, duplex, flow, etc.)
|
||||
*/
|
||||
static uint32_t
|
||||
ar8327_get_port_init_status(struct ar8327_port_cfg *cfg)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
if (!cfg->force_link)
|
||||
return (AR8X16_PORT_STS_LINK_AUTO);
|
||||
|
||||
t = AR8X16_PORT_STS_TXMAC | AR8X16_PORT_STS_RXMAC;
|
||||
t |= cfg->duplex ? AR8X16_PORT_STS_DUPLEX : 0;
|
||||
t |= cfg->rxpause ? AR8X16_PORT_STS_RXFLOW : 0;
|
||||
t |= cfg->txpause ? AR8X16_PORT_STS_TXFLOW : 0;
|
||||
|
||||
switch (cfg->speed) {
|
||||
case AR8327_PORT_SPEED_10:
|
||||
t |= AR8X16_PORT_STS_SPEED_10;
|
||||
break;
|
||||
case AR8327_PORT_SPEED_100:
|
||||
t |= AR8X16_PORT_STS_SPEED_100;
|
||||
break;
|
||||
case AR8327_PORT_SPEED_1000:
|
||||
t |= AR8X16_PORT_STS_SPEED_1000;
|
||||
break;
|
||||
}
|
||||
|
||||
return (t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise the ar8327 specific hardware features from
|
||||
* the hints provided in the boot environment.
|
||||
*/
|
||||
static int
|
||||
ar8327_init_pdata(struct arswitch_softc *sc)
|
||||
{
|
||||
struct ar8327_pad_cfg pc;
|
||||
struct ar8327_port_cfg port_cfg;
|
||||
uint32_t t;
|
||||
|
||||
/* XXX hard-coded DB120 defaults for now! */
|
||||
|
||||
/* Port 0 - rgmii; 1000/full */
|
||||
bzero(&port_cfg, sizeof(port_cfg));
|
||||
port_cfg.speed = AR8327_PORT_SPEED_1000;
|
||||
port_cfg.duplex = 1;
|
||||
port_cfg.rxpause = 1;
|
||||
port_cfg.txpause = 1;
|
||||
port_cfg.force_link = 1;
|
||||
sc->ar8327.port0_status = ar8327_get_port_init_status(&port_cfg);
|
||||
|
||||
/* Port 6 - ignore */
|
||||
bzero(&port_cfg, sizeof(port_cfg));
|
||||
sc->ar8327.port6_status = ar8327_get_port_init_status(&port_cfg);
|
||||
|
||||
/* Pad 0 */
|
||||
bzero(&pc, sizeof(pc));
|
||||
pc.mode = AR8327_PAD_MAC_RGMII,
|
||||
pc.txclk_delay_en = true,
|
||||
pc.rxclk_delay_en = true,
|
||||
pc.txclk_delay_sel = AR8327_CLK_DELAY_SEL1,
|
||||
pc.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2,
|
||||
|
||||
t = ar8327_get_pad_cfg(&pc);
|
||||
#if 0
|
||||
if (AR8X16_IS_SWITCH(sc, AR8337))
|
||||
t |= AR8337_PAD_MAC06_EXCHANGE_EN;
|
||||
#endif
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PAD0_MODE, t);
|
||||
|
||||
/* Pad 5 */
|
||||
bzero(&pc, sizeof(pc));
|
||||
t = ar8327_get_pad_cfg(&pc);
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PAD5_MODE, t);
|
||||
|
||||
/* Pad 6 */
|
||||
bzero(&pc, sizeof(pc));
|
||||
t = ar8327_get_pad_cfg(&pc);
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PAD6_MODE, t);
|
||||
|
||||
/* XXX LED config */
|
||||
|
||||
/* XXX SGMII config */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ar8327_hw_setup(struct arswitch_softc *sc)
|
||||
{
|
||||
int i;
|
||||
int err;
|
||||
|
||||
/* pdata fetch and setup */
|
||||
err = ar8327_init_pdata(sc);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
|
||||
/* XXX init leds */
|
||||
|
||||
for (i = 0; i < AR8327_NUM_PHYS; i++) {
|
||||
/* phy fixup */
|
||||
ar8327_phy_fixup(sc, i);
|
||||
|
||||
/* start PHY autonegotiation? */
|
||||
/* XXX is this done as part of the normal PHY setup? */
|
||||
|
||||
};
|
||||
|
||||
/* Let things settle */
|
||||
DELAY(1000);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise other global values, for the AR8327.
|
||||
*/
|
||||
static int
|
||||
ar8327_hw_global_setup(struct arswitch_softc *sc)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
/* enable CPU port and disable mirror port */
|
||||
t = AR8327_FWD_CTRL0_CPU_PORT_EN |
|
||||
AR8327_FWD_CTRL0_MIRROR_PORT;
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL0, t);
|
||||
|
||||
/* forward multicast and broadcast frames to CPU */
|
||||
t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
|
||||
(AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
|
||||
(AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL1, t);
|
||||
|
||||
/* enable jumbo frames */
|
||||
/* XXX need to macro-shift the value! */
|
||||
arswitch_modifyreg(sc->sc_dev, AR8327_REG_MAX_FRAME_SIZE,
|
||||
AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2);
|
||||
|
||||
/* Enable MIB counters */
|
||||
arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN,
|
||||
AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Port setup.
|
||||
*/
|
||||
static void
|
||||
ar8327_port_init(struct arswitch_softc *sc, int port)
|
||||
{
|
||||
uint32_t t;
|
||||
|
||||
if (port == AR8X16_PORT_CPU)
|
||||
t = sc->ar8327.port0_status;
|
||||
else if (port == 6)
|
||||
t = sc->ar8327.port6_status;
|
||||
else
|
||||
#if 0
|
||||
/* XXX DB120 - hard-code port0 to 1000/full */
|
||||
if (port == 0) {
|
||||
t = AR8X16_PORT_STS_SPEED_1000;
|
||||
t |= AR8X16_PORT_STS_TXMAC | AR8X16_PORT_STS_RXMAC;
|
||||
t |= AR8X16_PORT_STS_DUPLEX;
|
||||
t |= AR8X16_PORT_STS_RXFLOW;
|
||||
t |= AR8X16_PORT_STS_TXFLOW;
|
||||
} else
|
||||
#endif
|
||||
t = AR8X16_PORT_STS_LINK_AUTO;
|
||||
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_STATUS(port), t);
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_HEADER(port), 0);
|
||||
|
||||
t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
|
||||
t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
|
||||
|
||||
t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S;
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(port), t);
|
||||
|
||||
t = AR8327_PORT_LOOKUP_LEARN;
|
||||
t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port), t);
|
||||
}
|
||||
|
||||
static int
|
||||
ar8327_port_vlan_setup(struct arswitch_softc *sc, etherswitch_port_t *p)
|
||||
{
|
||||
|
||||
/* XXX stub for now */
|
||||
device_printf(sc->sc_dev, "%s: called\n", __func__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ar8327_port_vlan_get(struct arswitch_softc *sc, etherswitch_port_t *p)
|
||||
{
|
||||
|
||||
/* XXX stub for now */
|
||||
device_printf(sc->sc_dev, "%s: called\n", __func__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ar8327_reset_vlans(struct arswitch_softc *sc)
|
||||
{
|
||||
int i;
|
||||
uint32_t mode, t;
|
||||
|
||||
/*
|
||||
* For now, let's default to one portgroup, just so traffic
|
||||
* flows. All ports can see other ports.
|
||||
*/
|
||||
for (i = 0; i < AR8327_NUM_PORTS; i++) {
|
||||
/* set pvid = i */
|
||||
t = i << AR8327_PORT_VLAN0_DEF_SVID_S;
|
||||
t |= i << AR8327_PORT_VLAN0_DEF_CVID_S;
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(i), t);
|
||||
|
||||
/* set egress == out_keep */
|
||||
mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
|
||||
|
||||
t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
|
||||
t |= mode << AR8327_PORT_VLAN1_OUT_MODE_S;
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(i), t);
|
||||
|
||||
/* Set ingress = out_keep; members = 0x3f for all ports */
|
||||
|
||||
t = 0x3f; /* all ports */
|
||||
t |= AR8327_PORT_LOOKUP_LEARN;
|
||||
|
||||
/* in_port_only, forward */
|
||||
t |= AR8X16_PORT_VLAN_MODE_PORT_ONLY << AR8327_PORT_LOOKUP_IN_MODE_S;
|
||||
t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
|
||||
arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(i), t);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ar8327_vlan_getvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
|
||||
{
|
||||
device_printf(sc->sc_dev, "%s: called\n", __func__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ar8327_vlan_setvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
|
||||
{
|
||||
|
||||
device_printf(sc->sc_dev, "%s: called\n", __func__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ar8327_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
|
||||
{
|
||||
|
||||
device_printf(sc->sc_dev, "%s: called\n", __func__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ar8327_set_pvid(struct arswitch_softc *sc, int port, int pvid)
|
||||
{
|
||||
|
||||
device_printf(sc->sc_dev, "%s: called\n", __func__);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ar8327_attach(struct arswitch_softc *sc)
|
||||
{
|
||||
|
||||
sc->hal.arswitch_hw_setup = ar8327_hw_setup;
|
||||
sc->hal.arswitch_hw_global_setup = ar8327_hw_global_setup;
|
||||
|
||||
sc->hal.arswitch_port_init = ar8327_port_init;
|
||||
sc->hal.arswitch_port_vlan_setup = ar8327_port_vlan_setup;
|
||||
sc->hal.arswitch_port_vlan_get = ar8327_port_vlan_get;
|
||||
|
||||
sc->hal.arswitch_vlan_init_hw = ar8327_reset_vlans;
|
||||
sc->hal.arswitch_vlan_getvgroup = ar8327_vlan_getvgroup;
|
||||
sc->hal.arswitch_vlan_setvgroup = ar8327_vlan_setvgroup;
|
||||
sc->hal.arswitch_vlan_get_pvid = ar8327_get_pvid;
|
||||
sc->hal.arswitch_vlan_set_pvid = ar8327_set_pvid;
|
||||
|
||||
/* Set the switch vlan capabilities. */
|
||||
sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q |
|
||||
ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG;
|
||||
sc->info.es_nvlangroups = AR8X16_MAX_VLANS;
|
||||
}
|
91
sys/dev/etherswitch/arswitch/arswitch_8327.h
Normal file
91
sys/dev/etherswitch/arswitch/arswitch_8327.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __ARSWITCH_8327_H__
|
||||
#define __ARSWITCH_8327_H__
|
||||
|
||||
enum ar8327_pad_mode {
|
||||
AR8327_PAD_NC = 0,
|
||||
AR8327_PAD_MAC2MAC_MII,
|
||||
AR8327_PAD_MAC2MAC_GMII,
|
||||
AR8327_PAD_MAC_SGMII,
|
||||
AR8327_PAD_MAC2PHY_MII,
|
||||
AR8327_PAD_MAC2PHY_GMII,
|
||||
AR8327_PAD_MAC_RGMII,
|
||||
AR8327_PAD_PHY_GMII,
|
||||
AR8327_PAD_PHY_RGMII,
|
||||
AR8327_PAD_PHY_MII,
|
||||
};
|
||||
|
||||
enum ar8327_clk_delay_sel {
|
||||
AR8327_CLK_DELAY_SEL0 = 0,
|
||||
AR8327_CLK_DELAY_SEL1,
|
||||
AR8327_CLK_DELAY_SEL2,
|
||||
AR8327_CLK_DELAY_SEL3,
|
||||
};
|
||||
|
||||
/* XXX update the field types */
|
||||
struct ar8327_pad_cfg {
|
||||
uint32_t mode;
|
||||
uint32_t rxclk_sel;
|
||||
uint32_t txclk_sel;
|
||||
uint32_t txclk_delay_sel;
|
||||
uint32_t rxclk_delay_sel;
|
||||
uint32_t txclk_delay_en;
|
||||
uint32_t rxclk_delay_en;
|
||||
uint32_t sgmii_delay_en;
|
||||
uint32_t pipe_rxclk_sel;
|
||||
};
|
||||
|
||||
struct ar8327_sgmii_cfg {
|
||||
uint32_t sgmii_ctrl;
|
||||
uint32_t serdes_aen;
|
||||
};
|
||||
|
||||
struct ar8327_led_cfg {
|
||||
uint32_t led_ctrl0;
|
||||
uint32_t led_ctrl1;
|
||||
uint32_t led_ctrl2;
|
||||
uint32_t led_ctrl3;
|
||||
uint32_t open_drain;
|
||||
};
|
||||
|
||||
struct ar8327_port_cfg {
|
||||
#define AR8327_PORT_SPEED_10 1
|
||||
#define AR8327_PORT_SPEED_100 2
|
||||
#define AR8327_PORT_SPEED_1000 3
|
||||
uint32_t speed;
|
||||
uint32_t force_link;
|
||||
uint32_t duplex;
|
||||
uint32_t txpause;
|
||||
uint32_t rxpause;
|
||||
};
|
||||
|
||||
extern void ar8327_attach(struct arswitch_softc *sc);
|
||||
|
||||
#endif /* __ARSWITCH_8327_H__ */
|
||||
|
@ -171,7 +171,7 @@ arswitch_set_port_vlan(struct arswitch_softc *sc, uint32_t ports, int vid)
|
||||
* Reset vlans to default state.
|
||||
*/
|
||||
void
|
||||
arswitch_reset_vlans(struct arswitch_softc *sc)
|
||||
ar8xxx_reset_vlans(struct arswitch_softc *sc)
|
||||
{
|
||||
uint32_t ports;
|
||||
int i, j;
|
||||
@ -220,7 +220,7 @@ arswitch_reset_vlans(struct arswitch_softc *sc)
|
||||
sc->vid[0] = 1;
|
||||
/* Set PVID for everyone. */
|
||||
for (i = 0; i <= sc->numphys; i++)
|
||||
arswitch_set_pvid(sc, i, sc->vid[0]);
|
||||
sc->hal.arswitch_vlan_set_pvid(sc, i, sc->vid[0]);
|
||||
ports = 0;
|
||||
for (i = 0; i <= sc->numphys; i++)
|
||||
ports |= (1 << i);
|
||||
@ -259,12 +259,10 @@ arswitch_reset_vlans(struct arswitch_softc *sc)
|
||||
}
|
||||
|
||||
int
|
||||
arswitch_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
ar8xxx_getvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
|
||||
{
|
||||
struct arswitch_softc *sc;
|
||||
int err;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
|
||||
|
||||
if (vg->es_vlangroup > sc->info.es_nvlangroups)
|
||||
@ -305,12 +303,10 @@ arswitch_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
}
|
||||
|
||||
int
|
||||
arswitch_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
ar8xxx_setvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
|
||||
{
|
||||
struct arswitch_softc *sc;
|
||||
int err, vid;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
|
||||
|
||||
/* Check VLAN mode. */
|
||||
@ -362,7 +358,7 @@ arswitch_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
|
||||
}
|
||||
|
||||
int
|
||||
arswitch_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
|
||||
ar8xxx_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
@ -373,7 +369,7 @@ arswitch_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
|
||||
}
|
||||
|
||||
int
|
||||
arswitch_set_pvid(struct arswitch_softc *sc, int port, int pvid)
|
||||
ar8xxx_set_pvid(struct arswitch_softc *sc, int port, int pvid)
|
||||
{
|
||||
|
||||
ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
|
||||
|
@ -29,10 +29,10 @@
|
||||
#ifndef __ARSWITCH_VLANS_H__
|
||||
#define __ARSWITCH_VLANS_H__
|
||||
|
||||
void arswitch_reset_vlans(struct arswitch_softc *);
|
||||
int arswitch_getvgroup(device_t, etherswitch_vlangroup_t *);
|
||||
int arswitch_setvgroup(device_t, etherswitch_vlangroup_t *);
|
||||
int arswitch_get_pvid(struct arswitch_softc *, int, int *);
|
||||
int arswitch_set_pvid(struct arswitch_softc *, int, int);
|
||||
void ar8xxx_reset_vlans(struct arswitch_softc *);
|
||||
int ar8xxx_getvgroup(struct arswitch_softc *, etherswitch_vlangroup_t *);
|
||||
int ar8xxx_setvgroup(struct arswitch_softc *, etherswitch_vlangroup_t *);
|
||||
int ar8xxx_get_pvid(struct arswitch_softc *, int, int *);
|
||||
int ar8xxx_set_pvid(struct arswitch_softc *, int, int);
|
||||
|
||||
#endif /* __ARSWITCH_VLANS_H__ */
|
||||
|
@ -45,6 +45,9 @@ typedef enum {
|
||||
#define AR8X16_IS_SWITCH(_sc, _type) \
|
||||
(!!((_sc)->sc_switchtype == AR8X16_SWITCH_ ## _type))
|
||||
|
||||
#define ARSWITCH_NUM_PORTS MAX(AR8327_NUM_PORTS, AR8X16_NUM_PORTS)
|
||||
#define ARSWITCH_NUM_PHYS MAX(AR8327_NUM_PHYS, AR8X16_NUM_PHYS)
|
||||
|
||||
struct arswitch_softc {
|
||||
struct mtx sc_mtx; /* serialize access to softc */
|
||||
device_t sc_dev;
|
||||
@ -59,9 +62,10 @@ struct arswitch_softc {
|
||||
int chip_rev;
|
||||
int mii_lo_first;
|
||||
ar8x16_switch_type sc_switchtype;
|
||||
char *ifname[AR8X16_NUM_PHYS];
|
||||
device_t miibus[AR8X16_NUM_PHYS];
|
||||
struct ifnet *ifp[AR8X16_NUM_PHYS];
|
||||
/* should be the max of both pre-AR8327 and AR8327 ports */
|
||||
char *ifname[ARSWITCH_NUM_PHYS];
|
||||
device_t miibus[ARSWITCH_NUM_PHYS];
|
||||
struct ifnet *ifp[ARSWITCH_NUM_PHYS];
|
||||
struct callout callout_tick;
|
||||
etherswitch_info_t info;
|
||||
|
||||
@ -82,7 +86,22 @@ struct arswitch_softc {
|
||||
etherswitch_port_t *);
|
||||
int (* arswitch_port_vlan_get) (struct arswitch_softc *,
|
||||
etherswitch_port_t *);
|
||||
void (* arswitch_vlan_init_hw) (struct arswitch_softc *);
|
||||
int (* arswitch_vlan_getvgroup) (struct arswitch_softc *,
|
||||
etherswitch_vlangroup_t *);
|
||||
int (* arswitch_vlan_setvgroup) (struct arswitch_softc *,
|
||||
etherswitch_vlangroup_t *);
|
||||
int (* arswitch_vlan_get_pvid) (struct arswitch_softc *, int,
|
||||
int *);
|
||||
int (* arswitch_vlan_set_pvid) (struct arswitch_softc *, int,
|
||||
int);
|
||||
} hal;
|
||||
|
||||
struct {
|
||||
uint32_t port0_status;
|
||||
uint32_t port5_status;
|
||||
uint32_t port6_status;
|
||||
} ar8327;
|
||||
};
|
||||
|
||||
#define ARSWITCH_LOCK(_sc) \
|
||||
|
@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/iwn/if_iwn_devid.h>
|
||||
#include <dev/iwn/if_iwn_chip_cfg.h>
|
||||
#include <dev/iwn/if_iwn_debug.h>
|
||||
#include <dev/iwn/if_iwn_ioctl.h>
|
||||
|
||||
struct iwn_ident {
|
||||
uint16_t vendor;
|
||||
@ -3140,6 +3141,16 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc,
|
||||
memcpy(sc->calibcmd[idx].buf, calib, len);
|
||||
}
|
||||
|
||||
static void
|
||||
iwn_stats_update(struct iwn_softc *sc, struct iwn_calib_state *calib,
|
||||
struct iwn_stats *stats)
|
||||
{
|
||||
|
||||
/* XXX lock assert */
|
||||
memcpy(&sc->last_stat, stats, sizeof(struct iwn_stats));
|
||||
sc->last_stat_valid = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
|
||||
* The latter is sent by the firmware after each received beacon.
|
||||
@ -3172,6 +3183,9 @@ iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc,
|
||||
__func__, desc->type);
|
||||
sc->calib_cnt = 0; /* Reset TX power calibration timeout. */
|
||||
|
||||
/* Collect/track general statistics for reporting */
|
||||
iwn_stats_update(sc, calib, stats);
|
||||
|
||||
/* Test if temperature has changed. */
|
||||
if (stats->general.temp != sc->rawtemp) {
|
||||
/* Convert "raw" temperature to degC. */
|
||||
@ -4712,6 +4726,19 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
case SIOCGIFMEDIA:
|
||||
error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
|
||||
break;
|
||||
case SIOCGIWNSTATS:
|
||||
IWN_LOCK(sc);
|
||||
/* XXX validate permissions/memory/etc? */
|
||||
error = copyout(&sc->last_stat, ifr->ifr_data,
|
||||
sizeof(struct iwn_stats));
|
||||
IWN_UNLOCK(sc);
|
||||
break;
|
||||
case SIOCZIWNSTATS:
|
||||
IWN_LOCK(sc);
|
||||
memset(&sc->last_stat, 0, sizeof(struct iwn_stats));
|
||||
IWN_UNLOCK(sc);
|
||||
error = 0;
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
@ -43,6 +43,7 @@ enum {
|
||||
IWN_DEBUG_TXRATE = 0x00002000, /* TX rate debugging */
|
||||
IWN_DEBUG_PWRSAVE = 0x00004000, /* Power save operations */
|
||||
IWN_DEBUG_SCAN = 0x00008000, /* Scan related operations */
|
||||
IWN_DEBUG_STATS = 0x00010000, /* Statistics updates */
|
||||
IWN_DEBUG_REGISTER = 0x20000000, /* print chipset register */
|
||||
IWN_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
|
||||
IWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
|
||||
|
25
sys/dev/iwn/if_iwn_ioctl.h
Normal file
25
sys/dev/iwn/if_iwn_ioctl.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __IF_IWN_IOCTL_H__
|
||||
#define __IF_IWN_IOCTL_H__
|
||||
|
||||
/* XXX how should I pick appropriate ioctl numbers? */
|
||||
#define SIOCGIWNSTATS _IOWR('i', 145, struct ifreq)
|
||||
#define SIOCZIWNSTATS _IOWR('i', 146, struct ifreq)
|
||||
|
||||
#endif /* __IF_IWN_IOCTL_H__ */
|
@ -328,6 +328,22 @@ struct iwn_softc {
|
||||
int ctx;
|
||||
struct ieee80211vap *ivap[IWN_NUM_RXON_CTX];
|
||||
|
||||
/* General statistics */
|
||||
/*
|
||||
* The statistics are reset after each channel
|
||||
* change. So it may be zeroed after things like
|
||||
* a background scan.
|
||||
*
|
||||
* So for now, this is just a cheap hack to
|
||||
* expose the last received statistics dump
|
||||
* via an ioctl(). Later versions of this
|
||||
* could expose the last 'n' messages, or just
|
||||
* provide a pipeline for the firmware responses
|
||||
* via something like BPF.
|
||||
*/
|
||||
struct iwn_stats last_stat;
|
||||
int last_stat_valid;
|
||||
|
||||
uint8_t uc_scan_progress;
|
||||
uint32_t rawtemp;
|
||||
int temp;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -100,7 +100,8 @@ SYSCTL_INT(_hw_usb_run, OID_AUTO, debug, CTLFLAG_RW, &run_debug, 0,
|
||||
static const STRUCT_USB_HOST_ID run_devs[] = {
|
||||
#define RUN_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
|
||||
#define RUN_DEV_EJECT(v,p) \
|
||||
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, 0) }
|
||||
{ USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, RUN_EJECT) }
|
||||
#define RUN_EJECT 1
|
||||
RUN_DEV(ABOCOM, RT2770),
|
||||
RUN_DEV(ABOCOM, RT2870),
|
||||
RUN_DEV(ABOCOM, RT3070),
|
||||
@ -315,7 +316,7 @@ static const STRUCT_USB_HOST_ID run_devs[] = {
|
||||
RUN_DEV(ZINWELL, RT3072_2),
|
||||
RUN_DEV(ZYXEL, RT2870_1),
|
||||
RUN_DEV(ZYXEL, RT2870_2),
|
||||
RUN_DEV(ZYXEL, NWD2705),
|
||||
RUN_DEV_EJECT(ZYXEL, NWD2705),
|
||||
RUN_DEV_EJECT(RALINK, RT_STOR),
|
||||
#undef RUN_DEV_EJECT
|
||||
#undef RUN_DEV
|
||||
@ -707,6 +708,8 @@ run_attach(device_t self)
|
||||
device_set_usb_desc(self);
|
||||
sc->sc_udev = uaa->device;
|
||||
sc->sc_dev = self;
|
||||
if (USB_GET_DRIVER_INFO(uaa) != RUN_EJECT)
|
||||
sc->sc_flags |= RUN_FLAG_FWLOAD_NEEDED;
|
||||
|
||||
mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
|
||||
MTX_NETWORK_LOCK, MTX_DEF);
|
||||
@ -1151,7 +1154,7 @@ run_load_microcode(struct run_softc *sc)
|
||||
}
|
||||
|
||||
/* write microcode image */
|
||||
if (sc->mac_ver != 0x3593) {
|
||||
if (sc->sc_flags & RUN_FLAG_FWLOAD_NEEDED) {
|
||||
run_write_region_1(sc, RT2870_FW_BASE, base, 4096);
|
||||
run_write(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff);
|
||||
run_write(sc, RT2860_H2M_MAILBOX_STATUS, 0xffffffff);
|
||||
|
@ -154,6 +154,11 @@ struct run_softc {
|
||||
device_t sc_dev;
|
||||
struct usb_device *sc_udev;
|
||||
struct ifnet *sc_ifp;
|
||||
int sc_need_fwload;
|
||||
|
||||
int sc_flags;
|
||||
#define RUN_FLAG_FWLOAD_NEEDED 0x01
|
||||
|
||||
uint16_t wcid_stats[RT2870_WCID_MAX + 1][3];
|
||||
#define RUN_TXCNT 0
|
||||
#define RUN_SUCCESS 1
|
||||
|
@ -14,13 +14,37 @@ hint.argemdio.0.order=0
|
||||
hint.ar934x_gmac.0.gmac_cfg=0x41
|
||||
|
||||
# GMAC0 here - connected to an AR8327
|
||||
#hint.arswitch.0.at="mdio0"
|
||||
#hint.arswitch.0.is_7240=0
|
||||
#hint.arswitch.0.is_9340=0 # not the internal switch!
|
||||
#hint.arswitch.0.numphys=5
|
||||
#hint.arswitch.0.phy4cpu=0
|
||||
#hint.arswitch.0.is_rgmii=1
|
||||
#hint.arswitch.0.is_gmii=0
|
||||
hint.arswitch.0.at="mdio0"
|
||||
hint.arswitch.0.is_7240=0
|
||||
hint.arswitch.0.is_9340=0 # not the internal switch!
|
||||
hint.arswitch.0.numphys=5
|
||||
hint.arswitch.0.phy4cpu=0
|
||||
hint.arswitch.0.is_rgmii=1
|
||||
hint.arswitch.0.is_gmii=0
|
||||
# XXX other AR8327 configuration parameters
|
||||
|
||||
# pad0 cfg:
|
||||
# .mode = AR8327_PAD_MAC_RGMII,
|
||||
# .txclk_delay_en = true,
|
||||
# .rxclk_delay_en = true,
|
||||
# .txclk_delay_sel = AR8327_CLK_DELAY_SEL1,
|
||||
# .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2,
|
||||
|
||||
# .led_ctrl0 = 0x00000000,
|
||||
# .led_ctrl1 = 0xc737c737,
|
||||
# .led_ctrl2 = 0x00000000,
|
||||
# .led_ctrl3 = 0x00c30c00,
|
||||
# .open_drain = true,
|
||||
|
||||
# .port0_cfg = {
|
||||
# .force_link = 1,
|
||||
# .speed = AR8327_PORT_SPEED_1000,
|
||||
# .duplex = 1,
|
||||
# .txpause = 1,
|
||||
# .rxpause = 1,
|
||||
# },
|
||||
|
||||
# port6 cfg?
|
||||
|
||||
# XXX OpenWRT DB120 BSP doesn't have media/duplex set?
|
||||
hint.arge.0.phymask=0x0
|
||||
@ -36,7 +60,9 @@ hint.argemdio.1.msize=0x1000
|
||||
hint.argemdio.1.order=0
|
||||
|
||||
# Embedded switch on the AR9344
|
||||
hint.arswitch.1.at="mdio1"
|
||||
# mdio1 is actually created as the AR8327 internal bus; so
|
||||
# this pops up as mdio2.
|
||||
hint.arswitch.1.at="mdio2"
|
||||
hint.arswitch.1.is_7240=0
|
||||
hint.arswitch.1.is_9340=1
|
||||
hint.arswitch.1.numphys=4
|
||||
|
@ -1688,7 +1688,7 @@ static int
|
||||
fire_alloc_msix(device_t dev, device_t child, int *irq)
|
||||
{
|
||||
struct fire_softc *sc;
|
||||
u_int i, msiq;
|
||||
int i, msiq;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
if ((sc->sc_flags & FIRE_MSIX) == 0)
|
||||
|
@ -130,7 +130,7 @@ spitfire_icache_page_inval(vm_paddr_t pa)
|
||||
: "=r" (tag) : "r" (addr), "n" (ASI_ICACHE_TAG));
|
||||
if (((tag >> IC_VALID_SHIFT) & IC_VALID_MASK) == 0)
|
||||
continue;
|
||||
tag &= IC_TAG_MASK << IC_TAG_SHIFT;
|
||||
tag &= (u_long)IC_TAG_MASK << IC_TAG_SHIFT;
|
||||
if (tag == target) {
|
||||
PMAP_STATS_INC(spitfire_icache_npage_inval_match);
|
||||
stxa_sync(addr, ASI_ICACHE_TAG, tag);
|
||||
|
5
tools/tools/iwn/Makefile
Normal file
5
tools/tools/iwn/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SUBDIR= iwnstats
|
||||
|
||||
.include <bsd.subdir.mk>
|
22
tools/tools/iwn/iwnstats/Makefile
Normal file
22
tools/tools/iwn/iwnstats/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
# $FreeBSD$
|
||||
|
||||
NO_MAN=1
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.PATH: ${.CURDIR}/../../../../sys/dev/iwn/
|
||||
|
||||
CFLAGS+=-I${.CURDIR}/../../../../sys/dev/iwn/
|
||||
CFLAGS+=-I${.CURDIR}/../../../../sys/
|
||||
|
||||
PROG= iwnstats
|
||||
|
||||
# Because of a clang preprocessor parser limitation causing this
|
||||
# to not compile, use gcc for now.
|
||||
#CC= gcc
|
||||
|
||||
SRCS= main.c iwn_ioctl.c
|
||||
|
||||
# CFLAGS.clang+= -fbracket-depth=512
|
||||
|
||||
.include <bsd.prog.mk>
|
91
tools/tools/iwn/iwnstats/iwn_ioctl.c
Normal file
91
tools/tools/iwn/iwnstats/iwn_ioctl.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
|
||||
* 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,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
|
||||
* redistribution must be conditioned upon including a substantially
|
||||
* similar Disclaimer requirement for further binary redistribution.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* iwn ioctl API.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_var.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
|
||||
|
||||
#include "net80211/ieee80211_ioctl.h"
|
||||
#include "net80211/ieee80211_radiotap.h"
|
||||
|
||||
#include "if_iwn_ioctl.h"
|
||||
|
||||
/*
|
||||
* This contains the register definitions for iwn; including
|
||||
* the statistics definitions.
|
||||
*/
|
||||
#include "if_iwnreg.h"
|
||||
|
||||
#include "iwnstats.h"
|
||||
|
||||
#include "iwn_ioctl.h"
|
||||
|
||||
void
|
||||
iwn_setifname(struct iwnstats *is, const char *ifname)
|
||||
{
|
||||
|
||||
strncpy(is->ifr.ifr_name, ifname, sizeof (is->ifr.ifr_name));
|
||||
}
|
||||
|
||||
void
|
||||
iwn_zerostats(struct iwnstats *is)
|
||||
{
|
||||
|
||||
if (ioctl(is->s, SIOCZIWNSTATS, &is->ifr) < 0)
|
||||
err(-1, "ioctl: %s", is->ifr.ifr_name);
|
||||
}
|
||||
|
||||
int
|
||||
iwn_collect(struct iwnstats *is)
|
||||
{
|
||||
int err;
|
||||
|
||||
is->ifr.ifr_data = (caddr_t) &is->st;
|
||||
err = ioctl(is->s, SIOCGIWNSTATS, &is->ifr);
|
||||
if (err < 0)
|
||||
warn("ioctl: %s", is->ifr.ifr_name);
|
||||
return (err);
|
||||
}
|
38
tools/tools/iwn/iwnstats/iwn_ioctl.h
Normal file
38
tools/tools/iwn/iwnstats/iwn_ioctl.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
|
||||
* 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,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
|
||||
* redistribution must be conditioned upon including a substantially
|
||||
* similar Disclaimer requirement for further binary redistribution.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __IWN_IOCTL_H__
|
||||
#define __IWN_IOCTL_H__
|
||||
|
||||
extern void iwn_setifname(struct iwnstats *is, const char *ifname);
|
||||
extern void iwn_zerostats(struct iwnstats *is);
|
||||
extern int iwn_collect(struct iwnstats *is);
|
||||
|
||||
#endif /* __IWN_IOCTL_H__ */
|
40
tools/tools/iwn/iwnstats/iwnstats.h
Normal file
40
tools/tools/iwn/iwnstats/iwnstats.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
|
||||
* 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,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
|
||||
* redistribution must be conditioned upon including a substantially
|
||||
* similar Disclaimer requirement for further binary redistribution.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef __IWNSTATS_H__
|
||||
#define __IWNSTATS_H__
|
||||
|
||||
struct iwnstats {
|
||||
int s;
|
||||
struct ifreq ifr;
|
||||
struct iwn_stats st;
|
||||
};
|
||||
|
||||
#endif /* __IWNSTATS_H__ */
|
282
tools/tools/iwn/iwnstats/main.c
Normal file
282
tools/tools/iwn/iwnstats/main.c
Normal file
@ -0,0 +1,282 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
|
||||
* 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,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
|
||||
* redistribution must be conditioned upon including a substantially
|
||||
* similar Disclaimer requirement for further binary redistribution.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
|
||||
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
#include "net80211/ieee80211_ioctl.h"
|
||||
#include "net80211/ieee80211_radiotap.h"
|
||||
|
||||
#include "if_iwn_ioctl.h"
|
||||
#include "if_iwnreg.h"
|
||||
#include "iwnstats.h"
|
||||
#include "iwn_ioctl.h"
|
||||
|
||||
#define IWN_DEFAULT_IF "iwn0"
|
||||
|
||||
struct iwnstats *
|
||||
iwnstats_new(const char *ifname)
|
||||
{
|
||||
struct iwnstats *is;
|
||||
|
||||
is = calloc(1, sizeof(struct iwnstats));
|
||||
if (is == NULL)
|
||||
return (NULL);
|
||||
|
||||
is->s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (is->s < 0)
|
||||
err(1, "socket");
|
||||
|
||||
iwn_setifname(is, ifname);
|
||||
return (is);
|
||||
}
|
||||
|
||||
static void
|
||||
iwn_stats_phy_print(struct iwnstats *is, struct iwn_rx_phy_stats *rxphy,
|
||||
const char *prefix)
|
||||
{
|
||||
|
||||
printf("%s: %s: ina=%d, fina=%d, bad_plcp=%d, bad_crc32=%d, overrun=%d, eoverrun=%d\n",
|
||||
__func__,
|
||||
prefix,
|
||||
le32toh(rxphy->ina),
|
||||
le32toh(rxphy->fina),
|
||||
le32toh(rxphy->bad_plcp),
|
||||
le32toh(rxphy->bad_crc32),
|
||||
le32toh(rxphy->overrun),
|
||||
le32toh(rxphy->eoverrun));
|
||||
|
||||
printf("%s: %s: fa=%d, bad_fina_sync=%d, sfd_timeout=%d, fina_timeout=%d, no_rts_ack=%d\n",
|
||||
__func__,
|
||||
prefix,
|
||||
le32toh(rxphy->fa),
|
||||
le32toh(rxphy->bad_fina_sync),
|
||||
le32toh(rxphy->sfd_timeout),
|
||||
le32toh(rxphy->fina_timeout),
|
||||
le32toh(rxphy->no_rts_ack));
|
||||
|
||||
printf("%s: %s: rxe_limit=%d, ack=%d, cts=%d, ba_resp=%d, dsp_kill=%d, bad_mh=%d, rssi_sum=%d\n",
|
||||
__func__,
|
||||
prefix,
|
||||
le32toh(rxphy->rxe_limit),
|
||||
le32toh(rxphy->ack),
|
||||
le32toh(rxphy->cts),
|
||||
le32toh(rxphy->ba_resp),
|
||||
le32toh(rxphy->dsp_kill),
|
||||
le32toh(rxphy->bad_mh),
|
||||
le32toh(rxphy->rssi_sum));
|
||||
}
|
||||
|
||||
static void
|
||||
iwn_stats_rx_general_print(struct iwnstats *is, struct iwn_rx_general_stats *g)
|
||||
{
|
||||
|
||||
printf("%s: bad_cts=%d, bad_ack=%d, not_bss=%d, filtered=%d, bad_chan=%d, beacons=%d\n",
|
||||
__func__,
|
||||
le32toh(g->bad_cts),
|
||||
le32toh(g->bad_ack),
|
||||
le32toh(g->not_bss),
|
||||
le32toh(g->filtered),
|
||||
le32toh(g->bad_chan),
|
||||
le32toh(g->beacons));
|
||||
|
||||
/* XXX it'd be nice to have adc/ina saturated as a % of time */
|
||||
printf("%s: missed_beacons=%d, adc_saturated=%d, ina_searched=%d\n",
|
||||
__func__,
|
||||
le32toh(g->missed_beacons),
|
||||
le32toh(g->adc_saturated),
|
||||
le32toh(g->ina_searched));
|
||||
|
||||
printf("%s: noise=[%d, %d, %d] flags=0x%08x, load=%d, fa=%d\n",
|
||||
__func__,
|
||||
le32toh(g->noise[0]),
|
||||
le32toh(g->noise[1]),
|
||||
le32toh(g->noise[2]),
|
||||
le32toh(g->flags),
|
||||
le32toh(g->load),
|
||||
le32toh(g->fa));
|
||||
|
||||
printf("%s: rssi=[%d, %d, %d] energy=[%d %d %d]\n",
|
||||
__func__,
|
||||
le32toh(g->rssi[0]),
|
||||
le32toh(g->rssi[1]),
|
||||
le32toh(g->rssi[2]),
|
||||
le32toh(g->energy[0]),
|
||||
le32toh(g->energy[1]),
|
||||
le32toh(g->energy[2]));
|
||||
}
|
||||
|
||||
static void
|
||||
iwn_stats_tx_print(struct iwnstats *is, struct iwn_tx_stats *tx)
|
||||
{
|
||||
|
||||
printf("%s: preamble=%d, rx_detected=%d, bt_defer=%d, bt_kill=%d, short_len=%d\n",
|
||||
__func__,
|
||||
le32toh(tx->preamble),
|
||||
le32toh(tx->rx_detected),
|
||||
le32toh(tx->bt_defer),
|
||||
le32toh(tx->bt_kill),
|
||||
le32toh(tx->short_len));
|
||||
|
||||
printf("%s: cts_timeout=%d, ack_timeout=%d, exp_ack=%d, ack=%d, msdu=%d\n",
|
||||
__func__,
|
||||
le32toh(tx->cts_timeout),
|
||||
le32toh(tx->ack_timeout),
|
||||
le32toh(tx->exp_ack),
|
||||
le32toh(tx->ack),
|
||||
le32toh(tx->msdu));
|
||||
|
||||
printf("%s: burst_err1=%d, burst_err2=%d, cts_collision=%d, ack_collision=%d\n",
|
||||
__func__,
|
||||
le32toh(tx->burst_err1),
|
||||
le32toh(tx->burst_err2),
|
||||
le32toh(tx->cts_collision),
|
||||
le32toh(tx->ack_collision));
|
||||
|
||||
printf("%s: ba_timeout=%d, ba_resched=%d, query_ampdu=%d, query=%d, query_ampdu_frag=%d\n",
|
||||
__func__,
|
||||
le32toh(tx->ba_timeout),
|
||||
le32toh(tx->ba_resched),
|
||||
le32toh(tx->query_ampdu),
|
||||
le32toh(tx->query),
|
||||
le32toh(tx->query_ampdu_frag));
|
||||
|
||||
printf("%s: query_mismatch=%d, not_ready=%d, underrun=%d, bt_ht_kill=%d, rx_ba_resp=%d\n",
|
||||
__func__,
|
||||
le32toh(tx->query_mismatch),
|
||||
le32toh(tx->not_ready),
|
||||
le32toh(tx->underrun),
|
||||
le32toh(tx->bt_ht_kill),
|
||||
le32toh(tx->rx_ba_resp));
|
||||
}
|
||||
|
||||
static void
|
||||
iwn_stats_ht_phy_print(struct iwnstats *is, struct iwn_rx_ht_phy_stats *ht)
|
||||
{
|
||||
|
||||
printf("%s: bad_plcp=%d, overrun=%d, eoverrun=%d, good_crc32=%d, bad_crc32=%d\n",
|
||||
__func__,
|
||||
le32toh(ht->bad_plcp),
|
||||
le32toh(ht->overrun),
|
||||
le32toh(ht->eoverrun),
|
||||
le32toh(ht->good_crc32),
|
||||
le32toh(ht->bad_crc32));
|
||||
|
||||
printf("%s: bad_mh=%d, good_ampdu_crc32=%d, ampdu=%d, fragment=%d\n",
|
||||
__func__,
|
||||
le32toh(ht->bad_plcp),
|
||||
le32toh(ht->good_ampdu_crc32),
|
||||
le32toh(ht->ampdu),
|
||||
le32toh(ht->fragment));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
iwn_stats_general_print(struct iwnstats *is, struct iwn_stats *stats)
|
||||
{
|
||||
|
||||
/* General */
|
||||
printf("%s: temp=%d, temp_m=%d, burst_check=%d, burst=%d, sleep=%d, slot_out=%d, slot_idle=%d\n",
|
||||
__func__,
|
||||
le32toh(stats->general.temp),
|
||||
le32toh(stats->general.temp_m),
|
||||
le32toh(stats->general.burst_check),
|
||||
le32toh(stats->general.burst),
|
||||
le32toh(stats->general.sleep),
|
||||
le32toh(stats->general.slot_out),
|
||||
le32toh(stats->general.slot_idle));
|
||||
printf("%s: slot_out=%d, ttl_tstamp=0x%08x, tx_ant_a=%d, tx_ant_b=%d, exec=%d, probe=%d\n",
|
||||
__func__,
|
||||
le32toh(stats->general.slot_out),
|
||||
le32toh(stats->general.ttl_tstamp),
|
||||
le32toh(stats->general.tx_ant_a),
|
||||
le32toh(stats->general.tx_ant_b),
|
||||
le32toh(stats->general.exec),
|
||||
le32toh(stats->general.probe));
|
||||
printf("%s: rx_enabled=%d\n",
|
||||
__func__,
|
||||
le32toh(stats->general.rx_enabled));
|
||||
}
|
||||
|
||||
static void
|
||||
iwn_print(struct iwnstats *is)
|
||||
{
|
||||
struct iwn_stats *s;
|
||||
|
||||
s = &is->st;
|
||||
|
||||
iwn_stats_general_print(is, s);
|
||||
|
||||
/* RX */
|
||||
iwn_stats_phy_print(is, &s->rx.ofdm, "ofdm");
|
||||
iwn_stats_phy_print(is, &s->rx.cck, "cck");
|
||||
iwn_stats_ht_phy_print(is, &s->rx.ht);
|
||||
iwn_stats_rx_general_print(is, &s->rx.general);
|
||||
|
||||
/* TX */
|
||||
iwn_stats_tx_print(is, &s->tx);
|
||||
printf("--\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
struct iwnstats *is;
|
||||
|
||||
is = iwnstats_new(IWN_DEFAULT_IF);
|
||||
|
||||
if (is == NULL) {
|
||||
fprintf(stderr, "%s: couldn't allocate new stats structure\n",
|
||||
argv[0]);
|
||||
exit(127);
|
||||
}
|
||||
|
||||
/* begin fetching data */
|
||||
while (1) {
|
||||
if (iwn_collect(is) != 0) {
|
||||
fprintf(stderr, "%s: fetch failed\n", argv[0]);
|
||||
goto next;
|
||||
}
|
||||
|
||||
iwn_print(is);
|
||||
|
||||
next:
|
||||
usleep(100 * 1000);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
@ -299,7 +299,7 @@ parse_fingerprint(ucl_object_t *obj)
|
||||
fct = HASH_SHA256;
|
||||
|
||||
if (fct == HASH_UNKNOWN) {
|
||||
warnx("Unsupported hashing function: %s\n", function);
|
||||
warnx("Unsupported hashing function: %s", function);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ DPADD= ${LIBELF} ${LIBKVM} ${LIBPMC} ${LIBM} ${LIBNCURSES}
|
||||
LDADD= -lelf -lkvm -lpmc -lm -lncurses
|
||||
|
||||
SRCS= pmcstat.c pmcstat.h pmcstat_log.c \
|
||||
pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c pmcpl_calltree.c
|
||||
pmcpl_callgraph.c pmcpl_gprof.c pmcpl_annotate.c \
|
||||
pmcpl_annotate_cg.c pmcpl_calltree.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
127
usr.sbin/pmcstat/pmcpl_annotate_cg.c
Normal file
127
usr.sbin/pmcstat/pmcpl_annotate_cg.c
Normal file
@ -0,0 +1,127 @@
|
||||
/*-
|
||||
* Copyright (c) 2005-2007, Joseph Koshy
|
||||
* Copyright (c) 2007 The FreeBSD Foundation
|
||||
* Copyright (c) 2014, Adrian Chadd, Netflix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by A. Joseph Koshy under
|
||||
* sponsorship from the FreeBSD Foundation and Google, Inc.
|
||||
*
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Transform a hwpmc(4) log into human readable form, and into
|
||||
* gprof(1) compatible profiles.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/gmon.h>
|
||||
#include <sys/imgact_aout.h>
|
||||
#include <sys/imgact_elf.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/pmc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gelf.h>
|
||||
#include <libgen.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <pmc.h>
|
||||
#include <pmclog.h>
|
||||
#include <sysexits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pmcstat.h"
|
||||
#include "pmcstat_log.h"
|
||||
#include "pmcpl_annotate_cg.h"
|
||||
|
||||
/*
|
||||
* Record a callchain.
|
||||
*/
|
||||
|
||||
void
|
||||
pmcpl_annotate_cg_process(struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
|
||||
uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu)
|
||||
{
|
||||
struct pmcstat_pcmap *map;
|
||||
struct pmcstat_symbol *sym;
|
||||
uintfptr_t newpc;
|
||||
struct pmcstat_image *image;
|
||||
int i;
|
||||
char filename[PATH_MAX], funcname[PATH_MAX];
|
||||
unsigned sline;
|
||||
|
||||
(void) pmcr; (void) nsamples; (void) usermode; (void) cpu;
|
||||
|
||||
for (i = 0; i < (int) nsamples; i++) {
|
||||
map = NULL;
|
||||
sym = NULL;
|
||||
image = NULL;
|
||||
filename[0] = '\0';
|
||||
funcname[0] = '\0';
|
||||
sline = 0;
|
||||
|
||||
map = pmcstat_process_find_map(usermode ? pp : pmcstat_kernproc, cc[i]);
|
||||
if (map != NULL) {
|
||||
assert(cc[i] >= map->ppm_lowpc && cc[i] < map->ppm_highpc);
|
||||
image = map->ppm_image;
|
||||
newpc = cc[i] - (map->ppm_lowpc +
|
||||
(image->pi_vaddr - image->pi_start));
|
||||
sym = pmcstat_symbol_search(image, newpc);
|
||||
}
|
||||
|
||||
if (map != NULL && image != NULL && sym != NULL) {
|
||||
(void) pmcstat_image_addr2line(image, cc[i],
|
||||
filename, sizeof(filename), &sline, funcname, sizeof(funcname));
|
||||
}
|
||||
|
||||
if (map != NULL && sym != NULL) {
|
||||
fprintf(args.pa_graphfile, "%p %s %s:%d\n",
|
||||
(void *)cc[i],
|
||||
funcname,
|
||||
filename,
|
||||
sline);
|
||||
} else {
|
||||
fprintf(args.pa_graphfile, "%p <unknown> ??:0\n",
|
||||
(void *) cc[i]);
|
||||
}
|
||||
}
|
||||
fprintf(args.pa_graphfile, "--\n");
|
||||
}
|
42
usr.sbin/pmcstat/pmcpl_annotate_cg.h
Normal file
42
usr.sbin/pmcstat/pmcpl_annotate_cg.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*-
|
||||
* Copyright (c) 2005-2007, Joseph Koshy
|
||||
* Copyright (c) 2007 The FreeBSD Foundation
|
||||
* Copyright (c) 2014, Adrian Chadd, Netflix Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by A. Joseph Koshy under
|
||||
* sponsorship from the FreeBSD Foundation and Google, Inc.
|
||||
*
|
||||
* 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _PMCSTAT_PL_ANNOTATE_CG_H_
|
||||
#define _PMCSTAT_PL_ANNOTATE_CG_H_
|
||||
|
||||
/* Function prototypes */
|
||||
void pmcpl_annotate_cg_process(
|
||||
struct pmcstat_process *pp, struct pmcstat_pmcrecord *pmcr,
|
||||
uint32_t nsamples, uintfptr_t *cc, int usermode, uint32_t cpu);
|
||||
|
||||
#endif /* _PMCSTAT_PL_ANNOTATE_CG_H_ */
|
@ -503,6 +503,7 @@ pmcstat_show_usage(void)
|
||||
"\t -S spec\t allocate a system-wide sampling PMC\n"
|
||||
"\t -T\t\t start in top mode\n"
|
||||
"\t -W\t\t (toggle) show counts per context switch\n"
|
||||
"\t -a <file>\t print sampled PCs and callgraph to \"file\"\n"
|
||||
"\t -c cpu-list\t set cpus for subsequent system-wide PMCs\n"
|
||||
"\t -d\t\t (toggle) track descendants\n"
|
||||
"\t -f spec\t pass \"spec\" to as plugin option\n"
|
||||
@ -617,8 +618,14 @@ main(int argc, char **argv)
|
||||
CPU_SET(hcpu, &cpumask);
|
||||
|
||||
while ((option = getopt(argc, argv,
|
||||
"CD:EF:G:M:NO:P:R:S:TWc:df:gk:m:n:o:p:qr:s:t:vw:z:")) != -1)
|
||||
"CD:EF:G:M:NO:P:R:S:TWa:c:df:gk:m:n:o:p:qr:s:t:vw:z:")) != -1)
|
||||
switch (option) {
|
||||
case 'a': /* Annotate + callgraph */
|
||||
args.pa_flags |= FLAG_DO_ANNOTATE;
|
||||
args.pa_plugin = PMCSTAT_PL_ANNOTATE_CG;
|
||||
graphfilename = optarg;
|
||||
break;
|
||||
|
||||
case 'C': /* cumulative values */
|
||||
use_cumulative_counts = !use_cumulative_counts;
|
||||
args.pa_required |= FLAG_HAS_COUNTING_PMCS;
|
||||
@ -917,7 +924,8 @@ main(int argc, char **argv)
|
||||
|
||||
/* -m option is allowed with -R only. */
|
||||
if (args.pa_flags & FLAG_DO_ANNOTATE && args.pa_inputpath == NULL)
|
||||
errx(EX_USAGE, "ERROR: option -m requires an input file");
|
||||
errx(EX_USAGE, "ERROR: option %s requires an input file",
|
||||
args.pa_plugin == PMCSTAT_PL_ANNOTATE ? "-m" : "-a");
|
||||
|
||||
/* -m option is not allowed combined with -g or -G. */
|
||||
if (args.pa_flags & FLAG_DO_ANNOTATE &&
|
||||
|
@ -91,6 +91,7 @@
|
||||
#define PMCSTAT_PL_GPROF 2
|
||||
#define PMCSTAT_PL_ANNOTATE 3
|
||||
#define PMCSTAT_PL_CALLTREE 4
|
||||
#define PMCSTAT_PL_ANNOTATE_CG 5
|
||||
|
||||
#define PMCSTAT_TOP_DELTA 0
|
||||
#define PMCSTAT_TOP_ACCUM 1
|
||||
|
@ -149,6 +149,7 @@ struct pmcstat_process *pmcstat_kernproc; /* kernel 'process' */
|
||||
#include "pmcpl_gprof.h"
|
||||
#include "pmcpl_callgraph.h"
|
||||
#include "pmcpl_annotate.h"
|
||||
#include "pmcpl_annotate_cg.h"
|
||||
#include "pmcpl_calltree.h"
|
||||
|
||||
static struct pmc_plugins {
|
||||
@ -213,6 +214,11 @@ static struct pmc_plugins {
|
||||
.pl_topkeypress = pmcpl_ct_topkeypress,
|
||||
.pl_topdisplay = pmcpl_ct_topdisplay
|
||||
},
|
||||
{
|
||||
.pl_name = "annotate_cg",
|
||||
.pl_process = pmcpl_annotate_cg_process
|
||||
},
|
||||
|
||||
{
|
||||
.pl_name = NULL
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user