Merge from head up to r262472.

This commit is contained in:
Dimitry Andric 2014-02-25 07:40:37 +00:00
commit c3bb517174
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/clang-sparc64/; revision=262473
55 changed files with 3533 additions and 1347 deletions

View File

@ -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 ...

View File

@ -339,7 +339,7 @@ _citrus_prop_read_symbol(struct _memstream * __restrict ms,
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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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/

View File

@ -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 */

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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();

View File

@ -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
View 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

View File

@ -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

View 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);
}

View File

@ -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"

View File

@ -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)

View File

@ -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

View File

@ -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>;

View File

@ -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",

View 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";
};
};

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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),

View 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;
}

View 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__ */

View File

@ -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);

View File

@ -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__ */

View File

@ -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) \

View File

@ -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;

View File

@ -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 */

View 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__ */

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
View File

@ -0,0 +1,5 @@
# $FreeBSD$
SUBDIR= iwnstats
.include <bsd.subdir.mk>

View 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>

View 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);
}

View 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__ */

View 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__ */

View 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);
}

View File

@ -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);
}

View File

@ -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>

View 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");
}

View 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_ */

View File

@ -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 &&

View File

@ -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

View File

@ -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
}